summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_nht.c45
-rw-r--r--bgpd/bgp_nht.h9
-rw-r--r--bgpd/bgpd.c6
-rw-r--r--doc/developer/building-frr-for-centos6.rst6
-rw-r--r--doc/developer/building-frr-for-ubuntu1804.rst2
-rw-r--r--doc/developer/conf.py2
-rw-r--r--doc/developer/maintainer-release-build.rst4
-rw-r--r--doc/developer/modules.rst6
-rw-r--r--doc/developer/next-hop-tracking.rst2
-rw-r--r--doc/developer/packaging-debian.rst4
-rw-r--r--doc/developer/packaging.rst1
-rw-r--r--doc/developer/process-architecture.rst4
-rw-r--r--doc/user/installation.rst4
-rw-r--r--doc/user/isisd.rst25
-rw-r--r--doc/user/static.rst6
-rw-r--r--doc/user/zebra.rst2
-rw-r--r--zebra/if_netlink.c31
-rw-r--r--zebra/interface.c18
-rw-r--r--zebra/interface.h10
-rw-r--r--zebra/zebra_l2.c38
-rw-r--r--zebra/zebra_l2.h11
-rw-r--r--zebra/zebra_routemap.c41
22 files changed, 229 insertions, 48 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 8aa7798af4..0dce96f432 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -838,3 +838,48 @@ void bgp_nht_register_nexthops(struct bgp *bgp)
}
}
}
+
+void bgp_nht_register_enhe_capability_interfaces(struct peer *peer)
+{
+ struct bgp *bgp;
+ struct bgp_node *rn;
+ struct bgp_nexthop_cache *bnc;
+ struct nexthop *nhop;
+ struct interface *ifp;
+ struct prefix p;
+
+ if (peer->ifp)
+ return;
+
+ bgp = peer->bgp;
+
+ if (!bgp->nexthop_cache_table[AFI_IP6])
+ return;
+
+ if (!sockunion2hostprefix(&peer->su, &p)) {
+ if (BGP_DEBUG(nht, NHT))
+ zlog_debug("%s: Unable to convert prefix to sockunion",
+ __PRETTY_FUNCTION__);
+ return;
+ }
+
+ if (p.family != AF_INET6)
+ return;
+ rn = bgp_node_lookup(bgp->nexthop_cache_table[AFI_IP6], &p);
+
+ bnc = bgp_nexthop_get_node_info(rn);
+ if (!bnc)
+ return;
+
+ if (peer != bnc->nht_info)
+ return;
+
+ for (nhop = bnc->nexthop; nhop; nhop = nhop->next) {
+ ifp = if_lookup_by_index(nhop->ifindex,
+ nhop->vrf_id);
+ zclient_send_interface_radv_req(zclient,
+ nhop->vrf_id,
+ ifp, true,
+ BGP_UNNUM_DEFAULT_RA_INTERVAL);
+ }
+}
diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h
index 96dd915596..7daae93b25 100644
--- a/bgpd/bgp_nht.h
+++ b/bgpd/bgp_nht.h
@@ -88,4 +88,13 @@ extern void path_nh_map(struct bgp_path_info *path,
*/
extern void bgp_nht_register_nexthops(struct bgp *bgp);
+/*
+ * When we have the the PEER_FLAG_CAPABILITY_ENHE flag
+ * set on a peer *after* it has been brought up we need
+ * to notice and setup the interface based RA,
+ * this code can walk the registered nexthops and
+ * register the important ones with zebra for RA.
+ */
+extern void bgp_nht_register_enhe_capability_interfaces(struct peer *peer);
+
#endif /* _BGP_NHT_H */
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 19384eec2f..0c26fa6720 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -3905,6 +3905,9 @@ static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
return 0;
}
+ if (set && flag == PEER_FLAG_CAPABILITY_ENHE)
+ bgp_nht_register_enhe_capability_interfaces(peer);
+
/*
* Update peer-group members, unless they are explicitely overriding
* peer-group configuration.
@@ -3928,6 +3931,9 @@ static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
/* Update flag on peer-group member. */
COND_FLAG(member->flags, flag, set != member_invert);
+ if (set && flag == PEER_FLAG_CAPABILITY_ENHE)
+ bgp_nht_register_enhe_capability_interfaces(member);
+
/* Execute flag action on peer-group member. */
if (action.type == peer_change_reset)
peer_flag_modify_action(member, flag);
diff --git a/doc/developer/building-frr-for-centos6.rst b/doc/developer/building-frr-for-centos6.rst
index 5f9ce705f2..c57573cb9f 100644
--- a/doc/developer/building-frr-for-centos6.rst
+++ b/doc/developer/building-frr-for-centos6.rst
@@ -244,7 +244,7 @@ Load the modifed sysctl's on the system:
Add init.d startup files
^^^^^^^^^^^^^^^^^^^^^^^^
-.. code-block::
+.. code-block:: shell
sudo install -p -m 755 redhat/frr.init /etc/init.d/frr
sudo chkconfig --add frr
@@ -252,13 +252,13 @@ Add init.d startup files
Enable FRR daemon at startup
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. code-block::
+.. code-block:: shell
sudo chkconfig frr on
Start FRR manually (or reboot)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. code-block::
+.. code-block:: shell
sudo /etc/init.d/frr start
diff --git a/doc/developer/building-frr-for-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst
index 2d1edc063d..e69ded8f73 100644
--- a/doc/developer/building-frr-for-ubuntu1804.rst
+++ b/doc/developer/building-frr-for-ubuntu1804.rst
@@ -115,7 +115,7 @@ Create empty FRR configuration files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Although not strictly necessary, it's good practice to create empty
-configuration files _before_ starting FRR. This assures that the permissions
+configuration files _before_ starting FRR. This assures that the permissions
are correct. If the files are not already present, FRR will create them.
It's also important to consider _which_ files to create. FRR supports writing
diff --git a/doc/developer/conf.py b/doc/developer/conf.py
index 61253c4b2f..254c9f6bfc 100644
--- a/doc/developer/conf.py
+++ b/doc/developer/conf.py
@@ -131,7 +131,7 @@ language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
+exclude_patterns = ['_build', 'building-libyang.rst']
# The reST default role (used for this markup: `text`) to use for all
# documents.
diff --git a/doc/developer/maintainer-release-build.rst b/doc/developer/maintainer-release-build.rst
index 907bd14ee6..85aaa5365a 100644
--- a/doc/developer/maintainer-release-build.rst
+++ b/doc/developer/maintainer-release-build.rst
@@ -1,5 +1,5 @@
-Release Build Procedure for FRR maintainers
-=========================================================
+Release Build Procedure for FRR Maintainers
+===========================================
1. Rename branch (if needed)
diff --git a/doc/developer/modules.rst b/doc/developer/modules.rst
index bde7682e4e..99c79462ab 100644
--- a/doc/developer/modules.rst
+++ b/doc/developer/modules.rst
@@ -103,9 +103,9 @@ standard entry point for loadable modules.
Command line parameters
-----------------------
-Command line parameters can be passed directly to a module by appending a
-colon to the module name when loading it, e.g. ``-M mymodule:myparameter``.
-The text after the colon will be accessible in the module's code through
+Command line parameters can be passed directly to a module by appending a
+colon to the module name when loading it, e.g. ``-M mymodule:myparameter``.
+The text after the colon will be accessible in the module's code through
``THIS_MODULE->load_args``. For example, see how the format parameter is
configured in the ``zfpm_init()`` function inside ``zebra_fpm.c``.
diff --git a/doc/developer/next-hop-tracking.rst b/doc/developer/next-hop-tracking.rst
index e6484102a8..a9af5e749c 100644
--- a/doc/developer/next-hop-tracking.rst
+++ b/doc/developer/next-hop-tracking.rst
@@ -269,7 +269,7 @@ RNH table::
O O
/ \
O O
-
+
struct rnh
{
uint8_t flags;
diff --git a/doc/developer/packaging-debian.rst b/doc/developer/packaging-debian.rst
index 4ea784c0fc..c812a38212 100644
--- a/doc/developer/packaging-debian.rst
+++ b/doc/developer/packaging-debian.rst
@@ -1,5 +1,5 @@
-Debian
-======
+Packaging Debian
+================
(Tested on Ubuntu 12.04, 14.04, 16.04, 17.10, 18.04, Debian 8 and 9)
diff --git a/doc/developer/packaging.rst b/doc/developer/packaging.rst
index e9bb3a5409..27e6e155fb 100644
--- a/doc/developer/packaging.rst
+++ b/doc/developer/packaging.rst
@@ -5,4 +5,5 @@ Packaging
.. toctree::
:maxdepth: 2
+ maintainer-release-build
packaging-debian
diff --git a/doc/developer/process-architecture.rst b/doc/developer/process-architecture.rst
index 806afa644c..6e0eb68188 100644
--- a/doc/developer/process-architecture.rst
+++ b/doc/developer/process-architecture.rst
@@ -118,7 +118,7 @@ The following diagram illustrates a simplified version of this infrastructure.
.. todo: replace these with SVG
.. figure:: ../figures/threadmaster-single.png
:align: center
-
+
Lifecycle of a program using a single threadmaster.
The series of "task" boxes represents the current ready task queue. The various
@@ -183,7 +183,7 @@ running their own ``threadmaster``-based event loop.
.. todo: replace these with SVG
.. figure:: ../figures/threadmaster-multiple.png
:align: center
-
+
Lifecycle of a program using multiple pthreads, each running their own
``threadmaster``
diff --git a/doc/user/installation.rst b/doc/user/installation.rst
index 0a8cef53e1..9654cc2eb8 100644
--- a/doc/user/installation.rst
+++ b/doc/user/installation.rst
@@ -385,7 +385,7 @@ Additional kernel modules are also needed to support MPLS forwarding.
appropriate value.
:makevar:`VRF forwarding`
- General information on Linux VRF support can be found in
+ General information on Linux VRF support can be found in
https://www.kernel.org/doc/Documentation/networking/vrf.txt. Kernel
support for VRFs was introduced in 4.3 and improved upon through
4.13, which is the version most used in FRR testing (as of June
@@ -421,7 +421,7 @@ Additional kernel modules are also needed to support MPLS forwarding.
included in future kernel versions so upgrading your kernel may also
address this issue.
-
+
Building
^^^^^^^^
diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst
index ee681858d1..f7607a54f7 100644
--- a/doc/user/isisd.rst
+++ b/doc/user/isisd.rst
@@ -30,14 +30,11 @@ configuration file :file:`isisd.conf`.
ISIS router
===========
-To start ISIS process you have to specify the ISIS router. As of this
+To start the ISIS process you have to specify the ISIS router. As of this
writing, *isisd* does not support multiple ISIS processes.
-.. index:: router isis WORD
-.. clicmd:: router isis WORD
-
-.. index:: no router isis WORD
-.. clicmd:: no router isis WORD
+.. index:: [no] router isis WORD
+.. clicmd:: [no] router isis WORD
Enable or disable the ISIS process by specifying the ISIS domain with
'WORD'. *isisd* does not yet support multiple ISIS processes but you must
@@ -197,17 +194,15 @@ ISIS region
ISIS interface
==============
-.. index:: ip router isis WORD
-.. clicmd:: ip router isis WORD
-
-.. index:: no ip router isis WORD
-.. clicmd:: no ip router isis WORD
-
.. _ip-router-isis-word:
- Activate ISIS adjacency on this interface. Note that the name
- of ISIS instance must be the same as the one used to configure the ISIS process
- (see command :clicmd:`router isis WORD`).
+.. index:: [no] <ip|ipv6> router isis WORD
+.. clicmd:: [no] <ip|ipv6> router isis WORD
+
+ Activate ISIS adjacency on this interface. Note that the name of ISIS
+ instance must be the same as the one used to configure the ISIS process (see
+ command :clicmd:`router isis WORD`). To enable IPv4, issue ``ip router isis
+ WORD``; to enable IPv6, issue ``ipv6 router isis WORD``.
.. index:: isis circuit-type [level-1 | level-1-2 | level-2]
.. clicmd:: isis circuit-type [level-1 | level-1-2 | level-2]
diff --git a/doc/user/static.rst b/doc/user/static.rst
index 6755c809eb..1705b6379e 100644
--- a/doc/user/static.rst
+++ b/doc/user/static.rst
@@ -9,7 +9,7 @@ of static routes.
.. _starting-static:
-Starting STATIC
+Starting STATIC
===============
Default configuration file for *staticd* is :file:`staticd.conf`. The typical
@@ -45,11 +45,11 @@ a static prefix and gateway.
initial form of the command. GATEWAY is gateway for the prefix it currently
must match the v4 or v6 route type specified at the start of the command.
GATEWAY can also be treated as an interface name. If the interface name
- is ``null0`` then zebra installs a blackhole route. TABLENO
+ is ``null0`` then zebra installs a blackhole route. TABLENO
is an optional parameter for namespaces that allows you to create the
route in a specified table associated with the vrf namespace. table will
be rejected if you are not using namespace based vrfs. ``nexthop-vrf``
- allows you to create a leaked route with a nexthop in the specified VRFNAME
+ allows you to create a leaked route with a nexthop in the specified VRFNAME
vrf VRFNAME allows you to create the route in a specified vrf.
``nexthop-vrf`` cannot be currently used with namespace based vrfs
currently as well.
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index 1cfb7953d4..dc2c95cd7a 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -186,7 +186,7 @@ Standard Commands
Enable/disable link-detect on platforms which support this. Currently only
Linux and Solaris, and only where network interface drivers support
reporting link-state via the ``IFF_RUNNING`` flag.
-
+
In FRR, link-detect is on by default.
.. _link-parameters-commands:
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 8e459160c6..f4bd193569 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 afb08f7012..76e0a09c17 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 e4c05e8dc4..01dd697772 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 529fc48edf..f4b2fe4794 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 db6cb0e53a..68c9d4a7a1 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 */
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index bacef49836..c9918a7887 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -1116,15 +1116,15 @@ static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = {
/* Match function should return 1 if match is success else return
zero. */
-static route_map_result_t route_match_ip_address(void *rule,
- const struct prefix *prefix,
- route_map_object_t type,
- void *object)
+static route_map_result_t route_match_address(afi_t afi, void *rule,
+ const struct prefix *prefix,
+ route_map_object_t type,
+ void *object)
{
struct access_list *alist;
if (type == RMAP_ZEBRA) {
- alist = access_list_lookup(AFI_IP, (char *)rule);
+ alist = access_list_lookup(afi, (char *)rule);
if (alist == NULL)
return RMAP_NOMATCH;
@@ -1135,23 +1135,45 @@ static route_map_result_t route_match_ip_address(void *rule,
return RMAP_NOMATCH;
}
+static route_map_result_t route_match_ip_address(void *rule,
+ const struct prefix *prefix,
+ route_map_object_t type,
+ void *object)
+{
+ return route_match_address(AFI_IP, rule, prefix, type, object);
+}
+
+static route_map_result_t route_match_ipv6_address(void *rule,
+ const struct prefix *prefix,
+ route_map_object_t type,
+ void *object)
+
+{
+ return route_match_address(AFI_IP6, rule, prefix, type, object);
+}
+
/* Route map `ip address' match statement. `arg' should be
access-list name. */
-static void *route_match_ip_address_compile(const char *arg)
+static void *route_match_address_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
/* Free route map's compiled `ip address' value. */
-static void route_match_ip_address_free(void *rule)
+static void route_match_address_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip address matching. */
static struct route_map_rule_cmd route_match_ip_address_cmd = {
- "ip address", route_match_ip_address, route_match_ip_address_compile,
- route_match_ip_address_free};
+ "ip address", route_match_ip_address, route_match_address_compile,
+ route_match_address_free};
+
+/* Route map commands for ipv6 address matching. */
+static struct route_map_rule_cmd route_match_ipv6_address_cmd = {
+ "ipv6 address", route_match_ipv6_address, route_match_address_compile,
+ route_match_address_free};
/* `match ip address prefix-list PREFIX_LIST' */
@@ -1869,6 +1891,7 @@ void zebra_route_map_init()
route_map_install_match(&route_match_ip_next_hop_cmd);
route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd);
route_map_install_match(&route_match_ip_address_cmd);
+ route_map_install_match(&route_match_ipv6_address_cmd);
route_map_install_match(&route_match_ip_address_prefix_list_cmd);
route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
route_map_install_match(&route_match_ip_address_prefix_len_cmd);