diff options
| author | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2019-01-14 15:45:33 -0800 | 
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-01-25 14:19:26 -0500 | 
| commit | cde1af847e8295ae4a6eb6667f0902bf21604c9a (patch) | |
| tree | b7e9cb2f873058f8e5399026bd115a7b645b0a0f /zebra/connected.c | |
| parent | ec0ab5443f5d51e452a174cee5a078738b4d7bf7 (diff) | |
zebra: set connected route metric based on the devaddr metric
MACVLAN devices are typically used for applications such as VRR/VRRP that
require a second MAC address (virtual). These devices have a corresponding
SVI/VLAN device -
root@TORC11:~# ip addr show vlan1002
39: vlan1002@bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9152 qdisc noqueue master vrf1 state UP group default
    link/ether 00:02:00:00:00:2e brd ff:ff:ff:ff:ff:ff
    inet6 2001:aa:1::2/64 scope global
       valid_lft forever preferred_lft forever
root@TORC11:~# ip addr show vlan1002-v0
40: vlan1002-v0@vlan1002: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9152 qdisc noqueue master vrf1 state UP group default
    link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff
    inet6 2001:aa:1::a/64 metric 1024 scope global
       valid_lft forever preferred_lft forever
root@TORC11:~#
The macvlan device is used primarily for RX (VR-IP/VR-MAC). And TX is via
the SVI. To acheive that functionality the macvlan network's metric
is set to a higher value.
Zebra currently ignores the devaddr metric sent by the kernel and hardcodes
it to 0. This commit eliminates that hardcoding. If the devaddr metric
is available (METRIC_MAX) it is used for setting up the connected route
otherwise we fallback to the dev/interface metric.
Setting the macvlan metric to a higher value ensures that zebra will always
select the connected route on the SVI (and subsequently use it for next hop
resolution etc.) -
root@TORC11:~# vtysh -c "show ip route vrf vrf1 2001:aa:1::/64"
Routing entry for 2001:aa:1::/64
  Known via "connected", distance 0, metric 1024, vrf vrf1
  Last update 11:30:56 ago
  * directly connected, vlan1002-v0
Routing entry for 2001:aa:1::/64
  Known via "connected", distance 0, metric 0, vrf vrf1, best
  Last update 11:30:56 ago
  * directly connected, vlan1002
root@TORC11:~#
Ticket: CM-23511
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Diffstat (limited to 'zebra/connected.c')
| -rw-r--r-- | zebra/connected.c | 13 | 
1 files changed, 9 insertions, 4 deletions
diff --git a/zebra/connected.c b/zebra/connected.c index ab66eb3324..c449855f6d 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -209,6 +209,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)  		.ifindex = ifp->ifindex,  		.vrf_id = ifp->vrf_id,  	}; +	uint32_t metric;  	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))  		return; @@ -243,11 +244,13 @@ void connected_up(struct interface *ifp, struct connected *ifc)  		break;  	} +	metric = (ifc->metric < (uint32_t)METRIC_MAX) ? +				ifc->metric : ifp->metric;  	rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, -		NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); +		NULL, &nh, RT_TABLE_MAIN, metric, 0, 0, 0);  	rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, -		NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); +		NULL, &nh, RT_TABLE_MAIN, metric, 0, 0, 0);  	if (IS_ZEBRA_DEBUG_RIB_DETAILED) {  		char buf[PREFIX_STRLEN]; @@ -276,7 +279,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)  /* Add connected IPv4 route to the interface. */  void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,  			uint16_t prefixlen, struct in_addr *broad, -			const char *label) +			const char *label, uint32_t metric)  {  	struct prefix_ipv4 *p;  	struct connected *ifc; @@ -288,6 +291,7 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,  	ifc = connected_new();  	ifc->ifp = ifp;  	ifc->flags = flags; +	ifc->metric = metric;  	/* If we get a notification from the kernel,  	 * we can safely assume the address is known to the kernel */  	SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); @@ -500,7 +504,7 @@ void connected_delete_ipv4(struct interface *ifp, int flags,  /* Add connected IPv6 route to the interface. */  void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,  			struct in6_addr *broad, uint16_t prefixlen, -			const char *label) +			const char *label, uint32_t metric)  {  	struct prefix_ipv6 *p;  	struct connected *ifc; @@ -512,6 +516,7 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,  	ifc = connected_new();  	ifc->ifp = ifp;  	ifc->flags = flags; +	ifc->metric = metric;  	/* If we get a notification from the kernel,  	 * we can safely assume the address is known to the kernel */  	SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);  | 
