summaryrefslogtreecommitdiffstats
path: root/lib/if.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/if.c')
-rw-r--r--lib/if.c139
1 files changed, 118 insertions, 21 deletions
diff --git a/lib/if.c b/lib/if.c
index bbf22ab1..f003754a 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -189,11 +189,13 @@ if_lookup_address (struct in_addr src)
listnode node;
struct prefix addr;
struct prefix best;
+ struct prefix peer;
listnode cnode;
struct interface *ifp;
struct prefix *p;
struct connected *c;
struct interface *match;
+ int prefixlen;
/* Zero structures - get rid of rubbish from stack */
memset(&addr, 0, sizeof(addr));
@@ -212,34 +214,24 @@ if_lookup_address (struct in_addr src)
for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
{
c = getdata (cnode);
+ p = c->address;
- if (if_is_pointopoint (ifp))
+ if (p->family == AF_INET)
{
- p = c->address;
+ prefixlen = p->prefixlen;
- if (p && p->family == AF_INET)
+ if (if_is_pointopoint (ifp) ||
+ prefixlen >= IPV4_MAX_PREFIXLEN - 1)
{
-#ifdef OLD_RIB /* PTP links are conventionally identified
- by the address of the far end - MAG */
- if (IPV4_ADDR_SAME (&p->u.prefix4, &src))
- return ifp;
-#endif
- p = c->destination;
- if (p && IPV4_ADDR_SAME (&p->u.prefix4, &src))
- return ifp;
+ peer = *c->destination;
+ peer.prefixlen = prefixlen;
+ p = &peer;
}
- }
- else
- {
- p = c->address;
- if (p->family == AF_INET)
+ if (prefix_match (p, &addr) && prefixlen > best.prefixlen)
{
- if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen)
- {
- best = *p;
- match = ifp;
- }
+ best = *p;
+ match = ifp;
}
}
}
@@ -270,6 +262,22 @@ if_is_up (struct interface *ifp)
return ifp->flags & IFF_UP;
}
+/* Is interface running? */
+int
+if_is_running (struct interface *ifp)
+{
+ return ifp->flags & IFF_RUNNING;
+}
+
+/* Is the interface operative, eg. either UP & RUNNING
+ or UP & !ZEBRA_INTERFACE_LINK_DETECTION */
+int
+if_is_operative (struct interface *ifp)
+{
+ return ((ifp->flags & IFF_UP) &&
+ (ifp->flags & IFF_RUNNING || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
+}
+
/* Is this loopback interface ? */
int
if_is_loopback (struct interface *ifp)
@@ -432,6 +440,36 @@ DEFUN (interface,
return CMD_SUCCESS;
}
+DEFUN_NOSH (no_interface,
+ no_interface_cmd,
+ "no interface IFNAME",
+ NO_STR
+ "Delete a pseudo interface's configuration\n"
+ "Interface's name\n")
+{
+ // deleting interface
+ struct interface *ifp;
+
+ ifp = if_lookup_by_name (argv[0]);
+
+ if (ifp == NULL)
+ {
+ vty_out (vty, "%% Inteface %s does not exist%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
+ {
+ vty_out (vty, "%% Only inactive interfaces can be deleted%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if_delete(ifp);
+
+ return CMD_SUCCESS;
+}
+
/* For debug purpose. */
DEFUN (show_address,
show_address_cmd,
@@ -553,6 +591,65 @@ connected_delete_by_prefix (struct interface *ifp, struct prefix *p)
return NULL;
}
+/* Find the IPv4 address on our side that will be used when packets
+ are sent to dst. */
+struct connected *
+connected_lookup_address (struct interface *ifp, struct in_addr dst)
+{
+ struct prefix addr;
+ struct prefix best;
+ listnode cnode;
+ struct prefix *p;
+ struct connected *c;
+ struct connected *match;
+
+ /* Zero structures - get rid of rubbish from stack */
+ memset(&addr, 0, sizeof(addr));
+ memset(&best, 0, sizeof(best));
+
+ addr.family = AF_INET;
+ addr.u.prefix4 = dst;
+ addr.prefixlen = IPV4_MAX_BITLEN;
+
+ match = NULL;
+
+ for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
+ {
+ c = getdata (cnode);
+
+ if (if_is_pointopoint (ifp))
+ {
+ p = c->address;
+
+ if (p && p->family == AF_INET)
+ {
+#ifdef OLD_RIB /* PTP links are conventionally identified
+ by the address of the far end - MAG */
+ if (IPV4_ADDR_SAME (&p->u.prefix4, &dst))
+ return c;
+#endif
+ p = c->destination;
+ if (p && IPV4_ADDR_SAME (&p->u.prefix4, &dst))
+ return c;
+ }
+ }
+ else
+ {
+ p = c->address;
+
+ if (p->family == AF_INET)
+ {
+ if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen)
+ {
+ best = *p;
+ match = c;
+ }
+ }
+ }
+ }
+ return match;
+}
+
/* Check the connected information is PtP style or not. */
int
ifc_pointopoint (struct connected *ifc)