mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-27 07:15:33 +00:00
commit
e546c80068
@ -393,6 +393,8 @@ void nhrp_interface_set_protection(struct interface *ifp, const char *profile, c
|
||||
|
||||
if (nifp->ipsec_fallback_profile) free(nifp->ipsec_fallback_profile);
|
||||
nifp->ipsec_fallback_profile = fallback_profile ? strdup(fallback_profile) : NULL;
|
||||
|
||||
notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_ADDRESS_CHANGED);
|
||||
}
|
||||
|
||||
void nhrp_interface_set_source(struct interface *ifp, const char *ifname)
|
||||
|
@ -18,19 +18,6 @@ DEFINE_MTYPE_STATIC(NHRPD, NHRP_NHS, "NHRP next hop server")
|
||||
DEFINE_MTYPE_STATIC(NHRPD, NHRP_REGISTRATION, "NHRP registration entries")
|
||||
|
||||
static int nhrp_nhs_resolve(struct thread *t);
|
||||
|
||||
struct nhrp_registration {
|
||||
struct list_head reglist_entry;
|
||||
struct thread *t_register;
|
||||
struct nhrp_nhs *nhs;
|
||||
struct nhrp_reqid reqid;
|
||||
unsigned int timeout;
|
||||
unsigned mark : 1;
|
||||
union sockunion proto_addr;
|
||||
struct nhrp_peer *peer;
|
||||
struct notifier_block peer_notifier;
|
||||
};
|
||||
|
||||
static int nhrp_reg_send_req(struct thread *t);
|
||||
|
||||
static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg)
|
||||
@ -370,3 +357,18 @@ void nhrp_nhs_terminate(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nhrp_nhs_foreach(struct interface *ifp, afi_t afi, void (*cb)(struct nhrp_nhs *, struct nhrp_registration *, void *), void *ctx)
|
||||
{
|
||||
struct nhrp_interface *nifp = ifp->info;
|
||||
struct nhrp_nhs *nhs;
|
||||
struct nhrp_registration *reg;
|
||||
|
||||
list_for_each_entry(nhs, &nifp->afi[afi].nhslist_head, nhslist_entry) {
|
||||
if (!list_empty(&nhs->reglist_head)) {
|
||||
list_for_each_entry(reg, &nhs->reglist_head, reglist_entry)
|
||||
cb(nhs, reg, ctx);
|
||||
} else
|
||||
cb(nhs, 0, ctx);
|
||||
}
|
||||
}
|
||||
|
@ -250,6 +250,8 @@ int nhrp_peer_check(struct nhrp_peer *p, int establish)
|
||||
return 0;
|
||||
if (p->requested)
|
||||
return 0;
|
||||
if (!nifp->ipsec_profile)
|
||||
return 0;
|
||||
if (sockunion_family(&vc->local.nbma) == AF_UNSPEC)
|
||||
return 0;
|
||||
|
||||
@ -730,6 +732,15 @@ static void nhrp_packet_debug(struct zbuf *zb, const char *dir)
|
||||
reply ? buf[0] : buf[1]);
|
||||
}
|
||||
|
||||
static int proto2afi(uint16_t proto)
|
||||
{
|
||||
switch (proto) {
|
||||
case ETH_P_IP: return AFI_IP;
|
||||
case ETH_P_IPV6: return AFI_IP6;
|
||||
}
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
|
||||
struct nhrp_route_info {
|
||||
int local;
|
||||
struct interface *ifp;
|
||||
@ -749,7 +760,7 @@ void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb)
|
||||
const char *info = NULL;
|
||||
union sockunion *target_addr;
|
||||
unsigned paylen, extoff, extlen, realsize;
|
||||
afi_t afi;
|
||||
afi_t nbma_afi, proto_afi;
|
||||
|
||||
debugf(NHRP_DEBUG_KERNEL, "PACKET: Recv %s -> %s",
|
||||
sockunion2str(&vc->remote.nbma, buf[0], sizeof buf[0]),
|
||||
@ -777,20 +788,21 @@ void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb)
|
||||
pp.hdr = hdr;
|
||||
pp.peer = p;
|
||||
|
||||
afi = htons(hdr->afnum);
|
||||
nbma_afi = htons(hdr->afnum);
|
||||
proto_afi = proto2afi(htons(hdr->protocol_type));
|
||||
if (hdr->type > ZEBRA_NUM_OF(packet_types) ||
|
||||
hdr->version != NHRP_VERSION_RFC2332 ||
|
||||
afi >= AFI_MAX ||
|
||||
nbma_afi >= AFI_MAX || proto_afi == AF_UNSPEC ||
|
||||
packet_types[hdr->type].type == PACKET_UNKNOWN ||
|
||||
htons(hdr->packet_size) > realsize) {
|
||||
zlog_info("From %s: error: packet type %d, version %d, AFI %d, size %d (real size %d)",
|
||||
zlog_info("From %s: error: packet type %d, version %d, AFI %d, proto %x, size %d (real size %d)",
|
||||
sockunion2str(&vc->remote.nbma, buf[0], sizeof buf[0]),
|
||||
(int) hdr->type, (int) hdr->version, (int) afi,
|
||||
(int) htons(hdr->packet_size),
|
||||
(int) realsize);
|
||||
(int) hdr->type, (int) hdr->version,
|
||||
(int) nbma_afi, (int) htons(hdr->protocol_type),
|
||||
(int) htons(hdr->packet_size), (int) realsize);
|
||||
goto drop;
|
||||
}
|
||||
pp.if_ad = &((struct nhrp_interface *)ifp->info)->afi[afi];
|
||||
pp.if_ad = &((struct nhrp_interface *)ifp->info)->afi[proto_afi];
|
||||
|
||||
extoff = htons(hdr->extension_offset);
|
||||
if (extoff) {
|
||||
@ -806,7 +818,7 @@ void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb)
|
||||
extlen = zbuf_used(zb);
|
||||
zbuf_init(&pp.extensions, zbuf_pulln(zb, extlen), extlen, extlen);
|
||||
|
||||
if (!nifp->afi[afi].network_id) {
|
||||
if (!nifp->afi[proto_afi].network_id) {
|
||||
info = "nhrp not enabled";
|
||||
goto drop;
|
||||
}
|
||||
|
115
nhrpd/nhrp_vty.c
115
nhrpd/nhrp_vty.c
@ -504,6 +504,32 @@ DEFUN(if_nhrp_map, if_nhrp_map_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(if_no_nhrp_map, if_no_nhrp_map_cmd,
|
||||
"no " AFI_CMD " nhrp map <A.B.C.D|X:X::X:X>",
|
||||
NO_STR
|
||||
AFI_STR
|
||||
NHRP_STR
|
||||
"Nexthop Server configuration\n"
|
||||
"IPv4 protocol address\n"
|
||||
"IPv6 protocol address\n")
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(interface,ifp);
|
||||
afi_t afi = cmd_to_afi(argv[1]);
|
||||
union sockunion proto_addr;
|
||||
struct nhrp_cache *c;
|
||||
|
||||
if (str2sockunion(argv[4]->arg, &proto_addr) < 0 ||
|
||||
afi2family(afi) != sockunion_family(&proto_addr))
|
||||
return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
|
||||
|
||||
c = nhrp_cache_get(ifp, &proto_addr, 0);
|
||||
if (!c || !c->map)
|
||||
return nhrp_vty_return(vty, NHRP_ERR_ENTRY_NOT_FOUND);
|
||||
|
||||
nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(if_nhrp_nhs, if_nhrp_nhs_cmd,
|
||||
AFI_CMD " nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
|
||||
AFI_STR
|
||||
@ -592,6 +618,56 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
static void show_ip_nhrp_nhs(struct nhrp_nhs *n, struct nhrp_registration *reg, void *pctx)
|
||||
{
|
||||
struct info_ctx *ctx = pctx;
|
||||
struct vty *vty = ctx->vty;
|
||||
char buf[2][SU_ADDRSTRLEN];
|
||||
|
||||
if (!ctx->count) {
|
||||
vty_out(vty, "%-8s %-24s %-16s %-16s%s",
|
||||
"Iface",
|
||||
"FQDN",
|
||||
"NBMA",
|
||||
"Protocol",
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
ctx->count++;
|
||||
|
||||
vty_out(vty, "%-8s %-24s %-16s %-16s%s",
|
||||
n->ifp->name,
|
||||
n->nbma_fqdn,
|
||||
(reg && reg->peer) ? sockunion2str(®->peer->vc->remote.nbma, buf[0], sizeof buf[0]) : "-",
|
||||
sockunion2str(reg ? ®->proto_addr : &n->proto_addr, buf[1], sizeof buf[1]),
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
static void show_ip_nhrp_shortcut(struct nhrp_shortcut *s, void *pctx)
|
||||
{
|
||||
struct info_ctx *ctx = pctx;
|
||||
struct nhrp_cache *c;
|
||||
struct vty *vty = ctx->vty;
|
||||
char buf1[PREFIX_STRLEN], buf2[SU_ADDRSTRLEN];
|
||||
|
||||
if (!ctx->count) {
|
||||
vty_out(vty, "%-8s %-24s %-24s %s%s",
|
||||
"Type",
|
||||
"Prefix",
|
||||
"Via",
|
||||
"Identity",
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
ctx->count++;
|
||||
|
||||
c = s->cache;
|
||||
vty_out(ctx->vty, "%-8s %-24s %-24s %s%s",
|
||||
nhrp_cache_type_str[s->type],
|
||||
prefix2str(s->p, buf1, sizeof buf1),
|
||||
c ? sockunion2str(&c->remote_addr, buf2, sizeof buf2) : "",
|
||||
(c && c->cur.peer) ? c->cur.peer->vc->remote.id : "",
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx)
|
||||
{
|
||||
struct info_ctx *ctx = pctx;
|
||||
@ -631,38 +707,13 @@ static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx)
|
||||
vty_out(ctx->vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
static void show_ip_nhrp_shortcut(struct nhrp_shortcut *s, void *pctx)
|
||||
{
|
||||
struct info_ctx *ctx = pctx;
|
||||
struct nhrp_cache *c;
|
||||
struct vty *vty = ctx->vty;
|
||||
char buf1[PREFIX_STRLEN], buf2[SU_ADDRSTRLEN];
|
||||
|
||||
if (!ctx->count) {
|
||||
vty_out(vty, "%-8s %-24s %-24s %s%s",
|
||||
"Type",
|
||||
"Prefix",
|
||||
"Via",
|
||||
"Identity",
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
ctx->count++;
|
||||
|
||||
c = s->cache;
|
||||
vty_out(ctx->vty, "%-8s %-24s %-24s %s%s",
|
||||
nhrp_cache_type_str[s->type],
|
||||
prefix2str(s->p, buf1, sizeof buf1),
|
||||
c ? sockunion2str(&c->remote_addr, buf2, sizeof buf2) : "",
|
||||
(c && c->cur.peer) ? c->cur.peer->vc->remote.id : "",
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
DEFUN(show_ip_nhrp, show_ip_nhrp_cmd,
|
||||
"show " AFI_CMD " nhrp [cache|shortcut|opennhrp]",
|
||||
"show " AFI_CMD " nhrp [cache|nhs|shortcut|opennhrp]",
|
||||
SHOW_STR
|
||||
AFI_STR
|
||||
"NHRP information\n"
|
||||
"Forwarding cache information\n"
|
||||
"Next hop server information\n"
|
||||
"Shortcut information\n"
|
||||
"opennhrpctl style cache dump\n")
|
||||
{
|
||||
@ -676,13 +727,16 @@ DEFUN(show_ip_nhrp, show_ip_nhrp_cmd,
|
||||
if (argc <= 3 || argv[3]->text[0] == 'c') {
|
||||
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
|
||||
nhrp_cache_foreach(ifp, show_ip_nhrp_cache, &ctx);
|
||||
} else if (argv[3]->text[0] == 'o') {
|
||||
} else if (argv[3]->text[0] == 'n') {
|
||||
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
|
||||
nhrp_nhs_foreach(ifp, ctx.afi, show_ip_nhrp_nhs, &ctx);
|
||||
} else if (argv[3]->text[0] == 's') {
|
||||
nhrp_shortcut_foreach(ctx.afi, show_ip_nhrp_shortcut, &ctx);
|
||||
} else {
|
||||
vty_out(vty, "Status: ok%s%s", VTY_NEWLINE, VTY_NEWLINE);
|
||||
ctx.count++;
|
||||
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
|
||||
nhrp_cache_foreach(ifp, show_ip_opennhrp_cache, &ctx);
|
||||
} else {
|
||||
nhrp_shortcut_foreach(ctx.afi, show_ip_nhrp_shortcut, &ctx);
|
||||
}
|
||||
|
||||
if (!ctx.count) {
|
||||
@ -919,6 +973,7 @@ void nhrp_config_init(void)
|
||||
install_element(INTERFACE_NODE, &if_nhrp_reg_flags_cmd);
|
||||
install_element(INTERFACE_NODE, &if_no_nhrp_reg_flags_cmd);
|
||||
install_element(INTERFACE_NODE, &if_nhrp_map_cmd);
|
||||
install_element(INTERFACE_NODE, &if_no_nhrp_map_cmd);
|
||||
install_element(INTERFACE_NODE, &if_nhrp_nhs_cmd);
|
||||
install_element(INTERFACE_NODE, &if_no_nhrp_nhs_cmd);
|
||||
}
|
||||
|
@ -254,6 +254,18 @@ struct nhrp_nhs {
|
||||
struct list_head reglist_head;
|
||||
};
|
||||
|
||||
struct nhrp_registration {
|
||||
struct list_head reglist_entry;
|
||||
struct thread *t_register;
|
||||
struct nhrp_nhs *nhs;
|
||||
struct nhrp_reqid reqid;
|
||||
unsigned int timeout;
|
||||
unsigned mark : 1;
|
||||
union sockunion proto_addr;
|
||||
struct nhrp_peer *peer;
|
||||
struct notifier_block peer_notifier;
|
||||
};
|
||||
|
||||
#define NHRP_IFF_SHORTCUT 0x0001
|
||||
#define NHRP_IFF_REDIRECT 0x0002
|
||||
#define NHRP_IFF_REG_NO_UNIQUE 0x0100
|
||||
@ -311,6 +323,7 @@ int nhrp_nhs_add(struct interface *ifp, afi_t afi, union sockunion *proto_addr,
|
||||
int nhrp_nhs_del(struct interface *ifp, afi_t afi, union sockunion *proto_addr, const char *nbma_fqdn);
|
||||
int nhrp_nhs_free(struct nhrp_nhs *nhs);
|
||||
void nhrp_nhs_terminate(void);
|
||||
void nhrp_nhs_foreach(struct interface *ifp, afi_t afi, void (*cb)(struct nhrp_nhs *, struct nhrp_registration *, void *), void *ctx);
|
||||
|
||||
void nhrp_route_update_nhrp(const struct prefix *p, struct interface *ifp);
|
||||
void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix *p, struct interface *ifp, const union sockunion *nexthop, uint32_t mtu);
|
||||
|
28
nhrpd/vici.c
28
nhrpd/vici.c
@ -220,6 +220,23 @@ static void parse_sa_message(
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_cmd_response(
|
||||
struct vici_message_ctx *ctx,
|
||||
enum vici_type_t msgtype,
|
||||
const struct blob *key, const struct blob *val)
|
||||
{
|
||||
char buf[512];
|
||||
|
||||
switch (msgtype) {
|
||||
case VICI_KEY_VALUE:
|
||||
if (blob_equal(key, "errmsg") && blob2buf(val, buf, sizeof(buf)))
|
||||
zlog_err("VICI: strongSwan: %s", buf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void vici_recv_sa(struct vici_conn *vici, struct zbuf *msg, int event)
|
||||
{
|
||||
char buf[32];
|
||||
@ -265,11 +282,14 @@ static void vici_recv_message(struct vici_conn *vici, struct zbuf *msg)
|
||||
else if (blob_equal(&name, "child-state-destroying"))
|
||||
vici_recv_sa(vici, msg, 2);
|
||||
break;
|
||||
case VICI_CMD_RESPONSE:
|
||||
vici_parse_message(vici, msg, parse_cmd_response, 0);
|
||||
break;
|
||||
case VICI_EVENT_UNKNOWN:
|
||||
case VICI_CMD_UNKNOWN:
|
||||
zlog_err("VICI: StrongSwan does not support mandatory events (unpatched?)");
|
||||
break;
|
||||
case VICI_EVENT_CONFIRM:
|
||||
case VICI_CMD_RESPONSE:
|
||||
break;
|
||||
default:
|
||||
zlog_notice("VICI: Unrecognized message type %d", msgtype);
|
||||
@ -449,9 +469,9 @@ void vici_request_vc(const char *profile, union sockunion *src, union sockunion
|
||||
vici_submit_request(
|
||||
vici, "initiate",
|
||||
VICI_KEY_VALUE, "child", strlen(profile), profile,
|
||||
VICI_KEY_VALUE, "timeout", 2, "-1",
|
||||
VICI_KEY_VALUE, "async", 1, "1",
|
||||
VICI_KEY_VALUE, "init-limits", 1, prio ? "0" : "1",
|
||||
VICI_KEY_VALUE, "timeout", (size_t) 2, "-1",
|
||||
VICI_KEY_VALUE, "async", (size_t) 1, "1",
|
||||
VICI_KEY_VALUE, "init-limits", (size_t) 1, prio ? "0" : "1",
|
||||
VICI_KEY_VALUE, "my-host", strlen(buf[0]), buf[0],
|
||||
VICI_KEY_VALUE, "other-host", strlen(buf[1]), buf[1],
|
||||
VICI_END);
|
||||
|
Loading…
Reference in New Issue
Block a user