summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorStephen Worley <sworley1995@gmail.com>2018-07-26 21:34:56 +0200
committerGitHub <noreply@github.com>2018-07-26 21:34:56 +0200
commit2e2b0fb3c289fd241a02c62bbaccdbf502bfe353 (patch)
treef38fa078bcb705b0afd8f89a61fbdc3295987cd9 /zebra
parentzebra: Make prefix length check return error (diff)
parentMerge pull request #2727 from donaldsharp/pim_jp_lollipops (diff)
downloadfrr-2e2b0fb3c289fd241a02c62bbaccdbf502bfe353.tar.xz
frr-2e2b0fb3c289fd241a02c62bbaccdbf502bfe353.zip
Merge branch 'master' into Netlink-Prefix-Len-Check
Diffstat (limited to 'zebra')
-rw-r--r--zebra/if_netlink.c26
-rw-r--r--zebra/rt.h2
-rw-r--r--zebra/rt_netlink.c72
-rw-r--r--zebra/rt_socket.c10
-rw-r--r--zebra/rule_netlink.c6
-rw-r--r--zebra/zebra_pbr.c41
-rw-r--r--zebra/zebra_pbr.h2
-rw-r--r--zebra/zebra_rib.c4
-rw-r--r--zebra/zebra_routemap.c36
-rw-r--r--zebra/zebra_routemap.h5
-rw-r--r--zebra/zebra_vty.c14
-rw-r--r--zebra/zebra_vxlan.c88
-rw-r--r--zebra/zebra_vxlan.h3
-rw-r--r--zebra/zebra_vxlan_private.h3
-rw-r--r--zebra/zserv.c1
15 files changed, 229 insertions, 84 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index a8cf5e31b..66e98e2e5 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -891,8 +891,12 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
zns = zebra_ns_lookup(ns_id);
ifa = NLMSG_DATA(h);
- if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6)
+ if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6) {
+ zlog_warn(
+ "Invalid address family: %d received from kernel interface addr change: %d",
+ ifa->ifa_family, h->nlmsg_type);
return 0;
+ }
if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
return 0;
@@ -1126,6 +1130,14 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
return 0;
}
+ if (!(ifi->ifi_family == AF_UNSPEC || ifi->ifi_family == AF_BRIDGE
+ || ifi->ifi_family == AF_INET6)) {
+ zlog_warn(
+ "Invalid address family: %d received from kernel link change: %d",
+ ifi->ifi_family, h->nlmsg_type);
+ return 0;
+ }
+
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
if (len < 0) {
zlog_err("%s: Message received from netlink is of a broken size %d %zu",
@@ -1230,6 +1242,12 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
/* Update interface information. */
set_ifindex(ifp, ifi->ifi_index, zns);
ifp->flags = ifi->ifi_flags & 0x0000fffff;
+ if (!tb[IFLA_MTU]) {
+ zlog_warn(
+ "RTM_NEWLINK for interface %s(%u) without MTU set",
+ name, ifi->ifi_index);
+ return 0;
+ }
ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]);
ifp->metric = 0;
ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
@@ -1279,6 +1297,12 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
bridge_ifindex, ifi->ifi_flags);
set_ifindex(ifp, ifi->ifi_index, zns);
+ if (!tb[IFLA_MTU]) {
+ zlog_warn(
+ "RTM_NEWLINK for interface %s(%u) without MTU set",
+ name, ifi->ifi_index);
+ return 0;
+ }
ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]);
ifp->metric = 0;
diff --git a/zebra/rt.h b/zebra/rt.h
index 57e62e4f6..e40bae3a3 100644
--- a/zebra/rt.h
+++ b/zebra/rt.h
@@ -122,7 +122,7 @@ extern int kernel_del_mac(struct interface *ifp, vlanid_t vid,
int local);
extern int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
- struct ethaddr *mac);
+ struct ethaddr *mac, uint8_t flags);
extern int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip);
/*
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 6eeede6f6..5facfa5fa 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -393,9 +393,15 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
memcpy(&p.u.prefix4, dest, 4);
p.prefixlen = rtm->rtm_dst_len;
- src_p.prefixlen =
- 0; // Forces debug below to not display anything
+ if (rtm->rtm_src_len != 0) {
+ char buf[PREFIX_STRLEN];
+ zlog_warn("unsupported IPv4 sourcedest route (dest %s vrf %u)",
+ prefix2str(&p, buf, sizeof(buf)), vrf_id);
+ return 0;
+ }
+ /* Force debug below to not display anything for source */
+ src_p.prefixlen = 0;
} else if (rtm->rtm_family == AF_INET6) {
p.family = AF_INET6;
if (rtm->rtm_dst_len > IPV6_MAX_BITLEN) {
@@ -418,14 +424,6 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
src_p.prefixlen = rtm->rtm_src_len;
}
- if (rtm->rtm_src_len != 0) {
- char buf[PREFIX_STRLEN];
- zlog_warn(
- "unsupported IPv[4|6] sourcedest route (dest %s vrf %u)",
- prefix2str(&p, buf, sizeof(buf)), vrf_id);
- return 0;
- }
-
/*
* For ZEBRA_ROUTE_KERNEL types:
*
@@ -511,7 +509,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
nh.vrf_id = nh_vrf_id;
rib_add(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p,
- NULL, &nh, table, metric, mtu, distance, tag);
+ &src_p, &nh, table, metric, mtu, distance, tag);
} else {
/* This is a multipath route */
@@ -600,6 +598,9 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
route_entry_nexthop_ifindex_add(
re, index, nh_vrf_id);
+ if (rtnh->rtnh_len == 0)
+ break;
+
len -= NLMSG_ALIGN(rtnh->rtnh_len);
rtnh = RTNH_NEXT(rtnh);
}
@@ -610,8 +611,8 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
if (re->nexthop_num == 0)
XFREE(MTYPE_RE, re);
else
- rib_add_multipath(afi, SAFI_UNICAST, &p, NULL,
- re);
+ rib_add_multipath(afi, SAFI_UNICAST, &p,
+ &src_p, re);
}
} else {
if (!tb[RTA_MULTIPATH]) {
@@ -643,12 +644,12 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
if (gate)
memcpy(&nh.gate, gate, sz);
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
- &p, NULL, &nh, table, metric, true);
+ &p, &src_p, &nh, table, metric, true);
} else {
/* XXX: need to compare the entire list of nexthops
* here for NLM_F_APPEND stupidity */
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
- &p, NULL, NULL, table, metric, true);
+ &p, &src_p, NULL, table, metric, true);
}
}
@@ -720,6 +721,9 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h,
oif[oif_count] = rtnh->rtnh_ifindex;
oif_count++;
+ if (rtnh->rtnh_len == 0)
+ break;
+
len -= NLMSG_ALIGN(rtnh->rtnh_len);
rtnh = RTNH_NEXT(rtnh);
}
@@ -759,6 +763,15 @@ int netlink_route_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
return 0;
}
+ if (!(rtm->rtm_family == AF_INET || rtm->rtm_family == AF_INET6
+ || rtm->rtm_family == AF_ETHERNET
+ || rtm->rtm_family == AF_MPLS)) {
+ zlog_warn(
+ "Invalid address family: %d received from kernel route change: %d",
+ rtm->rtm_family, h->nlmsg_type);
+ return 0;
+ }
+
/* Connected route. */
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("%s %s %s proto %s NS %u",
@@ -2170,6 +2183,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
char buf2[INET6_ADDRSTRLEN];
int mac_present = 0;
uint8_t ext_learned;
+ uint8_t router_flag;
ndm = NLMSG_DATA(h);
@@ -2260,6 +2274,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
}
ext_learned = (ndm->ndm_flags & NTF_EXT_LEARNED) ? 1 : 0;
+ router_flag = (ndm->ndm_flags & NTF_ROUTER) ? 1 : 0;
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
@@ -2282,7 +2297,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
if (ndm->ndm_state & NUD_VALID)
return zebra_vxlan_handle_kernel_neigh_update(
ifp, link_if, &ip, &mac, ndm->ndm_state,
- ext_learned);
+ ext_learned, router_flag);
return zebra_vxlan_handle_kernel_neigh_del(ifp, link_if, &ip);
}
@@ -2405,12 +2420,19 @@ int netlink_neigh_change(struct nlmsghdr *h, ns_id_t ns_id)
if (ndm->ndm_family == AF_INET || ndm->ndm_family == AF_INET6)
return netlink_ipneigh_change(h, len, ns_id);
+ else {
+ zlog_warn(
+ "Invalid address family: %d received from kernel neighbor change: %d",
+ ndm->ndm_family, h->nlmsg_type);
+ return 0;
+ }
return 0;
}
static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip,
- struct ethaddr *mac, uint32_t flags, int cmd)
+ struct ethaddr *mac, uint8_t flags,
+ uint16_t state, int cmd)
{
struct {
struct nlmsghdr n;
@@ -2433,11 +2455,10 @@ static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip,
req.n.nlmsg_flags |= (NLM_F_CREATE | NLM_F_REPLACE);
req.n.nlmsg_type = cmd; // RTM_NEWNEIGH or RTM_DELNEIGH
req.ndm.ndm_family = IS_IPADDR_V4(ip) ? AF_INET : AF_INET6;
- req.ndm.ndm_state = flags;
+ req.ndm.ndm_state = state;
req.ndm.ndm_ifindex = ifp->ifindex;
req.ndm.ndm_type = RTN_UNICAST;
- req.ndm.ndm_flags = NTF_EXT_LEARNED;
-
+ req.ndm.ndm_flags = flags;
ipa_len = IS_IPADDR_V4(ip) ? IPV4_MAX_BYTELEN : IPV6_MAX_BYTELEN;
addattr_l(&req.n, sizeof(req), NDA_DST, &ip->ip.addr, ipa_len);
@@ -2445,12 +2466,12 @@ static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip,
addattr_l(&req.n, sizeof(req), NDA_LLADDR, mac, 6);
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("Tx %s family %s IF %s(%u) Neigh %s MAC %s",
+ zlog_debug("Tx %s family %s IF %s(%u) Neigh %s MAC %s flags 0x%x",
nl_msg_type_to_str(cmd),
nl_family_to_str(req.ndm.ndm_family), ifp->name,
ifp->ifindex, ipaddr2str(ip, buf, sizeof(buf)),
mac ? prefix_mac2str(mac, buf2, sizeof(buf2))
- : "null");
+ : "null", flags);
return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
0);
@@ -2471,14 +2492,15 @@ int kernel_del_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
}
int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
- struct ethaddr *mac)
+ struct ethaddr *mac, uint8_t flags)
{
- return netlink_neigh_update2(ifp, ip, mac, NUD_NOARP, RTM_NEWNEIGH);
+ return netlink_neigh_update2(ifp, ip, mac, flags,
+ NUD_NOARP, RTM_NEWNEIGH);
}
int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip)
{
- return netlink_neigh_update2(ifp, ip, NULL, 0, RTM_DELNEIGH);
+ return netlink_neigh_update2(ifp, ip, NULL, 0, 0, RTM_DELNEIGH);
}
/*
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index cba037630..346699198 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -88,7 +88,8 @@ static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label,
#endif
/* Interface between zebra message and rtm message. */
-static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
+static int kernel_rtm_ipv4(int cmd, const struct prefix *p,
+ struct route_entry *re)
{
struct sockaddr_in *mask = NULL;
@@ -272,7 +273,8 @@ static int sin6_masklen(struct in6_addr mask)
#endif /* SIN6_LEN */
/* Interface between zebra message and rtm message. */
-static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
+static int kernel_rtm_ipv6(int cmd, const struct prefix *p,
+ struct route_entry *re)
{
struct sockaddr_in6 *mask;
struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
@@ -374,7 +376,7 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
return 0; /*XXX*/
}
-static int kernel_rtm(int cmd, struct prefix *p, struct route_entry *re)
+static int kernel_rtm(int cmd, const struct prefix *p, struct route_entry *re)
{
switch (PREFIX_FAMILY(p)) {
case AF_INET:
@@ -460,7 +462,7 @@ int kernel_del_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
}
int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
- struct ethaddr *mac)
+ struct ethaddr *mac, uint8_t flags)
{
return 0;
}
diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c
index c7a8517e1..d683e92bc 100644
--- a/zebra/rule_netlink.c
+++ b/zebra/rule_netlink.c
@@ -204,8 +204,12 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
}
frh = NLMSG_DATA(h);
- if (frh->family != AF_INET && frh->family != AF_INET6)
+ if (frh->family != AF_INET && frh->family != AF_INET6) {
+ zlog_warn(
+ "Invalid address family: %d received from kernel rule change: %d",
+ frh->family, h->nlmsg_type);
return 0;
+ }
if (frh->action != FR_ACT_TO_TBL)
return 0;
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 74ef25b03..e2217a5d2 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -832,6 +832,7 @@ struct zebra_pbr_ipset_entry_unique_display {
struct zebra_pbr_env_display {
struct zebra_ns *zns;
struct vty *vty;
+ char *name;
};
static const char *zebra_pbr_prefix2str(union prefixconstptr pu,
@@ -1037,6 +1038,7 @@ void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname)
}
uniqueipset.zns = zns;
uniqueipset.vty = vty;
+ uniqueipset.name = NULL;
hash_walk(zns->ipset_hash, zebra_pbr_show_ipset_walkcb,
&uniqueipset);
}
@@ -1060,19 +1062,25 @@ static int zebra_pbr_rule_lookup_fwmark_walkcb(struct hash_backet *backet,
return HASHWALK_CONTINUE;
}
-static int zebra_pbr_show_iptable_walkcb(struct hash_backet *backet, void *arg)
+static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable,
+ struct vty *vty,
+ struct zebra_ns *zns)
{
- struct zebra_pbr_iptable *iptable =
- (struct zebra_pbr_iptable *)backet->data;
- struct zebra_pbr_env_display *env = (struct zebra_pbr_env_display *)arg;
- struct vty *vty = env->vty;
- struct zebra_ns *zns = env->zns;
int ret;
uint64_t pkts = 0, bytes = 0;
vty_out(vty, "IPtable %s action %s (%u)\n", iptable->ipset_name,
iptable->action == ZEBRA_IPTABLES_DROP ? "drop" : "redirect",
iptable->unique);
+ if (iptable->type == IPSET_NET_PORT ||
+ iptable->type == IPSET_NET_PORT_NET) {
+ if (!(iptable->filter_bm & MATCH_ICMP_SET)) {
+ if (iptable->filter_bm & PBR_FILTER_DST_PORT)
+ vty_out(vty, "\t lookup dst port\n");
+ else if (iptable->filter_bm & PBR_FILTER_SRC_PORT)
+ vty_out(vty, "\t lookup src port\n");
+ }
+ }
if (iptable->pkt_len_min || iptable->pkt_len_max) {
if (!iptable->pkt_len_max)
vty_out(vty, "\t pkt len %u\n",
@@ -1129,17 +1137,34 @@ static int zebra_pbr_show_iptable_walkcb(struct hash_backet *backet, void *arg)
prfl.fwmark);
}
}
+}
+
+static int zebra_pbr_show_iptable_walkcb(struct hash_backet *backet, void *arg)
+{
+ struct zebra_pbr_iptable *iptable =
+ (struct zebra_pbr_iptable *)backet->data;
+ struct zebra_pbr_env_display *env = (struct zebra_pbr_env_display *)arg;
+ struct vty *vty = env->vty;
+ struct zebra_ns *zns = env->zns;
+ char *iptable_name = env->name;
+
+ if (!iptable_name)
+ zebra_pbr_show_iptable_unit(iptable, vty, zns);
+ else if (!strncmp(iptable_name,
+ iptable->ipset_name,
+ ZEBRA_IPSET_NAME_SIZE))
+ zebra_pbr_show_iptable_unit(iptable, vty, zns);
return HASHWALK_CONTINUE;
}
-void zebra_pbr_show_iptable(struct vty *vty)
+void zebra_pbr_show_iptable(struct vty *vty, char *iptable_name)
{
struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
struct zebra_pbr_env_display env;
env.vty = vty;
env.zns = zns;
-
+ env.name = iptable_name;
hash_walk(zns->iptable_hash, zebra_pbr_show_iptable_walkcb,
&env);
}
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index fd83502ae..0db33d1f8 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -235,7 +235,7 @@ extern int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2);
extern void zebra_pbr_init(void);
extern void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname);
-extern void zebra_pbr_show_iptable(struct vty *vty);
+extern void zebra_pbr_show_iptable(struct vty *vty, char *iptable);
extern void zebra_pbr_iptable_update_interfacelist(struct stream *s,
struct zebra_pbr_iptable *zpi);
size_t zebra_pbr_tcpflags_snprintf(char *buffer, size_t len,
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 9bf6bfa22..71d48632c 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2331,7 +2331,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
if (!re)
return 0;
- assert(!src_p || afi == AFI_IP6);
+ assert(!src_p || !src_p->prefixlen || afi == AFI_IP6);
/* Lookup table. */
table = zebra_vrf_table_with_table_id(afi, safi, re->vrf_id, re->table);
@@ -2421,7 +2421,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
char buf2[INET6_ADDRSTRLEN];
rib_dest_t *dest;
- assert(!src_p || afi == AFI_IP6);
+ assert(!src_p || !src_p->prefixlen || afi == AFI_IP6);
/* Lookup table. */
table = zebra_vrf_table_with_table_id(afi, safi, vrf_id, table_id);
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index bf6718164..0b48e87b1 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -137,7 +137,8 @@ static int zebra_route_match_delete(struct vty *vty, const char *command,
/* 'match tag TAG'
* Match function return 1 if match is success else return 0
*/
-static route_map_result_t route_match_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_tag(void *rule,
+ const struct prefix *prefix,
route_map_object_t type, void *object)
{
route_tag_t *tag;
@@ -163,7 +164,7 @@ static struct route_map_rule_cmd route_match_tag_cmd = {
/* `match interface IFNAME' */
/* Match function return 1 if match is success else return zero. */
static route_map_result_t route_match_interface(void *rule,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
@@ -879,7 +880,7 @@ DEFUN (show_ipv6_protocol_nht,
/* Match function return 1 if match is success else return zero. */
static route_map_result_t route_match_ip_next_hop(void *rule,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
@@ -937,7 +938,7 @@ static struct route_map_rule_cmd route_match_ip_next_hop_cmd = {
/* `match ip next-hop prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
@@ -993,7 +994,7 @@ 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,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
@@ -1032,7 +1033,7 @@ static struct route_map_rule_cmd route_match_ip_address_cmd = {
/* `match ip address prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
@@ -1068,7 +1069,7 @@ static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
/* `match ip address prefix-len PREFIXLEN' */
static route_map_result_t
-route_match_address_prefix_len(void *rule, struct prefix *prefix,
+route_match_address_prefix_len(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
uint32_t *prefixlen = (uint32_t *)rule;
@@ -1122,7 +1123,7 @@ static struct route_map_rule_cmd route_match_ipv6_address_prefix_len_cmd = {
/* `match ip nexthop prefix-len PREFIXLEN' */
static route_map_result_t
-route_match_ip_nexthop_prefix_len(void *rule, struct prefix *prefix,
+route_match_ip_nexthop_prefix_len(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
uint32_t *prefixlen = (uint32_t *)rule;
@@ -1162,7 +1163,7 @@ static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd = {
/* `match source-protocol PROTOCOL' */
static route_map_result_t route_match_source_protocol(void *rule,
- struct prefix *prefix,
+ const struct prefix *p,
route_map_object_t type,
void *object)
{
@@ -1204,7 +1205,7 @@ static struct route_map_rule_cmd route_match_source_protocol_cmd = {
/* `source-instance` */
static route_map_result_t route_match_source_instance(void *rule,
- struct prefix *prefix,
+ const struct prefix *p,
route_map_object_t type,
void *object)
{
@@ -1246,7 +1247,7 @@ static struct route_map_rule_cmd route_match_source_instance_cmd = {
/* `set src A.B.C.D' */
/* Set src. */
-static route_map_result_t route_set_src(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_src(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct nh_rmap_obj *nh_data;
@@ -1359,8 +1360,7 @@ route_map_result_t zebra_route_map_check(int family, int rib_type,
rmap = route_map_lookup_by_name(
proto_rm[family][ZEBRA_ROUTE_MAX]);
if (rmap) {
- ret = route_map_apply(rmap, (struct prefix *)p,
- RMAP_ZEBRA, &nh_obj);
+ ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
}
return (ret);
@@ -1385,7 +1385,8 @@ void zebra_del_import_table_route_map(afi_t afi, uint32_t table)
route_map_result_t
zebra_import_table_route_map_check(int family, int re_type, uint8_t instance,
- struct prefix *p, struct nexthop *nexthop,
+ const struct prefix *p,
+ struct nexthop *nexthop,
vrf_id_t vrf_id, route_tag_t tag,
const char *rmap_name)
{
@@ -1410,7 +1411,7 @@ zebra_import_table_route_map_check(int family, int re_type, uint8_t instance,
}
route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
- struct prefix *p,
+ const struct prefix *p,
struct route_entry *re,
struct nexthop *nexthop)
{
@@ -1430,11 +1431,10 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
if (!rmap && nht_rm[family][ZEBRA_ROUTE_MAX])
rmap = route_map_lookup_by_name(
nht_rm[family][ZEBRA_ROUTE_MAX]);
- if (rmap) {
+ if (rmap)
ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
- }
- return (ret);
+ return ret;
}
static void zebra_route_map_mark_update(const char *rmap_name)
diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h
index 688c8b720..d33487d7a 100644
--- a/zebra/zebra_routemap.h
+++ b/zebra/zebra_routemap.h
@@ -35,7 +35,8 @@ extern void zebra_route_map_write_delay_timer(struct vty *);
extern route_map_result_t
zebra_import_table_route_map_check(int family, int rib_type, uint8_t instance,
- struct prefix *p, struct nexthop *nexthop,
+ const struct prefix *p,
+ struct nexthop *nexthop,
vrf_id_t vrf_id, route_tag_t tag,
const char *rmap_name);
extern route_map_result_t
@@ -43,7 +44,7 @@ zebra_route_map_check(int family, int rib_type, uint8_t instance,
const struct prefix *p, struct nexthop *nexthop,
vrf_id_t vrf_id, route_tag_t tag);
extern route_map_result_t
-zebra_nht_route_map_check(int family, int client_proto, struct prefix *p,
+zebra_nht_route_map_check(int family, int client_proto, const struct prefix *p,
struct route_entry *, struct nexthop *nexthop);
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 8ee47d2f1..bed3b7f77 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -3474,12 +3474,20 @@ DEFUN (show_pbr_ipset,
/* policy routing contexts */
DEFUN (show_pbr_iptable,
show_pbr_iptable_cmd,
- "show pbr iptable",
+ "show pbr iptable [WORD]",
SHOW_STR
"Policy-Based Routing\n"
- "IPtable Context information\n")
+ "IPtable Context information\n"
+ "IPtable Name information\n")
{
- zebra_pbr_show_iptable(vty);
+ int idx = 0;
+ int found = 0;
+
+ found = argv_find(argv, argc, "WORD", &idx);
+ if (!found)
+ zebra_pbr_show_iptable(vty, NULL);
+ else
+ zebra_pbr_show_iptable(vty, argv[idx]->arg);
return CMD_SUCCESS;
}
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 59f0cf52f..06d1b3618 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -33,6 +33,9 @@
#include "jhash.h"
#include "vlan.h"
#include "vxlan.h"
+#ifdef GNU_LINUX
+#include <linux/neighbour.h>
+#endif
#include "zebra/rib.h"
#include "zebra/rt.h"
@@ -282,6 +285,7 @@ static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt)
ipaddr2str(&n->ip, buf, sizeof(buf)), width = strlen(buf);
if (width > wctx->addr_width)
wctx->addr_width = width;
+
}
/*
@@ -327,6 +331,10 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
else
json_object_boolean_true_add(json, "defaultGateway");
}
+ if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
+ if (!json)
+ vty_out(vty, " Router");
+ }
if (json == NULL)
vty_out(vty, "\n");
}
@@ -432,11 +440,11 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
return;
}
num_neigh = hashcount(zvni->neigh_table);
- if (json == NULL)
+ if (json == NULL) {
vty_out(vty,
"\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
zvni->vni, num_neigh);
- else {
+ } else {
json_vni = json_object_new_object();
json_object_int_add(json_vni, "numArpNd", num_neigh);
snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
@@ -458,9 +466,10 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
wctx.json = json_vni;
hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
- if (json == NULL)
+ if (json == NULL) {
vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
"Type", "MAC", "Remote VTEP");
+ }
hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
if (json)
@@ -581,6 +590,9 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
vty_out(vty, " Default-gateway Mac ");
+ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
+ vty_out(vty, " Remote-gateway Mac ");
+
vty_out(vty, "\n");
/* print all the associated neigh */
vty_out(vty, " Neighbors:\n");
@@ -1553,6 +1565,9 @@ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_DEF_GW))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+ /* Set router flag (R-bit) based on local neigh entry add */
+ if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ROUTER_FLAG))
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
ZEBRA_MACIP_ADD);
@@ -1576,6 +1591,8 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
struct interface *vlan_if;
+ uint8_t flags;
+ int ret = 0;
if (!(n->flags & ZEBRA_NEIGH_REMOTE))
return 0;
@@ -1588,8 +1605,13 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
if (!vlan_if)
return -1;
-
- return kernel_add_neigh(vlan_if, &n->ip, &n->emac);
+#ifdef GNU_LINUX
+ flags = NTF_EXT_LEARNED;
+ if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
+ flags |= NTF_ROUTER;
+ ret = kernel_add_neigh(vlan_if, &n->ip, &n->emac, flags);
+#endif
+ return ret;
}
/*
@@ -1811,6 +1833,9 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
/* Set "local" forwarding info. */
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
+ /* Set Router flag (R-bit) */
+ if (ip->ipa_type == IPADDR_V6)
+ SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
memcpy(&n->emac, macaddr, ETH_ALEN);
n->ifindex = ifp->ifindex;
@@ -1820,10 +1845,10 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
+ "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
ifp->name, ifp->ifindex, zvni->vni,
prefix_mac2str(macaddr, buf, sizeof(buf)),
- ipaddr2str(ip, buf2, sizeof(buf2)));
+ ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
@@ -1966,7 +1991,8 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
static int zvni_local_neigh_update(zebra_vni_t *zvni,
struct interface *ifp,
struct ipaddr *ip,
- struct ethaddr *macaddr)
+ struct ethaddr *macaddr,
+ uint8_t router_flag)
{
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
@@ -2084,15 +2110,19 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
return 0;
}
+ /*Set router flag (R-bit) */
+ if (router_flag)
+ SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+
/* Inform BGP. */
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u",
+ zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u with flags 0x%x",
ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)),
- zvni->vni);
+ zvni->vni, n->flags);
ZEBRA_NEIGH_SET_ACTIVE(n);
- return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, 0);
+ return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
}
static int zvni_remote_neigh_update(zebra_vni_t *zvni,
@@ -2534,7 +2564,8 @@ static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
return -1;
vxl = &zif->l2info.vxl;
- sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
+ sticky = CHECK_FLAG(mac->flags,
+ (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)) ? 1 : 0;
return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
mac->fwd_info.r_vtep_ip, sticky);
@@ -3362,14 +3393,22 @@ static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
*/
static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
{
+ uint8_t flags;
+ int ret = 0;
+
if (!is_l3vni_oper_up(zl3vni))
return -1;
if (!(n->flags & ZEBRA_NEIGH_REMOTE)
|| !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
return 0;
-
- return kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac);
+#ifdef GNU_LINUX
+ flags = NTF_EXT_LEARNED;
+ if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
+ flags |= NTF_ROUTER;
+ ret = kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac, flags);
+#endif
+ return ret;
}
/*
@@ -4513,9 +4552,11 @@ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
wctx.zvni = zvni;
wctx.vty = vty;
+ wctx.addr_width = 15;
wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
wctx.r_vtep_ip = vtep_ip;
wctx.json = json;
+ hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
if (use_json) {
@@ -4944,7 +4985,8 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
struct ipaddr *ip,
struct ethaddr *macaddr,
uint16_t state,
- uint8_t ext_learned)
+ uint8_t ext_learned,
+ uint8_t router_flag)
{
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
@@ -4975,7 +5017,8 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
/* Is this about a local neighbor or a remote one? */
if (!ext_learned)
- return zvni_local_neigh_update(zvni, ifp, ip, macaddr);
+ return zvni_local_neigh_update(zvni, ifp, ip, macaddr,
+ router_flag);
return zvni_remote_neigh_update(zvni, ifp, ip, macaddr, state);
}
@@ -5152,6 +5195,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
char buf[ETHER_ADDR_STRLEN];
char buf1[INET6_ADDRSTRLEN];
uint8_t sticky = 0;
+ u_char remote_gw = 0;
uint8_t flags = 0;
struct interface *ifp = NULL;
struct zebra_if *zif = NULL;
@@ -5193,6 +5237,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
/* Get flags - sticky mac and/or gateway mac */
STREAM_GETC(s, flags);
sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+ remote_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
l++;
if (IS_ZEBRA_DEBUG_VXLAN)
@@ -5266,6 +5311,8 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
|| (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
!= sticky
+ || (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? 1 : 0)
+ != remote_gw
|| !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
update_mac = 1;
@@ -5297,6 +5344,11 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
else
UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+ if (remote_gw)
+ SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
+ else
+ UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
+
zvni_process_neigh_on_remote_mac_add(zvni, mac);
/* Install the entry. */
@@ -5353,6 +5405,10 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
n->r_vtep_ip = vtep_ip;
SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
+ /* Set router flag (R-bit) to this Neighbor entry */
+ if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
+ SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+
/* Install the entry. */
zvni_neigh_install(zvni, n);
}
diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h
index 34d115275..2732ef72e 100644
--- a/zebra/zebra_vxlan.h
+++ b/zebra/zebra_vxlan.h
@@ -124,7 +124,8 @@ extern int zebra_vxlan_svi_down(struct interface *ifp,
struct interface *link_if);
extern int zebra_vxlan_handle_kernel_neigh_update(
struct interface *ifp, struct interface *link_if, struct ipaddr *ip,
- struct ethaddr *macaddr, uint16_t state, uint8_t ext_learned);
+ struct ethaddr *macaddr, uint16_t state, uint8_t ext_learned,
+ uint8_t router_flag);
extern int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
struct interface *link_if,
struct ipaddr *ip);
diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h
index fa7075f2d..e86967041 100644
--- a/zebra/zebra_vxlan_private.h
+++ b/zebra/zebra_vxlan_private.h
@@ -247,6 +247,8 @@ struct zebra_mac_t_ {
#define ZEBRA_MAC_STICKY 0x08 /* Static MAC */
#define ZEBRA_MAC_REMOTE_RMAC 0x10 /* remote router mac */
#define ZEBRA_MAC_DEF_GW 0x20
+/* remote VTEP advertised MAC as default GW */
+#define ZEBRA_MAC_REMOTE_DEF_GW 0x40
/* Local or remote info. */
union {
@@ -329,6 +331,7 @@ struct zebra_neigh_t_ {
#define ZEBRA_NEIGH_REMOTE 0x02
#define ZEBRA_NEIGH_REMOTE_NH 0x04 /* neigh entry for remote vtep */
#define ZEBRA_NEIGH_DEF_GW 0x08
+#define ZEBRA_NEIGH_ROUTER_FLAG 0x10
enum zebra_neigh_state state;
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 4c90757d7..725cc9229 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -1024,7 +1024,6 @@ DEFUN (show_zebra_client_summary,
void zserv_read_file(char *input)
{
int fd;
- struct zserv *client = NULL;
struct thread t;
fd = open(input, O_RDONLY | O_NONBLOCK);