-/* $OpenBSD: l2vpn.c,v 1.19 2016/06/27 19:08:39 renato Exp $ */
+/* $OpenBSD: l2vpn.c,v 1.20 2016/07/01 23:33:46 renato Exp $ */
/*
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
l2vpn_pw_negotiate(struct lde_nbr *ln, struct fec_node *fn, struct map *map)
{
struct l2vpn_pw *pw;
+ struct status_tlv status;
/* NOTE: thanks martini & friends for all this mess */
return (1);
} else if (!(map->flags & F_MAP_PW_CWORD) &&
(pw->flags & F_PW_CWORD_CONF)) {
- /* TODO append a "Wrong C-bit" status code */
- lde_send_labelwithdraw(ln, fn, NO_LABEL);
+ /* append a "Wrong C-bit" status code */
+ status.status_code = S_WRONG_CBIT;
+ status.msg_id = map->messageid;
+ status.msg_type = htons(MSG_TYPE_LABELMAPPING);
+ lde_send_labelwithdraw(ln, fn, NO_LABEL, &status);
pw->flags &= ~F_PW_CWORD;
lde_send_labelmapping(ln, fn, 1);
-/* $OpenBSD: labelmapping.c,v 1.53 2016/07/01 23:29:55 renato Exp $ */
+/* $OpenBSD: labelmapping.c,v 1.54 2016/07/01 23:33:46 renato Exp $ */
/*
* Copyright (c) 2014, 2015 Renato Westphal <renato@openbsd.org>
/* calculate size */
msg_size = LDP_MSG_SIZE + TLV_HDR_LEN;
-
switch (me->map.type) {
case MAP_TYPE_WILDCARD:
msg_size += FEC_ELM_WCARD_LEN;
msg_size += PW_STATUS_TLV_LEN;
break;
}
-
if (me->map.label != NO_LABEL)
msg_size += LABEL_TLV_LEN;
if (me->map.flags & F_MAP_REQ_ID)
msg_size += REQID_TLV_LEN;
+ if (me->map.flags & F_MAP_STATUS)
+ msg_size += STATUS_SIZE;
/* maximum pdu length exceeded, we need a new ldp pdu */
if (size + msg_size > nbr->max_pdu_len) {
err |= gen_reqid_tlv(buf, me->map.requestid);
if (me->map.flags & F_MAP_PW_STATUS)
err |= gen_pw_status_tlv(buf, me->map.pw_status);
+ if (me->map.flags & F_MAP_STATUS)
+ err |= gen_status_tlv(buf, me->map.status.code,
+ me->map.status.msg_id, me->map.status.msg_type);
if (err) {
ibuf_free(buf);
return;
break;
}
break;
+ case TLV_TYPE_STATUS:
+ if (tlv_len != STATUS_TLV_LEN) {
+ session_shutdown(nbr, S_BAD_TLV_LEN,
+ lm.msgid, lm.type);
+ goto err;
+ }
+ /* ignore */
+ break;
case TLV_TYPE_PW_STATUS:
switch (type) {
case MSG_TYPE_LABELMAPPING:
-/* $OpenBSD: lde.c,v 1.59 2016/06/18 01:25:53 renato Exp $ */
+/* $OpenBSD: lde.c,v 1.60 2016/07/01 23:33:46 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
}
void
-lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn, uint32_t label)
+lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn, uint32_t label,
+ struct status_tlv *status)
{
struct lde_wdraw *lw;
struct map map;
map.label = label;
}
+ if (status) {
+ map.status.code = status->status_code;
+ map.status.msg_id = status->msg_id;
+ map.status.msg_type = status->msg_type;
+ map.flags |= F_MAP_STATUS;
+ }
+
/* SWd.1: send label withdraw. */
lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD, ln->peerid, 0,
&map, sizeof(map));
struct lde_nbr *ln;
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
- lde_send_labelwithdraw(ln, fn, label);
+ lde_send_labelwithdraw(ln, fn, label, NULL);
}
void
RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
/* explicit withdraw */
if (was_implicit)
- lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IMPLNULL);
+ lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IMPLNULL,
+ NULL);
else {
if (ln->v4_enabled)
lde_send_labelwithdraw(ln, NULL,
- MPLS_LABEL_IPV4NULL);
+ MPLS_LABEL_IPV4NULL, NULL);
if (ln->v6_enabled)
lde_send_labelwithdraw(ln, NULL,
- MPLS_LABEL_IPV6NULL);
+ MPLS_LABEL_IPV6NULL, NULL);
}
/* advertise new label of connected prefixes */
-/* $OpenBSD: lde.h,v 1.41 2016/06/18 17:13:05 renato Exp $ */
+/* $OpenBSD: lde.h,v 1.42 2016/07/01 23:33:46 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
void lde_send_labelmapping(struct lde_nbr *, struct fec_node *,
int);
void lde_send_labelwithdraw(struct lde_nbr *, struct fec_node *,
- uint32_t);
+ uint32_t, struct status_tlv *);
void lde_send_labelwithdraw_all(struct fec_node *, uint32_t);
void lde_send_labelrelease(struct lde_nbr *, struct fec_node *,
uint32_t);
-/* $OpenBSD: ldpd.h,v 1.78 2016/07/01 23:14:31 renato Exp $ */
+/* $OpenBSD: ldpd.h,v 1.79 2016/07/01 23:33:46 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
uint16_t ifmtu;
} pwid;
} fec;
+ struct {
+ uint32_t code;
+ uint32_t msg_id;
+ uint16_t msg_type;
+ } status;
uint32_t label;
uint32_t requestid;
uint32_t pw_status;
uint8_t flags;
};
#define F_MAP_REQ_ID 0x01 /* optional request message id present */
-#define F_MAP_PW_CWORD 0x02 /* pseudowire control word */
-#define F_MAP_PW_ID 0x04 /* pseudowire connection id */
-#define F_MAP_PW_IFMTU 0x08 /* pseudowire interface parameter */
-#define F_MAP_PW_STATUS 0x10 /* pseudowire status */
+#define F_MAP_STATUS 0x02 /* status */
+#define F_MAP_PW_CWORD 0x04 /* pseudowire control word */
+#define F_MAP_PW_ID 0x08 /* pseudowire connection id */
+#define F_MAP_PW_IFMTU 0x10 /* pseudowire interface parameter */
+#define F_MAP_PW_STATUS 0x20 /* pseudowire status */
struct notify_msg {
uint32_t status;
-/* $OpenBSD: ldpe.h,v 1.65 2016/07/01 23:29:55 renato Exp $ */
+/* $OpenBSD: ldpe.h,v 1.66 2016/07/01 23:33:46 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
uint16_t);
void send_notification_nbr(struct nbr *, uint32_t, uint32_t, uint16_t);
int recv_notification(struct nbr *, char *, uint16_t);
+int gen_status_tlv(struct ibuf *, uint32_t, uint32_t, uint16_t);
/* address.c */
void send_address(struct nbr *, int, struct if_addr *, int);
-/* $OpenBSD: notification.c,v 1.37 2016/07/01 23:29:55 renato Exp $ */
+/* $OpenBSD: notification.c,v 1.38 2016/07/01 23:33:46 renato Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
#include "log.h"
#include "ldpe.h"
-static int gen_status_tlv(struct ibuf *, uint32_t, uint32_t, uint16_t);
-
void
send_notification_full(struct tcp_conn *tcp, struct notify_msg *nm)
{
return (0);
}
-static int
+int
gen_status_tlv(struct ibuf *buf, uint32_t status, uint32_t msgid, uint16_t type)
{
struct status_tlv st;