From b9368db98c961678f030e1a27202e89b5e1ef6bf Mon Sep 17 00:00:00 2001 From: Dinesh Dutt Date: Sat, 10 Nov 2018 15:54:43 -0500 Subject: [PATCH] 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 Signed-off-by: Donald Sharp --- zebra/if_netlink.c | 31 ++++++++++++++++++++++++++++--- zebra/interface.c | 18 ++++++++++++++++++ zebra/interface.h | 10 ++++++++++ zebra/zebra_l2.c | 38 ++++++++++++++++++++++++++++++++++++++ zebra/zebra_l2.h | 11 +++++++++++ 5 files changed, 105 insertions(+), 3 deletions(-) diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 8e459160c..f4bd19356 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -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 */ diff --git a/zebra/interface.c b/zebra/interface.c index afb08f701..76e0a09c1 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -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) diff --git a/zebra/interface.h b/zebra/interface.h index e4c05e8dc..01dd69777 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -1,3 +1,4 @@ + /* Interface function header. * Copyright (C) 1999 Kunihiro Ishiguro * @@ -192,6 +193,8 @@ 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 */ @@ -199,6 +202,7 @@ 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); diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index 529fc48ed..f4b2fe479 100644 --- a/zebra/zebra_l2.c +++ b/zebra/zebra_l2.c @@ -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); +} diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h index db6cb0e53..68c9d4a7a 100644 --- a/zebra/zebra_l2.h +++ b/zebra/zebra_l2.h @@ -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 */ -- 2.39.5