Skip to content
Permalink
Browse files

zebra: Let zebra know about bond and blond slave intf types

The interface type can be a bond or a bond slave, add some
code to note this and to display it as part of a show interface
command.

Signed-off-by: Dinesh Dutt <didutt@gmail.com>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
  • Loading branch information...
Dinesh Dutt authored and donaldsharp committed Nov 10, 2018
1 parent 5c5e0c0 commit b9368db98c961678f030e1a27202e89b5e1ef6bf
Showing with 105 additions and 3 deletions.
  1. +28 −3 zebra/if_netlink.c
  2. +18 −0 zebra/interface.c
  3. +10 −0 zebra/interface.h
  4. +38 −0 zebra/zebra_l2.c
  5. +11 −0 zebra/zebra_l2.h
@@ -243,7 +243,8 @@ static enum zebra_link_type netlink_to_zebra_link_type(unsigned int hwt)
}
}

static void netlink_determine_zebra_iftype(char *kind, zebra_iftype_t *zif_type)
static void netlink_determine_zebra_iftype(const char *kind,
zebra_iftype_t *zif_type)
{
*zif_type = ZEBRA_IF_OTHER;

@@ -262,6 +263,10 @@ static void netlink_determine_zebra_iftype(char *kind, zebra_iftype_t *zif_type)
*zif_type = ZEBRA_IF_MACVLAN;
else if (strcmp(kind, "veth") == 0)
*zif_type = ZEBRA_IF_VETH;
else if (strcmp(kind, "bond") == 0)
*zif_type = ZEBRA_IF_BOND;
else if (strcmp(kind, "bond_slave") == 0)
*zif_type = ZEBRA_IF_BOND_SLAVE;
}

#define parse_rtattr_nested(tb, max, rta) \
@@ -585,6 +590,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
ifindex_t link_ifindex = IFINDEX_INTERNAL;
ifindex_t bond_ifindex = IFINDEX_INTERNAL;
struct zebra_if *zif;

zns = zebra_ns_lookup(ns_id);
@@ -635,7 +641,10 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (linkinfo[IFLA_INFO_SLAVE_KIND])
slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);

netlink_determine_zebra_iftype(kind, &zif_type);
if ((slave_kind != NULL) && strcmp(slave_kind, "bond") == 0)
netlink_determine_zebra_iftype("bond_slave", &zif_type);
else
netlink_determine_zebra_iftype(kind, &zif_type);
}

/* If VRF, create the VRF structure itself. */
@@ -653,6 +662,9 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE;
bridge_ifindex =
*(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]);
} else if (slave_kind && (strcmp(slave_kind, "bond") == 0)) {
zif_slave_type = ZEBRA_IF_SLAVE_BOND;
bond_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]);
} else
zif_slave_type = ZEBRA_IF_SLAVE_OTHER;
}
@@ -700,6 +712,8 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
netlink_interface_update_l2info(ifp, linkinfo[IFLA_INFO_DATA], 1);
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
zebra_l2if_update_bridge_slave(ifp, bridge_ifindex);
else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
zebra_l2if_update_bond_slave(ifp, bond_ifindex);

return 0;
}
@@ -1081,6 +1095,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
zebra_iftype_t zif_type = ZEBRA_IF_OTHER;
zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
ifindex_t bond_ifindex = IFINDEX_INTERNAL;
ifindex_t link_ifindex = IFINDEX_INTERNAL;


@@ -1180,6 +1195,11 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE;
bridge_ifindex =
*(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]);
} else if (slave_kind
&& (strcmp(slave_kind, "bond") == 0)) {
zif_slave_type = ZEBRA_IF_SLAVE_BOND;
bond_ifindex =
*(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]);
} else
zif_slave_type = ZEBRA_IF_SLAVE_OTHER;
}
@@ -1239,6 +1259,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex);
else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
zebra_l2if_update_bond_slave(ifp, bond_ifindex);
} else if (ifp->vrf_id != vrf_id) {
/* VRF change for an interface. */
if (IS_ZEBRA_DEBUG_KERNEL)
@@ -1250,7 +1272,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)

if_handle_vrf_change(ifp, vrf_id);
} else {
int was_bridge_slave;
bool was_bridge_slave, was_bond_slave;

/* Interface update. */
if (IS_ZEBRA_DEBUG_KERNEL)
@@ -1273,6 +1295,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
/* Update interface type - NOTE: Only slave_type can
* change. */
was_bridge_slave = IS_ZEBRA_IF_BRIDGE_SLAVE(ifp);
was_bond_slave = IS_ZEBRA_IF_BOND_SLAVE(ifp);
zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);

netlink_interface_update_hw_addr(tb, ifp);
@@ -1312,6 +1335,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex);
else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave)
zebra_l2if_update_bond_slave(ifp, bond_ifindex);
}
} else {
/* Delete interface notification from kernel */
@@ -1150,6 +1150,15 @@ static const char *zebra_ziftype_2str(zebra_iftype_t zif_type)
return "VETH";
break;

case ZEBRA_IF_BOND:
return "bond";

case ZEBRA_IF_BOND_SLAVE:
return "bond_slave";

case ZEBRA_IF_MACVLAN:
return "macvlan";

default:
return "Unknown";
break;
@@ -1279,6 +1288,15 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
br_slave->bridge_ifindex);
}

