Module Name:    src
Committed By:   kefren
Date:           Thu Jul 18 11:45:36 UTC 2013

Modified Files:
        src/usr.sbin/ldpd: label.c label.h mpls_interface.c mpls_routes.c
            mpls_routes.h tlv_stack.c

Log Message:
* rework the reattachment code
* build an implnull label when a route is added and let mpls_add_label
  to take care of relabelling
* take out last piece of the code where we do route lookups - we should have
  every information we need in labels
* tested these changes using a number of rump kernels and some couple of
  thousands of flapping routes


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/usr.sbin/ldpd/label.c
cvs rdiff -u -r1.5 -r1.6 src/usr.sbin/ldpd/label.h \
    src/usr.sbin/ldpd/mpls_routes.h
cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/ldpd/mpls_interface.c \
    src/usr.sbin/ldpd/tlv_stack.c
cvs rdiff -u -r1.17 -r1.18 src/usr.sbin/ldpd/mpls_routes.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.8 src/usr.sbin/ldpd/label.c:1.9
--- src/usr.sbin/ldpd/label.c:1.8	Thu Jul 18 06:07:45 2013
+++ src/usr.sbin/ldpd/label.c	Thu Jul 18 11:45:36 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: label.c,v 1.8 2013/07/18 06:07:45 kefren Exp $ */
+/* $NetBSD: label.c,v 1.9 2013/07/18 11:45:36 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -106,53 +106,39 @@ label_del(struct label * l)
 }
 
 /*
- * Delete or Reuse the old IPv4 route, delete MPLS route (if any)
+ * Delete or Reuse the old IPv4 route, delete MPLS route
+ * readd = REATT_INET_CHANGE -> delete and recreate the INET route
+ * readd = REATT_INET_DEL -> deletes INET route
+ * readd = REATT_INET_NODEL -> doesn't touch the INET route
  */
 void
 label_reattach_route(struct label *l, int readd)
 {
-	union sockunion *u;
-	union sockunion emptysu;
-	struct rt_msg rg;
-	int oldbinding = l->binding;
 
 	warnp("[label_reattach_route] binding %d deleted\n",
 		l->binding);
 
-	l->p = NULL;
-	l->binding = MPLS_LABEL_IMPLNULL;
-
 	/* No gateway ? */
-	memset(&emptysu, 0, sizeof (union sockunion));
-	if (memcmp(&l->so_gate, &emptysu, sizeof(union sockunion)) == 0)
+	if (l->so_gate.sa.sa_len == 0)
 		return;
 
-	if (l->label != MPLS_LABEL_IMPLNULL && readd == LDP_READD_CHANGE) {
-	/* 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);
-		} 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) {
-			delete_route(&l->so_dest, NULL, NO_FREESO);
-			add_route(&l->so_dest, NULL, &l->so_gate, NULL, NULL,
-			    NO_FREESO, RTM_READD);
-		} else
-			add_route(&l->so_dest, &l->so_pref,
-			    &l->so_gate, NULL, NULL, NO_FREESO, RTM_READD);
-	} else
-		if (readd != LDP_READD_NODEL)
-			delete_route(&l->so_dest, &l->so_pref, NO_FREESO);
+	if (readd == REATT_INET_CHANGE) {
+		/* Delete the tagged route and re-add IPv4 route */
+		delete_route(&l->so_dest,
+		    l->so_pref.sa.sa_len != 0 ? &l->so_pref : NULL, NO_FREESO);
+		add_route(&l->so_dest,
+		    l->so_pref.sa.sa_len != 0 ? &l->so_pref : NULL, &l->so_gate,
+		    NULL, NULL, NO_FREESO, RTM_READD);
+	} else if (readd == REATT_INET_DEL)
+		delete_route(&l->so_dest, &l->so_pref, NO_FREESO);
+
+	/* Deletes the MPLS route */
+	if (l->binding >= min_label)
+		delete_route(make_mpls_union(l->binding), NULL, FREESO);
 
+	l->binding = MPLS_LABEL_IMPLNULL;
+	l->p = NULL;
 	l->label = 0;
-
-	/* Deletes pure MPLS route */
-	if (oldbinding >= min_label) {
-		u = make_mpls_union(oldbinding);
-		delete_route(u, NULL, FREESO);
-	}
 }
 /*
  * Get a label by dst and pref
@@ -260,14 +246,14 @@ get_free_local_label()
 }
 
 /*
- * Change local binding
+ * Announce peers that a label has changed its binding
+ * by withdrawing it and reannouncing it
  */
 void
