mirror of
https://github.com/openbsd/src.git
synced 2025-01-03 06:45:37 -08:00
Send VPLS MAC withdrawals.
RFC 4762 says that MAC address withdrawal messages can be used to improve convergence time in VPLS networks. This patch makes ldpd send MAC withdrawals whenever a non-pseudowire interface pertaining to a VPLS goes down. The processing of received MAC withdrawals will be implemented later.
This commit is contained in:
parent
9982546c37
commit
38e6508824
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: address.c,v 1.34 2017/03/04 00:18:43 renato Exp $ */
|
||||
/* $OpenBSD: address.c,v 1.35 2017/03/04 00:21:48 renato Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
|
||||
@ -28,12 +28,14 @@
|
||||
|
||||
static void send_address(struct nbr *, int, struct if_addr_head *,
|
||||
unsigned int, int);
|
||||
static int gen_address_list_tlv(struct ibuf *, uint16_t, int,
|
||||
struct if_addr_head *, unsigned int);
|
||||
static int gen_address_list_tlv(struct ibuf *, int, struct if_addr_head *,
|
||||
unsigned int);
|
||||
static int gen_mac_list_tlv(struct ibuf *, uint8_t *);
|
||||
static void address_list_add(struct if_addr_head *, struct if_addr *);
|
||||
static void address_list_clr(struct if_addr_head *);
|
||||
static void log_msg_address(int, uint16_t, struct nbr *, int,
|
||||
union ldpd_addr *);
|
||||
static void log_msg_mac_withdrawal(int, struct nbr *, uint8_t *);
|
||||
|
||||
static void
|
||||
send_address(struct nbr *nbr, int af, struct if_addr_head *addr_list,
|
||||
@ -87,8 +89,7 @@ send_address(struct nbr *nbr, int af, struct if_addr_head *addr_list,
|
||||
size -= LDP_HDR_SIZE;
|
||||
err |= gen_msg_hdr(buf, msg_type, size);
|
||||
size -= LDP_MSG_SIZE;
|
||||
err |= gen_address_list_tlv(buf, size, af, addr_list,
|
||||
tlv_addr_count);
|
||||
err |= gen_address_list_tlv(buf, af, addr_list, tlv_addr_count);
|
||||
if (err) {
|
||||
address_list_clr(addr_list);
|
||||
ibuf_free(buf);
|
||||
@ -139,6 +140,40 @@ send_address_all(struct nbr *nbr, int af)
|
||||
send_address(nbr, af, &addr_list, addr_count, 0);
|
||||
}
|
||||
|
||||
void
|
||||
send_mac_withdrawal(struct nbr *nbr, struct map *fec, uint8_t *mac)
|
||||
{
|
||||
struct ibuf *buf;
|
||||
uint16_t size;
|
||||
int err;
|
||||
|
||||
size = LDP_HDR_SIZE + LDP_MSG_SIZE + ADDR_LIST_SIZE + len_fec_tlv(fec) +
|
||||
TLV_HDR_SIZE;
|
||||
if (mac)
|
||||
size += ETHER_ADDR_LEN;
|
||||
|
||||
if ((buf = ibuf_open(size)) == NULL)
|
||||
fatal(__func__);
|
||||
|
||||
err = gen_ldp_hdr(buf, size);
|
||||
size -= LDP_HDR_SIZE;
|
||||
err |= gen_msg_hdr(buf, MSG_TYPE_ADDRWITHDRAW, size);
|
||||
size -= LDP_MSG_SIZE;
|
||||
err |= gen_address_list_tlv(buf, AF_INET, NULL, 0);
|
||||
err |= gen_fec_tlv(buf, fec);
|
||||
err |= gen_mac_list_tlv(buf, mac);
|
||||
if (err) {
|
||||
ibuf_free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
log_msg_mac_withdrawal(1, nbr, mac);
|
||||
|
||||
evbuf_enqueue(&nbr->tcp->wbuf, buf);
|
||||
|
||||
nbr_fsm(nbr, NBR_EVT_PDU_SENT);
|
||||
}
|
||||
|
||||
int
|
||||
recv_address(struct nbr *nbr, char *buf, uint16_t len)
|
||||
{
|
||||
@ -280,8 +315,8 @@ recv_address(struct nbr *nbr, char *buf, uint16_t len)
|
||||
}
|
||||
|
||||
static int
|
||||
gen_address_list_tlv(struct ibuf *buf, uint16_t size, int af,
|
||||
struct if_addr_head *addr_list, unsigned int tlv_addr_count)
|
||||
gen_address_list_tlv(struct ibuf *buf, int af, struct if_addr_head *addr_list,
|
||||
unsigned int tlv_addr_count)
|
||||
{
|
||||
struct address_list_tlv alt;
|
||||
uint16_t addr_size;
|
||||
@ -290,7 +325,6 @@ gen_address_list_tlv(struct ibuf *buf, uint16_t size, int af,
|
||||
|
||||
memset(&alt, 0, sizeof(alt));
|
||||
alt.type = htons(TLV_TYPE_ADDRLIST);
|
||||
alt.length = htons(size - TLV_HDR_SIZE);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
@ -304,8 +338,12 @@ gen_address_list_tlv(struct ibuf *buf, uint16_t size, int af,
|
||||
default:
|
||||
fatalx("gen_address_list_tlv: unknown af");
|
||||
}
|
||||
alt.length = htons(sizeof(alt.family) + addr_size * tlv_addr_count);
|
||||
|
||||
err |= ibuf_add(buf, &alt, sizeof(alt));
|
||||
if (addr_list == NULL)
|
||||
return (err);
|
||||
|
||||
LIST_FOREACH(if_addr, addr_list, entry) {
|
||||
err |= ibuf_add(buf, &if_addr->addr, addr_size);
|
||||
if (--tlv_addr_count == 0)
|
||||
@ -315,6 +353,23 @@ gen_address_list_tlv(struct ibuf *buf, uint16_t size, int af,
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
gen_mac_list_tlv(struct ibuf *buf, uint8_t *mac)
|
||||
{
|
||||
struct tlv tlv;
|
||||
int err;
|
||||
|
||||
memset(&tlv, 0, sizeof(tlv));
|
||||
tlv.type = htons(TLV_TYPE_MAC_LIST);
|
||||
if (mac)
|
||||
tlv.length = htons(ETHER_ADDR_LEN);
|
||||
err = ibuf_add(buf, &tlv, sizeof(tlv));
|
||||
if (mac)
|
||||
err |= ibuf_add(buf, mac, ETHER_ADDR_LEN);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
address_list_add(struct if_addr_head *addr_list, struct if_addr *if_addr)
|
||||
{
|
||||
@ -346,3 +401,11 @@ log_msg_address(int out, uint16_t msg_type, struct nbr *nbr, int af,
|
||||
log_debug("msg-%s: %s: lsr-id %s, address %s", (out) ? "out" : "in",
|
||||
msg_name(msg_type), inet_ntoa(nbr->id), log_addr(af, addr));
|
||||
}
|
||||
|
||||
static void
|
||||
log_msg_mac_withdrawal(int out, struct nbr *nbr, uint8_t *mac)
|
||||
{
|
||||
log_debug("msg-%s: mac withdrawal: lsr-id %s, mac %s",
|
||||
(out) ? "out" : "in", inet_ntoa(nbr->id),
|
||||
(mac) ? ether_ntoa((struct ether_addr *)mac) : "wildcard");
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kroute.c,v 1.64 2017/03/03 23:41:27 renato Exp $ */
|
||||
/* $OpenBSD: kroute.c,v 1.65 2017/03/04 00:21:48 renato Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015, 2016 Renato Westphal <renato@openbsd.org>
|
||||
@ -25,6 +25,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netmpls/mpls.h>
|
||||
#include <errno.h>
|
||||
@ -873,6 +874,8 @@ kif_update(unsigned short ifindex, int flags, struct if_data *ifd,
|
||||
|
||||
kif->k.flags = flags;
|
||||
kif->k.link_state = ifd->ifi_link_state;
|
||||
if (sdl)
|
||||
memcpy(kif->k.mac, LLADDR(sdl), sizeof(kif->k.mac));
|
||||
kif->k.if_type = ifd->ifi_type;
|
||||
kif->k.baudrate = ifd->ifi_baudrate;
|
||||
kif->k.mtu = ifd->ifi_mtu;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: l2vpn.c,v 1.23 2017/03/04 00:12:25 renato Exp $ */
|
||||
/* $OpenBSD: l2vpn.c,v 1.24 2017/03/04 00:21:48 renato Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
|
||||
@ -111,7 +111,7 @@ l2vpn_if_new(struct l2vpn *l2vpn, struct kif *kif)
|
||||
strlcpy(lif->ifname, kif->ifname, sizeof(lif->ifname));
|
||||
lif->ifindex = kif->ifindex;
|
||||
lif->flags = kif->flags;
|
||||
lif->link_state = kif->link_state;
|
||||
lif->linkstate = kif->link_state;
|
||||
|
||||
return (lif);
|
||||
}
|
||||
@ -128,6 +128,33 @@ l2vpn_if_find(struct l2vpn *l2vpn, unsigned int ifindex)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
l2vpn_if_update(struct l2vpn_if *lif)
|
||||
{
|
||||
struct l2vpn *l2vpn = lif->l2vpn;
|
||||
struct l2vpn_pw *pw;
|
||||
struct map fec;
|
||||
struct nbr *nbr;
|
||||
|
||||
if ((lif->flags & IFF_UP) && LINK_STATE_IS_UP(lif->linkstate))
|
||||
return;
|
||||
|
||||
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
|
||||
nbr = nbr_find_ldpid(pw->lsr_id.s_addr);
|
||||
if (nbr == NULL)
|
||||
continue;
|
||||
|
||||
memset(&fec, 0, sizeof(fec));
|
||||
fec.type = MAP_TYPE_PWID;
|
||||
fec.fec.pwid.type = l2vpn->pw_type;
|
||||
fec.fec.pwid.group_id = 0;
|
||||
fec.flags |= F_MAP_PW_ID;
|
||||
fec.fec.pwid.pwid = pw->pwid;
|
||||
|
||||
send_mac_withdrawal(nbr, &fec, lif->mac);
|
||||
}
|
||||
}
|
||||
|
||||
struct l2vpn_pw *
|
||||
l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: lde.h,v 1.49 2017/03/04 00:15:35 renato Exp $ */
|
||||
/* $OpenBSD: lde.h,v 1.50 2017/03/04 00:21:48 renato Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
|
||||
@ -198,6 +198,7 @@ void l2vpn_init(struct l2vpn *);
|
||||
void l2vpn_exit(struct l2vpn *);
|
||||
struct l2vpn_if *l2vpn_if_new(struct l2vpn *, struct kif *);
|
||||
struct l2vpn_if *l2vpn_if_find(struct l2vpn *, unsigned int);
|
||||
void l2vpn_if_update(struct l2vpn_if *);
|
||||
struct l2vpn_pw *l2vpn_pw_new(struct l2vpn *, struct kif *);
|
||||
struct l2vpn_pw *l2vpn_pw_find(struct l2vpn *, unsigned int);
|
||||
void l2vpn_pw_init(struct l2vpn_pw *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ldp.h,v 1.41 2017/03/04 00:15:35 renato Exp $ */
|
||||
/* $OpenBSD: ldp.h,v 1.42 2017/03/04 00:21:48 renato Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
|
||||
@ -95,6 +95,7 @@
|
||||
#define TLV_TYPE_FRSESSION 0x0502
|
||||
#define TLV_TYPE_LABELREQUEST 0x0600
|
||||
/* RFC 4447 */
|
||||
#define TLV_TYPE_MAC_LIST 0x8404
|
||||
#define TLV_TYPE_PW_STATUS 0x896A
|
||||
#define TLV_TYPE_PW_IF_PARAM 0x096B
|
||||
#define TLV_TYPE_PW_GROUP_ID 0x096C
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ldpd.h,v 1.86 2017/03/04 00:12:26 renato Exp $ */
|
||||
/* $OpenBSD: ldpd.h,v 1.87 2017/03/04 00:21:48 renato Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
|
||||
@ -26,8 +26,10 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/tree.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <event.h>
|
||||
#include <imsg.h>
|
||||
|
||||
@ -327,7 +329,8 @@ struct l2vpn_if {
|
||||
char ifname[IF_NAMESIZE];
|
||||
unsigned int ifindex;
|
||||
uint16_t flags;
|
||||
uint8_t link_state;
|
||||
uint8_t linkstate;
|
||||
uint8_t mac[ETHER_ADDR_LEN];
|
||||
};
|
||||
|
||||
struct l2vpn_pw {
|
||||
@ -474,6 +477,7 @@ struct kif {
|
||||
unsigned short ifindex;
|
||||
int flags;
|
||||
uint8_t link_state;
|
||||
uint8_t mac[ETHER_ADDR_LEN];
|
||||
int mtu;
|
||||
unsigned int rdomain;
|
||||
uint8_t if_type;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ldpe.c,v 1.73 2017/03/03 23:41:27 renato Exp $ */
|
||||
/* $OpenBSD: ldpe.c,v 1.74 2017/03/04 00:21:48 renato Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
|
||||
@ -221,8 +221,8 @@ ldpe_dispatch_main(int fd, short event, void *bula)
|
||||
struct iface *niface;
|
||||
struct tnbr *ntnbr;
|
||||
struct nbr_params *nnbrp;
|
||||
static struct l2vpn *nl2vpn;
|
||||
struct l2vpn_if *nlif;
|
||||
static struct l2vpn *l2vpn, *nl2vpn;
|
||||
struct l2vpn_if *lif = NULL, *nlif;
|
||||
struct l2vpn_pw *npw;
|
||||
struct imsg imsg;
|
||||
struct imsgev *iev = bula;
|
||||
@ -265,12 +265,24 @@ ldpe_dispatch_main(int fd, short event, void *bula)
|
||||
kif = imsg.data;
|
||||
|
||||
iface = if_lookup(leconf, kif->ifindex);
|
||||
if (!iface)
|
||||
if (iface) {
|
||||
iface->flags = kif->flags;
|
||||
iface->linkstate = kif->link_state;
|
||||
if_update(iface, AF_UNSPEC);
|
||||
break;
|
||||
}
|
||||
|
||||
iface->flags = kif->flags;
|
||||
iface->linkstate = kif->link_state;
|
||||
if_update(iface, AF_UNSPEC);
|
||||
LIST_FOREACH(l2vpn, &leconf->l2vpn_list, entry) {
|
||||
lif = l2vpn_if_find(l2vpn, kif->ifindex);
|
||||
if (lif) {
|
||||
lif->flags = kif->flags;
|
||||
lif->linkstate = kif->link_state;
|
||||
memcpy(lif->mac, kif->mac,
|
||||
sizeof(lif->mac));
|
||||
l2vpn_if_update(lif);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IMSG_NEWADDR:
|
||||
if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ldpe.h,v 1.74 2017/03/04 00:15:35 renato Exp $ */
|
||||
/* $OpenBSD: ldpe.h,v 1.75 2017/03/04 00:21:48 renato Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
|
||||
@ -173,6 +173,7 @@ int gen_status_tlv(struct ibuf *, uint32_t, uint32_t, uint16_t);
|
||||
/* address.c */
|
||||
void send_address_single(struct nbr *, struct if_addr *, int);
|
||||
void send_address_all(struct nbr *, int);
|
||||
void send_mac_withdrawal(struct nbr *, struct map *, uint8_t *);
|
||||
int recv_address(struct nbr *, char *, uint16_t);
|
||||
|
||||
/* labelmapping.c */
|
||||
|
Loading…
Reference in New Issue
Block a user