Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/ldpd Make sure labels are always updated when a rou...



details:   https://anonhg.NetBSD.org/src/rev/ca0c8efaab9c
branches:  trunk
changeset: 788680:ca0c8efaab9c
user:      kefren <kefren%NetBSD.org@localhost>
date:      Thu Jul 18 06:07:45 2013 +0000

description:
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

diffstat:

 usr.sbin/ldpd/label.c          |   36 +++++-
 usr.sbin/ldpd/label.h          |    3 +-
 usr.sbin/ldpd/ldp_command.c    |   11 +-
 usr.sbin/ldpd/ldp_command.h    |    7 +-
 usr.sbin/ldpd/ldp_peer.c       |    9 +-
 usr.sbin/ldpd/mpls_interface.c |  188 ++++++++++++----------------------------
 usr.sbin/ldpd/mpls_interface.h |    6 +-
 usr.sbin/ldpd/mpls_routes.c    |   80 +++++++++-------
 usr.sbin/ldpd/socketops.c      |   32 ++++++-
 usr.sbin/ldpd/tlv_stack.c      |   30 ++++--
 10 files changed, 197 insertions(+), 205 deletions(-)

diffs (truncated from 815 to 300 lines):

diff -r e89a6bedc11c -r ca0c8efaab9c usr.sbin/ldpd/label.c
--- a/usr.sbin/ldpd/label.c     Thu Jul 18 04:05:32 2013 +0000
+++ b/usr.sbin/ldpd/label.c     Thu Jul 18 06:07:45 2013 +0000
@@ -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 @@
        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 @@
        /* 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 @@
 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 @@
                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;
+                               }
+}
diff -r e89a6bedc11c -r ca0c8efaab9c usr.sbin/ldpd/label.h
--- a/usr.sbin/ldpd/label.h     Thu Jul 18 04:05:32 2013 +0000
+++ b/usr.sbin/ldpd/label.h     Thu Jul 18 06:07:45 2013 +0000
@@ -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 @@
 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_ */
diff -r e89a6bedc11c -r ca0c8efaab9c usr.sbin/ldpd/ldp_command.c
--- a/usr.sbin/ldpd/ldp_command.c       Thu Jul 18 04:05:32 2013 +0000
+++ b/usr.sbin/ldpd/ldp_command.c       Thu Jul 18 06:07:45 2013 +0000
@@ -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 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 @@
 /*
  * Show functions
  */
-static int
+int
 show_neighbours(int s, char *recvspace)
 {
        struct ldp_peer *p;
@@ -480,7 +477,7 @@
 }
 
 /* Shows labels grabbed from unsolicited label maps */
-static int
+int
 show_labels(int s, char *recvspace)
 {
        struct ldp_peer *p;
@@ -504,7 +501,7 @@
        return 1;
 }
 
-static int
+int
 show_bindings(int s, char *recvspace)
 {
        struct label *l;
diff -r e89a6bedc11c -r ca0c8efaab9c usr.sbin/ldpd/ldp_command.h
--- a/usr.sbin/ldpd/ldp_command.h       Thu Jul 18 04:05:32 2013 +0000
+++ b/usr.sbin/ldpd/ldp_command.h       Thu Jul 18 06:07:45 2013 +0000
@@ -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 @@
 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_ */
diff -r e89a6bedc11c -r ca0c8efaab9c usr.sbin/ldpd/ldp_peer.c
--- a/usr.sbin/ldpd/ldp_peer.c  Thu Jul 18 04:05:32 2013 +0000
+++ b/usr.sbin/ldpd/ldp_peer.c  Thu Jul 18 06:07:45 2013 +0000
@@ -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 @@
 
        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));
 
diff -r e89a6bedc11c -r ca0c8efaab9c usr.sbin/ldpd/mpls_interface.c
--- a/usr.sbin/ldpd/mpls_interface.c    Thu Jul 18 04:05:32 2013 +0000
+++ b/usr.sbin/ldpd/mpls_interface.c    Thu Jul 18 06:07:45 2013 +0000
@@ -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;
+       char            p_str[20];
+       union sockunion *so_dest, *so_nexthop, *so_tag, so_ifa;
+       uint8_t prefixlen;
+       uint32_t oldbinding;
+
+       assert(lab != NULL);
 
-       strlcpy(padd, satos(p->address), 20);
-       debugp("Trying to add %s/%d as label %d to peer %s\n", satos(addr),
-               len, label, padd);
+       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;
        }



Home | Main Index | Thread Index | Old Index