Merge pull request #3307 from donaldsharp/bondo

zebra: Let zebra know about bond and blond slave intf types
This commit is contained in:
Jafar Al-Gharaibeh 2018-11-12 16:51:22 -06:00 committed by GitHub
commit d680337d6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 3 deletions

View File

@ -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; *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; *zif_type = ZEBRA_IF_MACVLAN;
else if (strcmp(kind, "veth") == 0) else if (strcmp(kind, "veth") == 0)
*zif_type = ZEBRA_IF_VETH; *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) \ #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; zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
ifindex_t bridge_ifindex = IFINDEX_INTERNAL; ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
ifindex_t link_ifindex = IFINDEX_INTERNAL; ifindex_t link_ifindex = IFINDEX_INTERNAL;
ifindex_t bond_ifindex = IFINDEX_INTERNAL;
struct zebra_if *zif; struct zebra_if *zif;
zns = zebra_ns_lookup(ns_id); 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]) if (linkinfo[IFLA_INFO_SLAVE_KIND])
slave_kind = RTA_DATA(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. */ /* 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; zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE;
bridge_ifindex = bridge_ifindex =
*(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]); *(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 } else
zif_slave_type = ZEBRA_IF_SLAVE_OTHER; 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); netlink_interface_update_l2info(ifp, linkinfo[IFLA_INFO_DATA], 1);
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
zebra_l2if_update_bridge_slave(ifp, bridge_ifindex); 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; 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_iftype_t zif_type = ZEBRA_IF_OTHER;
zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE; zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
ifindex_t bridge_ifindex = IFINDEX_INTERNAL; ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
ifindex_t bond_ifindex = IFINDEX_INTERNAL;
ifindex_t link_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; zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE;
bridge_ifindex = bridge_ifindex =
*(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]); *(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 } else
zif_slave_type = ZEBRA_IF_SLAVE_OTHER; 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)) if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
zebra_l2if_update_bridge_slave(ifp, zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex); 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) { } else if (ifp->vrf_id != vrf_id) {
/* VRF change for an interface. */ /* VRF change for an interface. */
if (IS_ZEBRA_DEBUG_KERNEL) 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); if_handle_vrf_change(ifp, vrf_id);
} else { } else {
int was_bridge_slave; bool was_bridge_slave, was_bond_slave;
/* Interface update. */ /* Interface update. */
if (IS_ZEBRA_DEBUG_KERNEL) 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 /* Update interface type - NOTE: Only slave_type can
* change. */ * change. */
was_bridge_slave = IS_ZEBRA_IF_BRIDGE_SLAVE(ifp); 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); zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);
netlink_interface_update_hw_addr(tb, ifp); 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) if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
zebra_l2if_update_bridge_slave(ifp, zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex); bridge_ifindex);
else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave)
zebra_l2if_update_bond_slave(ifp, bond_ifindex);
} }
} else { } else {
/* Delete interface notification from kernel */ /* Delete interface notification from kernel */

View File

@ -1150,6 +1150,15 @@ static const char *zebra_ziftype_2str(zebra_iftype_t zif_type)
return "VETH"; return "VETH";
break; break;
case ZEBRA_IF_BOND:
return "bond";
case ZEBRA_IF_BOND_SLAVE:
return "bond_slave";
case ZEBRA_IF_MACVLAN:
return "macvlan";
default: default:
return "Unknown"; return "Unknown";
break; break;
@ -1279,6 +1288,15 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
br_slave->bridge_ifindex); 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) { if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
vty_out(vty, " Link ifindex %u", zebra_if->link_ifindex); vty_out(vty, " Link ifindex %u", zebra_if->link_ifindex);
if (zebra_if->link) if (zebra_if->link)

View File

@ -1,3 +1,4 @@
/* Interface function header. /* Interface function header.
* Copyright (C) 1999 Kunihiro Ishiguro * Copyright (C) 1999 Kunihiro Ishiguro
* *
@ -192,6 +193,8 @@ typedef enum {
ZEBRA_IF_VLAN, /* VLAN sub-interface */ ZEBRA_IF_VLAN, /* VLAN sub-interface */
ZEBRA_IF_MACVLAN, /* MAC VLAN interface*/ ZEBRA_IF_MACVLAN, /* MAC VLAN interface*/
ZEBRA_IF_VETH, /* VETH interface*/ ZEBRA_IF_VETH, /* VETH interface*/
ZEBRA_IF_BOND, /* Bond */
ZEBRA_IF_BOND_SLAVE, /* Bond */
} zebra_iftype_t; } zebra_iftype_t;
/* Zebra "slave" interface type */ /* Zebra "slave" interface type */
@ -199,6 +202,7 @@ typedef enum {
ZEBRA_IF_SLAVE_NONE, /* Not a slave */ ZEBRA_IF_SLAVE_NONE, /* Not a slave */
ZEBRA_IF_SLAVE_VRF, /* Member of a VRF */ ZEBRA_IF_SLAVE_VRF, /* Member of a VRF */
ZEBRA_IF_SLAVE_BRIDGE, /* Member of a bridge */ 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_IF_SLAVE_OTHER, /* Something else - e.g., bond slave */
} zebra_slave_iftype_t; } zebra_slave_iftype_t;
@ -268,6 +272,8 @@ struct zebra_if {
*/ */
struct zebra_l2info_brslave brslave_info; struct zebra_l2info_brslave brslave_info;
struct zebra_l2info_bondslave bondslave_info;
/* Link fields - for sub-interfaces. */ /* Link fields - for sub-interfaces. */
ifindex_t link_ifindex; ifindex_t link_ifindex;
struct interface *link; struct interface *link;
@ -324,6 +330,10 @@ static inline void zebra_if_set_ziftype(struct interface *ifp,
#define IS_ZEBRA_IF_VRF_SLAVE(ifp) \ #define IS_ZEBRA_IF_VRF_SLAVE(ifp) \
(((struct zebra_if *)(ifp->info))->zif_slave_type == ZEBRA_IF_SLAVE_VRF) (((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 void zebra_if_init(void);
extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t); extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t);

View File

@ -99,6 +99,23 @@ void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave)
br_slave->br_if = NULL; 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, * Handle Bridge interface add or update. Update relevant info,
* map slaves (if any) to the bridge. * 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); 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);
}

View File

@ -52,6 +52,11 @@ struct zebra_l2info_vxlan {
vlanid_t access_vlan; /* Access VLAN - for VLAN-aware bridge. */ 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 { union zebra_l2if_info {
struct zebra_l2info_bridge br; struct zebra_l2info_bridge br;
struct zebra_l2info_vlan vl; 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_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave);
extern void extern void
zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave); 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, extern void zebra_l2_bridge_add_update(struct interface *ifp,
struct zebra_l2info_bridge *bridge_info, struct zebra_l2info_bridge *bridge_info,
int add); 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, extern void zebra_l2if_update_bridge_slave(struct interface *ifp,
ifindex_t bridge_ifindex); ifindex_t bridge_ifindex);
extern void zebra_l2if_update_bond_slave(struct interface *ifp,
ifindex_t bond_ifindex);
#endif /* _ZEBRA_L2_H */ #endif /* _ZEBRA_L2_H */