diff options
Diffstat (limited to 'ldpd/packet.c')
| -rw-r--r-- | ldpd/packet.c | 82 |
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); |
