summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/log.c4
-rw-r--r--lib/zclient.c56
-rw-r--r--lib/zclient.h16
-rw-r--r--nhrpd/netlink_arp.c48
-rw-r--r--nhrpd/nhrp_route.c15
-rw-r--r--zebra/rt_netlink.c13
-rw-r--r--zebra/zapi_msg.c85
-rw-r--r--zebra/zapi_msg.h2
-rw-r--r--zebra/zebra_dplane.c11
-rw-r--r--zebra/zebra_dplane.h3
10 files changed, 130 insertions, 123 deletions
diff --git a/lib/log.c b/lib/log.c
index ce0b1c9670..ca2f501686 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -470,8 +470,8 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_NHRP_NEIGH_GET),
DESC_ENTRY(ZEBRA_NHRP_NEIGH_REGISTER),
DESC_ENTRY(ZEBRA_NHRP_NEIGH_UNREGISTER),
- DESC_ENTRY(ZEBRA_NEIGH_ADD),
- DESC_ENTRY(ZEBRA_NEIGH_DEL),
+ DESC_ENTRY(ZEBRA_NEIGH_IP_ADD),
+ DESC_ENTRY(ZEBRA_NEIGH_IP_DEL),
DESC_ENTRY(ZEBRA_CONFIGURE_ARP)};
#undef DESC_ENTRY
diff --git a/lib/zclient.c b/lib/zclient.c
index 8d94fe1aca..d613906d82 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -4196,3 +4196,59 @@ char *zclient_evpn_dump_macip_flags(uint8_t flags, char *buf, size_t len)
return buf;
}
+
+static int zclient_neigh_ip_read_entry(struct stream *s, struct ipaddr *add)
+{
+ uint8_t family;
+
+ STREAM_GETC(s, family);
+ if (family != AF_INET && family != AF_INET6)
+ return -1;
+
+ STREAM_GET(&add->ip.addr, s, family2addrsize(family));
+ add->ipa_type = family;
+ return 0;
+ stream_failure:
+ return -1;
+}
+
+int zclient_neigh_ip_encode(struct stream *s,
+ uint16_t cmd,
+ union sockunion *in,
+ union sockunion *out,
+ struct interface *ifp)
+{
+ int ret = 0;
+
+ zclient_create_header(s, cmd, ifp->vrf_id);
+ stream_putc(s, sockunion_family(in));
+ stream_write(s, sockunion_get_addr(in), sockunion_get_addrlen(in));
+ if (out && sockunion_family(out) != AF_UNSPEC) {
+ stream_putc(s, sockunion_family(out));
+ stream_write(s, sockunion_get_addr(out),
+ sockunion_get_addrlen(out));
+ } else
+ stream_putc(s, AF_UNSPEC);
+ stream_putl(s, ifp->ifindex);
+ if (out)
+ stream_putl(s, ZEBRA_NEIGH_STATE_REACHABLE);
+ else
+ stream_putl(s, ZEBRA_NEIGH_STATE_FAILED);
+ return ret;
+}
+
+int zclient_neigh_ip_decode(struct stream *s, struct zapi_neigh_ip *api)
+{
+ int ret;
+
+ ret = zclient_neigh_ip_read_entry(s, &api->ip_in);
+ if (ret < 0)
+ return -1;
+ zclient_neigh_ip_read_entry(s, &api->ip_out);
+
+ STREAM_GETL(s, api->index);
+ STREAM_GETL(s, api->ndm_state);
+ return 0;
+ stream_failure:
+ return -1;
+}
diff --git a/lib/zclient.h b/lib/zclient.h
index 25b7103116..90240e40b2 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -229,8 +229,8 @@ typedef enum {
ZEBRA_NHRP_NEIGH_GET,
ZEBRA_NHRP_NEIGH_REGISTER,
ZEBRA_NHRP_NEIGH_UNREGISTER,
- ZEBRA_NEIGH_ADD,
- ZEBRA_NEIGH_DEL,
+ ZEBRA_NEIGH_IP_ADD,
+ ZEBRA_NEIGH_IP_DEL,
ZEBRA_CONFIGURE_ARP,
} zebra_message_types_t;
@@ -809,13 +809,23 @@ extern struct zclient_options zclient_options_default;
/* link layer representation for GRE like interfaces
* ip_in is the underlay IP, ip_out is the tunnel dest
* index stands for the index of the interface
+ * ndm state stands for the NDM value in netlink
*/
-struct zapi_nbr {
+#define ZEBRA_NEIGH_STATE_REACHABLE (0x02)
+#define ZEBRA_NEIGH_STATE_FAILED (0x20)
+struct zapi_neigh_ip {
int cmd;
struct ipaddr ip_in;
struct ipaddr ip_out;
ifindex_t index;
+ uint32_t ndm_state;
};
+int zclient_neigh_ip_decode(struct stream *s, struct zapi_neigh_ip *api);
+int zclient_neigh_ip_encode(struct stream *s,
+ uint16_t cmd,
+ union sockunion *in,
+ union sockunion *out,
+ struct interface *ifp);
/*
* We reserve the top 4 bits for l2-NHG, everything else
diff --git a/nhrpd/netlink_arp.c b/nhrpd/netlink_arp.c
index 4cca177c9a..8eab7cd54d 100644
--- a/nhrpd/netlink_arp.c
+++ b/nhrpd/netlink_arp.c
@@ -154,31 +154,26 @@ void nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS)
{
union sockunion addr = {}, lladdr = {};
struct interface *ifp;
- ifindex_t idx;
- struct ethaddr mac;
int state, ndm_state;
struct nhrp_cache *c;
- unsigned short l2_len;
-
- STREAM_GETL(zclient->ibuf, idx);
- ifp = if_lookup_by_index(idx, vrf_id);
- STREAM_GETW(zclient->ibuf, addr.sa.sa_family);
- if (addr.sa.sa_family == AF_INET) {
- STREAM_GET(&addr.sin.sin_addr.s_addr,
- zclient->ibuf, IPV4_MAX_BYTELEN);
- } else {
- STREAM_GET(&addr.sin6.sin6_addr.s6_addr,
- zclient->ibuf, IPV6_MAX_BYTELEN);
- }
- STREAM_GETL(zclient->ibuf, ndm_state);
-
- STREAM_GETL(zclient->ibuf, l2_len);
- if (l2_len) {
- STREAM_GET(&mac, zclient->ibuf, l2_len);
- if (l2_len == IPV4_MAX_BYTELEN)
- sockunion_set(&lladdr, AF_INET, (const uint8_t *)&mac,
- l2_len);
- }
+ struct zapi_neigh_ip api = {};
+
+ zclient_neigh_ip_decode(zclient->ibuf, &api);
+ if (api.ip_in.ipa_type == AF_UNSPEC)
+ return;
+ sockunion_family(&addr) = api.ip_in.ipa_type;
+ memcpy((uint8_t *)sockunion_get_addr(&addr), &api.ip_in.ip.addr,
+ family2addrsize(api.ip_in.ipa_type));
+
+ sockunion_family(&lladdr) = api.ip_out.ipa_type;
+ if (api.ip_out.ipa_type != AF_UNSPEC)
+ memcpy((uint8_t *)sockunion_get_addr(&lladdr),
+ &api.ip_out.ip.addr,
+ family2addrsize(api.ip_out.ipa_type));
+
+ ifp = if_lookup_by_index(api.index, vrf_id);
+ ndm_state = api.ndm_state;
+
if (!ifp)
return;
c = nhrp_cache_get(ifp, &addr, 0);
@@ -205,12 +200,9 @@ void nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS)
}
} else {
state = (cmd == ZEBRA_NHRP_NEIGH_ADDED) ? ndm_state
- : NUD_FAILED;
- nhrp_cache_set_used(c, state == NUD_REACHABLE);
+ : ZEBRA_NEIGH_STATE_FAILED;
+ nhrp_cache_set_used(c, state == ZEBRA_NEIGH_STATE_REACHABLE);
}
- return;
- stream_failure:
- return;
}
void netlink_init(void)
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c
index 99f35b79de..23fa0771ef 100644
--- a/nhrpd/nhrp_route.c
+++ b/nhrpd/nhrp_route.c
@@ -422,18 +422,9 @@ void nhrp_send_zebra_nbr(union sockunion *in,
return;
s = zclient->obuf;
stream_reset(s);
- zclient_create_header(s,
- out ? ZEBRA_NEIGH_ADD : ZEBRA_NEIGH_DEL,
- ifp->vrf_id);
- stream_putc(s, sockunion_family(in));
- stream_write(s, sockunion_get_addr(in), sockunion_get_addrlen(in));
- if (out) {
- stream_putc(s, sockunion_family(out));
- stream_write(s, sockunion_get_addr(out),
- sockunion_get_addrlen(out));
- }
- stream_putl(s, ifp->ifindex);
-
+ zclient_neigh_ip_encode(s, out ? ZEBRA_NEIGH_IP_ADD :
+ ZEBRA_NEIGH_IP_DEL, in, out,
+ ifp);
stream_putw_at(s, 0, stream_get_endp(s));
zclient_send_message(zclient);
}
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index b641d07000..dc0c839674 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -3390,9 +3390,18 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
l2_len = RTA_PAYLOAD(tb[NDA_LLADDR]);
memcpy(&mac, RTA_DATA(tb[NDA_LLADDR]), l2_len);
}
- if (l2_len == IPV4_MAX_BYTELEN || l2_len == 0)
+ 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),
+ &mac, l2_len);
+ } else
+ sockunion_family(&link_layer_ipv4) = AF_UNSPEC;
zsend_nhrp_neighbor_notify(cmd, ifp, &ip, ndm->ndm_state,
- &mac, l2_len);
+ &link_layer_ipv4);
+ }
if (h->nlmsg_type == RTM_GETNEIGH)
return 0;
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 46e4766e97..e854d7ff3a 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -976,45 +976,30 @@ void zsend_ipset_entry_notify_owner(const struct zebra_dplane_ctx *ctx,
void zsend_nhrp_neighbor_notify(int cmd, struct interface *ifp,
struct ipaddr *ipaddr, int ndm_state,
- void *mac, int macsize)
+ union sockunion *link_layer_ipv4)
{
struct stream *s;
struct listnode *node, *nnode;
struct zserv *client;
afi_t afi;
+ union sockunion ip;
if (IS_ZEBRA_DEBUG_PACKET)
zlog_debug("%s: Notifying Neighbor entry (%u)",
__PRETTY_FUNCTION__, cmd);
- if (ipaddr->ipa_type == IPADDR_V4)
- afi = AFI_IP;
- else if (ipaddr->ipa_type == IPADDR_V6)
- afi = AFI_IP6;
- else
- return;
+ sockunion_family(&ip) = ipaddr_family(ipaddr);
+ afi = family2afi(sockunion_family(&ip));
+ memcpy((char *)sockunion_get_addr(&ip), &ipaddr->ip.addr,
+ family2addrsize(sockunion_family(&ip)));
+
for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
if (!vrf_bitmap_check(client->nhrp_neighinfo[afi], ifp->vrf_id))
continue;
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
-
- zclient_create_header(s, cmd, ifp->vrf_id);
- stream_putl(s, ifp->ifindex);
- if (ipaddr->ipa_type == IPADDR_V4) {
- stream_putw(s, AF_INET);
- stream_put(s, &ipaddr->ip._v4_addr, IPV4_MAX_BYTELEN);
- } else if (ipaddr->ipa_type == IPADDR_V6) {
- stream_putw(s, AF_INET6);
- stream_put(s, &ipaddr->ip._v6_addr, IPV6_MAX_BYTELEN);
- } else
- return;
- stream_putl(s, ndm_state);
- stream_putl(s, macsize);
- if (mac)
- stream_put(s, mac, macsize);
+ zclient_neigh_ip_encode(s, cmd, &ip, link_layer_ipv4, ifp);
stream_putw_at(s, 0, stream_get_endp(s));
-
zserv_send_message(client, s);
}
}
@@ -3214,38 +3199,6 @@ stream_failure:
return;
}
-static int zebra_neigh_read_ip(struct stream *s, struct ipaddr *add)
-{
- uint8_t family;
-
- STREAM_GETC(s, family);
- if (family != AF_INET && family != AF_INET6)
- return -1;
-
- STREAM_GET(&add->ip.addr, s, family2addrsize(family));
- add->ipa_type = family;
- return 0;
-stream_failure:
- return -1;
-}
-
-static int zebra_neigh_get(struct stream *s, struct zapi_nbr *api, bool add)
-{
- int ret;
-
- ret = zebra_neigh_read_ip(s, &api->ip_in);
- if (ret < 0)
- return -1;
- if (add) {
- ret = zebra_neigh_read_ip(s, &api->ip_out);
- if (ret < 0)
- return -1;
- }
- STREAM_GETL(s, api->index);
- return 0;
-stream_failure:
- return -1;
-}
static inline void zebra_neigh_register(ZAPI_HANDLER_ARGS)
{
@@ -3299,43 +3252,41 @@ stream_failure:
return;
}
-static inline void zebra_neigh_add(ZAPI_HANDLER_ARGS)
+static inline void zebra_neigh_ip_add(ZAPI_HANDLER_ARGS)
{
struct stream *s;
- struct zapi_nbr api;
+ struct zapi_neigh_ip api = {};
int ret;
const struct interface *ifp;
s = msg;
- memset(&api, 0, sizeof(api));
- ret = zebra_neigh_get(s, &api, true);
+ ret = zclient_neigh_ip_decode(s, &api);
if (ret < 0)
return;
ifp = if_lookup_by_index(api.index, zvrf_id(zvrf));
if (!ifp)
return;
dplane_neigh_ip_update(DPLANE_OP_NEIGH_IP_INSTALL, ifp, &api.ip_out,
- &api.ip_in, false, client->proto);
+ &api.ip_in, api.ndm_state, client->proto);
}
-static inline void zebra_neigh_del(ZAPI_HANDLER_ARGS)
+static inline void zebra_neigh_ip_del(ZAPI_HANDLER_ARGS)
{
struct stream *s;
- struct zapi_nbr api;
+ struct zapi_neigh_ip api = {};
int ret;
struct interface *ifp;
s = msg;
- memset(&api, 0, sizeof(api));
- ret = zebra_neigh_get(s, &api, false);
+ ret = zclient_neigh_ip_decode(s, &api);
if (ret < 0)
return;
ifp = if_lookup_by_index(api.index, zvrf_id(zvrf));
if (!ifp)
return;
dplane_neigh_ip_update(DPLANE_OP_NEIGH_IP_DELETE, ifp, &api.ip_out,
- &api.ip_in, true, client->proto);
+ &api.ip_in, api.ndm_state, client->proto);
}
@@ -3524,8 +3475,8 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_ROUTE_NOTIFY_REQUEST] = zread_route_notify_request,
[ZEBRA_EVPN_REMOTE_NH_ADD] = zebra_evpn_proc_remote_nh,
[ZEBRA_EVPN_REMOTE_NH_DEL] = zebra_evpn_proc_remote_nh,
- [ZEBRA_NEIGH_ADD] = zebra_neigh_add,
- [ZEBRA_NEIGH_DEL] = zebra_neigh_del,
+ [ZEBRA_NEIGH_IP_ADD] = zebra_neigh_ip_add,
+ [ZEBRA_NEIGH_IP_DEL] = zebra_neigh_ip_del,
[ZEBRA_NHRP_NEIGH_REGISTER] = zebra_neigh_register,
[ZEBRA_NHRP_NEIGH_UNREGISTER] = zebra_neigh_unregister,
[ZEBRA_CONFIGURE_ARP] = zebra_configure_arp,
diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h
index 2822619da9..0beb3cc100 100644
--- a/zebra/zapi_msg.h
+++ b/zebra/zapi_msg.h
@@ -106,7 +106,7 @@ extern int zsend_sr_policy_notify_status(uint32_t color,
int status);
extern void zsend_nhrp_neighbor_notify(int cmd, struct interface *ifp,
struct ipaddr *ipaddr, int ndm_state,
- void *mac, int macsize);
+ union sockunion *link_layer_ipv4);
extern int zsend_client_close_notify(struct zserv *client,
struct zserv *closed_client);
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 8186ab98a5..c7f396ebf9 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -3509,7 +3509,7 @@ enum zebra_dplane_result dplane_neigh_ip_update(enum dplane_op_e op,
const struct interface *ifp,
struct ipaddr *link_ip,
struct ipaddr *ip,
- bool permanent, int protocol)
+ uint32_t ndm_state, int protocol)
{
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
uint16_t state = 0;
@@ -3523,12 +3523,9 @@ enum zebra_dplane_result dplane_neigh_ip_update(enum dplane_op_e op,
zlog_debug("init link ctx %s: ifp %s, ip %s link %s",
dplane_op2str(op), ifp->name, buf1, buf2);
}
- if (op == DPLANE_OP_NEIGH_IP_INSTALL) {
- if (!permanent)
- state = DPLANE_NUD_REACHABLE;
- else
- state = DPLANE_NUD_PERMANENT;
- } else
+ if (ndm_state == ZEBRA_NEIGH_STATE_REACHABLE)
+ state = DPLANE_NUD_REACHABLE;
+ else if (ndm_state == ZEBRA_NEIGH_STATE_FAILED)
state = DPLANE_NUD_FAILED;
update_flags = DPLANE_NEIGH_NO_EXTENSION;
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index c678706354..8d51d93cd4 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -611,7 +611,8 @@ enum zebra_dplane_result dplane_neigh_ip_update(enum dplane_op_e op,
const struct interface *ifp,
struct ipaddr *link_ip,
struct ipaddr *ip,
- bool permanent, int protocol);
+ uint32_t ndm_state,
+ int protocol);
/*
* Enqueue evpn mac operations for the dataplane.