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)
{
ZEBRA_INTERFACE_UP,
ZEBRA_INTERFACE_DOWN,
ZEBRA_INTERFACE_SET_MASTER,
+ ZEBRA_INTERFACE_SET_PROTODOWN,
ZEBRA_ROUTE_ADD,
ZEBRA_ROUTE_DELETE,
ZEBRA_ROUTE_NOTIFY_OWNER,
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,
/* Enable ND Router Advertisements */
if (r->family == AF_INET6)
vrrp_zebra_radv_set(r, true);
+
+ vrrp_zclient_send_interface_protodown(r->mvl_ifp, false);
}
/*
/* Disable ND Router Advertisements */
if (r->family == AF_INET6)
vrrp_zebra_radv_set(r, false);
+
+ vrrp_zclient_send_interface_protodown(r->mvl_ifp, true);
}
/*
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 */
#ifndef __VRRP_ZEBRA_H__
#define __VRRP_ZEBRA_H__
+#include <zebra.h>
+
+#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__ */
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)
{
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
#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"
}
}
-
+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)
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);
{
}
+/*
+ * 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)
{
[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,