From 07dd76be11b9c8d9e93af4d46b295381a792aa0f Mon Sep 17 00:00:00 2001 From: zhangzujian Date: Wed, 30 Oct 2024 07:05:42 +0000 Subject: [PATCH] northd: skip arp/nd request for lrp addresses from localnet ports Signed-off-by: zhangzujian --- northd/northd.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index 409cfd7b81..b8ebe7010e 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -7906,9 +7906,7 @@ build_lswitch_dnat_mod_dl_dst_rules(struct ovn_port *op, if (peer->lrp_networks.n_ipv6_addrs) { for (int i = 0; i < peer->lrp_networks.n_ipv6_addrs; i++) { struct ipv6_netaddr *addrs = &peer->lrp_networks.ipv6_addrs[i]; - if (addrs->plen >= 10 && - (addrs->addr.s6_addr[0] & 0xff) == 0xfe && - (addrs->addr.s6_addr[1] & 0xc0) == 0x80) { + if (in6_is_lla(&addrs->network)) { // skip link local address continue; } @@ -9132,6 +9130,58 @@ build_lswitch_arp_nd_responder_known_ips(struct ovn_port *op, return; } + struct ovn_port *lrp = op->peer; + if (lrp && lrp->nbrp && !lrp->l3dgw_port && + !lrp->nbrp->n_gateway_chassis && !lrp->nbrp->ha_chassis_group && + lsp_is_router(op->nbsp)) { + ovs_be32 lla_ip4; + inet_pton(AF_INET, "169.254.0.0", &lla_ip4); + for (size_t i = 0; i < op->od->n_localnet_ports; i++) { + struct ovn_port *localnet_port = op->od->localnet_ports[i]; + for (size_t j = 0; j < lrp->lrp_networks.n_ipv4_addrs; j++) { + struct ipv4_netaddr *addrs; + addrs = &lrp->lrp_networks.ipv4_addrs[j]; + if (addrs->plen >= 16 && + (addrs->addr & htonl(0xffff0000)) == lla_ip4) { + // skip link local address + continue; + } + ds_clear(match); + ds_put_format(match, + "inport == %s && " + "arp.tpa == %s && arp.op == 1", + localnet_port->json_key, addrs->addr_s); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_ARP_ND_RSP, + 105, ds_cstr(match), + "drop;", op->key, + &op->nbsp->header_, + op->lflow_ref); + } + for (size_t j = 0; j < lrp->lrp_networks.n_ipv6_addrs; j++) { + struct ipv6_netaddr *addrs; + addrs = &lrp->lrp_networks.ipv6_addrs[j]; + if (in6_is_lla(&addrs->network)) { + // skip link local address + continue; + } + ds_clear(match); + ds_put_format(match, + "inport == %s && nd_ns && " + "ip6.dst == {%s, %s} && nd.target == %s", + localnet_port->json_key, + addrs->addr_s, addrs->sn_addr_s, + addrs->addr_s); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_ARP_ND_RSP, + 105, ds_cstr(match), + "drop;", op->key, + &op->nbsp->header_, + op->lflow_ref); + } + } + } + for (size_t i = 0; i < op->n_lsp_addrs; i++) { for (size_t j = 0; j < op->lsp_addrs[i].n_ipv4_addrs; j++) { ds_clear(match);