summaryrefslogtreecommitdiff
path: root/zebra/rt_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/rt_netlink.c')
-rw-r--r--zebra/rt_netlink.c405
1 files changed, 221 insertions, 184 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index de01ced411..f092fc5c85 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -66,6 +66,7 @@
#include "zebra/zebra_evpn_mh.h"
#include "zebra/zebra_trace.h"
#include "zebra/zebra_neigh.h"
+#include "lib/srv6.h"
#ifndef AF_MPLS
#define AF_MPLS 28
@@ -77,6 +78,8 @@
#define BR_SPH_LIST_SIZE 10
#endif
+DEFINE_MTYPE_STATIC(LIB, NH_SRV6, "Nexthop srv6");
+
static vlanid_t filter_vlan = 0;
/* We capture whether the current kernel supports nexthop ids; by
@@ -275,6 +278,7 @@ int zebra2proto(int proto)
proto = RTPROT_ZEBRA;
break;
case ZEBRA_ROUTE_CONNECT:
+ case ZEBRA_ROUTE_LOCAL:
case ZEBRA_ROUTE_KERNEL:
proto = RTPROT_KERNEL;
break;
@@ -363,7 +367,8 @@ static inline int proto2zebra(int proto, int family, bool is_nexthop)
proto = ZEBRA_ROUTE_NHG;
break;
}
- /* Intentional fall thru */
+ proto = ZEBRA_ROUTE_KERNEL;
+ break;
default:
/*
* When a user adds a new protocol this will show up
@@ -380,33 +385,6 @@ static inline int proto2zebra(int proto, int family, bool is_nexthop)
return proto;
}
-/*
-Pending: create an efficient table_id (in a tree/hash) based lookup)
- */
-vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id)
-{
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
- zvrf = vrf->info;
- if (zvrf == NULL)
- continue;
- /* case vrf with netns : match the netnsid */
- if (vrf_is_backend_netns()) {
- if (ns_id == zvrf_id(zvrf))
- return zvrf_id(zvrf);
- } else {
- /* VRF is VRF_BACKEND_VRF_LITE */
- if (zvrf->table_id != table_id)
- continue;
- return zvrf_id(zvrf);
- }
- }
-
- return VRF_DEFAULT;
-}
-
/**
* @parse_encap_mpls() - Parses encapsulated mpls attributes
* @tb: Pointer to rtattr to look for nested items in.
@@ -434,6 +412,36 @@ static int parse_encap_mpls(struct rtattr *tb, mpls_label_t *labels)
return num_labels;
}
+/**
+ * @parse_encap_seg6local_flavors() - Parses encapsulated SRv6 flavors
+ * attributes
+ * @tb: Pointer to rtattr to look for nested items in.
+ * @flv: Pointer to store SRv6 flavors info in.
+ *
+ * Return: 0 on success, non-zero on error
+ */
+static int parse_encap_seg6local_flavors(struct rtattr *tb,
+ struct seg6local_flavors_info *flv)
+{
+ struct rtattr *tb_encap[SEG6_LOCAL_FLV_MAX + 1] = {};
+
+ netlink_parse_rtattr_nested(tb_encap, SEG6_LOCAL_FLV_MAX, tb);
+
+ if (tb_encap[SEG6_LOCAL_FLV_OPERATION])
+ flv->flv_ops = *(uint32_t *)RTA_DATA(
+ tb_encap[SEG6_LOCAL_FLV_OPERATION]);
+
+ if (tb_encap[SEG6_LOCAL_FLV_LCBLOCK_BITS])
+ flv->lcblock_len = *(uint8_t *)RTA_DATA(
+ tb_encap[SEG6_LOCAL_FLV_LCBLOCK_BITS]);
+
+ if (tb_encap[SEG6_LOCAL_FLV_LCNODE_FN_BITS])
+ flv->lcnode_func_len = *(uint8_t *)RTA_DATA(
+ tb_encap[SEG6_LOCAL_FLV_LCNODE_FN_BITS]);
+
+ return 0;
+}
+
static enum seg6local_action_t
parse_encap_seg6local(struct rtattr *tb,
struct seg6local_context *ctx)
@@ -461,6 +469,11 @@ parse_encap_seg6local(struct rtattr *tb,
ctx->table =
*(uint32_t *)RTA_DATA(tb_encap[SEG6_LOCAL_VRFTABLE]);
+ if (tb_encap[SEG6_LOCAL_FLAVORS]) {
+ parse_encap_seg6local_flavors(tb_encap[SEG6_LOCAL_FLAVORS],
+ &ctx->flv);
+ }
+
return act;
}
@@ -468,19 +481,19 @@ static int parse_encap_seg6(struct rtattr *tb, struct in6_addr *segs)
{
struct rtattr *tb_encap[SEG6_IPTUNNEL_MAX + 1] = {};
struct seg6_iptunnel_encap *ipt = NULL;
- struct in6_addr *segments = NULL;
+ int i;
netlink_parse_rtattr_nested(tb_encap, SEG6_IPTUNNEL_MAX, tb);
- /*
- * TODO: It's not support multiple SID list.
- */
if (tb_encap[SEG6_IPTUNNEL_SRH]) {
ipt = (struct seg6_iptunnel_encap *)
RTA_DATA(tb_encap[SEG6_IPTUNNEL_SRH]);
- segments = ipt->srh[0].segments;
- *segs = segments[0];
- return 1;
+
+ for (i = ipt->srh[0].first_segment; i >= 0; i--)
+ memcpy(&segs[i], &ipt->srh[0].segments[i],
+ sizeof(struct in6_addr));
+
+ return ipt->srh[0].first_segment + 1;
}
return 0;
@@ -498,7 +511,7 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
int num_labels = 0;
enum seg6local_action_t seg6l_act = ZEBRA_SEG6_LOCAL_ACTION_UNSPEC;
struct seg6local_context seg6l_ctx = {};
- struct in6_addr seg6_segs = {};
+ struct in6_addr segs[SRV6_MAX_SIDS] = {};
int num_segs = 0;
vrf_id_t nh_vrf_id = vrf_id;
@@ -547,7 +560,7 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
if (tb[RTA_ENCAP] && tb[RTA_ENCAP_TYPE]
&& *(uint16_t *)RTA_DATA(tb[RTA_ENCAP_TYPE])
== LWTUNNEL_ENCAP_SEG6) {
- num_segs = parse_encap_seg6(tb[RTA_ENCAP], &seg6_segs);
+ num_segs = parse_encap_seg6(tb[RTA_ENCAP], segs);
}
if (rtm->rtm_flags & RTNH_F_ONLINK)
@@ -559,11 +572,21 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
if (num_labels)
nexthop_add_labels(&nh, ZEBRA_LSP_STATIC, num_labels, labels);
+ /* Resolve default values for SRv6 flavors */
+ if (seg6l_ctx.flv.flv_ops != ZEBRA_SEG6_LOCAL_FLV_OP_UNSPEC) {
+ if (seg6l_ctx.flv.lcblock_len == 0)
+ seg6l_ctx.flv.lcblock_len =
+ ZEBRA_DEFAULT_SEG6_LOCAL_FLV_LCBLOCK_LEN;
+ if (seg6l_ctx.flv.lcnode_func_len == 0)
+ seg6l_ctx.flv.lcnode_func_len =
+ ZEBRA_DEFAULT_SEG6_LOCAL_FLV_LCNODE_FN_LEN;
+ }
+
if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
nexthop_add_srv6_seg6local(&nh, seg6l_act, &seg6l_ctx);
if (num_segs)
- nexthop_add_srv6_seg6(&nh, &seg6_segs);
+ nexthop_add_srv6_seg6(&nh, segs, num_segs);
return nh;
}
@@ -583,7 +606,7 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
int num_labels = 0;
enum seg6local_action_t seg6l_act = ZEBRA_SEG6_LOCAL_ACTION_UNSPEC;
struct seg6local_context seg6l_ctx = {};
- struct in6_addr seg6_segs = {};
+ struct in6_addr segs[SRV6_MAX_SIDS] = {};
int num_segs = 0;
struct rtattr *rtnh_tb[RTA_MAX + 1] = {};
@@ -639,7 +662,7 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
&& *(uint16_t *)RTA_DATA(rtnh_tb[RTA_ENCAP_TYPE])
== LWTUNNEL_ENCAP_SEG6) {
num_segs = parse_encap_seg6(rtnh_tb[RTA_ENCAP],
- &seg6_segs);
+ segs);
}
}
@@ -666,12 +689,23 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
nexthop_add_labels(nh, ZEBRA_LSP_STATIC,
num_labels, labels);
+ /* Resolve default values for SRv6 flavors */
+ if (seg6l_ctx.flv.flv_ops !=
+ ZEBRA_SEG6_LOCAL_FLV_OP_UNSPEC) {
+ if (seg6l_ctx.flv.lcblock_len == 0)
+ seg6l_ctx.flv.lcblock_len =
+ ZEBRA_DEFAULT_SEG6_LOCAL_FLV_LCBLOCK_LEN;
+ if (seg6l_ctx.flv.lcnode_func_len == 0)
+ seg6l_ctx.flv.lcnode_func_len =
+ ZEBRA_DEFAULT_SEG6_LOCAL_FLV_LCNODE_FN_LEN;
+ }
+
if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
nexthop_add_srv6_seg6local(nh, seg6l_act,
&seg6l_ctx);
if (num_segs)
- nexthop_add_srv6_seg6(nh, &seg6_segs);
+ nexthop_add_srv6_seg6(nh, segs, num_segs);
if (rtnh->rtnh_flags & RTNH_F_ONLINK)
SET_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK);
@@ -790,7 +824,7 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h,
table = rtm->rtm_table;
/* Map to VRF */
- vrf_id = vrf_lookup_by_table(table, ns_id);
+ vrf_id = zebra_vrf_lookup_by_table(table, ns_id);
if (vrf_id == VRF_DEFAULT) {
if (!is_zebra_valid_kernel_table(table)
&& !is_zebra_main_routing_table(table))
@@ -993,6 +1027,8 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h,
re, ng, startup, ctx);
if (ng)
nexthop_group_delete(&ng);
+ if (ctx)
+ zebra_rib_route_entry_free(re);
} else {
/*
* I really don't see how this is possible
@@ -1079,7 +1115,7 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h,
else
table = rtm->rtm_table;
- vrf = vrf_lookup_by_table(table, ns_id);
+ vrf = zebra_vrf_lookup_by_table(table, ns_id);
if (tb[RTA_IIF])
iif = *(int *)RTA_DATA(tb[RTA_IIF]);
@@ -1485,37 +1521,80 @@ static bool _netlink_route_encode_nexthop_src(const struct nexthop *nexthop,
}
static ssize_t fill_seg6ipt_encap(char *buffer, size_t buflen,
- const struct in6_addr *seg)
+ struct seg6_seg_stack *segs)
{
struct seg6_iptunnel_encap *ipt;
struct ipv6_sr_hdr *srh;
- const size_t srhlen = 24;
+ size_t srhlen;
+ int i;
- /*
- * Caution: Support only SINGLE-SID, not MULTI-SID
- * This function only supports the case where segs represents
- * a single SID. If you want to extend the SRv6 functionality,
- * you should improve the Boundary Check.
- * Ex. In case of set a SID-List include multiple-SIDs as an
- * argument of the Transit Behavior, we must support variable
- * boundary check for buflen.
- */
- if (buflen < (sizeof(struct seg6_iptunnel_encap) +
- sizeof(struct ipv6_sr_hdr) + 16))
+ if (segs->num_segs > SRV6_MAX_SEGS) {
+ /* Exceeding maximum supported SIDs */
+ return -1;
+ }
+
+ srhlen = SRH_BASE_HEADER_LENGTH + SRH_SEGMENT_LENGTH * segs->num_segs;
+
+ if (buflen < (sizeof(struct seg6_iptunnel_encap) + srhlen))
return -1;
memset(buffer, 0, buflen);
ipt = (struct seg6_iptunnel_encap *)buffer;
ipt->mode = SEG6_IPTUN_MODE_ENCAP;
- srh = ipt->srh;
+
+ srh = (struct ipv6_sr_hdr *)&ipt->srh;
srh->hdrlen = (srhlen >> 3) - 1;
srh->type = 4;
- srh->segments_left = 0;
- srh->first_segment = 0;
- memcpy(&srh->segments[0], seg, sizeof(struct in6_addr));
+ srh->segments_left = segs->num_segs - 1;
+ srh->first_segment = segs->num_segs - 1;
+
+ for (i = 0; i < segs->num_segs; i++) {
+ memcpy(&srh->segments[i], &segs->seg[i],
+ sizeof(struct in6_addr));
+ }
+
+ return sizeof(struct seg6_iptunnel_encap) + srhlen;
+}
+
+static bool
+_netlink_nexthop_encode_seg6local_flavor(const struct nexthop *nexthop,
+ struct nlmsghdr *nlmsg, size_t buflen)
+{
+ struct rtattr *nest;
+ struct seg6local_flavors_info *flv;
+
+ assert(nexthop);
+
+ if (!nexthop->nh_srv6)
+ return false;
+
+ flv = &nexthop->nh_srv6->seg6local_ctx.flv;
+
+ if (flv->flv_ops == ZEBRA_SEG6_LOCAL_FLV_OP_UNSPEC)
+ return true;
+
+ nest = nl_attr_nest(nlmsg, buflen, SEG6_LOCAL_FLAVORS);
+ if (!nest)
+ return false;
+
+ if (!nl_attr_put32(nlmsg, buflen, SEG6_LOCAL_FLV_OPERATION,
+ flv->flv_ops))
+ return false;
- return srhlen + 4;
+ if (flv->lcblock_len)
+ if (!nl_attr_put8(nlmsg, buflen, SEG6_LOCAL_FLV_LCBLOCK_BITS,
+ flv->lcblock_len))
+ return false;
+
+ if (flv->lcnode_func_len)
+ if (!nl_attr_put8(nlmsg, buflen, SEG6_LOCAL_FLV_LCNODE_FN_BITS,
+ flv->lcnode_func_len))
+ return false;
+
+ nl_attr_nest_end(nlmsg, nest);
+
+ return true;
}
/* This function takes a nexthop as argument and adds
@@ -1649,10 +1728,17 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
nexthop->nh_srv6->seg6local_action);
return false;
}
+
+ if (!_netlink_nexthop_encode_seg6local_flavor(
+ nexthop, nlmsg, req_size))
+ return false;
+
nl_attr_nest_end(nlmsg, nest);
}
- if (!sid_zero(&nexthop->nh_srv6->seg6_segs)) {
+ if (nexthop->nh_srv6->seg6_segs &&
+ nexthop->nh_srv6->seg6_segs->num_segs &&
+ !sid_zero(nexthop->nh_srv6->seg6_segs)) {
char tun_buf[4096];
ssize_t tun_len;
struct rtattr *nest;
@@ -1663,8 +1749,9 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
if (!nest)
return false;
- tun_len = fill_seg6ipt_encap(tun_buf, sizeof(tun_buf),
- &nexthop->nh_srv6->seg6_segs);
+ tun_len =
+ fill_seg6ipt_encap(tun_buf, sizeof(tun_buf),
+ nexthop->nh_srv6->seg6_segs);
if (tun_len < 0)
return false;
if (!nl_attr_put(nlmsg, req_size, SEG6_IPTUNNEL_SRH,
@@ -2087,10 +2174,10 @@ static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen,
* Returns -1 on failure, 0 when the msg doesn't fit entirely in the buffer
* otherwise the number of bytes written to buf.
*/
-ssize_t netlink_route_multipath_msg_encode(int cmd,
- struct zebra_dplane_ctx *ctx,
+ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx,
uint8_t *data, size_t datalen,
- bool fpm, bool force_nhg)
+ bool fpm, bool force_nhg,
+ bool force_rr)
{
int bytelen;
struct nexthop *nexthop = NULL;
@@ -2124,8 +2211,10 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
- if ((cmd == RTM_NEWROUTE) &&
- ((p->family == AF_INET) || v6_rr_semantics))
+ if (((cmd == RTM_NEWROUTE) &&
+ ((p->family == AF_INET) || kernel_nexthops_supported() ||
+ zrouter.v6_rr_semantics)) ||
+ force_rr)
req->n.nlmsg_flags |= NLM_F_REPLACE;
req->n.nlmsg_type = cmd;
@@ -2328,19 +2417,21 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
p, routedesc, bytelen, nexthop,
&req->n, &req->r, datalen, cmd))
return 0;
+
+ /*
+ * Add encapsulation information when
+ * installing via FPM.
+ */
+ if (fpm) {
+ if (!netlink_route_nexthop_encap(&req->n,
+ datalen,
+ nexthop))
+ return 0;
+ }
+
nexthop_num++;
break;
}
-
- /*
- * Add encapsulation information when installing via
- * FPM.
- */
- if (fpm) {
- if (!netlink_route_nexthop_encap(
- &req->n, datalen, nexthop))
- return 0;
- }
}
if (setsrc) {
@@ -2387,6 +2478,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
tag))
return 0;
+ /*
+ * Add encapsulation information when installing via
+ * FPM.
+ */
+ if (fpm) {
+ if (!netlink_route_nexthop_encap(
+ &req->n, datalen, nexthop))
+ return 0;
+ }
+
if (!setsrc && src1) {
if (p->family == AF_INET)
src.ipv4 = src1->ipv4;
@@ -2400,23 +2501,6 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
nl_attr_nest_end(&req->n, nest);
- /*
- * Add encapsulation information when installing via
- * FPM.
- */
- if (fpm) {
- for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx),
- nexthop)) {
- if (CHECK_FLAG(nexthop->flags,
- NEXTHOP_FLAG_RECURSIVE))
- continue;
- if (!netlink_route_nexthop_encap(
- &req->n, datalen, nexthop))
- return 0;
- }
- }
-
-
if (setsrc) {
if (p->family == AF_INET) {
if (!nl_attr_put(&req->n, datalen, RTA_PREFSRC,
@@ -2503,7 +2587,7 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in)
* are trying to give me. So now we have this little hack.
*/
if (mroute->family == AF_INET)
- actual_table = (zvrf->table_id == RT_TABLE_MAIN)
+ actual_table = (zvrf->table_id == rt_table_main_id)
? RT_TABLE_DEFAULT
: zvrf->table_id;
else
@@ -2543,7 +2627,7 @@ static bool _netlink_nexthop_build_group(struct nlmsghdr *n, size_t req_size,
if (IS_ZEBRA_DEBUG_KERNEL) {
if (i == 0)
- snprintf(buf, sizeof(buf1), "group %u",
+ snprintf(buf, sizeof(buf), "group %u",
grp[i].id);
else {
snprintf(buf1, sizeof(buf1), "/%u",
@@ -2888,10 +2972,17 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
__func__, action);
return 0;
}
+
+ if (!_netlink_nexthop_encode_seg6local_flavor(
+ nh, &req->n, buflen))
+ return false;
+
nl_attr_nest_end(&req->n, nest);
}
- if (!sid_zero(&nh->nh_srv6->seg6_segs)) {
+ if (nh->nh_srv6->seg6_segs &&
+ nh->nh_srv6->seg6_segs->num_segs &&
+ !sid_zero(nh->nh_srv6->seg6_segs)) {
char tun_buf[4096];
ssize_t tun_len;
struct rtattr *nest;
@@ -2904,9 +2995,9 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
NHA_ENCAP | NLA_F_NESTED);
if (!nest)
return 0;
- tun_len = fill_seg6ipt_encap(tun_buf,
- sizeof(tun_buf),
- &nh->nh_srv6->seg6_segs);
+ tun_len = fill_seg6ipt_encap(
+ tun_buf, sizeof(tun_buf),
+ nh->nh_srv6->seg6_segs);
if (tun_len < 0)
return 0;
if (!nl_attr_put(&req->n, buflen,
@@ -2980,14 +3071,14 @@ static ssize_t netlink_newroute_msg_encoder(struct zebra_dplane_ctx *ctx,
void *buf, size_t buflen)
{
return netlink_route_multipath_msg_encode(RTM_NEWROUTE, ctx, buf,
- buflen, false, false);
+ buflen, false, false, false);
}
static ssize_t netlink_delroute_msg_encoder(struct zebra_dplane_ctx *ctx,
void *buf, size_t buflen)
{
return netlink_route_multipath_msg_encode(RTM_DELROUTE, ctx, buf,
- buflen, false, false);
+ buflen, false, false, false);
}
enum netlink_msg_status
@@ -3001,8 +3092,8 @@ netlink_put_route_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx)
} else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL) {
cmd = RTM_NEWROUTE;
} else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) {
-
- if (p->family == AF_INET || v6_rr_semantics) {
+ if (p->family == AF_INET || kernel_nexthops_supported() ||
+ zrouter.v6_rr_semantics) {
/* Single 'replace' operation */
/*
@@ -4151,11 +4242,11 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
* - struct ethaddr mac; (for NEW)
*/
if (h->nlmsg_type == RTM_NEWNEIGH)
- cmd = ZEBRA_NHRP_NEIGH_ADDED;
+ cmd = ZEBRA_NEIGH_ADDED;
else if (h->nlmsg_type == RTM_GETNEIGH)
- cmd = ZEBRA_NHRP_NEIGH_GET;
+ cmd = ZEBRA_NEIGH_GET;
else if (h->nlmsg_type == RTM_DELNEIGH)
- cmd = ZEBRA_NHRP_NEIGH_REMOVED;
+ cmd = ZEBRA_NEIGH_REMOVED;
else {
zlog_debug("%s(): unknown nlmsg type %u", __func__,
h->nlmsg_type);
@@ -4165,20 +4256,18 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
/* copy LLADDR information */
l2_len = RTA_PAYLOAD(tb[NDA_LLADDR]);
}
- if (l2_len == IPV4_MAX_BYTELEN || l2_len == 0) {
- union sockunion link_layer_ipv4;
- if (l2_len) {
- sockunion_family(&link_layer_ipv4) = AF_INET;
- memcpy((void *)sockunion_get_addr(&link_layer_ipv4),
- RTA_DATA(tb[NDA_LLADDR]), l2_len);
- } else
- sockunion_family(&link_layer_ipv4) = AF_UNSPEC;
- zsend_nhrp_neighbor_notify(
- cmd, ifp, &ip,
- netlink_nbr_entry_state_to_zclient(ndm->ndm_state),
- &link_layer_ipv4);
- }
+ union sockunion link_layer_ipv4;
+
+ if (l2_len) {
+ sockunion_family(&link_layer_ipv4) = AF_INET;
+ memcpy((void *)sockunion_get_addr(&link_layer_ipv4),
+ RTA_DATA(tb[NDA_LLADDR]), l2_len);
+ } else
+ sockunion_family(&link_layer_ipv4) = AF_UNSPEC;
+ zsend_neighbor_notify(cmd, ifp, &ip,
+ netlink_nbr_entry_state_to_zclient(ndm->ndm_state),
+ &link_layer_ipv4, l2_len);
if (h->nlmsg_type == RTM_GETNEIGH)
return 0;
@@ -4631,76 +4720,24 @@ static ssize_t netlink_neigh_msg_encoder(struct zebra_dplane_ctx *ctx,
void *buf, size_t buflen)
{
ssize_t ret = 0;
+ enum dplane_op_e op;
- switch (dplane_ctx_get_op(ctx)) {
- case DPLANE_OP_NEIGH_INSTALL:
- case DPLANE_OP_NEIGH_UPDATE:
- case DPLANE_OP_NEIGH_DISCOVER:
- case DPLANE_OP_NEIGH_IP_INSTALL:
+ op = dplane_ctx_get_op(ctx);
+ if (op == DPLANE_OP_NEIGH_INSTALL || op == DPLANE_OP_NEIGH_UPDATE ||
+ op == DPLANE_OP_NEIGH_DISCOVER || op == DPLANE_OP_NEIGH_IP_INSTALL)
ret = netlink_neigh_update_ctx(ctx, RTM_NEWNEIGH, buf, buflen);
- break;
- case DPLANE_OP_NEIGH_DELETE:
- case DPLANE_OP_NEIGH_IP_DELETE:
+ else if (op == DPLANE_OP_NEIGH_DELETE || op == DPLANE_OP_NEIGH_IP_DELETE)
ret = netlink_neigh_update_ctx(ctx, RTM_DELNEIGH, buf, buflen);
- break;
- case DPLANE_OP_VTEP_ADD:
+ else if (op == DPLANE_OP_VTEP_ADD)
ret = netlink_vxlan_flood_update_ctx(ctx, RTM_NEWNEIGH, buf,
buflen);
- break;
- case DPLANE_OP_VTEP_DELETE:
+ else if (op == DPLANE_OP_VTEP_DELETE)
ret = netlink_vxlan_flood_update_ctx(ctx, RTM_DELNEIGH, buf,
buflen);
- break;
- case DPLANE_OP_NEIGH_TABLE_UPDATE:
+ else if (op == DPLANE_OP_NEIGH_TABLE_UPDATE)
ret = netlink_neigh_table_update_ctx(ctx, buf, buflen);
- break;
- case DPLANE_OP_ROUTE_INSTALL:
- case DPLANE_OP_ROUTE_UPDATE:
- case DPLANE_OP_ROUTE_DELETE:
- case DPLANE_OP_ROUTE_NOTIFY:
- case DPLANE_OP_NH_INSTALL:
- case DPLANE_OP_NH_UPDATE:
- case DPLANE_OP_NH_DELETE:
- case DPLANE_OP_LSP_INSTALL:
- case DPLANE_OP_LSP_UPDATE:
- case DPLANE_OP_LSP_DELETE:
- case DPLANE_OP_LSP_NOTIFY:
- case DPLANE_OP_PW_INSTALL:
- case DPLANE_OP_PW_UNINSTALL:
- case DPLANE_OP_SYS_ROUTE_ADD:
- case DPLANE_OP_SYS_ROUTE_DELETE:
- case DPLANE_OP_ADDR_INSTALL:
- case DPLANE_OP_ADDR_UNINSTALL:
- case DPLANE_OP_MAC_INSTALL:
- case DPLANE_OP_MAC_DELETE:
- case DPLANE_OP_RULE_ADD:
- case DPLANE_OP_RULE_DELETE:
- case DPLANE_OP_RULE_UPDATE:
- case DPLANE_OP_BR_PORT_UPDATE:
- case DPLANE_OP_IPTABLE_ADD:
- case DPLANE_OP_IPTABLE_DELETE:
- case DPLANE_OP_IPSET_ADD:
- case DPLANE_OP_IPSET_DELETE:
- case DPLANE_OP_IPSET_ENTRY_ADD:
- case DPLANE_OP_IPSET_ENTRY_DELETE:
- case DPLANE_OP_GRE_SET:
- case DPLANE_OP_INTF_ADDR_ADD:
- case DPLANE_OP_INTF_ADDR_DEL:
- case DPLANE_OP_INTF_NETCONFIG:
- case DPLANE_OP_INTF_INSTALL:
- case DPLANE_OP_INTF_UPDATE:
- case DPLANE_OP_INTF_DELETE:
- case DPLANE_OP_TC_QDISC_INSTALL:
- case DPLANE_OP_TC_QDISC_UNINSTALL:
- case DPLANE_OP_TC_CLASS_ADD:
- case DPLANE_OP_TC_CLASS_DELETE:
- case DPLANE_OP_TC_CLASS_UPDATE:
- case DPLANE_OP_TC_FILTER_ADD:
- case DPLANE_OP_TC_FILTER_DELETE:
- case DPLANE_OP_TC_FILTER_UPDATE:
- case DPLANE_OP_NONE:
+ else
ret = -1;
- }
return ret;
}
@@ -4785,7 +4822,7 @@ ssize_t netlink_mpls_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx,
req->n.nlmsg_pid = nl->snl.nl_pid;
req->r.rtm_family = AF_MPLS;
- req->r.rtm_table = RT_TABLE_MAIN;
+ req->r.rtm_table = rt_table_main_id;
req->r.rtm_dst_len = MPLS_LABEL_LEN_BITS;
req->r.rtm_scope = RT_SCOPE_UNIVERSE;
req->r.rtm_type = RTN_UNICAST;