Add support for unicast compose_nd_ns that allows the caller to
specify if the packet should be created as multicast or unicast
to specified address.

Signed-off-by: Ales Musil <[email protected]>
---
Note: This is planned to be used by OVN for MAC binding refresh,
as that it would be nice if this could be backported.
---
 lib/packets.c                | 16 ++++++++++------
 lib/packets.h                |  1 +
 ofproto/ofproto-dpif-xlate.c |  2 +-
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/lib/packets.c b/lib/packets.c
index 998a73afe..fc4bc6c7f 100644
--- a/lib/packets.c
+++ b/lib/packets.c
@@ -1869,19 +1869,23 @@ compose_ipv6(struct dp_packet *packet, uint8_t proto,
 /* Compose an IPv6 Neighbor Discovery Neighbor Solicitation message. */
 void
 compose_nd_ns(struct dp_packet *b, const struct eth_addr eth_src,
+              const struct eth_addr eth_dst, bool multicast,
               const struct in6_addr *ipv6_src, const struct in6_addr *ipv6_dst)
 {
-    struct in6_addr sn_addr;
-    struct eth_addr eth_dst;
     struct ovs_nd_msg *ns;
     struct ovs_nd_lla_opt *lla_opt;
     uint32_t icmp_csum;
 
-    in6_addr_solicited_node(&sn_addr, ipv6_dst);
-    ipv6_multicast_to_ethernet(&eth_dst, &sn_addr);
+    struct in6_addr ipv6_dst_ = *ipv6_dst;
+    struct eth_addr eth_dst_ = eth_dst;
 
-    eth_compose(b, eth_dst, eth_src, ETH_TYPE_IPV6, IPV6_HEADER_LEN);
-    ns = compose_ipv6(b, IPPROTO_ICMPV6, ipv6_src, &sn_addr,
+    if (multicast) {
+        in6_addr_solicited_node(&ipv6_dst_, ipv6_dst);
+        ipv6_multicast_to_ethernet(&eth_dst_, &ipv6_dst_);
+    }
+
+    eth_compose(b, eth_dst_, eth_src, ETH_TYPE_IPV6, IPV6_HEADER_LEN);
+    ns = compose_ipv6(b, IPPROTO_ICMPV6, ipv6_src, &ipv6_dst_,
                       0, 0, 255, ND_MSG_LEN + ND_LLA_OPT_LEN);
 
     ns->icmph.icmp6_type = ND_NEIGHBOR_SOLICIT;
diff --git a/lib/packets.h b/lib/packets.h
index 4d680412a..28aefae52 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -1674,6 +1674,7 @@ void compose_arp(struct dp_packet *, uint16_t arp_op,
                  const struct eth_addr arp_tha, bool broadcast,
                  ovs_be32 arp_spa, ovs_be32 arp_tpa);
 void compose_nd_ns(struct dp_packet *, const struct eth_addr eth_src,
+                   const struct eth_addr eth_dst, bool multicast,
                    const struct in6_addr *ipv6_src,
                    const struct in6_addr *ipv6_dst);
 void compose_nd_na(struct dp_packet *, const struct eth_addr eth_src,
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index c1ba447e9..8e94df9c5 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -3761,7 +3761,7 @@ tnl_send_nd_request(struct xlate_ctx *ctx, const struct 
xport *out_dev,
     struct dp_packet packet;
 
     dp_packet_init(&packet, 0);
-    compose_nd_ns(&packet, eth_src, ipv6_src, ipv6_dst);
+    compose_nd_ns(&packet, eth_src, eth_addr_zero, true, ipv6_src, ipv6_dst);
     compose_table_xlate(ctx, out_dev, &packet);
     dp_packet_uninit(&packet);
 }
-- 
2.54.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to