summaryrefslogtreecommitdiff
path: root/zebra/interface.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-08-29 19:53:30 -0400
committerGitHub <noreply@github.com>2017-08-29 19:53:30 -0400
commitcc1edd39297bd763e0e1a942e15881a3ac99453a (patch)
tree8932fece0a8ac41646a1936761b2f259ceadf806 /zebra/interface.c
parent32592ffb4f04f18b7eacaeca3c6fc254bafbc5b3 (diff)
parent1ac2e7761c8157ede19d571ed75d7b36744920e5 (diff)
Merge pull request #1059 from opensourcerouting/oldbits-1
zebra: PtP address configuration support
Diffstat (limited to 'zebra/interface.c')
-rw-r--r--zebra/interface.c115
1 files changed, 96 insertions, 19 deletions
diff --git a/zebra/interface.c b/zebra/interface.c
index 63f0b9e386..eea3674c8e 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -242,7 +242,7 @@ int if_subnet_add(struct interface *ifp, struct connected *ifc)
/* Get address derived subnet node and associated address list, while
marking
address secondary attribute appropriately. */
- cp = *ifc->address;
+ cp = *CONNECTED_PREFIX(ifc);
apply_mask(&cp);
rn = route_node_get(zebra_if->ipv4_subnets, &cp);
@@ -267,12 +267,16 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc)
struct route_node *rn;
struct zebra_if *zebra_if;
struct list *addr_list;
+ struct prefix cp;
assert(ifp && ifp->info && ifc);
zebra_if = ifp->info;
+ cp = *CONNECTED_PREFIX(ifc);
+ apply_mask(&cp);
+
/* Get address derived subnet node. */
- rn = route_node_lookup(zebra_if->ipv4_subnets, ifc->address);
+ rn = route_node_lookup(zebra_if->ipv4_subnets, &cp);
if (!(rn && rn->info)) {
zlog_warn(
"Trying to remove an address from an unknown subnet."
@@ -565,7 +569,7 @@ static void if_uninstall_connected(struct interface *ifp)
static void if_delete_connected(struct interface *ifp)
{
struct connected *ifc;
- struct prefix *p;
+ struct prefix cp;
struct route_node *rn;
struct zebra_if *zebra_if;
@@ -578,11 +582,13 @@ static void if_delete_connected(struct interface *ifp)
while ((node = (last ? last->next
: listhead(ifp->connected)))) {
ifc = listgetdata(node);
- p = ifc->address;
- if (p->family == AF_INET
+ cp = *CONNECTED_PREFIX(ifc);
+ apply_mask(&cp);
+
+ if (cp.family == AF_INET
&& (rn = route_node_lookup(zebra_if->ipv4_subnets,
- p))) {
+ &cp))) {
struct listnode *anode;
struct listnode *next;
struct listnode *first;
@@ -635,7 +641,7 @@ static void if_delete_connected(struct interface *ifp)
list_delete(addr_list);
rn->info = NULL;
route_unlock_node(rn);
- } else if (p->family == AF_INET6) {
+ } else if (cp.family == AF_INET6) {
connected_down_ipv6(ifp, ifc);
zebra_interface_address_delete_update(ifp, ifc);
@@ -968,6 +974,8 @@ static void connected_dump_vty(struct vty *vty, struct connected *connected)
vty_out(vty,
(CONNECTED_PEER(connected) ? " peer " : " broadcast "));
prefix_vty_out(vty, connected->destination);
+ if (CONNECTED_PEER(connected))
+ vty_out(vty, "/%d", connected->destination->prefixlen);
}
if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))
@@ -2367,38 +2375,56 @@ static int ip_address_install(struct vty *vty, struct interface *ifp,
const char *label)
{
struct zebra_if *if_data;
- struct prefix_ipv4 cp;
+ struct prefix_ipv4 lp, pp;
struct connected *ifc;
struct prefix_ipv4 *p;
int ret;
if_data = ifp->info;
- ret = str2prefix_ipv4(addr_str, &cp);
+ ret = str2prefix_ipv4(addr_str, &lp);
if (ret <= 0) {
vty_out(vty, "%% Malformed address \n");
return CMD_WARNING_CONFIG_FAILED;
}
- if (ipv4_martian(&cp.prefix)) {
+ if (ipv4_martian(&lp.prefix)) {
vty_out(vty, "%% Invalid address\n");
return CMD_WARNING_CONFIG_FAILED;
}
- ifc = connected_check(ifp, (struct prefix *)&cp);
+ if (peer_str) {
+ if (lp.prefixlen != 32) {
+ vty_out(vty,
+ "%% Local prefix length for P-t-P address must be /32\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = str2prefix_ipv4(peer_str, &pp);
+ if (ret <= 0) {
+ vty_out(vty, "%% Malformed peer address\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+
+ ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
if (!ifc) {
ifc = connected_new();
ifc->ifp = ifp;
/* Address. */
p = prefix_ipv4_new();
- *p = cp;
+ *p = lp;
ifc->address = (struct prefix *)p;
- /* Broadcast. */
- if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) {
+ if (peer_str) {
+ SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
+ p = prefix_ipv4_new();
+ *p = pp;
+ ifc->destination = (struct prefix *)p;
+ } else if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) {
p = prefix_ipv4_new();
- *p = cp;
+ *p = lp;
p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,
p->prefixlen);
ifc->destination = (struct prefix *)p;
@@ -2447,19 +2473,33 @@ static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
const char *addr_str, const char *peer_str,
const char *label)
{
- struct prefix_ipv4 cp;
+ struct prefix_ipv4 lp, pp;
struct connected *ifc;
int ret;
/* Convert to prefix structure. */
- ret = str2prefix_ipv4(addr_str, &cp);
+ ret = str2prefix_ipv4(addr_str, &lp);
if (ret <= 0) {
vty_out(vty, "%% Malformed address \n");
return CMD_WARNING_CONFIG_FAILED;
}
+ if (peer_str) {
+ if (lp.prefixlen != 32) {
+ vty_out(vty,
+ "%% Local prefix length for P-t-P address must be /32\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = str2prefix_ipv4(peer_str, &pp);
+ if (ret <= 0) {
+ vty_out(vty, "%% Malformed peer address\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+
/* Check current interface address. */
- ifc = connected_check(ifp, (struct prefix *)&cp);
+ ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
if (!ifc) {
vty_out(vty, "%% Can't find address\n");
return CMD_WARNING_CONFIG_FAILED;
@@ -2519,6 +2559,32 @@ DEFUN (no_ip_address,
NULL, NULL);
}
+DEFUN (ip_address_peer,
+ ip_address_peer_cmd,
+ "ip address A.B.C.D peer A.B.C.D/M",
+ "Interface Internet Protocol config commands\n"
+ "Set the IP address of an interface\n"
+ "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
+ "Specify P-t-P address\n"
+ "Peer IP address (e.g. 10.0.0.1/8)\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL);
+}
+
+DEFUN (no_ip_address_peer,
+ no_ip_address_peer_cmd,
+ "no ip address A.B.C.D peer A.B.C.D/M",
+ NO_STR
+ "Interface Internet Protocol config commands\n"
+ "Set the IP address of an interface\n"
+ "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
+ "Specify P-t-P address\n"
+ "Peer IP address (e.g. 10.0.0.1/8)\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL);
+}
#ifdef HAVE_NETLINK
DEFUN (ip_address_label,
@@ -2822,7 +2888,16 @@ static int if_config_write(struct vty *vty)
p = ifc->address;
vty_out(vty, " ip%s address %s",
p->family == AF_INET ? "" : "v6",
- prefix2str(p, buf, sizeof(buf)));
+ inet_ntop(p->family, &p->u.prefix,
+ buf, sizeof(buf)));
+ if (CONNECTED_PEER (ifc)) {
+ p = ifc->destination;
+ vty_out(vty, " peer %s",
+ inet_ntop(p->family,
+ &p->u.prefix,
+ buf, sizeof(buf)));
+ }
+ vty_out (vty, "/%d", p->prefixlen);
if (ifc->label)
vty_out(vty, " label %s", ifc->label);
@@ -2878,6 +2953,8 @@ void zebra_if_init(void)
install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
install_element(INTERFACE_NODE, &ip_address_cmd);
install_element(INTERFACE_NODE, &no_ip_address_cmd);
+ install_element(INTERFACE_NODE, &ip_address_peer_cmd);
+ install_element(INTERFACE_NODE, &no_ip_address_peer_cmd);
install_element(INTERFACE_NODE, &ipv6_address_cmd);
install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
#ifdef HAVE_NETLINK