summaryrefslogtreecommitdiffstats
path: root/nhrpd
diff options
context:
space:
mode:
authorAmol Lad <amol.lad@4rf.com>2021-03-03 11:41:56 +0100
committerReuben Dowle <reuben.dowle@4rf.com>2021-03-18 04:35:41 +0100
commit85365e51f095db530a2dc0cc6521d3c9c5acb972 (patch)
treeb75c6935ab37ee547ef93d3faf1776cd2947b99d /nhrpd
parentnhrpd: add NHS details in NAT Extension header (diff)
downloadfrr-85365e51f095db530a2dc0cc6521d3c9c5acb972.tar.xz
frr-85365e51f095db530a2dc0cc6521d3c9c5acb972.zip
nhrpd: Add Claimed NBMA field in sh ip nhrp cache output
Signed-off-by: Reuben Dowle <reuben.dowle@4rf.com>
Diffstat (limited to 'nhrpd')
-rw-r--r--nhrpd/nhrp_cache.c15
-rw-r--r--nhrpd/nhrp_interface.c10
-rw-r--r--nhrpd/nhrp_nhs.c18
-rw-r--r--nhrpd/nhrp_peer.c11
-rw-r--r--nhrpd/nhrp_shortcut.c4
-rw-r--r--nhrpd/nhrp_vty.c27
-rw-r--r--nhrpd/nhrpd.h4
7 files changed, 61 insertions, 28 deletions
diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c
index 259e58e25..a8b12a080 100644
--- a/nhrpd/nhrp_cache.c
+++ b/nhrpd/nhrp_cache.c
@@ -212,7 +212,7 @@ static int nhrp_cache_do_timeout(struct thread *t)
c->t_timeout = NULL;
if (c->cur.type != NHRP_CACHE_INVALID)
- nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL);
+ nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL, NULL);
return 0;
}
@@ -301,7 +301,7 @@ static void nhrp_cache_peer_notifier(struct notifier_block *n,
case NOTIFY_PEER_DOWN:
case NOTIFY_PEER_IFCONFIG_CHANGED:
notifier_call(&c->notifier_list, NOTIFY_CACHE_DOWN);
- nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL);
+ nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL, NULL);
break;
case NOTIFY_PEER_NBMA_CHANGING:
if (c->cur.type == NHRP_CACHE_DYNAMIC)
@@ -422,7 +422,7 @@ static void nhrp_cache_newpeer_notifier(struct notifier_block *n,
int nhrp_cache_update_binding(struct nhrp_cache *c, enum nhrp_cache_type type,
int holding_time, struct nhrp_peer *p,
- uint32_t mtu, union sockunion *nbma_oa)
+ uint32_t mtu, union sockunion *nbma_oa, union sockunion *nbma_claimed)
{
char buf[2][SU_ADDRSTRLEN];
@@ -464,6 +464,12 @@ int nhrp_cache_update_binding(struct nhrp_cache *c, enum nhrp_cache_type type,
memset(&c->cur.remote_nbma_natoa, 0,
sizeof(c->cur.remote_nbma_natoa));
+ if (nbma_claimed)
+ c->cur.remote_nbma_claimed = *nbma_claimed;
+ else
+ memset(&c->cur.remote_nbma_claimed, 0,
+ sizeof(c->cur.remote_nbma_claimed));
+
nhrp_peer_unref(p);
} else {
debugf(NHRP_DEBUG_COMMON,
@@ -478,6 +484,9 @@ int nhrp_cache_update_binding(struct nhrp_cache *c, enum nhrp_cache_type type,
if (nbma_oa)
c->new.remote_nbma_natoa = *nbma_oa;
+ if (nbma_claimed)
+ c->new.remote_nbma_claimed = *nbma_claimed;
+
if (holding_time > 0)
c->new.expires = monotime(NULL) + holding_time;
else if (holding_time < 0)
diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c
index b348cc0de..ebbe6a9b7 100644
--- a/nhrpd/nhrp_interface.c
+++ b/nhrpd/nhrp_interface.c
@@ -255,7 +255,7 @@ static void nhrp_interface_update_address(struct interface *ifp, afi_t afi,
nc = nhrp_cache_get(ifp, &if_ad->addr, 0);
if (nc)
nhrp_cache_update_binding(nc, NHRP_CACHE_LOCAL, -1,
- NULL, 0, NULL);
+ NULL, 0, NULL, NULL);
}
debugf(NHRP_DEBUG_KERNEL, "%s: IPv%d address changed to %s", ifp->name,
@@ -267,7 +267,7 @@ static void nhrp_interface_update_address(struct interface *ifp, afi_t afi,
nc = nhrp_cache_get(ifp, &addr, 1);
if (nc)
nhrp_cache_update_binding(nc, NHRP_CACHE_LOCAL, 0, NULL,
- 0, NULL);
+ 0, NULL, NULL);
}
notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_ADDRESS_CHANGED);
@@ -364,7 +364,7 @@ static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc,
if (c && c->map) {
nhrp_cache_update_binding(
c, c->cur.type, -1,
- nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
+ nhrp_peer_get(ifp, &nbma_addr), 0, NULL, NULL);
}
return;
}
@@ -375,11 +375,11 @@ static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc,
c->map = 1;
if (cc->type == NHRP_CACHE_LOCAL)
nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
- NULL);
+ NULL, NULL);
else {
nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
nhrp_peer_get(ifp, &cc->nbma), 0,
- NULL);
+ NULL, NULL);
}
}
diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c
index 93bbcb1b6..86eaeeb4b 100644
--- a/nhrpd/nhrp_nhs.c
+++ b/nhrpd/nhrp_nhs.c
@@ -32,7 +32,8 @@ static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg)
struct nhrp_cie_header *cie;
struct nhrp_cache *c;
struct zbuf extpl;
- union sockunion cie_nbma, cie_proto, *proto;
+ union sockunion cie_nbma, cie_nbma_nhs, cie_proto, cie_proto_nhs, *proto;
+ char buf[64];
int ok = 0, holdtime;
unsigned short mtu = 0;
@@ -66,6 +67,7 @@ static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg)
/* Parse extensions */
sockunion_family(&nifp->nat_nbma) = AF_UNSPEC;
+ sockunion_family(&cie_nbma_nhs) = AF_UNSPEC;
while ((ext = nhrp_ext_pull(&p->extensions, &extpl)) != NULL) {
switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) {
case NHRP_EXTENSION_NAT_ADDRESS:
@@ -75,10 +77,16 @@ static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg)
&cie_proto)) {
nifp->nat_nbma = cie_nbma;
debugf(NHRP_DEBUG_IF,
- "%s: NAT detected, real NBMA address: %pSU",
- ifp->name, &nifp->nbma);
+ "%s: NAT detected, real NBMA address: %s",
+ ifp->name,
+ sockunion2str(&nifp->nbma, buf,
+ sizeof(buf)));
}
break;
+ case NHRP_EXTENSION_RESPONDER_ADDRESS:
+ /* NHS adds its own record as responder address */
+ nhrp_cie_pull(&extpl, p->hdr, &cie_nbma_nhs, &cie_proto_nhs);
+ break;
}
}
@@ -96,7 +104,7 @@ static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg)
c = nhrp_cache_get(ifp, &p->dst_proto, 1);
if (c)
nhrp_cache_update_binding(c, NHRP_CACHE_NHS, holdtime,
- nhrp_peer_ref(r->peer), mtu, NULL);
+ nhrp_peer_ref(r->peer), mtu, NULL, &cie_nbma_nhs);
}
static int nhrp_reg_timeout(struct thread *t)
@@ -111,7 +119,7 @@ static int nhrp_reg_timeout(struct thread *t)
c = nhrp_cache_get(r->nhs->ifp, &r->proto_addr, 0);
if (c)
nhrp_cache_update_binding(c, NHRP_CACHE_NHS, -1, NULL,
- 0, NULL);
+ 0, NULL, NULL);
sockunion_family(&r->proto_addr) = AF_UNSPEC;
}
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index 86e52be17..dfede1d7d 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -427,7 +427,7 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp)
struct nhrp_cie_header *cie;
struct nhrp_extension_header *ext;
struct nhrp_cache *c;
- union sockunion cie_nbma, cie_nbma_nat, cie_proto, *proto_addr, *nbma_addr;
+ union sockunion cie_nbma, cie_nbma_nat, cie_proto, *proto_addr, *nbma_addr, *claimed_nbma_addr;
int holdtime, prefix_len, hostprefix_len;
struct nhrp_interface *nifp = ifp->info;
struct nhrp_peer *peer;
@@ -510,6 +510,11 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp)
else
nbma_addr = &pp->src_nbma;
+ if(sockunion_family(&cie_nbma) != AF_UNSPEC)
+ claimed_nbma_addr = &cie_nbma;
+ else
+ claimed_nbma_addr = &pp->src_nbma;
+
holdtime = htons(cie->holding_time);
debugf(NHRP_DEBUG_COMMON,
"shortcut res_rep: holdtime is %u (if 0, using %u)",
@@ -533,7 +538,7 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp)
nbma_addr ? buf : "(NULL)");
if (!nhrp_cache_update_binding(c, NHRP_CACHE_DYNAMIC, holdtime,
nhrp_peer_get(pp->ifp, nbma_addr),
- htons(cie->mtu), nbma_addr)) {
+ htons(cie->mtu), nbma_addr, claimed_nbma_addr)) {
cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED;
continue;
}
@@ -677,7 +682,7 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
if (!nhrp_cache_update_binding(c, NHRP_CACHE_DYNAMIC, holdtime,
nhrp_peer_ref(p->peer),
- htons(cie->mtu), nbma_natoa)) {
+ htons(cie->mtu), nbma_natoa, nbma_addr)) {
cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED;
continue;
}
diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c
index fd86ab996..139308044 100644
--- a/nhrpd/nhrp_shortcut.c
+++ b/nhrpd/nhrp_shortcut.c
@@ -325,7 +325,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid,
nhrp_cache_update_binding(c, NHRP_CACHE_DYNAMIC,
holding_time,
nhrp_peer_get(pp->ifp, nbma),
- htons(cie->mtu), nbma);
+ htons(cie->mtu), nbma, &cie_nbma);
} else {
debugf(NHRP_DEBUG_COMMON,
"Shortcut: no cache for nbma %s", buf[2]);
@@ -340,7 +340,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid,
nhrp_cache_update_binding(c_dst_proto, NHRP_CACHE_DYNAMIC,
holding_time,
nhrp_peer_get(pp->ifp, nbma),
- htons(cie->mtu), nbma);
+ htons(cie->mtu), nbma, &cie_nbma);
} else {
debugf(NHRP_DEBUG_COMMON,
"Shortcut: no cache for nbma %s", buf[2]);
diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c
index 1ea4c5e64..a55903707 100644
--- a/nhrpd/nhrp_vty.c
+++ b/nhrpd/nhrp_vty.c
@@ -525,11 +525,11 @@ DEFUN(if_nhrp_map, if_nhrp_map_cmd,
c->map = 1;
if (type == NHRP_CACHE_LOCAL)
nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
- NULL);
+ NULL, NULL);
else
nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
nhrp_peer_get(ifp, &nbma_addr), 0,
- NULL);
+ NULL, NULL);
return CMD_SUCCESS;
}
@@ -565,7 +565,7 @@ DEFUN(if_no_nhrp_map, if_no_nhrp_map_cmd,
return CMD_SUCCESS;
nhrp_cache_update_binding(c, c->cur.type, -1,
- nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
+ nhrp_peer_get(ifp, &nbma_addr), 0, NULL, NULL);
return CMD_SUCCESS;
}
@@ -629,7 +629,7 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
{
struct info_ctx *ctx = pctx;
struct vty *vty = ctx->vty;
- char buf[2][SU_ADDRSTRLEN];
+ char buf[3][SU_ADDRSTRLEN];
struct json_object *json = NULL;
if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
@@ -637,8 +637,8 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
if (!ctx->count && !ctx->json) {
- vty_out(vty, "%-8s %-8s %-24s %-24s %-6s %s\n", "Iface", "Type",
- "Protocol", "NBMA", "Flags", "Identity");
+ vty_out(vty, "%-8s %-8s %-24s %-24s %-24s %-6s %s\n", "Iface", "Type",
+ "Protocol", "NBMA", "Claimed NBMA", "Flags", "Identity");
}
ctx->count++;
@@ -649,6 +649,13 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
else
snprintf(buf[1], sizeof(buf[1]), "-");
+ if (c->cur.peer && sockunion_family(&c->cur.remote_nbma_claimed) != AF_UNSPEC)
+ sockunion2str(&c->cur.remote_nbma_claimed,
+ buf[2], sizeof(buf[2]));
+
+ else
+ snprintf(buf[2], sizeof(buf[2]), "-");
+
if (ctx->json) {
json = json_object_new_object();
json_object_string_add(json, "interface", c->ifp->name);
@@ -656,6 +663,7 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
nhrp_cache_type_str[c->cur.type]);
json_object_string_add(json, "protocol", buf[0]);
json_object_string_add(json, "nbma", buf[1]);
+ json_object_string_add(json, "claimed_nbma", buf[2]);
if (c->used)
json_object_boolean_true_add(json, "used");
@@ -681,9 +689,10 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
json_object_array_add(ctx->json, json);
return;
}
- vty_out(ctx->vty, "%-8s %-8s %-24s %-24s %c%c%c %s\n", c->ifp->name,
+ vty_out(ctx->vty, "%-8s %-8s %-24s %-24s %-24s %c%c%c %s\n",
+ c->ifp->name,
nhrp_cache_type_str[c->cur.type],
- buf[0], buf[1],
+ buf[0], buf[1], buf[2],
c->used ? 'U' : ' ', c->t_timeout ? 'T' : ' ',
c->t_auth ? 'A' : ' ',
c->cur.peer ? c->cur.peer->vc->remote.id : "-");
@@ -970,7 +979,7 @@ static void clear_nhrp_cache(struct nhrp_cache *c, void *data)
{
struct info_ctx *ctx = data;
if (c->cur.type <= NHRP_CACHE_DYNAMIC) {
- nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL);
+ nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL, NULL);
ctx->count++;
}
}
diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h
index b566fd65a..c8dd3daef 100644
--- a/nhrpd/nhrpd.h
+++ b/nhrpd/nhrpd.h
@@ -226,6 +226,7 @@ struct nhrp_cache {
struct {
enum nhrp_cache_type type;
union sockunion remote_nbma_natoa;
+ union sockunion remote_nbma_claimed;
struct nhrp_peer *peer;
time_t expires;
uint32_t mtu;
@@ -385,7 +386,8 @@ void nhrp_cache_config_foreach(struct interface *ifp,
void nhrp_cache_set_used(struct nhrp_cache *, int);
int nhrp_cache_update_binding(struct nhrp_cache *, enum nhrp_cache_type type,
int holding_time, struct nhrp_peer *p,
- uint32_t mtu, union sockunion *nbma_natoa);
+ uint32_t mtu, union sockunion *nbma_natoa,
+ union sockunion *claimed_nbma);
void nhrp_cache_notify_add(struct nhrp_cache *c, struct notifier_block *,
notifier_fn_t);
void nhrp_cache_notify_del(struct nhrp_cache *c, struct notifier_block *);