-change_local_label(struct label *l, uint32_t newbind)
+announce_label_change(struct label *l)
 {
 	send_withdraw_tlv_to_all(&(l->so_dest.sa),
 		from_union_to_cidr(&(l->so_pref)));
-	l->binding = newbind;
 	send_label_tlv_to_all(&(l->so_dest.sa),
 		from_union_to_cidr(&(l->so_pref)),
 		l->binding);

Index: src/usr.sbin/ldpd/label.h
diff -u src/usr.sbin/ldpd/label.h:1.5 src/usr.sbin/ldpd/label.h:1.6
--- src/usr.sbin/ldpd/label.h:1.5	Thu Jul 18 06:07:45 2013
+++ src/usr.sbin/ldpd/label.h	Thu Jul 18 11:45:36 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: label.h,v 1.5 2013/07/18 06:07:45 kefren Exp $ */
+/* $NetBSD: label.h,v 1.6 2013/07/18 11:45:36 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -37,9 +37,9 @@
 #include "mpls_routes.h"
 #include "ldp_peer.h"
 
-#define	LDP_READD_NODEL		0
-#define	LDP_READD_CHANGE	1
-#define	LDP_READD_NOCHANGE	2
+#define	REATT_INET_CHANGE	0
+#define	REATT_INET_DEL		1
+#define	REATT_INET_NODEL	2
 
 /*
  * MPLS label descriptor
@@ -67,7 +67,7 @@ struct label *	label_get(const union soc
 	const union sockunion *sopref);
 struct label *	label_get_by_prefix(const struct sockaddr *, int);
 uint32_t	get_free_local_label(void);
-void		change_local_label(struct label*, uint32_t);
+void		announce_label_change(struct label *);
 void		label_reattach_route(struct label*, int);
 void		label_check_assoc(struct ldp_peer *p);
 
Index: src/usr.sbin/ldpd/mpls_routes.h
diff -u src/usr.sbin/ldpd/mpls_routes.h:1.5 src/usr.sbin/ldpd/mpls_routes.h:1.6
--- src/usr.sbin/ldpd/mpls_routes.h:1.5	Tue Jul 16 02:54:32 2013
+++ src/usr.sbin/ldpd/mpls_routes.h	Thu Jul 18 11:45:36 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_routes.h,v 1.5 2013/07/16 02:54:32 kefren Exp $ */
+/* $NetBSD: mpls_routes.h,v 1.6 2013/07/18 11:45:36 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -68,8 +68,10 @@ void	from_cidr_to_mask(uint8_t, char *);
 int	add_route(union sockunion *, union sockunion *, union sockunion *,
 		union sockunion *, union sockunion *, int, int);
 int	delete_route(union sockunion *, union sockunion *, int);
+#if 0
 int	get_route(struct rt_msg *, const union sockunion *,
 		const union sockunion *, int);
+#endif
 int	bind_current_routes(void);
 int	flush_mpls_routes(void);
 int	check_route(struct rt_msg *, uint);

Index: src/usr.sbin/ldpd/mpls_interface.c
diff -u src/usr.sbin/ldpd/mpls_interface.c:1.10 src/usr.sbin/ldpd/mpls_interface.c:1.11
--- src/usr.sbin/ldpd/mpls_interface.c:1.10	Thu Jul 18 06:07:45 2013
+++ src/usr.sbin/ldpd/mpls_interface.c	Thu Jul 18 11:45:36 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_interface.c,v 1.10 2013/07/18 06:07:45 kefren Exp $ */
+/* $NetBSD: mpls_interface.c,v 1.11 2013/07/18 11:45:36 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -91,11 +91,12 @@ mpls_add_label(struct label *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());
+		lab->binding = get_free_local_label();
 		if (!lab->binding) {
 			fatalp("Label pool depleted\n");
 			return LDP_E_TOO_MANY_LABELS;
 		}
+		announce_label_change(lab);
 	}
 
 	warnp("[mpls_add_label] Adding %s/%d as local binding %d (%d), label %d"
@@ -177,7 +178,7 @@ mpls_delete_ldp_peer(const struct ldp_pe
 {
 
 	/* Reput all the routes also to IPv4 */
-	label_reattach_all_peer_labels(p, LDP_READD_CHANGE);
+	label_reattach_all_peer_labels(p, REATT_INET_CHANGE);
 
 	return LDP_E_OK;
 }
Index: src/usr.sbin/ldpd/tlv_stack.c
diff -u src/usr.sbin/ldpd/tlv_stack.c:1.10 src/usr.sbin/ldpd/tlv_stack.c:1.11
--- src/usr.sbin/ldpd/tlv_stack.c:1.10	Thu Jul 18 06:07:45 2013
+++ src/usr.sbin/ldpd/tlv_stack.c	Thu Jul 18 11:45:36 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: tlv_stack.c,v 1.10 2013/07/18 06:07:45 kefren Exp $ */
+/* $NetBSD: tlv_stack.c,v 1.11 2013/07/18 11:45:36 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -202,15 +202,15 @@ withdraw_label(struct ldp_peer * p, stru
 		 */
 		lab = label_get_by_prefix(&socktmp.sa, pref->prelen);
 		if ((lab) && (lab->p == p)) {
-			change_local_label(lab, MPLS_LABEL_IMPLNULL);
-			label_reattach_route(lab, LDP_READD_CHANGE);
+			label_reattach_route(lab, REATT_INET_CHANGE);
+			announce_label_change(lab); /* binding has changed */
 		}
 		break;
 	    case FEC_WILDCARD:
 		fatalp("LDP neighbour %s: Wildcard withdraw !!!\n",
 		    satos(p->address));
 		ldp_peer_delete_mapping(p, NULL, 0);
-		label_reattach_all_peer_labels(p, LDP_READD_CHANGE);
+		label_reattach_all_peer_labels(p, REATT_INET_CHANGE);
 		break;
 	    default:
 		fatalp("Unknown FEC type %d\n", pref->type);

Index: src/usr.sbin/ldpd/mpls_routes.c
diff -u src/usr.sbin/ldpd/mpls_routes.c:1.17 src/usr.sbin/ldpd/mpls_routes.c:1.18
--- src/usr.sbin/ldpd/mpls_routes.c:1.17	Thu Jul 18 06:07:45 2013
+++ src/usr.sbin/ldpd/mpls_routes.c	Thu Jul 18 11:45:36 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_routes.c,v 1.17 2013/07/18 06:07:45 kefren Exp $ */
+/* $NetBSD: mpls_routes.c,v 1.18 2013/07/18 11:45:36 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -66,7 +66,9 @@ extern int	debug_f, warn_f;
 struct rt_msg   replay_rt[REPLAY_MAX];
 int             replay_index = 0;
 
+#if 0
 static int read_route_socket(char *, int);
+#endif
 void	mask_addr(union sockunion *);
 int	compare_sockunion(const union sockunion *, const union sockunion *);
 static int check_if_addr_updown(struct rt_msg *, uint);
@@ -98,7 +100,7 @@ extern struct sockaddr mplssockaddr;
 	CHECK_LEN(dstunion) \
 	} while (0);
 
-
+#if 0
 static int 
 read_route_socket(char *s, int max)
 {
@@ -148,6 +150,7 @@ read_route_socket(char *s, int max)
 
 	return rv;
 }
+#endif	/* 0 */
 
 /* Recalculate length */
 void 
@@ -455,6 +458,7 @@ delete_route(union sockunion * so_dest, 
 	return LDP_E_OK;
 }
 
+#if 0
 /*
  * Check for a route and returns it in rg
  * If exact_match is set it compares also the so_dest and so_pref
@@ -565,6 +569,8 @@ get_route(struct rt_msg * rg, const unio
 	return LDP_E_OK;
 }
 
+#endif	/* 0 */
+
 /* triggered when a route event occurs */
 int 
 check_route(struct rt_msg * rg, uint rlen)
@@ -634,7 +640,7 @@ check_route(struct rt_msg * rg, uint rle
 		if (lab) {
 			send_withdraw_tlv_to_all(&so_dest->sa,
 			    prefixlen);
-			label_reattach_route(lab, LDP_READD_NODEL);
+			label_reattach_route(lab, REATT_INET_DEL);
 			label_del(lab);
 		}
 	/* Fallthrough */
@@ -655,8 +661,11 @@ check_route(struct rt_msg * rg, uint rle
 				pm = ldp_test_mapping(&so_dest->sa,
 					 prefixlen, &so_gate->sa);
 				if (pm) {
+					/* create an implnull label as it
+					 * gets rewritten in mpls_add_label */
 					lab = label_add(so_dest, so_pref,
-					   so_gate, 0, pm->peer, pm->lm->label);
+					    so_gate, MPLS_LABEL_IMPLNULL,
+					    pm->peer, pm->lm->label);
 					if (lab != NULL)
 						mpls_add_label(lab);
 					free(pm);
@@ -680,7 +689,7 @@ check_route(struct rt_msg * rg, uint rle
 			break;
 		send_withdraw_tlv_to_all(&so_dest->sa, prefixlen);
 		/* No readd or delete IP route. Just delete the MPLS route */
-		label_reattach_route(lab, LDP_READD_NODEL);
+		label_reattach_route(lab, REATT_INET_NODEL);
 		label_del(lab);
 		break;
 	}

Reply via email to