Add a method compose_na to compose a NA packet. The ND feature of OVN will base on this.
Signed-off-by: Zong Kai LI <zealo...@gmail.com> --- lib/packets.c | 33 +++++++++++++++++++++++++++++++++ lib/packets.h | 4 ++++ 2 files changed, 37 insertions(+) diff --git a/lib/packets.c b/lib/packets.c index 6a55d6f..cbc086e 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -1355,6 +1355,39 @@ compose_nd(struct dp_packet *b, const struct eth_addr eth_src, ND_MSG_LEN + ND_OPT_LEN)); } +void +compose_na(struct dp_packet *b, + const struct eth_addr eth_src, const struct eth_addr eth_dst, + const struct in6_addr *ipv6_src, const struct in6_addr *ipv6_dst, + ovs_be16 rco_flags) +{ + struct ovs_nd_msg *na; + struct ovs_nd_opt *nd_opt; + uint32_t icmp_csum; + + eth_compose(b, eth_dst, eth_src, ETH_TYPE_IPV6, IPV6_HEADER_LEN); + na = compose_ipv6(b, IPPROTO_ICMPV6, + ALIGNED_CAST(ovs_be32 *, ipv6_src->s6_addr), + ALIGNED_CAST(ovs_be32 *, ipv6_dst->s6_addr), + 0, 0, 255, + ND_MSG_LEN + ND_OPT_LEN); + + na->icmph.icmp6_type = ND_NEIGHBOR_ADVERT; + na->icmph.icmp6_code = 0; + na->rco_flags.hi = rco_flags; + + nd_opt = &na->options[0]; + nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR; + nd_opt->nd_opt_len = 1; + + packet_set_nd(b, ALIGNED_CAST(ovs_be32 *, ipv6_src->s6_addr), + eth_addr_zero, eth_src); + na->icmph.icmp6_cksum = 0; + icmp_csum = packet_csum_pseudoheader6(dp_packet_l3(b)); + na->icmph.icmp6_cksum = csum_finish(csum_continue(icmp_csum, na, + ND_MSG_LEN + ND_OPT_LEN)); +} + uint32_t packet_csum_pseudoheader(const struct ip_header *ip) { diff --git a/lib/packets.h b/lib/packets.h index 5945940..11b3b6d 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1069,6 +1069,10 @@ void compose_arp(struct dp_packet *, uint16_t arp_op, ovs_be32 arp_spa, ovs_be32 arp_tpa); void compose_nd(struct dp_packet *, const struct eth_addr eth_src, struct in6_addr *, struct in6_addr *); +void compose_na(struct dp_packet *, + const struct eth_addr eth_src, const struct eth_addr eth_dst, + const struct in6_addr *, const struct in6_addr *, + ovs_be16 rco_flags); uint32_t packet_csum_pseudoheader(const struct ip_header *); void IP_ECN_set_ce(struct dp_packet *pkt, bool is_ipv6); -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev