From 718e3744195351130f4ce7dbe0613f4b3e23df93 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 13 Dec 2002 20:15:29 +0000 Subject: Initial revision --- zebra/connected.c | 394 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 394 insertions(+) create mode 100644 zebra/connected.c (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c new file mode 100644 index 00000000..cb43074b --- /dev/null +++ b/zebra/connected.c @@ -0,0 +1,394 @@ +/* + * Address linked list routine. + * Copyright (C) 1997, 98 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include + +#include "prefix.h" +#include "linklist.h" +#include "if.h" +#include "table.h" +#include "rib.h" +#include "table.h" +#include "log.h" + +#include "zebra/zserv.h" +#include "zebra/redistribute.h" + +/* If same interface address is already exist... */ +struct connected * +connected_check_ipv4 (struct interface *ifp, struct prefix *p) +{ + struct connected *ifc; + listnode node; + + for (node = listhead (ifp->connected); node; node = nextnode (node)) + { + ifc = getdata (node); + + if (prefix_same (ifc->address, p)) + return ifc; + } + return NULL; +} + +/* Called from if_up(). */ +void +connected_up_ipv4 (struct interface *ifp, struct connected *ifc) +{ + struct prefix_ipv4 p; + struct prefix_ipv4 *addr; + struct prefix_ipv4 *dest; + + if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + return; + + addr = (struct prefix_ipv4 *) ifc->address; + dest = (struct prefix_ipv4 *) ifc->destination; + + memset (&p, 0, sizeof (struct prefix_ipv4)); + p.family = AF_INET; + p.prefixlen = addr->prefixlen; + + /* Point-to-point check. */ + if (if_is_pointopoint (ifp)) + p.prefix = dest->prefix; + else + p.prefix = addr->prefix; + + /* Apply mask to the network. */ + apply_mask_ipv4 (&p); + + /* In case of connected address is 0.0.0.0/0 we treat it tunnel + address. */ + if (prefix_ipv4_any (&p)) + return; + + rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, 0, 0); + + rib_update (); +} + +/* Add connected IPv4 route to the interface. */ +void +connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, + int prefixlen, struct in_addr *broad, char *label) +{ + struct prefix_ipv4 *p; + struct connected *ifc; + struct connected *current; + + /* Make connected structure. */ + ifc = connected_new (); + ifc->ifp = ifp; + ifc->flags = flags; + + /* Allocate new connected address. */ + p = prefix_ipv4_new (); + p->family = AF_INET; + p->prefix = *addr; + p->prefixlen = prefixlen; + ifc->address = (struct prefix *) p; + + /* If there is broadcast or pointopoint address. */ + if (broad) + { + p = prefix_ipv4_new (); + p->family = AF_INET; + p->prefix = *broad; + ifc->destination = (struct prefix *) p; + } + + /* Label of this address. */ + if (label) + ifc->label = strdup (label); + + /* Check same connected route. */ + current = connected_check_ipv4 (ifp, (struct prefix *) ifc->address); + if (current) + { + connected_free (ifc); + ifc = current; + } + else + { + listnode_add (ifp->connected, ifc); + } + + /* Update interface address information to protocol daemon. */ + if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + { + SET_FLAG (ifc->conf, ZEBRA_IFC_REAL); + + zebra_interface_address_add_update (ifp, ifc); + + if (if_is_up(ifp)) + connected_up_ipv4 (ifp, ifc); + } +} + +void +connected_down_ipv4 (struct interface *ifp, struct connected *ifc) +{ + struct prefix_ipv4 p; + struct prefix_ipv4 *addr; + struct prefix_ipv4 *dest; + + if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + return; + + addr = (struct prefix_ipv4 *)ifc->address; + dest = (struct prefix_ipv4 *)ifc->destination; + + memset (&p, 0, sizeof (struct prefix_ipv4)); + p.family = AF_INET; + p.prefixlen = addr->prefixlen; + + if (if_is_pointopoint (ifp)) + p.prefix = dest->prefix; + else + p.prefix = addr->prefix; + + /* Apply mask to the network. */ + apply_mask_ipv4 (&p); + + /* In case of connected address is 0.0.0.0/0 we treat it tunnel + address. */ + if (prefix_ipv4_any (&p)) + return; + + rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); + + rib_update (); +} + +/* Delete connected IPv4 route to the interface. */ +void +connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, + int prefixlen, struct in_addr *broad, char *label) +{ + struct prefix_ipv4 p; + struct connected *ifc; + + memset (&p, 0, sizeof (struct prefix_ipv4)); + p.family = AF_INET; + p.prefix = *addr; + p.prefixlen = prefixlen; + + ifc = connected_check_ipv4 (ifp, (struct prefix *) &p); + if (! ifc) + return; + + /* Update interface address information to protocol daemon. */ + if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + { + zebra_interface_address_delete_update (ifp, ifc); + + connected_down_ipv4 (ifp, ifc); + + UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); + } + + if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) + { + listnode_delete (ifp->connected, ifc); + connected_free (ifc); + } +} + +#ifdef HAVE_IPV6 +/* If same interface address is already exist... */ +struct connected * +connected_check_ipv6 (struct interface *ifp, struct prefix *p) +{ + struct connected *ifc; + listnode node; + + for (node = listhead (ifp->connected); node; node = nextnode (node)) + { + ifc = getdata (node); + + if (prefix_same (ifc->address, p)) + return ifc; + } + return 0; +} + +void +connected_up_ipv6 (struct interface *ifp, struct connected *ifc) +{ + struct prefix_ipv6 p; + struct prefix_ipv6 *addr; + struct prefix_ipv6 *dest; + + if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + return; + + addr = (struct prefix_ipv6 *) ifc->address; + dest = (struct prefix_ipv6 *) ifc->destination; + + memset (&p, 0, sizeof (struct prefix_ipv6)); + p.family = AF_INET6; + p.prefixlen = addr->prefixlen; + + if (if_is_pointopoint (ifp) && dest) + { + if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) + p.prefix = addr->prefix; + else + p.prefix = dest->prefix; + } + else + p.prefix = addr->prefix; + + /* Apply mask to the network. */ + apply_mask_ipv6 (&p); + + if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix)) + return; + + rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); + + rib_update (); +} + +/* Add connected IPv6 route to the interface. */ +void +connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, + int prefixlen, struct in6_addr *broad) +{ + struct prefix_ipv6 *p; + struct connected *ifc; + struct connected *current; + + /* Make connected structure. */ + ifc = connected_new (); + ifc->ifp = ifp; + + /* Allocate new connected address. */ + p = prefix_ipv6_new (); + p->family = AF_INET6; + IPV6_ADDR_COPY (&p->prefix, addr); + p->prefixlen = prefixlen; + ifc->address = (struct prefix *) p; + + /* If there is broadcast or pointopoint address. */ + if (broad) + { + p = prefix_ipv6_new (); + p->family = AF_INET6; + IPV6_ADDR_COPY (&p->prefix, broad); + ifc->destination = (struct prefix *) p; + } + + current = connected_check_ipv6 (ifp, (struct prefix *) ifc->address); + if (current) + { + connected_free (ifc); + ifc = current; + } + else + { + listnode_add (ifp->connected, ifc); + } + + /* Update interface address information to protocol daemon. */ + if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + { + SET_FLAG (ifc->conf, ZEBRA_IFC_REAL); + + zebra_interface_address_add_update (ifp, ifc); + + if (if_is_up(ifp)) + connected_up_ipv6 (ifp, ifc); + } +} + +void +connected_down_ipv6 (struct interface *ifp, struct connected *ifc) +{ + struct prefix_ipv6 p; + struct prefix_ipv6 *addr; + struct prefix_ipv6 *dest; + + if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + return; + + addr = (struct prefix_ipv6 *) ifc->address; + dest = (struct prefix_ipv6 *) ifc->destination; + + memset (&p, 0, sizeof (struct prefix_ipv6)); + p.family = AF_INET6; + p.prefixlen = addr->prefixlen; + + if (if_is_pointopoint (ifp) && dest) + { + if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) + p.prefix = addr->prefix; + else + p.prefix = dest->prefix; + } + else + p.prefix = addr->prefix; + + apply_mask_ipv6 (&p); + + if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix)) + return; + + rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); + + rib_update (); +} + +void +connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, + int prefixlen, struct in6_addr *broad) +{ + struct prefix_ipv6 p; + struct connected *ifc; + + memset (&p, 0, sizeof (struct prefix_ipv6)); + p.family = AF_INET6; + memcpy (&p.prefix, address, sizeof (struct in6_addr)); + p.prefixlen = prefixlen; + + ifc = connected_check_ipv6 (ifp, (struct prefix *) &p); + if (! ifc) + return; + + /* Update interface address information to protocol daemon. */ + if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + { + zebra_interface_address_delete_update (ifp, ifc); + + connected_down_ipv6 (ifp, ifc); + + UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); + } + + if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) + { + listnode_delete (ifp->connected, ifc); + connected_free (ifc); + } +} +#endif /* HAVE_IPV6 */ -- cgit v1.2.3 From 00df0c1e80811f3cf5eca0b28e720bf1bcc84a53 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 13 Dec 2002 21:07:36 +0000 Subject: [zebra 14631] Generic PtP and RFC3021 interface addressing support --- zebra/connected.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index cb43074b..22c9a1f6 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -69,7 +69,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -162,7 +162,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) p.family = AF_INET; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -249,7 +249,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp) && dest) + if (ifc_pointopoint (ifc) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; @@ -339,7 +339,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp) && dest) + if (ifc_pointopoint (ifc) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; -- cgit v1.2.3 From f2c806522030d4964b4ca649637a7901751d8496 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 13 Dec 2002 21:44:27 +0000 Subject: Kevin C Miller [zebra 16681] OSPF NSSA Patches --- zebra/connected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 22c9a1f6..dcb0b875 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -69,7 +69,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (ifc_pointopoint (ifc)) + if (ifc_pointopoint (ifc) && dest) p.prefix = dest->prefix; else p.prefix = addr->prefix; -- cgit v1.2.3 From 960182aaf05c2f11415789b2edcdc53ac3858f01 Mon Sep 17 00:00:00 2001 From: paul Date: Wed, 9 Apr 2003 07:16:04 +0000 Subject: Amir - revision 197 Log: I've fixed a small bug in connected_down_ipv4(): I changed if (ifc_pointopoint (ifc)) into if (ifc_pointopoint (ifc) && dest) like show in connected_up_ipv4() After changing this 'ip address x/y'; 'no ip address x/y' works without crash when done in sequence. --- zebra/connected.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index dcb0b875..5d1c6b66 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -162,7 +162,8 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) p.family = AF_INET; p.prefixlen = addr->prefixlen; - if (ifc_pointopoint (ifc)) + /* Point-to-point check. */ + if (dest && ifc_pointopoint (ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; -- cgit v1.2.3 From 726f9b2bbdd5a607f7b0a10a64547739b807e361 Mon Sep 17 00:00:00 2001 From: hasso Date: Sun, 25 May 2003 21:04:54 +0000 Subject: Last fixes from 6Wind patch. --- zebra/connected.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 5d1c6b66..280e423e 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -263,8 +263,11 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) /* Apply mask to the network. */ apply_mask_ipv6 (&p); +#if ! defined (MUSICA) && ! defined (LINUX) + /* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */ if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix)) return; +#endif rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); -- cgit v1.2.3 From 31a476c7e9014aa81dc0d50b4100431ab111bf3f Mon Sep 17 00:00:00 2001 From: paul Date: Mon, 29 Sep 2003 19:54:53 +0000 Subject: 2003-09-29 Paul Jakma * zebra/connected.c: revert the 'generic PtP' patch as it causes far too many problems. People who use FreeSWAN should investigate native linux ipsec. * zebra/rt_netlink.c: ditto * lib/if.c: ditto * ripd/ripd.h: ditto * ripd/ripd.c: ditto * ripd/rip_interface.c: ditto * ospfd/ospfd.c: ditto * ospfd/ospf_snmp.c: ditto * bgpd/bgp_nexthop.c: ditto --- zebra/connected.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 280e423e..1d19258f 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -69,7 +69,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (ifc_pointopoint (ifc) && dest) + if (if_is_pointopoint (ifc) && dest) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -163,7 +163,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (dest && ifc_pointopoint (ifc)) + if (dest && if_is_pointopoint (ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -250,7 +250,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (ifc_pointopoint (ifc) && dest) + if (if_is_pointopoint (ifp) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; @@ -343,7 +343,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (ifc_pointopoint (ifc) && dest) + if (if_is_pointopoint (ifp) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; -- cgit v1.2.3 From 2fe28bbb7bccedf2e486a8c0aaa43037c91b3336 Mon Sep 17 00:00:00 2001 From: paul Date: Mon, 13 Oct 2003 08:59:40 +0000 Subject: 2003-10-13 Douglas Fraser * zebra/connected.c: PtP revert fixup. Zebra was not creating connected route for PtP peer. --- zebra/connected.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 1d19258f..7fa5ea74 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -69,7 +69,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (if_is_pointopoint (ifc) && dest) + if (if_is_pointopoint (ifp) && dest) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -163,7 +163,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (dest && if_is_pointopoint (ifc)) + if (dest && if_is_pointopoint (ifp)) p.prefix = dest->prefix; else p.prefix = addr->prefix; -- cgit v1.2.3 From 52dc7ee65f8d887b0730abc0a5d44d27fc6ecafd Mon Sep 17 00:00:00 2001 From: hasso Date: Thu, 23 Sep 2004 19:18:23 +0000 Subject: Remove usage of evil list and listnode typedefs. --- zebra/connected.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 7fa5ea74..21af3e9c 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -38,7 +38,7 @@ struct connected * connected_check_ipv4 (struct interface *ifp, struct prefix *p) { struct connected *ifc; - listnode node; + struct listnode *node; for (node = listhead (ifp->connected); node; node = nextnode (node)) { @@ -221,7 +221,7 @@ struct connected * connected_check_ipv6 (struct interface *ifp, struct prefix *p) { struct connected *ifc; - listnode node; + struct listnode *node; for (node = listhead (ifp->connected); node; node = nextnode (node)) { -- cgit v1.2.3 From eef1fe11b89c5ec3c035ff6e4a9acfbc5780b539 Mon Sep 17 00:00:00 2001 From: hasso Date: Sun, 3 Oct 2004 18:46:08 +0000 Subject: New way to handle secondary addresses from Gilad Arnold. --- zebra/connected.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 21af3e9c..df0b56a0 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -32,6 +32,7 @@ #include "zebra/zserv.h" #include "zebra/redistribute.h" +#include "zebra/interface.h" /* If same interface address is already exist... */ struct connected * @@ -136,6 +137,8 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, /* Update interface address information to protocol daemon. */ if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) { + if_subnet_add (ifp, ifc); + SET_FLAG (ifc->conf, ZEBRA_IFC_REAL); zebra_interface_address_add_update (ifp, ifc); @@ -203,16 +206,15 @@ connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, { zebra_interface_address_delete_update (ifp, ifc); + if_subnet_delete (ifp, ifc); + connected_down_ipv4 (ifp, ifc); UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); } - if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) - { - listnode_delete (ifp->connected, ifc); - connected_free (ifc); - } + listnode_delete (ifp->connected, ifc); + connected_free (ifc); } #ifdef HAVE_IPV6 @@ -389,10 +391,7 @@ connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); } - if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) - { - listnode_delete (ifp->connected, ifc); - connected_free (ifc); - } + listnode_delete (ifp->connected, ifc); + connected_free (ifc); } #endif /* HAVE_IPV6 */ -- cgit v1.2.3 From fce954f8de1456dd62d26b52902a4a352ef17a93 Mon Sep 17 00:00:00 2001 From: hasso Date: Thu, 7 Oct 2004 20:29:24 +0000 Subject: Fix warnings. Didn't even look at files not compiled in Linux though. --- zebra/connected.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index df0b56a0..a043ef48 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -279,7 +279,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) /* Add connected IPv6 route to the interface. */ void connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, - int prefixlen, struct in6_addr *broad) + u_char prefixlen, struct in6_addr *broad) { struct prefix_ipv6 *p; struct connected *ifc; @@ -367,7 +367,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc) void connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, - int prefixlen, struct in6_addr *broad) + u_char prefixlen, struct in6_addr *broad) { struct prefix_ipv6 p; struct connected *ifc; -- cgit v1.2.3 From 3fb9cd6ef456959b6eff939d5c316f6785c2dda4 Mon Sep 17 00:00:00 2001 From: hasso Date: Tue, 19 Oct 2004 19:44:43 +0000 Subject: OK. Here it is - PtP patch from Andrew J. Schorr. No problems with ospfd, ripd might need some more testing though. --- zebra/connected.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index a043ef48..9a6fd669 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -70,7 +70,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (if_is_pointopoint (ifp) && dest) + if (CONNECTED_POINTOPOINT_HOST(ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -116,7 +116,49 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, p->family = AF_INET; p->prefix = *broad; ifc->destination = (struct prefix *) p; + + /* validate the destination address */ + if (ifp->flags & IFF_POINTOPOINT) + { + if (IPV4_ADDR_SAME(addr,broad)) + zlog_warn("warning: PtP interface %s has same local and peer " + "address %s, routing protocols may malfunction", + ifp->name,inet_ntoa(*addr)); + else if ((prefixlen != IPV4_MAX_PREFIXLEN) && + (ipv4_network_addr(addr->s_addr,prefixlen) != + ipv4_network_addr(broad->s_addr,prefixlen))) + { + char buf[2][INET_ADDRSTRLEN]; + zlog_warn("warning: PtP interface %s network mismatch: local " + "%s/%d vs. peer %s, routing protocols may malfunction", + ifp->name, + inet_ntop (AF_INET, addr, buf[0], sizeof(buf[0])), + prefixlen, + inet_ntop (AF_INET, broad, buf[1], sizeof(buf[1]))); + } + } + else + { + if (broad->s_addr != ipv4_broadcast_addr(addr->s_addr,prefixlen)) + { + char buf[2][INET_ADDRSTRLEN]; + struct in_addr bcalc; + bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,prefixlen); + zlog_warn("warning: interface %s broadcast addr %s/%d != " + "calculated %s, routing protocols may malfunction", + ifp->name, + inet_ntop (AF_INET, broad, buf[0], sizeof(buf[0])), + prefixlen, + inet_ntop (AF_INET, &bcalc, buf[1], sizeof(buf[1]))); + } + } + } + else + /* no broadcast or destination address was supplied */ + if (prefixlen == IPV4_MAX_PREFIXLEN) + zlog_warn("warning: interface %s with addr %s/%d needs a peer address", + ifp->name,inet_ntoa(*addr),prefixlen); /* Label of this address. */ if (label) @@ -166,7 +208,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (dest && if_is_pointopoint (ifp)) + if (CONNECTED_POINTOPOINT_HOST(ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; -- cgit v1.2.3 From 341a8f1ac9d584ca9dd44bd1b5f90588f475e769 Mon Sep 17 00:00:00 2001 From: ajs Date: Wed, 22 Dec 2004 16:32:16 +0000 Subject: 2004-12-22 Andrew J. Schorr * connected.c: (connected_add_ipv4) Limit warning about /32 addresses with no peer specified to PtP interfaces only. --- zebra/connected.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 9a6fd669..5f581915 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -156,9 +156,9 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, } else /* no broadcast or destination address was supplied */ - if (prefixlen == IPV4_MAX_PREFIXLEN) - zlog_warn("warning: interface %s with addr %s/%d needs a peer address", - ifp->name,inet_ntoa(*addr),prefixlen); + if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) + zlog_warn("warning: PtP interface %s with addr %s/%d needs a " + "peer address",ifp->name,inet_ntoa(*addr),prefixlen); /* Label of this address. */ if (label) -- cgit v1.2.3 From 1eb8ef2584833f18fb674e127d59cb5a7f771482 Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 7 Apr 2005 07:30:20 +0000 Subject: 2005-04-07 Paul Jakma * (global): Fix up list loops to match changes in lib/linklist, and some basic auditing of usage. * configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES * HACKING: Add notes about deprecating interfaces and commands. * lib/linklist.h: Add usage comments. Rename getdata macro to listgetdata. Rename nextnode to listnextnode and fix its odd behaviour to be less dangerous. Make listgetdata macro assert node is not null, NULL list entries should be bug condition. ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use with for loop, Suggested by Jim Carlson of Sun. Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the "safety" of previous macro. LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to distinguish from the similarly named functions, and reflect their effect better. Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section with the old defines which were modified above, for backwards compatibility - guarded to prevent Quagga using it.. * lib/linklist.c: fix up for linklist.h changes. * ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single scan of the area list, rather than scanning all areas first for INTER_ROUTER and then again for INTER_NETWORK. According to 16.2, the scan should be area specific anyway, and further ospf6d does not seem to implement 16.3 anyway. --- zebra/connected.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 5f581915..3ce59530 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -41,13 +41,10 @@ connected_check_ipv4 (struct interface *ifp, struct prefix *p) struct connected *ifc; struct listnode *node; - for (node = listhead (ifp->connected); node; node = nextnode (node)) - { - ifc = getdata (node); + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) + if (prefix_same (ifc->address, p)) + return ifc; - if (prefix_same (ifc->address, p)) - return ifc; - } return NULL; } @@ -267,13 +264,10 @@ connected_check_ipv6 (struct interface *ifp, struct prefix *p) struct connected *ifc; struct listnode *node; - for (node = listhead (ifp->connected); node; node = nextnode (node)) - { - ifc = getdata (node); + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) + if (prefix_same (ifc->address, p)) + return ifc; - if (prefix_same (ifc->address, p)) - return ifc; - } return 0; } -- cgit v1.2.3 From a1ac18c4d5b4f8f4f279efb2ae12b46258f22282 Mon Sep 17 00:00:00 2001 From: paul Date: Tue, 28 Jun 2005 17:17:12 +0000 Subject: 2005-06-28 Paul Jakma * (global) Extern and static'ification, with related fixups of declarations, ensuring files include their own headers, etc. if_ioctl.c: (interface_info_ioctl) fix obvious arg mis-order in list loop --- zebra/connected.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 3ce59530..46d2aab9 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -33,6 +33,7 @@ #include "zebra/zserv.h" #include "zebra/redistribute.h" #include "zebra/interface.h" +#include "zebra/connected.h" /* If same interface address is already exist... */ struct connected * @@ -88,7 +89,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) /* Add connected IPv4 route to the interface. */ void connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, - int prefixlen, struct in_addr *broad, char *label) + u_char prefixlen, struct in_addr *broad, char *label) { struct prefix_ipv4 *p; struct connected *ifc; @@ -226,7 +227,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) /* Delete connected IPv4 route to the interface. */ void connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, - int prefixlen, struct in_addr *broad, char *label) + u_char prefixlen, struct in_addr *broad, char *label) { struct prefix_ipv4 p; struct connected *ifc; -- cgit v1.2.3 From be61c4eb59b8df1aab496176d87bb2e1763f185e Mon Sep 17 00:00:00 2001 From: hasso Date: Sat, 27 Aug 2005 06:05:47 +0000 Subject: * zebra_rib.c, rib.h: Add distance and metric arguments to the rib_add_ipv6() function so that IPv6 routes in RIB can have correct metric. No IPv6 routing daemon uses distance yet though. * zserv.c, connected.c, kernel_socket.c, rt_netlink.c, rtread_proc.c,zserv.c: Pass metric and distance info to the rib_add_ipv6(). Forwardport from stable branch. --- zebra/connected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 46d2aab9..68269088 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -308,7 +308,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) return; #endif - rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); + rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, 0, 0); rib_update (); } -- cgit v1.2.3 From ca16218df74a43491e34a577db5023c89a7e79c8 Mon Sep 17 00:00:00 2001 From: paul Date: Mon, 12 Sep 2005 16:58:52 +0000 Subject: 2005-09-12 Paul Jakma * (general) RTM_CHANGE and implicit withdraw on RTM_NEWADDR support. * connected.c: (connected_withdraw) new function. withdraw a connected subnet address set from zebra, and pass information along to clients. (connected_announce) similar, but to announce a new connected subnet address set. (connected_check_ipv4) renamed to connected_check, as its AFI independent. (connected_add_ipv{4,6}) Remove the connected address announce stuff, use connected_announce instead. If connected_check indicates address is already present, treat it as an implicit withdraw of the existing address, ie remove the old address details and replace with the new details. (connected_delete_ipv{4,6}) Use connected_withdraw. (connected_check_ipv6) deleted in favour of connected_check. * connected.h: Rename connected_check_ipv4 to connected_check. delete connected_check_ipv6. * interface.c: Use connected_check rather than the AFI specific symbols. * kernel_socket.c: (rtm_read) RTM_CHANGE support. Create a rib delete event for the existing route, before adding route again. (kernel_read) we can handle RTM_CHANGE now. --- zebra/connected.c | 158 ++++++++++++++++++++++++------------------------------ 1 file changed, 69 insertions(+), 89 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 68269088..7599d24d 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -35,9 +35,63 @@ #include "zebra/interface.h" #include "zebra/connected.h" +/* withdraw a connected address */ +static void +connected_withdraw (struct connected *ifc) +{ + if (! ifc) + return; + + /* Update interface address information to protocol daemon. */ + if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + { + zebra_interface_address_delete_update (ifc->ifp, ifc); + + if_subnet_delete (ifc->ifp, ifc); + + if (ifc->address->family == AF_INET) + connected_down_ipv4 (ifc->ifp, ifc); + else + connected_down_ipv6 (ifc->ifp, ifc); + + UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); + } + + listnode_delete (ifc->ifp->connected, ifc); + connected_free (ifc); +} + +static void +connected_announce (struct interface *ifp, struct connected *ifc) +{ + if (!ifc) + return; + + listnode_add (ifp->connected, ifc); + + /* Update interface address information to protocol daemon. */ + if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) + { + if (ifc->address->family == AF_INET) + if_subnet_add (ifp, ifc); + + SET_FLAG (ifc->conf, ZEBRA_IFC_REAL); + + zebra_interface_address_add_update (ifp, ifc); + + if (if_is_up(ifp)) + { + if (ifc->address->family == AF_INET) + connected_up_ipv4 (ifp, ifc); + else + connected_up_ipv6 (ifp, ifc); + } + } +} + /* If same interface address is already exist... */ struct connected * -connected_check_ipv4 (struct interface *ifp, struct prefix *p) +connected_check (struct interface *ifp, struct prefix *p) { struct connected *ifc; struct listnode *node; @@ -106,7 +160,7 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, p->prefix = *addr; p->prefixlen = prefixlen; ifc->address = (struct prefix *) p; - + /* If there is broadcast or pointopoint address. */ if (broad) { @@ -163,29 +217,10 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, ifc->label = strdup (label); /* Check same connected route. */ - current = connected_check_ipv4 (ifp, (struct prefix *) ifc->address); - if (current) - { - connected_free (ifc); - ifc = current; - } - else - { - listnode_add (ifp->connected, ifc); - } - - /* Update interface address information to protocol daemon. */ - if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) - { - if_subnet_add (ifp, ifc); - - SET_FLAG (ifc->conf, ZEBRA_IFC_REAL); - - zebra_interface_address_add_update (ifp, ifc); - - if (if_is_up(ifp)) - connected_up_ipv4 (ifp, ifc); - } + if ((current = connected_check (ifp, (struct prefix *) ifc->address))) + connected_withdraw (current); /* implicit withdraw - freebsd does this */ + + connected_announce (ifp, ifc); } void @@ -237,41 +272,14 @@ connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, p.prefix = *addr; p.prefixlen = prefixlen; - ifc = connected_check_ipv4 (ifp, (struct prefix *) &p); + ifc = connected_check (ifp, (struct prefix *) &p); if (! ifc) return; - - /* Update interface address information to protocol daemon. */ - if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) - { - zebra_interface_address_delete_update (ifp, ifc); - - if_subnet_delete (ifp, ifc); - - connected_down_ipv4 (ifp, ifc); - - UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); - } - - listnode_delete (ifp->connected, ifc); - connected_free (ifc); + + connected_withdraw (ifc); } #ifdef HAVE_IPV6 -/* If same interface address is already exist... */ -struct connected * -connected_check_ipv6 (struct interface *ifp, struct prefix *p) -{ - struct connected *ifc; - struct listnode *node; - - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) - if (prefix_same (ifc->address, p)) - return ifc; - - return 0; -} - void connected_up_ipv6 (struct interface *ifp, struct connected *ifc) { @@ -342,27 +350,10 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, ifc->destination = (struct prefix *) p; } - current = connected_check_ipv6 (ifp, (struct prefix *) ifc->address); - if (current) - { - connected_free (ifc); - ifc = current; - } - else - { - listnode_add (ifp->connected, ifc); - } - - /* Update interface address information to protocol daemon. */ - if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) - { - SET_FLAG (ifc->conf, ZEBRA_IFC_REAL); - - zebra_interface_address_add_update (ifp, ifc); - - if (if_is_up(ifp)) - connected_up_ipv6 (ifp, ifc); - } + if ((current = connected_check (ifp, (struct prefix *) ifc->address))) + connected_withdraw (current); /* implicit update of existing address */ + + connected_announce (ifp, ifc); } void @@ -414,21 +405,10 @@ connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, memcpy (&p.prefix, address, sizeof (struct in6_addr)); p.prefixlen = prefixlen; - ifc = connected_check_ipv6 (ifp, (struct prefix *) &p); + ifc = connected_check (ifp, (struct prefix *) &p); if (! ifc) return; - /* Update interface address information to protocol daemon. */ - if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) - { - zebra_interface_address_delete_update (ifp, ifc); - - connected_down_ipv6 (ifp, ifc); - - UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); - } - - listnode_delete (ifp->connected, ifc); - connected_free (ifc); + connected_withdraw (ifc); } #endif /* HAVE_IPV6 */ -- cgit v1.2.3 From aa2e32be264710ef208516dfe1661b8148c3eede Mon Sep 17 00:00:00 2001 From: vincent Date: Wed, 28 Sep 2005 13:42:11 +0000 Subject: * connected.c: flag connected_up_ipv6() and connected_down_ipv6() usage with HAVE_IPV6 --- zebra/connected.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 7599d24d..5557819c 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -51,8 +51,10 @@ connected_withdraw (struct connected *ifc) if (ifc->address->family == AF_INET) connected_down_ipv4 (ifc->ifp, ifc); +#ifdef HAVE_IPV6 else connected_down_ipv6 (ifc->ifp, ifc); +#endif UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); } @@ -83,8 +85,10 @@ connected_announce (struct interface *ifp, struct connected *ifc) { if (ifc->address->family == AF_INET) connected_up_ipv4 (ifp, ifc); +#ifdef HAVE_IPV6 else connected_up_ipv6 (ifp, ifc); +#endif } } } -- cgit v1.2.3 From d06b2a64b7093f998e7b0f33454efc23190123ac Mon Sep 17 00:00:00 2001 From: paul Date: Tue, 11 Oct 2005 03:53:54 +0000 Subject: 2005-10-11 Paul Jakma * connected.{c,h}: (connected_{add,delete}_ipv4) label should be const qualified. --- zebra/connected.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 5557819c..58d964fc 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -147,7 +147,8 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) /* Add connected IPv4 route to the interface. */ void connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, - u_char prefixlen, struct in_addr *broad, char *label) + u_char prefixlen, struct in_addr *broad, + const char *label) { struct prefix_ipv4 *p; struct connected *ifc; @@ -266,7 +267,8 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) /* Delete connected IPv4 route to the interface. */ void connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, - u_char prefixlen, struct in_addr *broad, char *label) + u_char prefixlen, struct in_addr *broad, + const char *label) { struct prefix_ipv4 p; struct connected *ifc; -- cgit v1.2.3 From 0752ef0b2e9bbf6c7ab20ed0fe87840b3bd1b7f4 Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 3 Nov 2005 12:35:21 +0000 Subject: 2005-11-03 Paul Jakma * connected.{c,h}: Include memory.h (connected_add_ipv4) Use MTYPE for ifc label. (connected_add_ipv6) Also should accept label. Store it in ifp. (connected_del_ipv4) Taking label as argument is pointless. * rt_netlink.c: (netlink_interface_addr) update label usage for connected_{add,delete} functions. * if_ioctl.c: (if_getaddrs) NULL label for connected_add_ipv6. * if_ioctl_solaris.c: (interface_list_ioctl) Pass LIFC_NOXMIT so we also find out about NOXMIT interfaces like VNI. Bit of hackery to turn interface names into the primary interface name, later with routing socket messages we only will about primary interfaces anyway, so we must normalise the name. (if_get_addr) take label as argument, so it can be passed to connected_add. If label is provided, then it is interface name to issue the ioctl for address information on, not the ifp name. (interface_list) List AF_UNSPEC too, just in case. * if_proc.c: (ifaddr_proc_ipv6) label for connected_add_ipv6. * interface.c: (if_addr_wakeup) Some very bogus code - sets IFF_RUNNING - add comment. (if_refresh) (ip_address_install) Use MTYPE for ifc label. * ioctl_solaris.c: (if_mangle_up) New function. Hackery to make IFF_UP reflect whether any addresses are left on the interface, as we get signalled for IFF_UP flags change on the primary interface only. Logical interfaces dont generate IFINFO, but we do get an RTM_DELADDR. (if_get_flags) Call if_mangle_up before return. * kernel_socket.c: (ifam_read) Fixup calls to connected_{add,delete} to match above changes. Rename gate variable to brd, less confusing. Pass the interface name as a label, if it is not same name as ifp->name. --- zebra/connected.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 58d964fc..105e4b11 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -29,6 +29,7 @@ #include "rib.h" #include "table.h" #include "log.h" +#include "memory.h" #include "zebra/zserv.h" #include "zebra/redistribute.h" @@ -219,7 +220,7 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, /* Label of this address. */ if (label) - ifc->label = strdup (label); + ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); /* Check same connected route. */ if ((current = connected_check (ifp, (struct prefix *) ifc->address))) @@ -267,8 +268,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) /* Delete connected IPv4 route to the interface. */ void connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, - u_char prefixlen, struct in_addr *broad, - const char *label) + u_char prefixlen, struct in_addr *broad) { struct prefix_ipv4 p; struct connected *ifc; @@ -330,7 +330,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) /* Add connected IPv6 route to the interface. */ void connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, - u_char prefixlen, struct in6_addr *broad) + u_char prefixlen, struct in6_addr *broad, char *label) { struct prefix_ipv6 *p; struct connected *ifc; @@ -356,6 +356,10 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, ifc->destination = (struct prefix *) p; } + /* Label of this address. */ + if (label) + ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); + if ((current = connected_check (ifp, (struct prefix *) ifc->address))) connected_withdraw (current); /* implicit update of existing address */ -- cgit v1.2.3 From 89368d9f8b70fef5c196db9055bd6a7e7aaa4f36 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 26 Nov 2005 09:14:07 +0000 Subject: [zebra] fix connected_add_ipv6 declarations, label should be const. 2005-11-26 Paul Jakma * connected.{c,h}: (connected_add_ipv6) label should have const qualifier, fix declarations. --- zebra/connected.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 105e4b11..5417ffc5 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -330,7 +330,8 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) /* Add connected IPv6 route to the interface. */ void connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, - u_char prefixlen, struct in6_addr *broad, char *label) + u_char prefixlen, struct in6_addr *broad, + const char *label) { struct prefix_ipv6 *p; struct connected *ifc; -- cgit v1.2.3 From c713300ab429c8779be98ec3c8dc888821405d55 Mon Sep 17 00:00:00 2001 From: paul Date: Tue, 17 Jan 2006 17:56:18 +0000 Subject: [zebra] Include metric on connected routes. 2006-01-17 Gunnar Stigen * connected.c: (connected_up_ipv{4,6}) Include interface metric on connected routes. --- zebra/connected.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 5417ffc5..7e4f0fc7 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -140,7 +140,8 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) if (prefix_ipv4_any (&p)) return; - rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, 0, 0); + rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, + ifp->metric, 0); rib_update (); } @@ -322,7 +323,8 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) return; #endif - rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, 0, 0); + rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, + ifp->metric, 0); rib_update (); } -- cgit v1.2.3 From 323966fda67d218019f5b74d359f6a73fd452ba6 Mon Sep 17 00:00:00 2001 From: ajs Date: Fri, 19 May 2006 13:53:23 +0000 Subject: [interface configuration] Preserve flag indicating address was set by quagga. 2006-05-19 Andrew J. Schorr * connected.c: (connected_add_ipv4,connected_add_ipv6) If the new struct connected matches an already existing one (that will consequently be removed by connected_withdraw), then be sure to preserve the ZEBRA_IFC_CONFIGURED flag. --- zebra/connected.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 7e4f0fc7..39f47805 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -225,7 +225,11 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, /* Check same connected route. */ if ((current = connected_check (ifp, (struct prefix *) ifc->address))) - connected_withdraw (current); /* implicit withdraw - freebsd does this */ + { + if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) + SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + connected_withdraw (current); /* implicit withdraw - freebsd does this */ + } connected_announce (ifp, ifc); } @@ -364,7 +368,11 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); if ((current = connected_check (ifp, (struct prefix *) ifc->address))) - connected_withdraw (current); /* implicit update of existing address */ + { + if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) + SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + connected_withdraw (current); /* implicit update of existing address */ + } connected_announce (ifp, ifc); } -- cgit v1.2.3 From 883cdc1883fdd024a9c5c0ccce32dd82bdb39c95 Mon Sep 17 00:00:00 2001 From: ajs Date: Sun, 21 May 2006 04:04:49 +0000 Subject: [interface configuration] Try to avoid losing address info after shutdown. 2006-05-21 Andrew J. Schorr * if.h: (struct connected) Document the meaning of the ZEBRA_IFC_REAL and ZEBRA_IFC_CONFIGURED flags. * connected.c: (connected_withdraw) Do not delete the connected address if the ZEBRA_IFC_CONFIGURED flag is set. (connected_add_ipv4,connected_add_ipv6) Before calling connected_withdraw, unset the ZEBRA_IFC_CONFIGURED flag on the superseded connected structure. --- zebra/connected.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 39f47805..37aa456a 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -60,8 +60,11 @@ connected_withdraw (struct connected *ifc) UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); } - listnode_delete (ifc->ifp->connected, ifc); - connected_free (ifc); + if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) + { + listnode_delete (ifc->ifp->connected, ifc); + connected_free (ifc); + } } static void @@ -227,7 +230,10 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, if ((current = connected_check (ifp, (struct prefix *) ifc->address))) { if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) - SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + { + SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); + } connected_withdraw (current); /* implicit withdraw - freebsd does this */ } @@ -370,7 +376,10 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, if ((current = connected_check (ifp, (struct prefix *) ifc->address))) { if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) - SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + { + SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); + } connected_withdraw (current); /* implicit update of existing address */ } -- cgit v1.2.3 From 384fe65dc5e75839ea69748d4f4d8aa51a80f3a1 Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 15 Jun 2006 18:10:47 +0000 Subject: [zebra] Fix forgetfulness wrt configured address on FreeBSD 2006-06-15 Paul Jakma * (general) The key fixes are actually Andrew Schorr's. * interface.c: (ip_address_uninstall) Unset the configured flag. * connected.c: (connected_same) new helper, check whether two connected are same. (connected_implicit_withdraw) new helper, consolidation of existing code in connected_add_ipv{4,6}. Try filter out unneeded Zserv address delete/adds when address is exact same. Where old address is implicitely removed, be sure to preserve the IFC_CONFIGURED flag if set, fixes bug where configured addresses were being lost on FreeBSD. --- zebra/connected.c | 83 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 21 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 37aa456a..736b40b0 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -111,6 +111,63 @@ connected_check (struct interface *ifp, struct prefix *p) return NULL; } +/* Check if two ifc's describe the same address */ +static int +connected_same (struct connected *ifc1, struct connected *ifc2) +{ + if (ifc1->ifp != ifc2->ifp) + return 0; + + if (ifc1->destination) + if (!ifc2->destination) + return 0; + if (ifc2->destination) + if (!ifc1->destination) + return 0; + + if (ifc1->destination && ifc2->destination) + if (!prefix_same (ifc1->destination, ifc2->destination)) + return 0; + + if (ifc1->flags != ifc2->flags) + return 0; + + return 1; +} + +/* Handle implicit withdrawals of addresses, where a system ADDs an address + * to an interface which already has the same address configured. + * + * Returns the struct connected which must be announced to clients, + * or NULL if nothing to do. + */ +static struct connected * +connected_implicit_withdraw (struct interface *ifp, struct connected *ifc) +{ + struct connected *current; + + /* Check same connected route. */ + if ((current = connected_check (ifp, (struct prefix *) ifc->address))) + { + if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) + SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + + /* Avoid spurious withdraws, this might be just the kernel 'reflecting' + * back an address we have already added. + */ + if (connected_same (current, ifc)) + { + /* nothing to do */ + connected_free (ifc); + return NULL; + } + + UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); + connected_withdraw (current); /* implicit withdraw - freebsd does this */ + } + return ifc; +} + /* Called from if_up(). */ void connected_up_ipv4 (struct interface *ifp, struct connected *ifc) @@ -157,7 +214,6 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, { struct prefix_ipv4 *p; struct connected *ifc; - struct connected *current; /* Make connected structure. */ ifc = connected_new (); @@ -226,16 +282,9 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, if (label) ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); - /* Check same connected route. */ - if ((current = connected_check (ifp, (struct prefix *) ifc->address))) - { - if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) - { - SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); - UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); - } - connected_withdraw (current); /* implicit withdraw - freebsd does this */ - } + /* nothing to do? */ + if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL) + return; connected_announce (ifp, ifc); } @@ -347,7 +396,6 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, { struct prefix_ipv6 *p; struct connected *ifc; - struct connected *current; /* Make connected structure. */ ifc = connected_new (); @@ -373,15 +421,8 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, if (label) ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); - if ((current = connected_check (ifp, (struct prefix *) ifc->address))) - { - if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) - { - SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); - UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); - } - connected_withdraw (current); /* implicit update of existing address */ - } + if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL) + return; connected_announce (ifp, ifc); } -- cgit v1.2.3 From da0243824a9e32c69171ce0f262231a6b8672891 Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 27 Jul 2006 16:11:02 +0000 Subject: [zebra] Connected routes must always be added to main table 2006-07-27 Rumen Svobodnikov * connected.c: (connected_up_ipv4) interface connected routes always go to table main (or otherwise they cannot be used by linux as nexthops) * zserv.c: (zread_ipv4_add) send route to the correct routing table * zebra_rib.c (static_install_ipv4) set routing table --- zebra/connected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 736b40b0..44002e76 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -200,7 +200,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) if (prefix_ipv4_any (&p)) return; - rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, + rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0); rib_update (); -- cgit v1.2.3 From 5473a17309434869238cb6cfedf07a2e88f6de6d Mon Sep 17 00:00:00 2001 From: ajs Date: Tue, 12 Dec 2006 19:18:21 +0000 Subject: [PtP over ethernet] New peer flag allows much more addressing flexibility 2006-12-12 Andrew J. Schorr * if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating whether a peer address has been configured. Comment now shows the new interpretation of the destination addr: if ZEBRA_IFA_PEER is set, then it must contain the destination address, otherwise it may contain the broadcast address or be NULL. (CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete macros that were specific to IPv4 and not fully general. (CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag. (CONNECTED_PREFIX) New macro giving the prefix to insert into the RIB: if CONNECTED_PEER, then use the destination (peer) address, else use the address field. (CONNECTED_ID) New macro to come up with an identifying address for the struct connected. * if.c: (if_lookup_address, connected_lookup_address) Streamline logic with new CONNECTED_PREFIX macro. * prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros for better performance than the general prefix_copy function. * zclient.c: (zebra_interface_address_read) For non-null destination addresses, set prefixlen to equal the address prefixlen. This is needed to get the new CONNECTED_PREFIX macro to work properly. * connected.c: (connected_up_ipv4, connected_down_ipv4, connected_up_ipv6, connected_down_ipv6) Simplify logic using the new CONNECTED_PREFIX macro. (connected_add_ipv4) Set prefixlen in destination addresses (required by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead of testing for IFF_POINTOPOINT. Delete invalid warning message. Warn about cases where the ZEBRA_IFA_PEER is set but no destination address has been supplied (and turn off the flag). (connected_add_ipv6) Add new flags argument so callers may set the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning. Set prefixlen in destination address so CONNECTED_PREFIX will work. * connected.h: (connected_add_ipv6) Add new flags argument so callers may set the ZEBRA_IFA_PEER flag. * interface.c: (connected_dump_vty) Use CONNECTED_PEER macro to decide whether the destination address is a peer or broadcast address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT). * if_ioctl.c: (if_getaddrs) Instead of setting a peer address only when the IFF_POINTOPOINT is set, we now accept a peer address whenever it is available and not the same as the local address. Otherwise (no peer address assigned), we check for a broadcast address (regardless of the IFF_BROADCAST flag). And must now pass a flags value of ZEBRA_IFA_PEER to connected_add_ipv4 when a peer address is assigned. The same new logic is used with the IPv6 code as well (and we pass the new flags argument to connected_add_ipv6). (if_get_addr) Do not bother to check IFF_POINTOPOINT: just issue the SIOCGIFDSTADDR ioctl and see if we get back a peer address not matching the local address (and set the ZEBRA_IFA_PEER in that case). If there's no peer address, try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set. * if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl without bothering to check the IFF_POINTOPOINT flag. And if no peer address was found, just try the SIOCGLIFBRDADDR ioctl without checking the IFF_BROADCAST flag. Call connected_add_ipv4 and connected_add_ipv6 with appropriate flags. * if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to connected_add_ipv6. * kernel_socket.c: (ifam_read) Must pass new flags argument to connected_add_ipv6. * rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2 to determine local and possible peer address (so there's no longer a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately. Pass new flags argument to connected_add_ipv6. (netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast to determine whether the connected destination address is a broadcast address. * bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete) Simplify logic by using new CONNECTED_PREFIX macro. * ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix, ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX macro. * ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX macro, both options collapse into the same code. * ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new CONNECTED_ID macro. (ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX macro. * ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro instead of testing the IFF_POINTOPOINT flag. * ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro instead of testing with if_is_pointopoint. And add commented-out code to implement alternative (in my opinion) more elegant behavior that has no special-case treatment for PtP addresses. (ospf_network_run) Use new CONNECTED_ID macro to simplify logic. * rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID macro to simplify logic. (rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does not give a useful result if prefixlen is 32 (we require a peer address in such cases). * ripd.c: (rip_update_interface) Fix same bug as above. --- zebra/connected.c | 132 ++++++++++++++++++------------------------------------ 1 file changed, 43 insertions(+), 89 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 44002e76..3fe9717d 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -173,24 +173,11 @@ void connected_up_ipv4 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv4 p; - struct prefix_ipv4 *addr; - struct prefix_ipv4 *dest; if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; - addr = (struct prefix_ipv4 *) ifc->address; - dest = (struct prefix_ipv4 *) ifc->destination; - - memset (&p, 0, sizeof (struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = addr->prefixlen; - - /* Point-to-point check. */ - if (CONNECTED_POINTOPOINT_HOST(ifc)) - p.prefix = dest->prefix; - else - p.prefix = addr->prefix; + PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc)); /* Apply mask to the network. */ apply_mask_ipv4 (&p); @@ -227,33 +214,22 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, p->prefixlen = prefixlen; ifc->address = (struct prefix *) p; - /* If there is broadcast or pointopoint address. */ + /* If there is broadcast or peer address. */ if (broad) { p = prefix_ipv4_new (); p->family = AF_INET; p->prefix = *broad; + p->prefixlen = prefixlen; ifc->destination = (struct prefix *) p; /* validate the destination address */ - if (ifp->flags & IFF_POINTOPOINT) + if (CONNECTED_PEER(ifc)) { if (IPV4_ADDR_SAME(addr,broad)) - zlog_warn("warning: PtP interface %s has same local and peer " + zlog_warn("warning: interface %s has same local and peer " "address %s, routing protocols may malfunction", ifp->name,inet_ntoa(*addr)); - else if ((prefixlen != IPV4_MAX_PREFIXLEN) && - (ipv4_network_addr(addr->s_addr,prefixlen) != - ipv4_network_addr(broad->s_addr,prefixlen))) - { - char buf[2][INET_ADDRSTRLEN]; - zlog_warn("warning: PtP interface %s network mismatch: local " - "%s/%d vs. peer %s, routing protocols may malfunction", - ifp->name, - inet_ntop (AF_INET, addr, buf[0], sizeof(buf[0])), - prefixlen, - inet_ntop (AF_INET, broad, buf[1], sizeof(buf[1]))); - } } else { @@ -273,10 +249,20 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, } else - /* no broadcast or destination address was supplied */ - if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) - zlog_warn("warning: PtP interface %s with addr %s/%d needs a " - "peer address",ifp->name,inet_ntoa(*addr),prefixlen); + { + if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) + { + zlog_warn("warning: %s called for interface %s " + "with peer flag set, but no peer address supplied", + __func__, ifp->name); + UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); + } + + /* no broadcast or destination address was supplied */ + if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) + zlog_warn("warning: PtP interface %s with addr %s/%d needs a " + "peer address",ifp->name,inet_ntoa(*addr),prefixlen); + } /* Label of this address. */ if (label) @@ -293,24 +279,11 @@ void connected_down_ipv4 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv4 p; - struct prefix_ipv4 *addr; - struct prefix_ipv4 *dest; if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; - addr = (struct prefix_ipv4 *)ifc->address; - dest = (struct prefix_ipv4 *)ifc->destination; - - memset (&p, 0, sizeof (struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = addr->prefixlen; - - /* Point-to-point check. */ - if (CONNECTED_POINTOPOINT_HOST(ifc)) - p.prefix = dest->prefix; - else - p.prefix = addr->prefix; + PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc)); /* Apply mask to the network. */ apply_mask_ipv4 (&p); @@ -350,28 +323,11 @@ void connected_up_ipv6 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv6 p; - struct prefix_ipv6 *addr; - struct prefix_ipv6 *dest; if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; - addr = (struct prefix_ipv6 *) ifc->address; - dest = (struct prefix_ipv6 *) ifc->destination; - - memset (&p, 0, sizeof (struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = addr->prefixlen; - - if (if_is_pointopoint (ifp) && dest) - { - if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) - p.prefix = addr->prefix; - else - p.prefix = dest->prefix; - } - else - p.prefix = addr->prefix; + PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc)); /* Apply mask to the network. */ apply_mask_ipv6 (&p); @@ -390,7 +346,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) /* Add connected IPv6 route to the interface. */ void -connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, +connected_add_ipv6 (struct interface *ifp, int flags, struct in6_addr *addr, u_char prefixlen, struct in6_addr *broad, const char *label) { @@ -400,6 +356,7 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, /* Make connected structure. */ ifc = connected_new (); ifc->ifp = ifp; + ifc->flags = flags; /* Allocate new connected address. */ p = prefix_ipv6_new (); @@ -408,13 +365,27 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr, p->prefixlen = prefixlen; ifc->address = (struct prefix *) p; - /* If there is broadcast or pointopoint address. */ + /* If there is broadcast or peer address. */ if (broad) { - p = prefix_ipv6_new (); - p->family = AF_INET6; - IPV6_ADDR_COPY (&p->prefix, broad); - ifc->destination = (struct prefix *) p; + if (IN6_IS_ADDR_UNSPECIFIED(broad)) + zlog_warn("warning: %s called for interface %s with unspecified " + "destination address; ignoring!", __func__, ifp->name); + else + { + p = prefix_ipv6_new (); + p->family = AF_INET6; + IPV6_ADDR_COPY (&p->prefix, broad); + p->prefixlen = prefixlen; + ifc->destination = (struct prefix *) p; + } + } + if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER) && !ifc->destination) + { + zlog_warn("warning: %s called for interface %s " + "with peer flag set, but no peer address supplied", + __func__, ifp->name); + UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); } /* Label of this address. */ @@ -431,28 +402,11 @@ void connected_down_ipv6 (struct interface *ifp, struct connected *ifc) { struct prefix_ipv6 p; - struct prefix_ipv6 *addr; - struct prefix_ipv6 *dest; if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) return; - addr = (struct prefix_ipv6 *) ifc->address; - dest = (struct prefix_ipv6 *) ifc->destination; - - memset (&p, 0, sizeof (struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = addr->prefixlen; - - if (if_is_pointopoint (ifp) && dest) - { - if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) - p.prefix = addr->prefix; - else - p.prefix = dest->prefix; - } - else - p.prefix = addr->prefix; + PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc)); apply_mask_ipv6 (&p); -- cgit v1.2.3 From 9d0392fdbe6cbb796102c2cb55f5ad33312e4456 Mon Sep 17 00:00:00 2001 From: dyoung Date: Mon, 16 Apr 2007 05:54:02 +0000 Subject: Only suppress adding a connected route to the kernel if it is already marked "real" (ZEBRA_IFC_REAL), i.e., "in kernel." According to Paul Jakma, this probably fixes Quagga bug #202. --- zebra/connected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 3fe9717d..74e10ac6 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -155,7 +155,7 @@ connected_implicit_withdraw (struct interface *ifp, struct connected *ifc) /* Avoid spurious withdraws, this might be just the kernel 'reflecting' * back an address we have already added. */ - if (connected_same (current, ifc)) + if (connected_same (current, ifc) && CHECK_FLAG(current->conf, ZEBRA_IFC_REAL)) { /* nothing to do */ connected_free (ifc); -- cgit v1.2.3 From fb6ce7ca5dfee02536e32ec5c76be7ae8737cb4e Mon Sep 17 00:00:00 2001 From: paul Date: Wed, 2 May 2007 16:05:35 +0000 Subject: [zebra] Routemap support on received routes, with 'set src' command (linux) 2007-05-01 David L Stevens * (general) These changes collectively add route-map and prefix-list support to zebra and fix a bug in "show route-map" (with no argument). * doc/main.texi: added route-map, prefix-list, ip protocol and set src documentation * lib/command.h: added PROTOCOL_NODE type * lib/log.c: (proto_name2num) new function, protocol name to number translation. * lib/routemap.c: (vty_show_route_map) fixed "show route-map" without route-map name * lib/routemap.h: added RMAP_ZEBRA type * lib/zebra.h: added proto_name2num() prototype * vtysh/extract.pl.in: added VTYSH_ZEBRA flag for route-map and plist * vtysh/Makefile.am: added zebra_routemap.c * vtysh/vtysh.h: added VTYSH_ZEBRA flag to VTYSH_RMAP * zebra/connected.c: (connected_up_ipv4) added src preference argument to rib_add_ipv4() * zebra/kernel_socket.c: (rtm_read) ditto * zebra/main.c: added prefix list initialization * zebra/Makefile.am: added zebra_routemap.c source file * zebra/rib.h: added generic address union "g_addr" and use in existing places that had an explicit union. Added "src" to struct nexthop. Added preferred src arg to nexthop_ipv4_add and rib_add_ipv4. * zebra/rt_netlink.c: (netlink_routing_table) set preferred source on netlink messages. (netlink_route_change) ditto (netlink_route_multipath) ditto. * zebra/rtread_getmsg.c: (handle_route_entry) added (NULL) src to rib_add_ipv4() call. * zebra/rtread_proc.c: (proc_route_read) ditto * zebra/zebra_rib.c: (nexthop_ipv4_add) add src argument. (nexthop_ipv4_ifindex_add) ditto (rib_add_ipv4) ditto (nexthop_active_check) Add route-map processing. * zebra/zebra_routemap.c: new file for zebra route-map commands. * zebra/zebra_vty.c: (ip_protocol_cmd) Apply route-map to protocol (vty_show_ip_route_detail) added "src" printing (vty_show_ip_route) ditto (show_ip_protocol_cmd) new command, list routemaps. (config_write_protocol) write out routemap protocl config. (zebra_vty_init) Install the new routemap protocol commands. * zebra/zserv.c: (zread_ipv4_add) added (NULL) src arg (zebra_init) init zebra route-maps. * zebra/zserv.h: add zebra_route_map_init --- zebra/connected.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 74e10ac6..53aa2543 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -187,8 +187,8 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) if (prefix_ipv4_any (&p)) return; - rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN, - ifp->metric, 0); + rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex, + RT_TABLE_MAIN, ifp->metric, 0); rib_update (); } -- cgit v1.2.3 From b359e35f78c929071ed04d7f4d0b41f23c48e992 Mon Sep 17 00:00:00 2001 From: pilot Date: Mon, 12 Nov 2007 14:55:01 +0000 Subject: + fixed bug #418 (changing address on an existing interface doesn't cause existing static routes to be revalidated) --- zebra/connected.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 53aa2543..8bf1d337 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -35,6 +35,7 @@ #include "zebra/redistribute.h" #include "zebra/interface.h" #include "zebra/connected.h" +extern struct zebra_t zebrad; /* withdraw a connected address */ static void @@ -187,8 +188,15 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) if (prefix_ipv4_any (&p)) return; + /* Always push arriving/departing connected routes into the head of + * the working queue to make possible proper validation of the rest + * of the RIB queue (which will contain the whole RIB after the first + * call to rib_update()). + */ + work_queue_aim_head (zebrad.ribq, 1); rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0); + work_queue_aim_head (zebrad.ribq, 0); rib_update (); } @@ -293,7 +301,10 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) if (prefix_ipv4_any (&p)) return; + /* Same logic as for connected_up_ipv4(): push the changes into the head. */ + work_queue_aim_head (zebrad.ribq, 1); rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); + work_queue_aim_head (zebrad.ribq, 0); rib_update (); } @@ -338,8 +349,10 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) return; #endif + work_queue_aim_head (zebrad.ribq, 1); rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, ifp->metric, 0); + work_queue_aim_head (zebrad.ribq, 0); rib_update (); } @@ -413,7 +426,9 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc) if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix)) return; + work_queue_aim_head (zebrad.ribq, 1); rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); + work_queue_aim_head (zebrad.ribq, 0); rib_update (); } -- cgit v1.2.3 From 90443036ecda07a5f8d5c3501faef465301365bd Mon Sep 17 00:00:00 2001 From: pilot Date: Mon, 2 Jun 2008 12:03:22 +0000 Subject: + initial edition of meta-queue for RIB updates processing (bug #431) --- zebra/connected.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'zebra/connected.c') diff --git a/zebra/connected.c b/zebra/connected.c index 8bf1d337..ad3e9607 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -188,15 +188,8 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) if (prefix_ipv4_any (&p)) return; - /* Always push arriving/departing connected routes into the head of - * the working queue to make possible proper validation of the rest - * of the RIB queue (which will contain the whole RIB after the first - * call to rib_update()). - */ - work_queue_aim_head (zebrad.ribq, 1); rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0); - work_queue_aim_head (zebrad.ribq, 0); rib_update (); } @@ -302,9 +295,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) return; /* Same logic as for connected_up_ipv4(): push the changes into the head. */ - work_queue_aim_head (zebrad.ribq, 1); rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); - work_queue_aim_head (zebrad.ribq, 0); rib_update (); } @@ -349,10 +340,8 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) return; #endif - work_queue_aim_head (zebrad.ribq, 1); rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, ifp->metric, 0); - work_queue_aim_head (zebrad.ribq, 0); rib_update (); } @@ -426,9 +415,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc) if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix)) return; - work_queue_aim_head (zebrad.ribq, 1); rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0); - work_queue_aim_head (zebrad.ribq, 0); rib_update (); } -- cgit v1.2.3