For each lport, adds a priority 90 lflow in ls_in_port_sec and ls_out_port_sec stages to allow ipv6 traffic for - known ipv6 addresses - link local address of the lport - ip6 packet with ip6.src = :: and - ip6.dst=ff00::/8
Signed-off-by: Numan Siddique <nusid...@redhat.com> --- lib/packets.h | 16 ++++++++++++++++ ovn/northd/ovn-northd.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/lib/packets.h b/lib/packets.h index 31a4e92..7c28dfa 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -978,6 +978,22 @@ in6_addr_solicited_node(struct in6_addr *addr, const struct in6_addr *ip6) memcpy(&addr->s6_addr[13], &ip6->s6_addr[13], 3); } +/* + * Generates ipv6 link local address from the given eth addr + * with prefix 'fe80::/64' and stores it in 'lla' + */ +static inline void +in6_generate_lla(struct eth_addr ea, struct in6_addr *lla) +{ + union ovs_16aligned_in6_addr *taddr = (void *) lla; + memset(taddr->be16, 0, sizeof(taddr->be16)); + taddr->be16[0] = htons(0xfe80); + taddr->be16[4] = htons(((ea.ea[0] ^ 0x02) << 8) | ea.ea[1]); + taddr->be16[5] = htons(ea.ea[2] << 8 | 0x00ff); + taddr->be16[6] = htons(0xfe << 8 | ea.ea[3]); + taddr->be16[7] = ea.be16[2]; +} + static inline void ipv6_multicast_to_ethernet(struct eth_addr *eth, const struct in6_addr *ip6) { diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index ca7e02e..7003f10 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -1048,6 +1048,42 @@ build_port_security_ipv4_flow(enum ovn_pipeline pipeline, struct ds *match, ds_put_cstr(match, ")"); } +static void +build_port_security_ipv6_flow( + enum ovn_pipeline pipeline, struct ds *match, struct eth_addr ea, + struct ipv6_netaddr *ipv6_addrs, int n_ipv6_addrs) +{ + char *ip6_addr_field; + if (pipeline == P_IN) { + ip6_addr_field = "ip6.src"; + } + else { + ip6_addr_field = "ip6.dst"; + } + + char ip6_str[INET6_ADDRSTRLEN + 1]; + /* Allow link local address */ + struct in6_addr lla; + in6_generate_lla(ea, &lla); + memset(ip6_str, 0, sizeof(ip6_str)); + ipv6_string_mapped(ip6_str, &lla); + ds_put_format(match, " && ip6 && (%s == %s", ip6_addr_field, ip6_str); + + /* Allow ip6.src=:: and ip6.dst=ff00::/8 for ND packets */ + if (pipeline == P_IN) { + ds_put_cstr(match, " || ip6.src == ::"); + } + else { + ds_put_cstr(match, " || ip6.dst == ff00::/8"); + } + for(int i = 0; i < n_ipv6_addrs; i++) { + memset(ip6_str, 0, sizeof(ip6_str)); + ipv6_string_mapped(ip6_str, &ipv6_addrs[i].addr); + ds_put_format(match, " || %s == %s", ip6_addr_field, ip6_str); + } + ds_put_cstr(match, ")"); +} + /* * Build port security constraints on L2 and L3 address fields and add * logical flows to S_SWITCH_(IN/OUT)_PORT_SEC stage. @@ -1059,8 +1095,7 @@ build_port_security_ipv4_flow(enum ovn_pipeline pipeline, struct ds *match, * known ipv4 addresses. * - Add a priority 90 flow to allow ipv4 packets for known ipv4 addresses * - Add a priority 80 flow to drop arp (for ingress) and ip packets - * - Add a priority 90 flow to allow all ipv6 packets if port security - * has ipv6 address(es). + * - Add a priority 90 flow to allow ipv6 packets for known ipv6 addresses * - Add a priority 80 flow to drop ipv6 packets. * - Add a priority 50 flow to allow all other traffic with the matching * ethernet address. @@ -1158,12 +1193,13 @@ build_port_security(enum ovn_pipeline pipeline, struct ovn_port *op, ds_destroy(&match); if (ps->n_ipv6_addrs) { - /* XXX Need to add port security flows for ipv6. - * For now add a priority 90 flow to allow all ipv6 traffic */ + /* XXX Need to add port security flows for ipv6 ND */ ds_init(&match); - ds_put_format(&match, "%s == %s && %s == "ETH_ADDR_FMT" && ip6", + ds_put_format(&match, "%s == %s && %s == "ETH_ADDR_FMT, port_direction, op->json_key, eth_addr_field, ETH_ADDR_ARGS(ps->ea)); + build_port_security_ipv6_flow(pipeline, &match, ps->ea, + ps->ipv6_addrs, ps->n_ipv6_addrs); ovn_lflow_add(lflows, op->od, stage, 90, ds_cstr(&match), action); ds_destroy(&match); free(ps->ipv6_addrs); -- 2.5.0 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev