summaryrefslogtreecommitdiff
path: root/ldpd/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldpd/packet.c')
-rw-r--r--ldpd/packet.c82
1 files changed, 26 insertions, 56 deletions
diff --git a/ldpd/packet.c b/ldpd/packet.c
index 9b3151d720..a7be0f6b42 100644
--- a/ldpd/packet.c
+++ b/ldpd/packet.c
@@ -285,53 +285,24 @@ disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
{
struct iface *iface;
struct iface_af *ia;
- struct if_addr *if_addr;
- in_addr_t mask;
iface = if_lookup(leconf, ifindex);
if (iface == NULL)
return (NULL);
+ ia = iface_af_get(iface, af);
+ if (!ia->enabled)
+ return (NULL);
+
/*
- * For unicast packets, we just need to make sure that the interface
- * is enabled for the given address-family.
+ * RFC 7552 - Section 5.1:
+ * "Link-local IPv6 address MUST be used as the source IP address in
+ * IPv6 LDP Link Hellos".
*/
- if (!multicast) {
- ia = iface_af_get(iface, af);
- if (ia->enabled)
- return (iface);
+ if (multicast && af == AF_INET6 && !IN6_IS_ADDR_LINKLOCAL(&src->v6))
return (NULL);
- }
-
- switch (af) {
- case AF_INET:
- LIST_FOREACH(if_addr, &iface->addr_list, entry) {
- if (if_addr->af != AF_INET)
- continue;
-
- switch (iface->type) {
- case IF_TYPE_POINTOPOINT:
- if (if_addr->dstbrd.v4.s_addr == src->v4.s_addr)
- return (iface);
- break;
- default:
- mask = prefixlen2mask(if_addr->prefixlen);
- if ((if_addr->addr.v4.s_addr & mask) ==
- (src->v4.s_addr & mask))
- return (iface);
- break;
- }
- }
- break;
- case AF_INET6:
- if (IN6_IS_ADDR_LINKLOCAL(&src->v6))
- return (iface);
- break;
- default:
- fatalx("disc_find_iface: unknown af");
- }
- return (NULL);
+ return (iface);
}
int
@@ -548,13 +519,7 @@ session_read(struct thread *thread)
return (0);
}
break;
- case MSG_TYPE_ADDR:
- case MSG_TYPE_ADDRWITHDRAW:
- case MSG_TYPE_LABELMAPPING:
- case MSG_TYPE_LABELREQUEST:
- case MSG_TYPE_LABELWITHDRAW:
- case MSG_TYPE_LABELRELEASE:
- case MSG_TYPE_LABELABORTREQ:
+ default:
if (nbr->state != NBR_STA_OPER) {
session_shutdown(nbr, S_SHUTDOWN,
msg->id, msg->type);
@@ -562,8 +527,6 @@ session_read(struct thread *thread)
return (0);
}
break;
- default:
- break;
}
/* switch LDP packet type */
@@ -577,6 +540,9 @@ session_read(struct thread *thread)
case MSG_TYPE_KEEPALIVE:
ret = recv_keepalive(nbr, pdu, msg_size);
break;
+ case MSG_TYPE_CAPABILITY:
+ ret = recv_capability(nbr, pdu, msg_size);
+ break;
case MSG_TYPE_ADDR:
case MSG_TYPE_ADDRWITHDRAW:
ret = recv_address(nbr, pdu, msg_size);
@@ -593,7 +559,7 @@ session_read(struct thread *thread)
log_debug("%s: unknown LDP message from nbr %s",
__func__, inet_ntoa(nbr->id));
if (!(ntohs(msg->type) & UNKNOWN_FLAG))
- send_notification_nbr(nbr,
+ send_notification(nbr->tcp,
S_UNKNOWN_MSG, msg->id, msg->type);
/* ignore the message */
ret = 0;
@@ -661,7 +627,7 @@ session_shutdown(struct nbr *nbr, uint32_t status, uint32_t msg_id,
case NBR_STA_OPER:
log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
- send_notification_nbr(nbr, status, msg_id, msg_type);
+ send_notification(nbr->tcp, status, msg_id, msg_type);
nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
break;
@@ -715,8 +681,8 @@ struct tcp_conn *
tcp_new(int fd, struct nbr *nbr)
{
struct tcp_conn *tcp;
- struct sockaddr_storage src;
- socklen_t len = sizeof(src);
+ struct sockaddr_storage ss;
+ socklen_t len = sizeof(ss);
if ((tcp = calloc(1, sizeof(*tcp))) == NULL)
fatal(__func__);
@@ -732,10 +698,14 @@ tcp_new(int fd, struct nbr *nbr)
tcp->nbr = nbr;
}
- getsockname(fd, (struct sockaddr *)&src, &len);
- sa2addr((struct sockaddr *)&src, NULL, NULL, &tcp->lport);
- getpeername(fd, (struct sockaddr *)&src, &len);
- sa2addr((struct sockaddr *)&src, NULL, NULL, &tcp->rport);
+ if (getsockname(fd, (struct sockaddr *)&ss, &len) != 0)
+ log_warn("%s: getsockname", __func__);
+ else
+ sa2addr((struct sockaddr *)&ss, NULL, NULL, &tcp->lport);
+ if (getpeername(fd, (struct sockaddr *)&ss, &len) != 0)
+ log_warn("%s: getpeername", __func__);
+ else
+ sa2addr((struct sockaddr *)&ss, NULL, NULL, &tcp->rport);
return (tcp);
}
@@ -813,7 +783,7 @@ pending_conn_timeout(struct thread *thread)
* notification message reliably.
*/
tcp = tcp_new(pconn->fd, NULL);
- send_notification(S_NO_HELLO, tcp, 0, 0);
+ send_notification(tcp, S_NO_HELLO, 0, 0);
msgbuf_write(&tcp->wbuf.wbuf);
pending_conn_del(pconn);