diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-10-26 12:35:26 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-10-26 12:35:26 +0000 |
commit | 7e6ceb6e1c328b55b7d2044fd667143f2e461a1a (patch) | |
tree | 251292378691e17ce572c22dd8bf52308f021193 /usr.sbin/ldpd/labelmapping.c | |
parent | ed53b13769e7d9220fcd03934fa283cb214a0e23 (diff) |
For label release and withdraw messages make sure that a wildcard
FEC is the one and only FEC of that message. This is required by
the RFC. While it is not correct to have multiple FEC in anything
but label mapping messages ldpd will accept those since the RFC
is extra vague about this feature and it does not hurt.
Diffstat (limited to 'usr.sbin/ldpd/labelmapping.c')
-rw-r--r-- | usr.sbin/ldpd/labelmapping.c | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/usr.sbin/ldpd/labelmapping.c b/usr.sbin/ldpd/labelmapping.c index 7b469a3b03f..a61f6d6d5d6 100644 --- a/usr.sbin/ldpd/labelmapping.c +++ b/usr.sbin/ldpd/labelmapping.c @@ -1,4 +1,4 @@ -/* $OpenBSD: labelmapping.c,v 1.14 2010/10/26 12:22:35 claudio Exp $ */ +/* $OpenBSD: labelmapping.c,v 1.15 2010/10/26 12:35:25 claudio Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -300,7 +300,7 @@ recv_labelwithdraw(struct nbr *nbr, char *buf, u_int16_t len) struct ldp_msg *lw; struct fec_tlv *ft; u_int32_t optlabel = NO_LABEL; - int feclen, tlen; + int feclen, tlen, numfec = 0; u_int8_t addr_type; if (nbr->state != NBR_STA_OPER) @@ -356,12 +356,26 @@ recv_labelwithdraw(struct nbr *nbr, char *buf, u_int16_t len) } if (addr_type == FEC_WILDCARD) { + /* Wildcard FEC must be the only FEC element */ + if (numfec != 0) { + session_shutdown(nbr, S_BAD_TLV_VAL, lw->msgid, + lw->type); + return (-1); + } map.prefix.s_addr = 0; map.prefixlen = 0; map.flags |= F_MAP_WILDCARD; - - } else + numfec = -1; + } else { + /* Wildcard FEC must be the only FEC element */ + if (numfec == -1) { + session_shutdown(nbr, S_BAD_TLV_VAL, lw->msgid, + lw->type); + return (-1); + } + numfec++; map.flags &= ~F_MAP_WILDCARD; + } ldpe_imsg_compose_lde(IMSG_LABEL_WITHDRAW, nbr->peerid, 0, &map, sizeof(map)); @@ -427,7 +441,7 @@ recv_labelrelease(struct nbr *nbr, char *buf, u_int16_t len) struct ldp_msg *lr; struct fec_tlv *ft; u_int32_t optlabel = NO_LABEL; - int feclen, tlen; + int feclen, tlen, numfec = 0; u_int8_t addr_type; if (nbr->state != NBR_STA_OPER) @@ -483,12 +497,25 @@ recv_labelrelease(struct nbr *nbr, char *buf, u_int16_t len) } if (addr_type == FEC_WILDCARD) { + /* Wildcard FEC must be the only FEC element */ + if (numfec != 0) { + session_shutdown(nbr, S_BAD_TLV_VAL, lr->msgid, + lr->type); + return (-1); + } map.prefix.s_addr = 0; map.prefixlen = 0; map.flags |= F_MAP_WILDCARD; - } else + } else { + /* Wildcard FEC must be the only FEC element */ + if (numfec == -1) { + session_shutdown(nbr, S_BAD_TLV_VAL, lr->msgid, + lr->type); + return (-1); + } map.flags &= ~F_MAP_WILDCARD; + } ldpe_imsg_compose_lde(IMSG_LABEL_RELEASE, nbr->peerid, 0, &map, sizeof(map)); |