if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) {
struct zebra_l2info_bondslave *bond_slave;

bond_slave = &zebra_if->bondslave_info;
if (bond_slave->bond_ifindex != IFINDEX_INTERNAL)
vty_out(vty, " Master (bond) ifindex %u\n",
bond_slave->bond_ifindex);
}

if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
vty_out(vty, " Link ifindex %u", zebra_if->link_ifindex);
if (zebra_if->link)
@@ -1,3 +1,4 @@

/* Interface function header.
* Copyright (C) 1999 Kunihiro Ishiguro
*
@@ -192,13 +193,16 @@ typedef enum {
ZEBRA_IF_VLAN, /* VLAN sub-interface */
ZEBRA_IF_MACVLAN, /* MAC VLAN interface*/
ZEBRA_IF_VETH, /* VETH interface*/
ZEBRA_IF_BOND, /* Bond */
ZEBRA_IF_BOND_SLAVE, /* Bond */
} zebra_iftype_t;

/* Zebra "slave" interface type */
typedef enum {
ZEBRA_IF_SLAVE_NONE, /* Not a slave */
ZEBRA_IF_SLAVE_VRF, /* Member of a VRF */
ZEBRA_IF_SLAVE_BRIDGE, /* Member of a bridge */
ZEBRA_IF_SLAVE_BOND, /* Bond member */
ZEBRA_IF_SLAVE_OTHER, /* Something else - e.g., bond slave */
} zebra_slave_iftype_t;

@@ -268,6 +272,8 @@ struct zebra_if {
*/
struct zebra_l2info_brslave brslave_info;

struct zebra_l2info_bondslave bondslave_info;

/* Link fields - for sub-interfaces. */
ifindex_t link_ifindex;
struct interface *link;
@@ -324,6 +330,10 @@ static inline void zebra_if_set_ziftype(struct interface *ifp,
#define IS_ZEBRA_IF_VRF_SLAVE(ifp) \
(((struct zebra_if *)(ifp->info))->zif_slave_type == ZEBRA_IF_SLAVE_VRF)

#define IS_ZEBRA_IF_BOND_SLAVE(ifp) \
(((struct zebra_if *)(ifp->info))->zif_slave_type \
== ZEBRA_IF_SLAVE_BOND)

extern void zebra_if_init(void);

extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t);
@@ -99,6 +99,23 @@ void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave)
br_slave->br_if = NULL;
}

void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave)
{
struct interface *bond_if;

/* TODO: Handle change of master */
bond_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
bond_slave->bond_ifindex);
if (bond_if)
bond_slave->bond_if = bond_if;
}

void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave)
{
if (bond_slave != NULL)
bond_slave->bond_if = NULL;
}

/*
* Handle Bridge interface add or update. Update relevant info,
* map slaves (if any) to the bridge.
@@ -238,3 +255,24 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
zebra_l2_unmap_slave_from_bridge(&zif->brslave_info);
}
}

void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex)
{
struct zebra_if *zif;
ifindex_t old_bond_ifindex;

zif = ifp->info;
assert(zif);

old_bond_ifindex = zif->bondslave_info.bond_ifindex;
if (old_bond_ifindex == bond_ifindex)
return;

zif->bondslave_info.bond_ifindex = bond_ifindex;

/* Set up or remove link with master */
if (bond_ifindex != IFINDEX_INTERNAL)
zebra_l2_map_slave_to_bond(&zif->bondslave_info);
else if (old_bond_ifindex != IFINDEX_INTERNAL)
zebra_l2_unmap_slave_from_bond(&zif->bondslave_info);
}
@@ -52,6 +52,11 @@ struct zebra_l2info_vxlan {
vlanid_t access_vlan; /* Access VLAN - for VLAN-aware bridge. */
};

struct zebra_l2info_bondslave {
ifindex_t bond_ifindex; /* Bridge Master */
struct interface *bond_if; /* Pointer to master */
};

union zebra_l2if_info {
struct zebra_l2info_bridge br;
struct zebra_l2info_vlan vl;
@@ -70,6 +75,10 @@ union zebra_l2if_info {
extern void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave);
extern void
zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave);
extern void
zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave);
extern void
zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave);
extern void zebra_l2_bridge_add_update(struct interface *ifp,
struct zebra_l2info_bridge *bridge_info,
int add);
@@ -85,4 +94,6 @@ extern void zebra_l2_vxlanif_del(struct interface *ifp);
extern void zebra_l2if_update_bridge_slave(struct interface *ifp,
ifindex_t bridge_ifindex);

extern void zebra_l2if_update_bond_slave(struct interface *ifp,
ifindex_t bond_ifindex);
#endif /* _ZEBRA_L2_H */

0 comments on commit b9368db

Please sign in to comment.
You can’t perform that action at this time.