DESC_ENTRY(ZEBRA_INTERFACE_ADDRESS_DELETE),
DESC_ENTRY(ZEBRA_INTERFACE_UP),
DESC_ENTRY(ZEBRA_INTERFACE_DOWN),
+ DESC_ENTRY(ZEBRA_INTERFACE_SET_MASTER),
DESC_ENTRY(ZEBRA_IPV4_ROUTE_ADD),
DESC_ENTRY(ZEBRA_IPV4_ROUTE_DELETE),
DESC_ENTRY(ZEBRA_IPV6_ROUTE_ADD),
/* it seems that path is unix socket */
zclient_serv_path = path;
}
+
+void zclient_interface_set_master(struct zclient *client,
+ struct interface *master,
+ struct interface *slave)
+{
+ struct stream *s;
+
+ s = client->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
+
+ stream_putw(s, master->vrf_id);
+ stream_putl(s, master->ifindex);
+ stream_putw(s, slave->vrf_id);
+ stream_putl(s, slave->ifindex);
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+ zclient_send_message(client);
+}
ZEBRA_INTERFACE_ADDRESS_DELETE,
ZEBRA_INTERFACE_UP,
ZEBRA_INTERFACE_DOWN,
+ ZEBRA_INTERFACE_SET_MASTER,
ZEBRA_IPV4_ROUTE_ADD,
ZEBRA_IPV4_ROUTE_DELETE,
ZEBRA_IPV6_ROUTE_ADD,
u_char *marker, u_char *version,
vrf_id_t *vrf_id, u_int16_t *cmd);
+extern void zclient_interface_set_master(struct zclient *client,
+ struct interface *master,
+ struct interface *slave);
extern struct interface *zebra_interface_add_read(struct stream *, vrf_id_t);
extern struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t);
extern struct connected *zebra_interface_address_read(int, struct stream *,
if (PIM_DEBUG_ZEBRA) {
zlog_debug(
- "%s: %s index %d flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
(long)ifp->flags, ifp->metric, ifp->mtu,
if_is_operative(ifp));
}
if (PIM_DEBUG_ZEBRA) {
zlog_debug(
- "%s: %s index %d flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
(long)ifp->flags, ifp->metric, ifp->mtu,
if_is_operative(ifp));
}
zebra_size_t length, vrf_id_t vrf_id)
{
struct interface *ifp;
+ uint32_t table_id;
/*
zebra api notifies interface up/down events by using the same call
if (PIM_DEBUG_ZEBRA) {
zlog_debug(
- "%s: %s index %d flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
(long)ifp->flags, ifp->metric, ifp->mtu,
if_is_operative(ifp));
}
pim_if_addr_add_all(ifp);
}
+ /*
+ * If we have a pimreg device callback and it's for a specific
+ * table set the master appropriately
+ */
+ if (sscanf(ifp->name, "pimreg%d", &table_id) == 1) {
+ struct vrf *vrf;
+ RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
+ {
+ if ((table_id == vrf->data.l.table_id)
+ && (ifp->vrf_id != vrf->vrf_id)) {
+ struct interface *master = if_lookup_by_name(
+ vrf->name, vrf->vrf_id);
+ zclient_interface_set_master(zclient, master,
+ ifp);
+ }
+ }
+ }
return 0;
}
if (PIM_DEBUG_ZEBRA) {
zlog_debug(
- "%s: %s index %d flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
(long)ifp->flags, ifp->metric, ifp->mtu,
if_is_operative(ifp));
}
if (PIM_DEBUG_ZEBRA) {
char buf[BUFSIZ];
prefix2str(p, buf, BUFSIZ);
- zlog_debug("%s: %s connected IP address %s flags %u %s",
- __PRETTY_FUNCTION__, c->ifp->name, buf, c->flags,
- CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
- ? "secondary"
- : "primary");
+ zlog_debug("%s: %s(%d) connected IP address %s flags %u %s",
+ __PRETTY_FUNCTION__, c->ifp->name, vrf_id, buf,
+ c->flags, CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
+ ? "secondary"
+ : "primary");
#ifdef PIM_DEBUG_IFADDR_DUMP
dump_if_address(c->ifp);
char buf[BUFSIZ];
prefix2str(p, buf, BUFSIZ);
zlog_debug(
- "%s: %s disconnected IP address %s flags %u %s",
- __PRETTY_FUNCTION__, c->ifp->name, buf,
+ "%s: %s(%d) disconnected IP address %s flags %u %s",
+ __PRETTY_FUNCTION__, c->ifp->name, vrf_id, buf,
c->flags,
CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
? "secondary"
return 0;
}
+int kernel_interface_set_master(struct interface *master,
+ struct interface *slave)
+{
+ 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 = slave->ifindex;
+
+ addattr_l(&req.n, sizeof req, IFLA_MASTER, &master->ifindex, 4);
+ addattr_l(&req.n, sizeof req, IFLA_LINK, &slave->ifindex, 4);
+
+ return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
+ 0);
+}
+
/* Interface address modification. */
static int netlink_address(int cmd, int family, struct interface *ifp,
struct connected *ifc)
extern int kernel_address_add_ipv4(struct interface *, struct connected *);
extern int kernel_address_delete_ipv4(struct interface *, struct connected *);
extern int kernel_neigh_update(int, int, uint32_t, char *, int);
-
+extern int kernel_interface_set_master(struct interface *master,
+ struct interface *slave);
extern int kernel_add_lsp(zebra_lsp_t *);
extern int kernel_upd_lsp(zebra_lsp_t *);
extern int kernel_del_lsp(zebra_lsp_t *);
struct zebra_ns *zns = zvrf->zns;
mroute = mr;
- suc = netlink_request(RTNL_FAMILY_IPMR, RTM_GETROUTE,
- &zns->netlink_cmd);
+ suc = netlink_request_route(zns, RTNL_FAMILY_IPMR, RTM_GETROUTE);
if (suc < 0)
return suc;
{
return 0;
}
+
+extern int kernel_interface_set_master(struct interface *master,
+ struct interface *slave)
+{
+ return 0;
+}
#include "zebra/zebra_mroute.h"
#include "zebra/label_manager.h"
#include "zebra/zebra_vxlan.h"
+#include "zebra/rt.h"
/* Event list of zebra. */
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
zebra_vrf_update_all(client);
}
+static int zread_interface_set_master(struct zserv *client, int sock,
+ u_short length)
+{
+ struct interface *master;
+ struct interface *slave;
+ struct stream *s = client->ibuf;
+ int ifindex;
+ vrf_id_t vrf_id;
+
+ vrf_id = stream_getw(s);
+ ifindex = stream_getl(s);
+ master = if_lookup_by_index(ifindex, vrf_id);
+
+ vrf_id = stream_getw(s);
+ ifindex = stream_getl(s);
+ slave = if_lookup_by_index(ifindex, vrf_id);
+
+ if (!master || !slave)
+ return 0;
+
+ kernel_interface_set_master(master, slave);
+
+ return 1;
+}
+
/* Handler of zebra service request. */
static int zebra_client_read(struct thread *thread)
{
break;
case ZEBRA_REMOTE_MACIP_DEL:
zebra_vxlan_remote_macip_del(client, sock, length, zvrf);
+ case ZEBRA_INTERFACE_SET_MASTER:
+ zread_interface_set_master(client, sock, length);
break;
default:
zlog_info("Zebra received unknown command %d", command);