From: Quentin Young Date: Tue, 5 Feb 2019 22:02:40 +0000 (+0000) Subject: vrrpd: protodown macvlan in backup state X-Git-Tag: base_7.2~330^2~103 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=c3bd894e4d2395d2bc72b0d7a94984f04e93adb1;p=matthieu%2Ffrr.git vrrpd: protodown macvlan in backup state Signed-off-by: Quentin Young --- diff --git a/lib/zclient.c b/lib/zclient.c index 96a78efad6..6647a1ab18 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -555,6 +555,25 @@ void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id, zclient_send_message(zclient); } +int zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id, + struct interface *ifp, bool down) +{ + struct stream *s; + + if (zclient->sock < 0) + return -1; + + s = zclient->obuf; + stream_reset(s); + zclient_create_header(s, ZEBRA_INTERFACE_SET_PROTODOWN, vrf_id); + stream_putl(s, ifp->ifindex); + stream_putc(s, !!down); + stream_putw_at(s, 0, stream_get_endp(s)); + zclient_send_message(zclient); + + return 0; +} + /* Make connection to zebra daemon. */ int zclient_start(struct zclient *zclient) { diff --git a/lib/zclient.h b/lib/zclient.h index c46d63bfab..09f0acad84 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -76,6 +76,7 @@ typedef enum { ZEBRA_INTERFACE_UP, ZEBRA_INTERFACE_DOWN, ZEBRA_INTERFACE_SET_MASTER, + ZEBRA_INTERFACE_SET_PROTODOWN, ZEBRA_ROUTE_ADD, ZEBRA_ROUTE_DELETE, ZEBRA_ROUTE_NOTIFY_OWNER, @@ -466,6 +467,9 @@ extern void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id, struct interface *ifp, int enable, int ra_interval); +extern int zclient_send_interface_protodown(struct zclient *zclient, + vrf_id_t vrf_id, + struct interface *ifp, bool down); /* Send redistribute command to zebra daemon. Do not update zclient state. */ extern int zebra_redistribute_send(int command, struct zclient *, afi_t, diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index e5018d5853..76f8dfea5d 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -1028,6 +1028,8 @@ static void vrrp_change_state_master(struct vrrp_router *r) /* Enable ND Router Advertisements */ if (r->family == AF_INET6) vrrp_zebra_radv_set(r, true); + + vrrp_zclient_send_interface_protodown(r->mvl_ifp, false); } /* @@ -1041,6 +1043,8 @@ static void vrrp_change_state_backup(struct vrrp_router *r) /* Disable ND Router Advertisements */ if (r->family == AF_INET6) vrrp_zebra_radv_set(r, false); + + vrrp_zclient_send_interface_protodown(r->mvl_ifp, true); } /* diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c index 1bd5aa013f..c41915cbd9 100644 --- a/vrrpd/vrrp_zebra.c +++ b/vrrpd/vrrp_zebra.c @@ -226,6 +226,12 @@ void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable) enable, VRRP_RADV_INT); } +int vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down) +{ + return zclient_send_interface_protodown(zclient, VRF_DEFAULT, ifp, + down); +} + void vrrp_zebra_init(void) { /* Socket for receiving updates from Zebra daemon */ diff --git a/vrrpd/vrrp_zebra.h b/vrrpd/vrrp_zebra.h index 5e8ff09543..84bcba23c1 100644 --- a/vrrpd/vrrp_zebra.h +++ b/vrrpd/vrrp_zebra.h @@ -20,7 +20,13 @@ #ifndef __VRRP_ZEBRA_H__ #define __VRRP_ZEBRA_H__ +#include + +#include "lib/if.h" + extern void vrrp_zebra_init(void); extern void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable); +extern int vrrp_zclient_send_interface_protodown(struct interface *ifp, + bool down); #endif /* __VRRP_ZEBRA_H__ */ diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index ce0834f190..e7d988cd9f 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -1396,6 +1396,32 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) return 0; } +int netlink_protodown(struct interface *ifp, bool down) +{ + struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); + + struct { + struct nlmsghdr n; + struct ifinfomsg ifa; + char buf[NL_PKT_BUF_SIZE]; + } req; + + memset(&req, 0, sizeof req); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.n.nlmsg_type = RTM_SETLINK; + req.n.nlmsg_pid = zns->netlink_cmd.snl.nl_pid; + + req.ifa.ifi_index = ifp->ifindex; + + addattr_l(&req.n, sizeof req, IFLA_PROTO_DOWN, &down, 4); + addattr_l(&req.n, sizeof req, IFLA_LINK, &ifp->ifindex, 4); + + return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, + 0); +} + /* Interface information read by netlink. */ void interface_list(struct zebra_ns *zns) { diff --git a/zebra/if_netlink.h b/zebra/if_netlink.h index 710fd52558..29fd2aca35 100644 --- a/zebra/if_netlink.h +++ b/zebra/if_netlink.h @@ -32,6 +32,20 @@ extern int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, extern int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup); extern int interface_lookup_netlink(struct zebra_ns *zns); +/* + * Set protodown status of interface. + * + * ifp + * Interface to set protodown on. + * + * down + * If true, set protodown on. If false, set protodown off. + * + * Returns: + * 0 + */ +int netlink_protodown(struct interface *ifp, bool down); + #ifdef __cplusplus } #endif diff --git a/zebra/interface.c b/zebra/interface.c index b0ddcaf8bc..2ed8a82000 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -47,6 +47,7 @@ #include "zebra/irdp.h" #include "zebra/zebra_ptm.h" #include "zebra/rt_netlink.h" +#include "zebra/if_netlink.h" #include "zebra/interface.h" #include "zebra/zebra_vxlan.h" #include "zebra/zebra_errors.h" @@ -1063,7 +1064,10 @@ void zebra_if_update_all_links(void) } } - +void zebra_if_set_protodown(struct interface *ifp, bool down) +{ + netlink_protodown(ifp, down); +} /* Output prefix string to vty. */ static int prefix_vty_out(struct vty *vty, struct prefix *p) diff --git a/zebra/interface.h b/zebra/interface.h index bbb5445cc6..6a3914451a 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -422,6 +422,7 @@ extern void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id); extern void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex, ns_id_t ns_id); extern void zebra_if_update_all_links(void); +extern void zebra_if_set_protodown(struct interface *ifp, bool down); extern void vrf_add_update(struct vrf *vrfp); diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 03b9653ce6..a497331702 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1336,6 +1336,30 @@ static void zread_interface_delete(ZAPI_HANDLER_ARGS) { } +/* + * Handle message requesting interface be set up or down. + */ +static void zread_interface_set_protodown(ZAPI_HANDLER_ARGS) +{ + ifindex_t ifindex; + struct interface *ifp; + char down; + + STREAM_GETL(msg, ifindex); + STREAM_GETC(msg, down); + + /* set ifdown */ + ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ifindex); + zlog_info("Setting interface %s (%u): protodown %s", ifp->name, ifindex, + down ? "on" : "off"); + + zebra_if_set_protodown(ifp, down); + +stream_failure: + return; +} + + void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, const unsigned int nexthop_num) { @@ -2412,6 +2436,7 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_ROUTER_ID_DELETE] = zread_router_id_delete, [ZEBRA_INTERFACE_ADD] = zread_interface_add, [ZEBRA_INTERFACE_DELETE] = zread_interface_delete, + [ZEBRA_INTERFACE_SET_PROTODOWN] = zread_interface_set_protodown, [ZEBRA_ROUTE_ADD] = zread_route_add, [ZEBRA_ROUTE_DELETE] = zread_route_del, [ZEBRA_REDISTRIBUTE_ADD] = zebra_redistribute_add,