Module Name: src
Committed By: kefren
Date: Thu Jul 18 06:07:45 UTC 2013
Modified Files:
src/usr.sbin/ldpd: label.c label.h ldp_command.c ldp_command.h
ldp_peer.c mpls_interface.c mpls_interface.h mpls_routes.c
socketops.c tlv_stack.c
Log Message:
Make sure labels are always updated when a route is added and when a peer
is added
Rework mpls_add_label according to that so no route refresh is done anymore
Use poll when reading the PF_ROUTE socket
setsockopt SO_USELOOPBACK on the PF_ROUTE socket
Output some information on SIGINFO
Allow map changing for a ldp peer
Finally fix the connected routes admission into labels
Correct the route trigger when a label map is received
To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/ldpd/label.c
cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/ldpd/label.h
cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/ldpd/ldp_command.c
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/ldpd/ldp_command.h
cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/ldpd/ldp_peer.c
cvs rdiff -u -r1.9 -r1.10 src/usr.sbin/ldpd/mpls_interface.c \
src/usr.sbin/ldpd/tlv_stack.c
cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/ldpd/mpls_interface.h
cvs rdiff -u -r1.16 -r1.17 src/usr.sbin/ldpd/mpls_routes.c
cvs rdiff -u -r1.28 -r1.29 src/usr.sbin/ldpd/socketops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.sbin/ldpd/label.c
diff -u src/usr.sbin/ldpd/label.c:1.7 src/usr.sbin/ldpd/label.c:1.8
--- src/usr.sbin/ldpd/label.c:1.7 Tue Jul 16 02:54:32 2013
+++ src/usr.sbin/ldpd/label.c Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: label.c,v 1.7 2013/07/16 02:54:32 kefren Exp $ */
+/* $NetBSD: label.c,v 1.8 2013/07/18 06:07:45 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -70,12 +70,13 @@ label_add(const union sockunion * so_des
assert(so_dest);
assert(so_pref);
assert(so_dest->sa.sa_family == so_pref->sa.sa_family);
+ assert(label_get(so_dest, so_pref) == NULL);
- memcpy(&l->so_dest, so_dest, sizeof(union sockunion));
- memcpy(&l->so_pref, so_pref, sizeof(union sockunion));
+ memcpy(&l->so_dest, so_dest, so_dest->sa.sa_len);
+ memcpy(&l->so_pref, so_pref, so_pref->sa.sa_len);
if (so_gate)
- memcpy(&l->so_gate, so_gate, sizeof(union sockunion));
+ memcpy(&l->so_gate, so_gate, so_gate->sa.sa_len);
if (binding)
l->binding = binding;
else
@@ -130,8 +131,8 @@ label_reattach_route(struct label *l, in
/* Delete and re-add IPv4 route */
if (get_route(&rg, &l->so_dest, &l->so_pref, 1) == LDP_E_OK) {
delete_route(&l->so_dest, &l->so_pref, NO_FREESO);
- add_route(&l->so_dest, &l->so_pref, &l->so_gate, NULL, NULL,
- NO_FREESO, RTM_READD);
+ add_route(&l->so_dest, &l->so_pref, &l->so_gate, NULL,
+ NULL, NO_FREESO, RTM_READD);
} else if (from_union_to_cidr(&l->so_pref) == 32 &&
l->so_dest.sa.sa_family == AF_INET &&
get_route(&rg, &l->so_dest, NULL, 1) == LDP_E_OK) {
@@ -225,15 +226,15 @@ label_del_by_binding(uint32_t binding, i
struct label*
label_get_by_prefix(const struct sockaddr *a, int prefixlen)
{
- union sockunion *so_dest, *so_pref;
+ const union sockunion *so_dest;
+ union sockunion *so_pref;
struct label *l;
- so_dest = make_inet_union(satos(a)); // XXX: grobian
+ so_dest = (const union sockunion *)a;
so_pref = from_cidr_to_union(prefixlen);
l = label_get(so_dest, so_pref);
- free(so_dest);
free(so_pref);
return l;
@@ -271,3 +272,20 @@ change_local_label(struct label *l, uint
from_union_to_cidr(&(l->so_pref)),
l->binding);
}
+
+void
+label_check_assoc(struct ldp_peer *p)
+{
+ struct label *l;
+ struct ldp_peer_address *wp;
+
+ SLIST_FOREACH (l, &label_head, labels)
+ if (l->p == NULL && l->so_gate.sa.sa_family != 0)
+ SLIST_FOREACH(wp, &p->ldp_peer_address_head, addresses)
+ if (sockaddr_cmp(&l->so_gate.sa,
+ &wp->address.sa) == 0){
+ l->p = p;
+ l->label = MPLS_LABEL_IMPLNULL;
+ break;
+ }
+}
Index: src/usr.sbin/ldpd/label.h
diff -u src/usr.sbin/ldpd/label.h:1.4 src/usr.sbin/ldpd/label.h:1.5
--- src/usr.sbin/ldpd/label.h:1.4 Thu Jul 11 10:46:19 2013
+++ src/usr.sbin/ldpd/label.h Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: label.h,v 1.4 2013/07/11 10:46:19 kefren Exp $ */
+/* $NetBSD: label.h,v 1.5 2013/07/18 06:07:45 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -69,5 +69,6 @@ struct label * label_get_by_prefix(const
uint32_t get_free_local_label(void);
void change_local_label(struct label*, uint32_t);
void label_reattach_route(struct label*, int);
+void label_check_assoc(struct ldp_peer *p);
#endif /* !_LABEL_H_ */
Index: src/usr.sbin/ldpd/ldp_command.c
diff -u src/usr.sbin/ldpd/ldp_command.c:1.11 src/usr.sbin/ldpd/ldp_command.c:1.12
--- src/usr.sbin/ldpd/ldp_command.c:1.11 Tue Jul 16 02:54:32 2013
+++ src/usr.sbin/ldpd/ldp_command.c Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_command.c,v 1.11 2013/07/16 02:54:32 kefren Exp $ */
+/* $NetBSD: ldp_command.c,v 1.12 2013/07/18 06:07:45 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -74,11 +74,8 @@ static int set_func(int, char *);
static int exit_func(int, char *);
/* Show functions */
-static int show_neighbours(int, char *);
-static int show_bindings(int, char *);
static int show_debug(int, char *);
static int show_hellos(int, char *);
-static int show_labels(int, char *);
static int show_parameters(int, char *);
static int show_version(int, char *);
static int show_warning(int, char *);
@@ -402,7 +399,7 @@ exit_func(int s, char *recvspace)
/*
* Show functions
*/
-static int
+int
show_neighbours(int s, char *recvspace)
{
struct ldp_peer *p;
@@ -480,7 +477,7 @@ show_neighbours(int s, char *recvspace)
}
/* Shows labels grabbed from unsolicited label maps */
-static int
+int
show_labels(int s, char *recvspace)
{
struct ldp_peer *p;
@@ -504,7 +501,7 @@ show_labels(int s, char *recvspace)
return 1;
}
-static int
+int
show_bindings(int s, char *recvspace)
{
struct label *l;
Index: src/usr.sbin/ldpd/ldp_command.h
diff -u src/usr.sbin/ldpd/ldp_command.h:1.2 src/usr.sbin/ldpd/ldp_command.h:1.3
--- src/usr.sbin/ldpd/ldp_command.h:1.2 Thu Jun 16 08:27:28 2011
+++ src/usr.sbin/ldpd/ldp_command.h Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_command.h,v 1.2 2011/06/16 08:27:28 kefren Exp $ */
+/* $NetBSD: ldp_command.h,v 1.3 2013/07/18 06:07:45 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -53,4 +53,9 @@ int add_command_socket(int);
void command_dispatch(struct com_sock *);
void command_close(int);
+/* Used by SIGINFO handler */
+int show_bindings(int, char *);
+int show_labels(int, char *);
+int show_neighbours(int, char *);
+
#endif /* !_LDP_COMMAND_H_ */
Index: src/usr.sbin/ldpd/ldp_peer.c
diff -u src/usr.sbin/ldpd/ldp_peer.c:1.13 src/usr.sbin/ldpd/ldp_peer.c:1.14
--- src/usr.sbin/ldpd/ldp_peer.c:1.13 Thu Jul 11 05:55:13 2013
+++ src/usr.sbin/ldpd/ldp_peer.c Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_peer.c,v 1.13 2013/07/11 05:55:13 kefren Exp $ */
+/* $NetBSD: ldp_peer.c,v 1.14 2013/07/18 06:07:45 kefren Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -428,8 +428,11 @@ ldp_peer_add_mapping(struct ldp_peer * p
if (!p)
return -1;
- if (ldp_peer_get_lm(p, a, prefix))
- return LDP_E_ALREADY_DONE;
+ if ((lma = ldp_peer_get_lm(p, a, prefix)) != NULL) {
+ /* Change the current label */
+ lma->label = label;
+ return LDP_E_OK;
+ }
lma = malloc(sizeof(*lma));
Index: src/usr.sbin/ldpd/mpls_interface.c
diff -u src/usr.sbin/ldpd/mpls_interface.c:1.9 src/usr.sbin/ldpd/mpls_interface.c:1.10
--- src/usr.sbin/ldpd/mpls_interface.c:1.9 Thu Jul 11 05:45:23 2013
+++ src/usr.sbin/ldpd/mpls_interface.c Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_interface.c,v 1.9 2013/07/11 05:45:23 kefren Exp $ */
+/* $NetBSD: mpls_interface.c,v 1.10 2013/07/18 06:07:45 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -53,104 +53,43 @@
extern int no_default_route;
int
-mpls_add_label(const struct ldp_peer * p, struct rt_msg * inh_rg,
- struct sockaddr * addr, int len, int label, int rlookup)
+mpls_add_label(struct label *lab)
{
- char padd[20];
- int kount = 0, rv;
- union sockunion *so_dest, *so_pref = NULL, *so_gate, *so_nexthop,
- *so_tag, *so_oldifa = NULL, *so_ifa;
- struct rt_msg rg;
- struct rt_msg *rgp = &rg;
- struct label *lab;
-
- strlcpy(padd, satos(p->address), 20);
- debugp("Trying to add %s/%d as label %d to peer %s\n", satos(addr),
- len, label, padd);
+ char p_str[20];
+ union sockunion *so_dest, *so_nexthop, *so_tag, so_ifa;
+ uint8_t prefixlen;
+ uint32_t oldbinding;
+
+ assert(lab != NULL);
+
+ oldbinding = lab->binding;
+ prefixlen = from_union_to_cidr(&lab->so_pref);
+
+ strlcpy(p_str, satos(lab->p->address), sizeof(p_str));
+ warnp("Trying to add %s/%d as label %d (oldlocal %d) to peer %s\n",
+ satos(&lab->so_dest.sa), prefixlen, lab->label, lab->binding,p_str);
/* Check if we should accept default route */
- if (!len && no_default_route != 0)
+ if (prefixlen == 0 && no_default_route != 0)
return LDP_E_BAD_AF;
- /* Is there a label mapping for this ? */
- if (ldp_peer_get_lm(p, addr, len) == NULL)
+ /* double check if there is a label mapping for this */
+ if (ldp_peer_get_lm(lab->p, &lab->so_dest.sa, prefixlen) == NULL)
return LDP_E_NOENT;
- if (!inh_rg || (inh_rg->m_rtm.rtm_addrs & RTA_IFA) == 0) {
- /*
- * XXX: Check if we have a route for that.
- * Why the hell isn't kernel inserting the route immediatly ?
- * let's loop until we have it..
- */
-
- if ((so_dest = make_inet_union(satos(addr))) == NULL) // XXX
- return LDP_E_MEMORY;
- if (len != 32 && (so_pref = from_cidr_to_union(len)) == NULL) {
- free(so_dest);
- return LDP_E_MEMORY;
- }
- do {
- if (kount == rlookup) {
- debugp("No route for this prefix\n");
- return LDP_E_NO_SUCH_ROUTE;
- }
- if (kount > 0)
- debugp("Route test hit: %d\n", kount);
- kount++;
- /* Last time give it a higher chance */
- if (kount == rlookup)
- usleep(5000);
-
- rv = get_route(rgp, so_dest, so_pref, 1);
- if (rv != LDP_E_OK && len == 32)
- /* Host maybe ? */
- rv = get_route(rgp, so_dest, NULL, 1);
- } while (rv != LDP_E_OK);
-
- free(so_dest);
- if (so_pref)
- free(so_pref);
-
- } else
- rgp = inh_rg;
-
- /* Check if it's an IPv4 route */
-
- so_gate = (union sockunion *) rgp->m_space;
- so_gate = (union sockunion *)((char*)so_gate +
- RT_ROUNDUP(so_gate->sa.sa_len));
- if (rgp->m_rtm.rtm_addrs & RTA_IFA) {
- int li = 1;
- so_oldifa = so_gate;
- if (rgp->m_rtm.rtm_addrs & RTA_NETMASK)
- li++;
- if (rgp->m_rtm.rtm_addrs & RTA_GENMASK)
- li++;
- if (rgp->m_rtm.rtm_addrs & RTA_IFP)
- li++;
- for (int i = 0; i < li; i++)
- so_oldifa = (union sockunion *)((char*)so_oldifa +
- RT_ROUNDUP(so_oldifa->sa.sa_len));
- }
-
- if (so_gate->sa.sa_family != AF_INET &&
- so_gate->sa.sa_family != AF_INET6) {
- debugp("mpls_add_label: so_gate is not IP or IPv6\n");
+ if (lab->so_gate.sa.sa_family != AF_INET &&
+ lab->so_gate.sa.sa_family != AF_INET6) {
+ warnp("mpls_add_label: so_gate is not IP or IPv6\n");
return LDP_E_BAD_AF;
}
/* Check if the address is bounded to the peer */
- if (check_ifaddr(p, &so_gate->sa) == NULL) {
- debugp("Failed at next-hop check\n");
+ if (check_ifaddr(lab->p, &lab->so_gate.sa) == NULL) {
+ warnp("Failed at next-hop check\n");
return LDP_E_ROUTE_ERROR;
}
- /* Verify if we have a binding for this prefix */
- lab = label_get_by_prefix(addr, len);
-
- /* And we should have one because we have a route for it */
- assert (lab);
-
+ /* if binding is implicit null we need to generate a new one */
if (lab->binding == MPLS_LABEL_IMPLNULL) {
change_local_label(lab, get_free_local_label());
if (!lab->binding) {
@@ -159,63 +98,46 @@ mpls_add_label(const struct ldp_peer * p
}
}
- warnp("[mpls_add_label] Adding %s/%d as local binding %d, label %d"
- " to peer %s\n",
- satos(addr), len, lab->binding, label, padd);
-
- /* Modify existing label */
- lab->label = label;
- lab->p = p;
+ warnp("[mpls_add_label] Adding %s/%d as local binding %d (%d), label %d"
+ " to peer %s\n", satos(&lab->so_dest.sa), prefixlen, lab->binding,
+ oldbinding, lab->label, p_str);
/* Add switching route */
- so_dest = make_mpls_union(lab->binding);
- so_nexthop = malloc(sizeof(*so_nexthop));
- if (!so_nexthop) {
+ if ((so_dest = make_mpls_union(lab->binding)) == NULL)
+ return LDP_E_MEMORY;
+ if ((so_tag = make_mpls_union(lab->label)) == NULL) {
free(so_dest);
fatalp("Out of memory\n");
return LDP_E_MEMORY;
}
- memcpy(so_nexthop, so_gate, so_gate->sa.sa_len);
- if ((so_tag = make_mpls_union(label)) == NULL) {
+ if ((so_nexthop = malloc(lab->so_gate.sa.sa_len)) == NULL) {
free(so_dest);
- free(so_nexthop);
+ free(so_tag);
fatalp("Out of memory\n");
return LDP_E_MEMORY;
}
- if (add_route(so_dest, NULL, so_nexthop, NULL, so_tag,
- FREESO, RTM_ADD) != LDP_E_OK)
+ memcpy(so_nexthop, &lab->so_gate, lab->so_gate.sa.sa_len);
+
+ if (add_route(so_dest, NULL, so_nexthop, NULL, so_tag, FREESO,
+ oldbinding == MPLS_LABEL_IMPLNULL ? RTM_ADD : RTM_CHANGE)
+ != LDP_E_OK) {
+ fatalp("[mpls_add_label] MPLS route error\n");
return LDP_E_ROUTE_ERROR;
+ }
/* Now, let's add tag to IP route and point it to mpls interface */
- if ((so_dest = make_inet_union(satos(addr))) == NULL) { // XXX: grobian
- fatalp("Out of memory\n");
- return LDP_E_MEMORY;
- }
- /*
- * if prefixlen == 32 check if it's inserted as host
- * and treat it as host. It may also be set as /32 prefix
- * (thanks mlelstv for heads-up about this)
- */
- if ((len == 32) && (rgp->m_rtm.rtm_flags & RTF_HOST))
- so_pref = NULL;
- else if ((so_pref = from_cidr_to_union(len)) == NULL) {
- free(so_dest);
- fatalp("Out of memory\n");
- return LDP_E_MEMORY;
- }
+ if (getsockname(lab->p->socket, &so_ifa.sa,
+ & (socklen_t) { sizeof(union sockunion) } )) {
+ fatalp("[mpls_add_label]: getsockname\n");
+ return LDP_E_ROUTE_ERROR;
+ }
- /* Add tag to route */
- so_nexthop = malloc(sizeof(*so_nexthop));
- if (!so_nexthop) {
- free(so_dest);
- if (so_pref != NULL)
- free(so_pref);
+ if ((so_tag = make_mpls_union(lab->label)) == NULL) {
fatalp("Out of memory\n");
return LDP_E_MEMORY;
}
- memcpy(so_nexthop, so_gate, so_gate->sa.sa_len);
- so_tag = make_mpls_union(label);
+/*
if (so_oldifa != NULL) {
so_ifa = malloc(sizeof(*so_ifa));
if (so_ifa == NULL) {
@@ -230,12 +152,16 @@ mpls_add_label(const struct ldp_peer * p
memcpy(so_ifa, so_oldifa, so_oldifa->sa.sa_len);
} else
so_ifa = NULL;
- if (add_route(so_dest, so_pref, so_nexthop, so_ifa, so_tag,
- FREESO, RTM_CHANGE) != LDP_E_OK)
+*/
+ if (add_route(&lab->so_dest, &lab->so_pref, &lab->so_gate, &so_ifa,
+ so_tag, NO_FREESO, RTM_CHANGE) != LDP_E_OK) {
+ free(so_tag);
+ fatalp("[mpls_add_label]: INET route failure\n");
return LDP_E_ROUTE_ERROR;
+ }
+ free(so_tag);
- debugp("Added %s/%d as label %d to peer %s\n", satos(addr), len,
- label, padd);
+ warnp("[mpls_add_label]: SUCCESS\n");
return LDP_E_OK;
}
Index: src/usr.sbin/ldpd/tlv_stack.c
diff -u src/usr.sbin/ldpd/tlv_stack.c:1.9 src/usr.sbin/ldpd/tlv_stack.c:1.10
--- src/usr.sbin/ldpd/tlv_stack.c:1.9 Tue Jul 16 19:40:01 2013
+++ src/usr.sbin/ldpd/tlv_stack.c Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: tlv_stack.c,v 1.9 2013/07/16 19:40:01 kefren Exp $ */
+/* $NetBSD: tlv_stack.c,v 1.10 2013/07/18 06:07:45 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -63,6 +63,7 @@ map_label(struct ldp_peer * p, struct fe
int n;
struct prefix_tlv *pref;
union sockunion socktmp;
+ struct label *lbl_check;
if (ntohs(f->type) != TLV_FEC) {
debugp("Invalid FEC TLV !\n");
@@ -118,17 +119,24 @@ map_label(struct ldp_peer * p, struct fe
else
memcpy(&socktmp.sin6.sin6_addr, &pref->prefix,
ldp_ceil8(pref->prelen));
- debugp("Prefix/Host add: %s/%d\n", satos(&socktmp.sa),
+ warnp("Prefix/Host add from %s: %s/%d\n",
+ inet_ntoa(p->ldp_id), satos(&socktmp.sa),
pref->prelen);
ldp_peer_add_mapping(p, &socktmp.sa, pref->prelen,
ntohl(l->label));
/* Try to change RIB only if label is installed */
- if (label_get_by_prefix(&socktmp.sa, pref->prelen)
- != NULL)
- mpls_add_label(p, NULL, &socktmp.sa,
- pref->prelen, ntohl(l->label), 1);
+ lbl_check = label_get_by_prefix(&socktmp.sa,
+ pref->prelen);
+ if (lbl_check != NULL && lbl_check->p == p) {
+ lbl_check->label = ntohl(l->label);
+ mpls_add_label(lbl_check);
+ } else
+ warnp("[map_label] lbl check failed: %s\n",
+ lbl_check == NULL ? "(null)" :
+ lbl_check->p == NULL ? "(null peer)" :
+ inet_ntoa(lbl_check->p->ldp_id));
break;
case FEC_WILDCARD:
fatalp("LDP: Wildcard add from peer %s\n",
@@ -238,6 +246,9 @@ send_label_tlv(const struct ldp_peer * p
struct prefix_tlv *p;
struct label_tlv *l;
+ debugp("SENDING LABEL TLV %s TO %s\n", satos(addr),
+ inet_ntoa(peer->ldp_id));
+
/*
* Ok, so we have label map tlv that contains fec tlvs and label tlv
* but fec tlv contains prefix or host tlvs and prefix or host tlvs
@@ -245,7 +256,7 @@ send_label_tlv(const struct ldp_peer * p
* Got it ?
*/
- lmt = malloc(
+ lmt = calloc(1,
sizeof(struct label_map_tlv) +
sizeof(struct fec_tlv) +
sizeof(struct prefix_tlv) - sizeof(struct in_addr) +
@@ -255,7 +266,7 @@ send_label_tlv(const struct ldp_peer * p
(lrt != NULL ? sizeof(struct label_request_tlv) : 0) );
if (!lmt) {
- fatalp("send_label_tlv: malloc problem\n");
+ fatalp("send_label_tlv: calloc problem\n");
return;
}
@@ -271,8 +282,7 @@ send_label_tlv(const struct ldp_peer * p
/* FEC TLV */
fec = (struct fec_tlv *) & lmt[1];
fec->type = htons(TLV_FEC);
- fec->length = htons(sizeof(struct fec_tlv) - TLV_TYPE_LENGTH
- + sizeof(struct prefix_tlv) - sizeof(struct in_addr) +
+ fec->length = htons(sizeof(struct prefix_tlv) - sizeof(struct in_addr) +
ldp_ceil8(prefixlen));
/* Now let's do the even a dirtier job: PREFIX TLV */
Index: src/usr.sbin/ldpd/mpls_interface.h
diff -u src/usr.sbin/ldpd/mpls_interface.h:1.3 src/usr.sbin/ldpd/mpls_interface.h:1.4
--- src/usr.sbin/ldpd/mpls_interface.h:1.3 Thu Jul 11 05:45:23 2013
+++ src/usr.sbin/ldpd/mpls_interface.h Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_interface.h,v 1.3 2013/07/11 05:45:23 kefren Exp $ */
+/* $NetBSD: mpls_interface.h,v 1.4 2013/07/18 06:07:45 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -32,10 +32,10 @@
#ifndef _MPLS_INTERFACE_H_
#define _MPLS_INTERFACE_H_
+#include "label.h"
#include "mpls_routes.h"
-int mpls_add_label(const struct ldp_peer *, struct rt_msg *,
- struct sockaddr *, int, int, int);
+int mpls_add_label(struct label *);
int mpls_add_ldp_peer(const struct ldp_peer *);
int mpls_delete_ldp_peer(const struct ldp_peer *);
int mpls_start_ldp(void);
Index: src/usr.sbin/ldpd/mpls_routes.c
diff -u src/usr.sbin/ldpd/mpls_routes.c:1.16 src/usr.sbin/ldpd/mpls_routes.c:1.17
--- src/usr.sbin/ldpd/mpls_routes.c:1.16 Tue Jul 16 16:55:01 2013
+++ src/usr.sbin/ldpd/mpls_routes.c Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_routes.c,v 1.16 2013/07/16 16:55:01 kefren Exp $ */
+/* $NetBSD: mpls_routes.c,v 1.17 2013/07/18 06:07:45 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -43,6 +43,7 @@
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
+#include <poll.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -57,7 +58,7 @@
#include "socketops.h"
extern int route_socket;
-int rt_seq = 0;
+int rt_seq = 200;
int dont_catch = 0;
extern int no_default_route;
extern int debug_f, warn_f;
@@ -102,34 +103,31 @@ static int
read_route_socket(char *s, int max)
{
int rv, to_read;
- fd_set fs;
- struct timeval tv;
struct rt_msghdr *rhdr;
+ struct pollfd pfd;
- tv.tv_sec = 0;
- tv.tv_usec = 5000;
-
- FD_ZERO(&fs);
- FD_SET(route_socket, &fs);
+ pfd.fd = route_socket;
+ pfd.events = POLLRDNORM;
+ pfd.revents = 0;
errno = 0;
do {
- rv = select(route_socket + 1, &fs, NULL, &fs, &tv);
- } while ((rv == -1) && (errno == EINTR));
+ rv = poll(&pfd, 1, 100);
+ } while (rv == -1 && errno == EINTR);
if (rv < 1) {
if (rv == 0) {
- fatalp("read_route_socket: select timeout\n");
+ fatalp("read_route_socket: poll timeout\n");
} else
- fatalp("read_route_socket: select: %s",
+ fatalp("read_route_socket: poll: %s",
strerror(errno));
return 0;
}
do {
rv = recv(route_socket, s, max, MSG_PEEK);
- } while((rv == -1) && (errno == EINTR));
+ } while(rv == -1 && errno == EINTR);
if (rv < 1) {
debugp("read_route_socket: recv error\n");
@@ -507,7 +505,13 @@ get_route(struct rt_msg * rg, const unio
}
rm.m_rtm.rtm_msglen = l = cp - (char *) &rm;
- if ((rlen = write(route_socket, (char *) &rm, l)) < l) {
+ setsockopt(route_socket, SOL_SOCKET, SO_USELOOPBACK, &(int){1},
+ sizeof(int));
+ rlen = write(route_socket, (char *) &rm, l);
+ setsockopt(route_socket, SOL_SOCKET, SO_USELOOPBACK, &(int){0},
+ sizeof(int));
+
+ if (rlen < l) {
debugp("Cannot get a route !(rlen=%d instead of %d) - %s\n",
rlen, l, strerror(errno));
return LDP_E_NO_SUCH_ROUTE;
@@ -525,7 +529,14 @@ get_route(struct rt_msg * rg, const unio
if (rg->m_rtm.rtm_pid == getpid() &&
rg->m_rtm.rtm_seq == myseq)
break;
- debugp("Added to replay PID: %d, SEQ: %d\n",
+ /* Fast skip */
+ if (rg->m_rtm.rtm_type != RTM_ADD &&
+ rg->m_rtm.rtm_type != RTM_DELETE &&
+ rg->m_rtm.rtm_type != RTM_CHANGE &&
+ rg->m_rtm.rtm_type != RTM_NEWADDR &&
+ rg->m_rtm.rtm_type != RTM_DELADDR)
+ continue;
+ warnp("Added to replay PID: %d, SEQ: %d\n",
rg->m_rtm.rtm_pid, rg->m_rtm.rtm_seq);
memcpy(&replay_rt[replay_index], rg,
sizeof(struct rt_msg));
@@ -599,21 +610,14 @@ check_route(struct rt_msg * rg, uint rle
return LDP_E_OK;
}
if (rg->m_rtm.rtm_addrs & RTA_NETMASK) {
- if (so_gate)
- so_pref = so_gate;
- else
- so_pref = so_dest;
- GETNEXT(so_pref, so_pref);
- }
- if (!(rg->m_rtm.rtm_flags & RTF_GATEWAY)) {
- if (rg->m_rtm.rtm_addrs & RTA_GENMASK) {
- debugp("Used GENMASK\n");
+ if (so_gate != NULL) {
+ GETNEXT(so_pref, so_gate);
} else
- debugp("No GENMASK to use\n");
+ GETNEXT(so_pref, so_dest);
}
/* Calculate prefixlen */
if (so_pref)
- prefixlen = from_mask_to_cidr(inet_ntoa(so_pref->sin.sin_addr));
+ prefixlen = from_union_to_cidr(so_pref);
else {
prefixlen = 32;
if ((so_pref = from_cidr_to_union(32)) == NULL)
@@ -643,25 +647,25 @@ check_route(struct rt_msg * rg, uint rle
/* First of all check if we already know this one */
if (label_get(so_dest, so_pref) == NULL) {
- if (!(rg->m_rtm.rtm_flags & RTF_GATEWAY))
+ /* Just add an IMPLNULL label */
+ if (so_gate == NULL)
label_add(so_dest, so_pref, NULL,
MPLS_LABEL_IMPLNULL, NULL, 0);
else {
pm = ldp_test_mapping(&so_dest->sa,
prefixlen, &so_gate->sa);
if (pm) {
- label_add(so_dest, so_pref,
- so_gate, 0, NULL, 0);
- mpls_add_label(pm->peer, rg,
- &so_dest->sa, prefixlen,
- pm->lm->label, ROUTE_LOOKUP_LOOP);
+ lab = label_add(so_dest, so_pref,
+ so_gate, 0, pm->peer, pm->lm->label);
+ if (lab != NULL)
+ mpls_add_label(lab);
free(pm);
} else
label_add(so_dest, so_pref, so_gate,
MPLS_LABEL_IMPLNULL, NULL, 0);
}
} else /* We already know about this prefix */
- debugp("Binding already there for prefix %s/%d !\n",
+ fatalp("Binding already there for prefix %s/%d !\n",
satos(&so_dest->sa), prefixlen);
break;
case RTM_DELETE:
@@ -818,8 +822,7 @@ bind_current_routes()
rtmes = (struct rt_msghdr *) next;
rlen = rtmes->rtm_msglen;
size_cp = sizeof(struct rt_msghdr);
- so_pref = NULL;
- so_gate = NULL;
+ so_gate = so_pref = NULL;
if (rtmes->rtm_flags & RTF_LLINFO) /* No need for arps */
continue;
if (!(rtmes->rtm_addrs & RTA_DST)) {
@@ -830,6 +833,7 @@ bind_current_routes()
CHECK_MINSA;
so_dst = (union sockunion *) & rtmes[1];
CHECK_LEN(so_dst);
+
/*
* This function is called only at startup, so use
* this ocassion to delete all MPLS routes
@@ -879,6 +883,10 @@ bind_current_routes()
free(so_pref);
continue;
}
+
+ if (so_gate != NULL && so_gate->sa.sa_family == AF_LINK)
+ so_gate = NULL; /* connected route */
+
if (so_gate == NULL || so_gate->sa.sa_family == AF_INET)
label_add(so_dst, so_pref, so_gate,
MPLS_LABEL_IMPLNULL, NULL, 0);
Index: src/usr.sbin/ldpd/socketops.c
diff -u src/usr.sbin/ldpd/socketops.c:1.28 src/usr.sbin/ldpd/socketops.c:1.29
--- src/usr.sbin/ldpd/socketops.c:1.28 Thu Jul 11 05:45:23 2013
+++ src/usr.sbin/ldpd/socketops.c Thu Jul 18 06:07:45 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: socketops.c,v 1.28 2013/07/11 05:45:23 kefren Exp $ */
+/* $NetBSD: socketops.c,v 1.29 2013/07/18 06:07:45 kefren Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -80,6 +80,7 @@ bool may_connect;
void recv_pdu(int);
void send_hello_alarm(int);
__dead static void bail_out(int);
+static void print_info(int);
static int bind_socket(int s, int stype);
static int set_tos(int);
static int socket_reuse_port(int);
@@ -774,6 +775,19 @@ bail_out(int x)
exit(0);
}
+static void
+print_info(int x)
+{
+ printf("Info for %s\n-------\n", LDP_ID);
+ printf("Neighbours:\n");
+ show_neighbours(1, NULL);
+ printf("Bindings:\n");
+ show_bindings(1, NULL);
+ printf("Labels:\n");
+ show_labels(1, NULL);
+ printf("--------\n");
+}
+
/*
* The big poll that catches every single event
* on every socket.
@@ -798,12 +812,15 @@ the_big_loop(void)
signal(SIGPIPE, SIG_IGN);
signal(SIGINT, bail_out);
signal(SIGTERM, bail_out);
+ signal(SIGINFO, print_info);
/* Send first hellos in 5 seconds. Avoid No hello notifications */
may_connect = false;
alarm(5);
route_socket = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
+ setsockopt(route_socket, SOL_SOCKET, SO_USELOOPBACK, &(int){0},
+ sizeof(int));
sock_error = bind_current_routes();
if (sock_error != LDP_E_OK) {
@@ -996,7 +1013,7 @@ new_peer_connection()
}
}
if (peer_ldp_id == NULL) {
- fatalp("Got connection from %s, but no hello info exists\n",
+ warnp("Got connection from %s, but no hello info exists\n",
satos(&peer_address.sa));
close(s);
return;
@@ -1036,10 +1053,12 @@ keep_alive(const struct ldp_peer * p)
kt.messageid = htonl(get_message_id());
send_tlv(p, (struct tlv *) (void *) &kt);
-
}
-void
+/*
+ * Process a message received from a peer
+ */
+void
recv_session_pdu(struct ldp_peer * p)
{
struct ldp_pdu *rpdu;
@@ -1181,6 +1200,11 @@ recv_session_pdu(struct ldp_peer * p)
atlv = (struct address_tlv *) ttmp;
altlv = (struct al_tlv *) (&atlv[1]);
add_ifaddresses(p, altlv);
+ /*
+ * try to see if we have labels with null peer that
+ * would match the new peer
+ */
+ label_check_assoc(p);
print_bounded_addresses(p);
break;
case LDP_ADDRESS_WITHDRAW: