Skip to content

Commit

Permalink
Merge branch 'stable/3.0'
Browse files Browse the repository at this point in the history
... with a lot of fixups.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
  • Loading branch information
eqvinox committed Aug 9, 2017
2 parents 11f3bfd + 0e236c6 commit 9cdce03
Show file tree
Hide file tree
Showing 38 changed files with 1,362 additions and 93 deletions.
65 changes: 63 additions & 2 deletions ldpd/l2vpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,23 +235,31 @@ void
l2vpn_pw_init(struct l2vpn_pw *pw)
{
struct fec fec;
struct zapi_pw zpw;

l2vpn_pw_reset(pw);

l2vpn_pw_fec(pw, &fec);
lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0,
0, (void *)pw);
lde_kernel_update(&fec);

pw2zpw(pw, &zpw);
lde_imsg_compose_parent(IMSG_KPW_ADD, 0, &zpw, sizeof(zpw));
}

void
l2vpn_pw_exit(struct l2vpn_pw *pw)
{
struct fec fec;
struct zapi_pw zpw;

l2vpn_pw_fec(pw, &fec);
lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0);
lde_kernel_update(&fec);

pw2zpw(pw, &zpw);
lde_imsg_compose_parent(IMSG_KPW_DELETE, 0, &zpw, sizeof(zpw));
}

static void
Expand All @@ -269,7 +277,8 @@ l2vpn_pw_reset(struct l2vpn_pw *pw)
{
pw->remote_group = 0;
pw->remote_mtu = 0;
pw->remote_status = 0;
pw->local_status = PW_FORWARDING;
pw->remote_status = PW_NOT_FORWARDING;

if (pw->flags & F_PW_CWORD_CONF)
pw->flags |= F_PW_CWORD;
Expand Down Expand Up @@ -475,6 +484,56 @@ l2vpn_recv_pw_status_wcard(struct lde_nbr *ln, struct notify_msg *nm)
}
}

int
l2vpn_pw_status_update(struct zapi_pw_status *zpw)
{
struct l2vpn *l2vpn;
struct l2vpn_pw *pw = NULL;
struct lde_nbr *ln;
struct fec fec;
uint32_t local_status;

RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree) {
pw = l2vpn_pw_find(l2vpn, zpw->ifname);
if (pw)
break;
}
if (!pw) {
log_warnx("%s: pseudowire %s not found", __func__, zpw->ifname);
return (1);
}

if (zpw->status == PW_STATUS_UP)
local_status = PW_FORWARDING;
else
local_status = PW_NOT_FORWARDING;

/* local status didn't change */
if (pw->local_status == local_status)
return (0);
pw->local_status = local_status;

/* notify remote peer about the status update */
ln = lde_nbr_find_by_lsrid(pw->lsr_id);
if (ln == NULL)
return (0);
l2vpn_pw_fec(pw, &fec);
if (pw->flags & F_PW_STATUSTLV)
l2vpn_send_pw_status(ln, local_status, &fec);
else {
struct fec_node *fn;
fn = (struct fec_node *)fec_find(&ft, &fec);
if (fn) {
if (pw->local_status == PW_FORWARDING)
lde_send_labelmapping(ln, fn, 1);
else
lde_send_labelwithdraw(ln, fn, NULL, NULL);
}
}

return (0);
}

void
l2vpn_pw_ctl(pid_t pid)
{
Expand All @@ -491,7 +550,9 @@ l2vpn_pw_ctl(pid_t pid)
sizeof(pwctl.ifname));
pwctl.pwid = pw->pwid;
pwctl.lsr_id = pw->lsr_id;
pwctl.status = pw->flags & F_PW_STATUS_UP;
if (pw->local_status == PW_FORWARDING &&
pw->remote_status == PW_FORWARDING)
pwctl.status = 1;

lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_PW, 0,
pid, &pwctl, sizeof(pwctl));
Expand Down
60 changes: 26 additions & 34 deletions ldpd/lde.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,15 @@ lde_dispatch_parent(struct thread *thread)
}
}
break;
case IMSG_PW_UPDATE:
if (imsg.hdr.len != IMSG_HEADER_SIZE +
sizeof(struct zapi_pw_status))
fatalx("PW_UPDATE imsg with wrong len");

if (l2vpn_pw_status_update(imsg.data) != 0)
log_warnx("%s: error updating PW status",
__func__);
break;
case IMSG_NETWORK_ADD:
case IMSG_NETWORK_UPDATE:
if (imsg.hdr.len != IMSG_HEADER_SIZE +
Expand Down Expand Up @@ -712,8 +721,8 @@ lde_update_label(struct fec_node *fn)
void
lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
{
struct kroute kr;
struct kpw kpw;
struct kroute kr;
struct zapi_pw zpw;
struct l2vpn_pw *pw;

switch (fn->fec.type) {
Expand Down Expand Up @@ -751,19 +760,10 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
return;

pw = (struct l2vpn_pw *) fn->data;
pw->flags |= F_PW_STATUS_UP;

memset(&kpw, 0, sizeof(kpw));
kpw.ifindex = pw->ifindex;
kpw.pw_type = fn->fec.u.pwid.type;
kpw.af = pw->af;
kpw.nexthop = pw->addr;
kpw.local_label = fn->local_label;
kpw.remote_label = fnh->remote_label;
kpw.flags = pw->flags;

lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE, 0, &kpw,
sizeof(kpw));
pw2zpw(pw, &zpw);
zpw.local_label = fn->local_label;
zpw.remote_label = fnh->remote_label;
lde_imsg_compose_parent(IMSG_KPW_SET, 0, &zpw, sizeof(zpw));
break;
}
}
Expand All @@ -772,7 +772,7 @@ void
lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
{
struct kroute kr;
struct kpw kpw;
struct zapi_pw zpw;
struct l2vpn_pw *pw;

switch (fn->fec.type) {
Expand Down Expand Up @@ -806,21 +806,10 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
break;
case FEC_TYPE_PWID:
pw = (struct l2vpn_pw *) fn->data;
if (!(pw->flags & F_PW_STATUS_UP))
return;
pw->flags &= ~F_PW_STATUS_UP;

memset(&kpw, 0, sizeof(kpw));
kpw.ifindex = pw->ifindex;
kpw.pw_type = fn->fec.u.pwid.type;
kpw.af = pw->af;
kpw.nexthop = pw->addr;
kpw.local_label = fn->local_label;
kpw.remote_label = fnh->remote_label;
kpw.flags = pw->flags;

lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE, 0, &kpw,
sizeof(kpw));
pw2zpw(pw, &zpw);
zpw.local_label = fn->local_label;
zpw.remote_label = fnh->remote_label;
lde_imsg_compose_parent(IMSG_KPW_UNSET, 0, &zpw, sizeof(zpw));
break;
}
}
Expand Down Expand Up @@ -901,8 +890,12 @@ lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
*/
lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
if (lw) {
if (!fec_find(&ln->sent_map_pending, &fn->fec))
if (!fec_find(&ln->sent_map_pending, &fn->fec)) {
debug_evt("%s: FEC %s: scheduling to send label "
"mapping later (waiting for pending label release)",
__func__, log_fec(&fn->fec));
lde_map_pending_add(ln, fn);
}
return;
}

Expand Down Expand Up @@ -948,8 +941,7 @@ lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
map.flags |= F_MAP_PW_CWORD;
if (pw->flags & F_PW_STATUSTLV) {
map.flags |= F_MAP_PW_STATUS;
/* VPLS are always up */
map.pw_status = PW_FORWARDING;
map.pw_status = pw->local_status;
}
break;
}
Expand Down
1 change: 1 addition & 0 deletions ldpd/lde.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ void l2vpn_send_pw_status_wcard(struct lde_nbr *, uint32_t,
void l2vpn_recv_pw_status(struct lde_nbr *, struct notify_msg *);
void l2vpn_recv_pw_status_wcard(struct lde_nbr *,
struct notify_msg *);
int l2vpn_pw_status_update(struct zapi_pw_status *);
void l2vpn_pw_ctl(pid_t);
void l2vpn_binding_ctl(pid_t);

Expand Down
10 changes: 8 additions & 2 deletions ldpd/lde_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,7 @@ lde_kernel_update(struct fec *fec)
lde_gc_start_timer();
} else {
fn->local_label = lde_update_label(fn);
if (fn->local_label != NO_LABEL &&
RB_EMPTY(lde_map_head, &fn->upstream))
if (fn->local_label != NO_LABEL)
/* FEC.1: perform lsr label distribution procedure */
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
lde_send_labelmapping(ln, fn, 1);
Expand Down Expand Up @@ -531,6 +530,8 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln)
pw->remote_mtu = map->fec.pwid.ifmtu;
if (map->flags & F_MAP_PW_STATUS)
pw->remote_status = map->pw_status;
else
pw->remote_status = PW_FORWARDING;
fnh->remote_label = map->label;
if (l2vpn_pw_ok(pw, fnh))
lde_send_change_klabel(fn, fnh);
Expand Down Expand Up @@ -774,6 +775,7 @@ lde_check_withdraw(struct map *map, struct lde_nbr *ln)
pw = (struct l2vpn_pw *) fn->data;
if (pw == NULL)
continue;
pw->remote_status = PW_NOT_FORWARDING;
break;
default:
break;
Expand Down Expand Up @@ -802,6 +804,7 @@ lde_check_withdraw_wcard(struct map *map, struct lde_nbr *ln)
struct fec_node *fn;
struct fec_nh *fnh;
struct lde_map *me;
struct l2vpn_pw *pw;

/* LWd.2: send label release */
lde_send_labelrelease(ln, NULL, map, map->label);
Expand All @@ -825,6 +828,9 @@ lde_check_withdraw_wcard(struct map *map, struct lde_nbr *ln)
case FEC_TYPE_PWID:
if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr)
continue;
pw = (struct l2vpn_pw *) fn->data;
if (pw)
pw->remote_status = PW_NOT_FORWARDING;
break;
default:
break;
Expand Down
3 changes: 0 additions & 3 deletions ldpd/ldp.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,6 @@ struct address_list_tlv {
#define MAP_TYPE_GENPWID 0x81

#define CONTROL_WORD_FLAG 0x8000
#define PW_TYPE_ETHERNET_TAGGED 0x0004
#define PW_TYPE_ETHERNET 0x0005
#define PW_TYPE_WILDCARD 0x7FFF
#define DEFAULT_PW_TYPE PW_TYPE_ETHERNET

#define PW_TWCARD_RESERVED_BIT 0x8000
Expand Down
76 changes: 70 additions & 6 deletions ldpd/ldp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ static int ldp_interface_address_delete(int, struct zclient *,
zebra_size_t, vrf_id_t);
static int ldp_zebra_read_route(int, struct zclient *, zebra_size_t,
vrf_id_t);
static int ldp_zebra_read_pw_status_update(int, struct zclient *,
zebra_size_t, vrf_id_t);
static void ldp_zebra_connected(struct zclient *);

static struct zclient *zclient;
Expand Down Expand Up @@ -92,6 +94,25 @@ ifc2kaddr(struct interface *ifp, struct connected *ifc, struct kaddr *ka)
}
}

void
pw2zpw(struct l2vpn_pw *pw, struct zapi_pw *zpw)
{
memset(zpw, 0, sizeof(*zpw));
strlcpy(zpw->ifname, pw->ifname, sizeof(zpw->ifname));
zpw->ifindex = pw->ifindex;
zpw->type = pw->l2vpn->pw_type;
zpw->af = pw->af;
zpw->nexthop.ipv6 = pw->addr.v6;
zpw->local_label = NO_LABEL;
zpw->remote_label = NO_LABEL;
if (pw->flags & F_PW_CWORD)
zpw->flags = F_PSEUDOWIRE_CWORD;
zpw->data.ldp.lsr_id = pw->lsr_id;
zpw->data.ldp.pwid = pw->pwid;
strlcpy(zpw->data.ldp.vpn_name, pw->l2vpn->name,
sizeof(zpw->data.ldp.vpn_name));
}

static int
zebra_send_mpls_labels(int cmd, struct kroute *kr)
{
Expand Down Expand Up @@ -152,17 +173,40 @@ kr_delete(struct kroute *kr)
}

int
kmpw_set(struct kpw *kpw)
kmpw_add(struct zapi_pw *zpw)
{
/* TODO */
return (0);
debug_zebra_out("pseudowire %s nexthop %s (add)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));

return (zebra_send_pw(zclient, ZEBRA_PW_ADD, zpw));
}

int
kmpw_unset(struct kpw *kpw)
kmpw_del(struct zapi_pw *zpw)
{
/* TODO */
return (0);
debug_zebra_out("pseudowire %s nexthop %s (del)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));

return (zebra_send_pw(zclient, ZEBRA_PW_DELETE, zpw));
}

int
kmpw_set(struct zapi_pw *zpw)
{
debug_zebra_out("pseudowire %s nexthop %s labels %u/%u (set)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop),
zpw->local_label, zpw->remote_label);

return (zebra_send_pw(zclient, ZEBRA_PW_SET, zpw));
}

int
kmpw_unset(struct zapi_pw *zpw)
{
debug_zebra_out("pseudowire %s nexthop %s (unset)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));

return (zebra_send_pw(zclient, ZEBRA_PW_UNSET, zpw));
}

void
Expand Down Expand Up @@ -464,6 +508,25 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
return (0);
}

/*
* Receive PW status update from Zebra and send it to LDE process.
*/
static int
ldp_zebra_read_pw_status_update(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct zapi_pw_status zpw;

zebra_read_pw_status_update(command, zclient, length, vrf_id, &zpw);

debug_zebra_in("pseudowire %s status %s", zpw.ifname,
(zpw.status == PW_STATUS_UP) ? "up" : "down");

main_imsg_compose_lde(IMSG_PW_UPDATE, 0, &zpw, sizeof(zpw));

return (0);
}

static void
ldp_zebra_connected(struct zclient *zclient)
{
Expand Down Expand Up @@ -494,6 +557,7 @@ ldp_zebra_init(struct thread_master *master)
zclient->redistribute_route_ipv4_del = ldp_zebra_read_route;
zclient->redistribute_route_ipv6_add = ldp_zebra_read_route;
zclient->redistribute_route_ipv6_del = ldp_zebra_read_route;
zclient->pw_status_update = ldp_zebra_read_pw_status_update;
}

void
Expand Down
Loading

0 comments on commit 9cdce03

Please sign in to comment.