From 2ee43c873eab781bdb7b226ebb0f8a7df32b214e Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 11 Jan 2024 11:24:20 +0100 Subject: [PATCH 1/4] lib,zebra: add zapi message to control noarp flag Add a ZAPI message to control the setting of the IFF_NOARP flag. Signed-off-by: Louis Scalbert --- lib/zclient.c | 18 ++++++++++++++++++ lib/zclient.h | 4 ++++ zebra/interface.c | 21 +++++++++++++++++++++ zebra/interface.h | 1 + zebra/zapi_msg.c | 23 +++++++++++++++++++++++ 5 files changed, 67 insertions(+) diff --git a/lib/zclient.c b/lib/zclient.c index 25c6e2b8e559..51ebb5627557 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -4520,6 +4520,24 @@ static void zclient_event(enum zclient_event event, struct zclient *zclient) } } +enum zclient_send_status zclient_interface_set_arp(struct zclient *client, + struct interface *ifp, + bool arp_enable) +{ + struct stream *s; + + s = client->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_INTERFACE_SET_ARP, ifp->vrf->vrf_id); + + stream_putl(s, ifp->ifindex); + stream_putc(s, arp_enable); + + stream_putw_at(s, 0, stream_get_endp(s)); + return zclient_send_message(client); +} + enum zclient_send_status zclient_interface_set_master(struct zclient *client, struct interface *master, struct interface *slave) diff --git a/lib/zclient.h b/lib/zclient.h index 3027c2c37846..1bf91064e2d0 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -98,6 +98,7 @@ typedef enum { ZEBRA_INTERFACE_UP, ZEBRA_INTERFACE_DOWN, ZEBRA_INTERFACE_SET_MASTER, + ZEBRA_INTERFACE_SET_ARP, ZEBRA_INTERFACE_SET_PROTODOWN, ZEBRA_ROUTE_ADD, ZEBRA_ROUTE_DELETE, @@ -1036,6 +1037,9 @@ extern int zclient_read_header(struct stream *s, int sock, uint16_t *size, */ extern bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr); +extern enum zclient_send_status zclient_interface_set_arp(struct zclient *client, + struct interface *ifp, + bool arp_enable); extern enum zclient_send_status zclient_interface_set_master(struct zclient *client, struct interface *master, struct interface *slave); diff --git a/zebra/interface.c b/zebra/interface.c index 4c6fc8c36aee..9be4b469e7cc 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -3662,6 +3662,27 @@ DEFUN (show_interface_desc_vrf_all, return CMD_SUCCESS; } +void if_arp(struct interface *ifp, bool enable) +{ + int ret; + + if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) + return; + + if (enable) + ret = if_unset_flags(ifp, IFF_NOARP); + else + ret = if_set_flags(ifp, IFF_NOARP); + + if (ret < 0) { + zlog_debug("Can't %sset noarp flag on interface %s", + enable ? "" : "un", ifp->name); + return; + } + + if_refresh(ifp); +} + int if_multicast_set(struct interface *ifp) { struct zebra_if *if_data; diff --git a/zebra/interface.h b/zebra/interface.h index 62de2abc8031..a96f2ec7188d 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -314,6 +314,7 @@ extern int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix, extern int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix); extern int if_shutdown(struct interface *ifp); extern int if_no_shutdown(struct interface *ifp); +extern void if_arp(struct interface *ifp, bool enable); extern int if_multicast_set(struct interface *ifp); extern int if_multicast_unset(struct interface *ifp); extern int if_linkdetect(struct interface *ifp, bool detect); diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 296bf12bb5c5..76cabd1bf09b 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3124,6 +3124,28 @@ static void zread_interface_set_master(ZAPI_HANDLER_ARGS) } +static void zread_interface_set_arp(ZAPI_HANDLER_ARGS) +{ + struct stream *s = msg; + struct interface *ifp; + bool arp_enable; + vrf_id_t vrf_id = zvrf->vrf->vrf_id; + int ifindex; + + STREAM_GETL(s, ifindex); + STREAM_GETC(s, arp_enable); + ifp = if_lookup_by_index(ifindex, vrf_id); + + if (!ifp) + return; + + if_arp(ifp, arp_enable); + +stream_failure: + return; +} + + static void zread_vrf_label(ZAPI_HANDLER_ARGS) { struct interface *ifp; @@ -3905,6 +3927,7 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_REMOTE_MACIP_DEL] = zebra_vxlan_remote_macip_del, [ZEBRA_DUPLICATE_ADDR_DETECTION] = zebra_vxlan_dup_addr_detection, [ZEBRA_INTERFACE_SET_MASTER] = zread_interface_set_master, + [ZEBRA_INTERFACE_SET_ARP] = zread_interface_set_arp, [ZEBRA_PW_ADD] = zread_pseudowire, [ZEBRA_PW_DELETE] = zread_pseudowire, [ZEBRA_PW_SET] = zread_pseudowire, From bdbea51c98171c0c41bf9e93ed29e6e20a75ae49 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 11 Jan 2024 11:25:36 +0100 Subject: [PATCH 2/4] nhrpd: unset noarp flag using a zapi message Unset the IFF_NOARP interface flag using a ZAPI message. It removes the dependency to if.h headers. Signed-off-by: Louis Scalbert --- nhrpd/linux.c | 21 --------------------- nhrpd/nhrp_interface.c | 1 + nhrpd/nhrp_route.c | 6 ++++++ nhrpd/nhrpd.h | 1 + 4 files changed, 8 insertions(+), 21 deletions(-) diff --git a/nhrpd/linux.c b/nhrpd/linux.c index b25df9ff2fd2..e4df0dd9640d 100644 --- a/nhrpd/linux.c +++ b/nhrpd/linux.c @@ -8,7 +8,6 @@ #include #include #include -#include #include "nhrp_protocol.h" #include "os.h" @@ -98,25 +97,6 @@ int os_recvmsg(uint8_t *buf, size_t *len, int *ifindex, uint8_t *addr, return 0; } -static int linux_configure_arp(const char *iface, int on) -{ - struct ifreq ifr; - - strlcpy(ifr.ifr_name, iface, IFNAMSIZ); - if (ioctl(nhrp_socket_fd, SIOCGIFFLAGS, &ifr)) - return -1; - - if (on) - ifr.ifr_flags &= ~IFF_NOARP; - else - ifr.ifr_flags |= IFF_NOARP; - - if (ioctl(nhrp_socket_fd, SIOCSIFFLAGS, &ifr)) - return -1; - - return 0; -} - static int linux_icmp_redirect_off(const char *iface) { char fname[PATH_MAX]; @@ -144,7 +124,6 @@ int os_configure_dmvpn(unsigned int ifindex, const char *ifname, int af) ret |= linux_icmp_redirect_off(ifname); break; } - ret |= linux_configure_arp(ifname, 1); return ret; } diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index b82743f001f9..7d0ab9762f71 100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c @@ -351,6 +351,7 @@ void nhrp_interface_update(struct interface *ifp) if (!if_ad->configured) { os_configure_dmvpn(ifp->ifindex, ifp->name, afi2family(afi)); + nhrp_interface_update_arp(ifp, true); nhrp_send_zebra_configure_arp(ifp, afi2family(afi)); if_ad->configured = 1; nhrp_interface_update_address(ifp, afi, 1); diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index c05a8a3ba25d..fd9090bd6e74 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -452,6 +452,12 @@ int nhrp_send_zebra_gre_request(struct interface *ifp) return zclient_send_zebra_gre_request(zclient, ifp); } +void nhrp_interface_update_arp(struct interface *ifp, bool arp_enable) +{ + zclient_interface_set_arp(zclient, ifp, arp_enable); +} + + void nhrp_zebra_terminate(void) { zclient_register_neigh(zclient, VRF_DEFAULT, AFI_IP, false); diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h index 1421f0fc387a..50653c784acc 100644 --- a/nhrpd/nhrpd.h +++ b/nhrpd/nhrpd.h @@ -362,6 +362,7 @@ int sock_open_unix(const char *path); void nhrp_interface_init(void); void nhrp_interface_update(struct interface *ifp); +void nhrp_interface_update_arp(struct interface *ifp, bool arp_enable); void nhrp_interface_update_mtu(struct interface *ifp, afi_t afi); void nhrp_interface_update_nbma(struct interface *ifp, struct nhrp_gre_info *gre_info); From 3cd1c34cb79144413fe6c049e551481cfbf06ca2 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 11 Jan 2024 11:17:54 +0100 Subject: [PATCH 3/4] topotests: nhrp_topo, test absence of noarp flag Test the absence the NOARP flag on rX-gre0 interfaces. It is present by default. Signed-off-by: Louis Scalbert --- tests/topotests/nhrp_topo/test_nhrp_topo.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/topotests/nhrp_topo/test_nhrp_topo.py b/tests/topotests/nhrp_topo/test_nhrp_topo.py index 78b82eda79b2..26115de2b866 100644 --- a/tests/topotests/nhrp_topo/test_nhrp_topo.py +++ b/tests/topotests/nhrp_topo/test_nhrp_topo.py @@ -182,6 +182,27 @@ def test_protocols_convergence(): assertmsg = '"{}" JSON output mismatches'.format(router.name) assert result is None, assertmsg + # check that the NOARP flag is removed from rX-gre0 interfaces + for rname, router in router_list.items(): + if rname == "r3": + continue + + expected = { + "{}-gre0".format(rname): { + "flags": "", + } + } + test_func = partial( + topotest.router_json_cmp, + router, + "show interface {}-gre0 json".format(rname), + expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + + assertmsg = '"{}-gre0 interface flags incorrect'.format(router.name) + assert result is None, assertmsg + for rname, router in router_list.items(): if rname == "r3": continue From 6a44127597d05a7f8ea4d544ee90bcafa97adda0 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 11 Jan 2024 11:38:11 +0100 Subject: [PATCH 4/4] nhrpd: remove netlink_configure_arp declaration Remove the unused netlink_configure_arp() declaration. Signed-off-by: Louis Scalbert --- nhrpd/netlink.h | 1 - 1 file changed, 1 deletion(-) diff --git a/nhrpd/netlink.h b/nhrpd/netlink.h index 7a3029b6c133..33af1a02c1f6 100644 --- a/nhrpd/netlink.h +++ b/nhrpd/netlink.h @@ -11,7 +11,6 @@ extern int netlink_nflog_group; extern int netlink_mcast_nflog_group; -int netlink_configure_arp(unsigned int ifindex, int pf); void netlink_update_binding(struct interface *ifp, union sockunion *proto, union sockunion *nbma); void netlink_set_nflog_group(int nlgroup);