diff options
| -rw-r--r-- | bgpd/bgp_evpn_vty.c | 7 | ||||
| -rw-r--r-- | bgpd/bgp_fsm.c | 12 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 2 | ||||
| -rw-r--r-- | include/linux/if_link.h | 28 | ||||
| -rw-r--r-- | include/linux/rtnetlink.h | 17 | ||||
| -rw-r--r-- | zebra/debug_nl.c | 59 | ||||
| -rw-r--r-- | zebra/kernel_netlink.c | 22 | ||||
| -rw-r--r-- | zebra/zebra_vxlan.c | 2 |
8 files changed, 134 insertions, 15 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 32dc2a785f..d94dcdd362 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -2256,9 +2256,6 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni) struct bgpevpn *vpn; struct in_addr mcast_grp = {INADDR_ANY}; - if (!bgp->vnihash) - return NULL; - vpn = bgp_evpn_lookup_vni(bgp, vni); if (!vpn) { /* Check if this L2VNI is already configured as L3VNI */ @@ -2290,8 +2287,6 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni) */ static void evpn_delete_vni(struct bgp *bgp, struct bgpevpn *vpn) { - assert(bgp->vnihash); - if (!is_vni_live(vpn)) { bgp_evpn_free(bgp, vpn); return; @@ -6291,7 +6286,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi, if (bgp->advertise_all_vni) vty_out(vty, " advertise-all-vni\n"); - if (bgp->vnihash) { + if (hashcount(bgp->vnihash)) { struct list *vnilist = hash_to_list(bgp->vnihash); struct listnode *ln; struct bgpevpn *data; diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index ba018d3f56..fe4ab272ac 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1701,6 +1701,12 @@ static int bgp_connect_success(struct peer *peer) return -1; } + /* + * If we are doing nht for a peer that ls v6 LL based + * massage the event system to make things happy + */ + bgp_nht_interface_events(peer); + bgp_reads_on(peer); if (bgp_debug_neighbor_events(peer)) { @@ -1739,6 +1745,12 @@ static int bgp_connect_success_w_delayopen(struct peer *peer) return -1; } + /* + * If we are doing nht for a peer that ls v6 LL based + * massage the event system to make things happy + */ + bgp_nht_interface_events(peer); + bgp_reads_on(peer); if (bgp_debug_neighbor_events(peer)) { diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 9e22c6cdbd..9cfec0fe2f 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1554,7 +1554,7 @@ DEFUN (no_router_bgp, BGP_L2VPN_EVPN_ADV_IPV6_UNICAST) || CHECK_FLAG(tmp_bgp->af_flags[AFI_L2VPN][SAFI_EVPN], BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP))) || - (tmp_bgp->vnihash && hashcount(tmp_bgp->vnihash))) { + (hashcount(tmp_bgp->vnihash))) { vty_out(vty, "%% Cannot delete default BGP instance. Dependent VRF instances exist\n"); return CMD_WARNING_CONFIG_FAILED; diff --git a/include/linux/if_link.h b/include/linux/if_link.h index e5cea27829..53892303ba 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -519,6 +519,31 @@ enum ipvlan_mode { #define IPVLAN_F_PRIVATE 0x01 #define IPVLAN_F_VEPA 0x02 +/* Tunnel RTM header */ +struct tunnel_msg { + __u8 family; + __u8 reserved1; + __u16 reserved2; + __u32 ifindex; +}; + +enum { + VXLAN_VNIFILTER_ENTRY_UNSPEC, + VXLAN_VNIFILTER_ENTRY_START, + VXLAN_VNIFILTER_ENTRY_END, + VXLAN_VNIFILTER_ENTRY_GROUP, + VXLAN_VNIFILTER_ENTRY_GROUP6, + __VXLAN_VNIFILTER_ENTRY_MAX +}; +#define VXLAN_VNIFILTER_ENTRY_MAX (__VXLAN_VNIFILTER_ENTRY_MAX - 1) + +enum { + VXLAN_VNIFILTER_UNSPEC, + VXLAN_VNIFILTER_ENTRY, + __VXLAN_VNIFILTER_MAX +}; +#define VXLAN_VNIFILTER_MAX (__VXLAN_VNIFILTER_MAX - 1) + /* VXLAN section */ enum { IFLA_VXLAN_UNSPEC, @@ -550,6 +575,9 @@ enum { IFLA_VXLAN_LABEL, IFLA_VXLAN_GPE, IFLA_VXLAN_TTL_INHERIT, + IFLA_VXLAN_DF, + IFLA_VXLAN_VNIFILTER, /* only applicable when COLLECT_METADATA mode is + on */ __IFLA_VXLAN_MAX }; #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 5888492a52..b15b72a262 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -185,6 +185,16 @@ enum { RTM_GETNEXTHOPBUCKET, #define RTM_GETNEXTHOPBUCKET RTM_GETNEXTHOPBUCKET + RTM_SETHWFLAGS = 119, +#define RTM_SETHWFLAGS RTM_SETHWFLAGS + + RTM_NEWTUNNEL = 120, +#define RTM_NEWTUNNEL RTM_NEWTUNNEL + RTM_DELTUNNEL, +#define RTM_DELTUNNEL RTM_DELTUNNEL + RTM_GETTUNNEL, +#define RTM_GETTUNNEL RTM_GETTUNNEL + __RTM_MAX, #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) }; @@ -217,6 +227,11 @@ struct rtattr { #define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len)) #define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0))) #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) +#ifndef TUNNEL_RTA +#define TUNNEL_RTA(r) \ + ((struct rtattr *)(((char *)(r)) + \ + NLMSG_ALIGN(sizeof(struct tunnel_msg)))) +#endif @@ -754,6 +769,8 @@ enum rtnetlink_groups { #define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP RTNLGRP_BRVLAN, #define RTNLGRP_BRVLAN RTNLGRP_BRVLAN + RTNLGRP_TUNNEL, +#define RTNLGRP_TUNNEL RTNLGRP_TUNNEL __RTNLGRP_MAX }; #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) diff --git a/zebra/debug_nl.c b/zebra/debug_nl.c index f058205c25..89ef7a2076 100644 --- a/zebra/debug_nl.c +++ b/zebra/debug_nl.c @@ -33,6 +33,7 @@ #include "zebra/rt_netlink.h" #include "zebra/kernel_netlink.h" +#include "lib/vxlan.h" const char *nlmsg_type2str(uint16_t type) { @@ -92,6 +93,13 @@ const char *nlmsg_type2str(uint16_t type) case RTM_GETNEXTHOP: return "GETNEXTHOP"; + case RTM_NEWTUNNEL: + return "NEWTUNNEL"; + case RTM_DELTUNNEL: + return "DELTUNNEL"; + case RTM_GETTUNNEL: + return "GETTUNNEL"; + case RTM_NEWNETCONF: return "RTM_NEWNETCONF"; case RTM_DELNETCONF: @@ -1241,6 +1249,44 @@ next_rta: goto next_rta; } +static void nltnl_dump(struct tunnel_msg *tnlm, size_t msglen) +{ + struct rtattr *attr; + vni_t vni_start = 0, vni_end = 0; + struct rtattr *ttb[VXLAN_VNIFILTER_ENTRY_MAX + 1]; + uint8_t rta_type; + + attr = TUNNEL_RTA(tnlm); +next_attr: + /* Check the header for valid length and for outbound access. */ + if (RTA_OK(attr, msglen) == 0) + return; + + rta_type = attr->rta_type & NLA_TYPE_MASK; + + if (rta_type != VXLAN_VNIFILTER_ENTRY) { + attr = RTA_NEXT(attr, msglen); + goto next_attr; + } + + memset(ttb, 0, sizeof(ttb)); + + netlink_parse_rtattr_flags(ttb, VXLAN_VNIFILTER_ENTRY_MAX, + RTA_DATA(attr), RTA_PAYLOAD(attr), + NLA_F_NESTED); + + if (ttb[VXLAN_VNIFILTER_ENTRY_START]) + vni_start = + *(uint32_t *)RTA_DATA(ttb[VXLAN_VNIFILTER_ENTRY_START]); + + if (ttb[VXLAN_VNIFILTER_ENTRY_END]) + vni_end = *(uint32_t *)RTA_DATA(ttb[VXLAN_VNIFILTER_ENTRY_END]); + zlog_debug(" vni_start %u, vni_end %u", vni_start, vni_end); + + attr = RTA_NEXT(attr, msglen); + goto next_attr; +} + static const char *lwt_type2str(uint16_t type) { switch (type) { @@ -1529,6 +1575,7 @@ void nl_dump(void *msg, size_t msglen) struct nhmsg *nhm; struct netconfmsg *ncm; struct ifinfomsg *ifi; + struct tunnel_msg *tnlm; struct fib_rule_hdr *frh; char fbuf[128]; char ibuf[128]; @@ -1645,6 +1692,18 @@ next_header: nlnh_dump(nhm, nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(*nhm))); break; + case RTM_NEWTUNNEL: + case RTM_DELTUNNEL: + case RTM_GETTUNNEL: + tnlm = NLMSG_DATA(nlmsg); + zlog_debug(" tnlm [family=(%d) %s ifindex=%d ", tnlm->family, + af_type2str(tnlm->family), tnlm->ifindex); + nltnl_dump(tnlm, + nlmsg->nlmsg_len - + NLMSG_LENGTH(sizeof(struct tunnel_msg))); + break; + + case RTM_NEWNETCONF: case RTM_DELNETCONF: ncm = NLMSG_DATA(nlmsg); diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index aa31883dea..7adbb5ab85 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -289,7 +289,7 @@ static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize) /* Make socket for Linux netlink interface. */ static int netlink_socket(struct nlsock *nl, unsigned long groups, - ns_id_t ns_id) + unsigned long ext_groups, ns_id_t ns_id) { int ret; struct sockaddr_nl snl; @@ -308,6 +308,12 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups, snl.nl_family = AF_NETLINK; snl.nl_groups = groups; +#if defined SOL_NETLINK + if (ext_groups) + setsockopt(sock, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, + &ext_groups, sizeof(ext_groups)); +#endif + /* Bind the socket to the netlink structure for anything. */ ret = bind(sock, (struct sockaddr *)&snl, sizeof(snl)); } @@ -591,7 +597,7 @@ bool nl_addraw_l(struct nlmsghdr *n, unsigned int maxlen, const void *data, unsigned int len) { if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) { - zlog_err("ERROR message exceeded bound of %d\n", maxlen); + zlog_err("ERROR message exceeded bound of %d", maxlen); return false; } @@ -1678,7 +1684,7 @@ static bool kernel_netlink_nlsock_hash_equal(const void *arg1, const void *arg2) netlink_socket (). */ void kernel_init(struct zebra_ns *zns) { - uint32_t groups, dplane_groups; + uint32_t groups, dplane_groups, ext_groups; #if defined SOL_NETLINK int one, ret; #endif @@ -1710,11 +1716,13 @@ void kernel_init(struct zebra_ns *zns) ((uint32_t) 1 << (RTNLGRP_IPV6_NETCONF - 1)) | ((uint32_t) 1 << (RTNLGRP_MPLS_NETCONF - 1))); + /* Use setsockopt for > 31 group */ + ext_groups = RTNLGRP_TUNNEL; snprintf(zns->netlink.name, sizeof(zns->netlink.name), "netlink-listen (NS %u)", zns->ns_id); zns->netlink.sock = -1; - if (netlink_socket(&zns->netlink, groups, zns->ns_id) < 0) { + if (netlink_socket(&zns->netlink, groups, ext_groups, zns->ns_id) < 0) { zlog_err("Failure to create %s socket", zns->netlink.name); exit(-1); @@ -1725,7 +1733,7 @@ void kernel_init(struct zebra_ns *zns) snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name), "netlink-cmd (NS %u)", zns->ns_id); zns->netlink_cmd.sock = -1; - if (netlink_socket(&zns->netlink_cmd, 0, zns->ns_id) < 0) { + if (netlink_socket(&zns->netlink_cmd, 0, 0, zns->ns_id) < 0) { zlog_err("Failure to create %s socket", zns->netlink_cmd.name); exit(-1); @@ -1738,7 +1746,7 @@ void kernel_init(struct zebra_ns *zns) sizeof(zns->netlink_dplane_out.name), "netlink-dp (NS %u)", zns->ns_id); zns->netlink_dplane_out.sock = -1; - if (netlink_socket(&zns->netlink_dplane_out, 0, zns->ns_id) < 0) { + if (netlink_socket(&zns->netlink_dplane_out, 0, 0, zns->ns_id) < 0) { zlog_err("Failure to create %s socket", zns->netlink_dplane_out.name); exit(-1); @@ -1751,7 +1759,7 @@ void kernel_init(struct zebra_ns *zns) sizeof(zns->netlink_dplane_in.name), "netlink-dp-in (NS %u)", zns->ns_id); zns->netlink_dplane_in.sock = -1; - if (netlink_socket(&zns->netlink_dplane_in, dplane_groups, + if (netlink_socket(&zns->netlink_dplane_in, dplane_groups, 0, zns->ns_id) < 0) { zlog_err("Failure to create %s socket", zns->netlink_dplane_in.name); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 2145a10aa8..58a1713c56 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -2115,7 +2115,7 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, zebra_evpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC); /* Free up all remote VTEPs, if any. */ - zebra_evpn_vtep_del_all(zevpn, 0); + zebra_evpn_vtep_del_all(zevpn, 1); /* Delete the hash entry. */ if (zebra_evpn_vxlan_del(zevpn)) { |
