summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/bfd.c2
-rw-r--r--lib/bfd.h14
-rw-r--r--lib/command.c40
-rw-r--r--lib/command.h3
-rw-r--r--lib/filter.c6
-rw-r--r--lib/if.c72
-rw-r--r--lib/if.h5
-rw-r--r--lib/prefix.c20
-rw-r--r--lib/prefix.h10
9 files changed, 126 insertions, 46 deletions
diff --git a/lib/bfd.c b/lib/bfd.c
index 00dbd1b3d1..ffb3cbc1f8 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -315,6 +315,8 @@ const char *bfd_get_status_str(int status)
return "Down";
case BFD_STATUS_UP:
return "Up";
+ case BFD_STATUS_ADMIN_DOWN:
+ return "Admin Down";
case BFD_STATUS_UNKNOWN:
default:
return "Unknown";
diff --git a/lib/bfd.h b/lib/bfd.h
index e4781f4eaf..7f5d111504 100644
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -51,9 +51,17 @@ struct bfd_gbl {
#define BFD_FLAG_BFD_CBIT_ON (1 << 3) /* Peer registered with CBIT set to on */
#define BFD_FLAG_BFD_CHECK_CONTROLPLANE (1 << 4) /* BFD and controlplane daemon are linked */
-#define BFD_STATUS_UNKNOWN (1 << 0) /* BFD session status never received */
-#define BFD_STATUS_DOWN (1 << 1) /* BFD session status is down */
-#define BFD_STATUS_UP (1 << 2) /* BFD session status is up */
+#define BFD_STATUS_UNKNOWN (1 << 0) /* BFD session status never received */
+#define BFD_STATUS_DOWN (1 << 1) /* BFD session status is down */
+#define BFD_STATUS_UP (1 << 2) /* BFD session status is up */
+#define BFD_STATUS_ADMIN_DOWN (1 << 3) /* BFD session is admin down */
+
+#define BFD_SET_CLIENT_STATUS(current_status, new_status) \
+ do { \
+ (current_status) = \
+ (((new_status) == BFD_STATUS_ADMIN_DOWN) ? \
+ BFD_STATUS_DOWN : (new_status));\
+ } while (0)
enum bfd_sess_type {
BFD_TYPE_NOT_CONFIGURED,
diff --git a/lib/command.c b/lib/command.c
index e52893f0ba..59668e95fc 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -198,9 +198,6 @@ static struct cmd_node enable_node = {
static struct cmd_node config_node = {CONFIG_NODE, "%s(config)# ", 1};
-/* Default motd string. */
-static const char *default_motd = FRR_DEFAULT_MOTD;
-
static const struct facility_map {
int facility;
const char *name;
@@ -592,6 +589,10 @@ static int config_write_host(struct vty *vty)
if (host.motdfile)
vty_out(vty, "banner motd file %s\n", host.motdfile);
+ else if (host.motd
+ && strncmp(host.motd, FRR_DEFAULT_MOTD,
+ strlen(host.motd)))
+ vty_out(vty, "banner motd line %s\n", host.motd);
else if (!host.motd)
vty_out(vty, "no banner motd\n");
}
@@ -2668,6 +2669,13 @@ int cmd_banner_motd_file(const char *file)
return success;
}
+void cmd_banner_motd_line(const char *line)
+{
+ if (host.motd)
+ XFREE(MTYPE_HOST, host.motd);
+ host.motd = XSTRDUP(MTYPE_HOST, line);
+}
+
DEFUN (banner_motd_file,
banner_motd_file_cmd,
"banner motd file FILE",
@@ -2688,6 +2696,26 @@ DEFUN (banner_motd_file,
return cmd;
}
+DEFUN (banner_motd_line,
+ banner_motd_line_cmd,
+ "banner motd line LINE...",
+ "Set banner\n"
+ "Banner for motd\n"
+ "Banner from an input\n"
+ "Text\n")
+{
+ int idx = 0;
+ char *motd;
+
+ argv_find(argv, argc, "LINE", &idx);
+ motd = argv_concat(argv, argc, idx);
+
+ cmd_banner_motd_line(motd);
+ XFREE(MTYPE_TMP, motd);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (banner_motd_default,
banner_motd_default_cmd,
"banner motd default",
@@ -2695,7 +2723,7 @@ DEFUN (banner_motd_default,
"Strings for motd\n"
"Default string\n")
{
- host.motd = default_motd;
+ cmd_banner_motd_line(FRR_DEFAULT_MOTD);
return CMD_SUCCESS;
}
@@ -2864,7 +2892,7 @@ void cmd_init(int terminal)
host.config = NULL;
host.noconfig = (terminal < 0);
host.lines = -1;
- host.motd = default_motd;
+ cmd_banner_motd_line(FRR_DEFAULT_MOTD);
host.motdfile = NULL;
/* Install top nodes. */
@@ -2944,6 +2972,7 @@ void cmd_init(int terminal)
install_element(CONFIG_NODE, &no_service_password_encrypt_cmd);
install_element(CONFIG_NODE, &banner_motd_default_cmd);
install_element(CONFIG_NODE, &banner_motd_file_cmd);
+ install_element(CONFIG_NODE, &banner_motd_line_cmd);
install_element(CONFIG_NODE, &no_banner_motd_cmd);
install_element(CONFIG_NODE, &service_terminal_length_cmd);
install_element(CONFIG_NODE, &no_service_terminal_length_cmd);
@@ -2988,6 +3017,7 @@ void cmd_terminate(void)
XFREE(MTYPE_HOST, host.logfile);
XFREE(MTYPE_HOST, host.motdfile);
XFREE(MTYPE_HOST, host.config);
+ XFREE(MTYPE_HOST, host.motd);
list_delete(&varhandlers);
qobj_finish();
diff --git a/lib/command.h b/lib/command.h
index 2176b14615..68ac86f769 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -78,7 +78,7 @@ struct host {
int encrypt;
/* Banner configuration. */
- const char *motd;
+ char *motd;
char *motdfile;
};
@@ -499,6 +499,7 @@ extern void host_config_set(const char *);
extern void print_version(const char *);
extern int cmd_banner_motd_file(const char *);
+extern void cmd_banner_motd_line(const char *line);
/* struct host global, ick */
extern struct host host;
diff --git a/lib/filter.c b/lib/filter.c
index 8c210bd7ad..ed3ffe9c67 100644
--- a/lib/filter.c
+++ b/lib/filter.c
@@ -2147,7 +2147,7 @@ DEFUN (no_access_list_any,
"Specify packets to forward\n"
"Prefix to match. e.g. 10.0.0.0/8\n")
{
- int idx_word = 1;
+ int idx_word = 2;
int idx = 0;
char *seq = NULL;
char *permit_deny = NULL;
@@ -2352,7 +2352,7 @@ DEFUN (no_ipv6_access_list_exact,
{
int idx = 0;
int exact = 0;
- int idx_word = 2;
+ int idx_word = 3;
char *seq = NULL;
char *permit_deny = NULL;
char *prefix = NULL;
@@ -2394,7 +2394,7 @@ DEFUN (no_ipv6_access_list_any,
"Specify packets to forward\n"
"Any prefixi to match\n")
{
- int idx_word = 2;
+ int idx_word = 3;
int idx = 0;
char *seq = NULL;
char *permit_deny = NULL;
diff --git a/lib/if.c b/lib/if.c
index 594961d763..9d0f13ecbd 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -140,6 +140,13 @@ static int if_cmp_index_func(const struct interface *ifp1,
return ifp1->ifindex - ifp2->ifindex;
}
+static void ifp_connected_free(void *arg)
+{
+ struct connected *c = arg;
+
+ connected_free(&c);
+}
+
/* Create new interface structure. */
static struct interface *if_new(vrf_id_t vrf_id)
{
@@ -153,7 +160,7 @@ static struct interface *if_new(vrf_id_t vrf_id)
ifp->vrf_id = vrf_id;
ifp->connected = list_new();
- ifp->connected->del = (void (*)(void *))connected_free;
+ ifp->connected->del = ifp_connected_free;
ifp->nbr_connected = list_new();
ifp->nbr_connected->del = (void (*)(void *))nbr_connected_free;
@@ -178,7 +185,7 @@ void if_destroy_via_zapi(struct interface *ifp)
if_set_index(ifp, IFINDEX_INTERNAL);
if (!ifp->configured)
- if_delete(ifp);
+ if_delete(&ifp);
}
void if_up_via_zapi(struct interface *ifp)
@@ -276,27 +283,29 @@ void if_delete_retain(struct interface *ifp)
}
/* Delete and free interface structure. */
-void if_delete(struct interface *ifp)
+void if_delete(struct interface **ifp)
{
+ struct interface *ptr = *ifp;
struct vrf *vrf;
- vrf = vrf_lookup_by_id(ifp->vrf_id);
+ vrf = vrf_lookup_by_id(ptr->vrf_id);
assert(vrf);
- IFNAME_RB_REMOVE(vrf, ifp);
- if (ifp->ifindex != IFINDEX_INTERNAL)
- IFINDEX_RB_REMOVE(vrf, ifp);
+ IFNAME_RB_REMOVE(vrf, ptr);
+ if (ptr->ifindex != IFINDEX_INTERNAL)
+ IFINDEX_RB_REMOVE(vrf, ptr);
- if_delete_retain(ifp);
+ if_delete_retain(ptr);
- list_delete(&ifp->connected);
- list_delete(&ifp->nbr_connected);
+ list_delete(&ptr->connected);
+ list_delete(&ptr->nbr_connected);
- if_link_params_free(ifp);
+ if_link_params_free(ptr);
- XFREE(MTYPE_TMP, ifp->desc);
+ XFREE(MTYPE_TMP, ptr->desc);
- XFREE(MTYPE_IF, ifp);
+ XFREE(MTYPE_IF, ptr);
+ *ifp = NULL;
}
/* Used only internally to check within VRF only */
@@ -866,24 +875,27 @@ struct nbr_connected *nbr_connected_new(void)
}
/* Free connected structure. */
-void connected_free(struct connected *connected)
+void connected_free(struct connected **connected)
{
- if (connected->address)
- prefix_free(connected->address);
+ struct connected *ptr = *connected;
- if (connected->destination)
- prefix_free(connected->destination);
+ if (ptr->address)
+ prefix_free(&ptr->address);
- XFREE(MTYPE_CONNECTED_LABEL, connected->label);
+ if (ptr->destination)
+ prefix_free(&ptr->destination);
- XFREE(MTYPE_CONNECTED, connected);
+ XFREE(MTYPE_CONNECTED_LABEL, ptr->label);
+
+ XFREE(MTYPE_CONNECTED, ptr);
+ *connected = NULL;
}
/* Free nbr connected structure. */
void nbr_connected_free(struct nbr_connected *connected)
{
if (connected->address)
- prefix_free(connected->address);
+ prefix_free(&connected->address);
XFREE(MTYPE_NBR_CONNECTED, connected);
}
@@ -959,6 +971,20 @@ static int connected_same_prefix(struct prefix *p1, struct prefix *p2)
return 0;
}
+/* count the number of connected addresses that are in the given family */
+unsigned int connected_count_by_family(struct interface *ifp, int family)
+{
+ struct listnode *cnode;
+ struct connected *connected;
+ unsigned int cnt = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected))
+ if (connected->address->family == family)
+ cnt++;
+
+ return cnt;
+}
+
struct connected *connected_lookup_prefix_exact(struct interface *ifp,
struct prefix *p)
{
@@ -1145,7 +1171,7 @@ void if_terminate(struct vrf *vrf)
ifp->node->info = NULL;
route_unlock_node(ifp->node);
}
- if_delete(ifp);
+ if_delete(&ifp);
}
}
@@ -1527,7 +1553,7 @@ static int lib_interface_destroy(enum nb_event event,
ifp = nb_running_unset_entry(dnode);
ifp->configured = false;
- if_delete(ifp);
+ if_delete(&ifp);
break;
}
diff --git a/lib/if.h b/lib/if.h
index 1ee6561e8d..4ca2e79572 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -513,7 +513,7 @@ extern void if_delete_retain(struct interface *);
/* Delete and free the interface structure: calls if_delete_retain and then
deletes it from the interface list and frees the structure. */
-extern void if_delete(struct interface *);
+extern void if_delete(struct interface **ifp);
extern int if_is_up(const struct interface *ifp);
extern int if_is_running(const struct interface *ifp);
@@ -543,7 +543,7 @@ extern ifindex_t ifname2ifindex(const char *ifname, vrf_id_t vrf_id);
/* Connected address functions. */
extern struct connected *connected_new(void);
-extern void connected_free(struct connected *);
+extern void connected_free(struct connected **connected);
extern void connected_add(struct interface *, struct connected *);
extern struct connected *
connected_add_by_prefix(struct interface *, struct prefix *, struct prefix *);
@@ -553,6 +553,7 @@ extern struct connected *connected_lookup_prefix(struct interface *,
struct prefix *);
extern struct connected *connected_lookup_prefix_exact(struct interface *,
struct prefix *);
+extern unsigned int connected_count_by_family(struct interface *, int family);
extern struct nbr_connected *nbr_connected_new(void);
extern void nbr_connected_free(struct nbr_connected *);
struct nbr_connected *nbr_connected_check(struct interface *, struct prefix *);
diff --git a/lib/prefix.c b/lib/prefix.c
index 5071ca8201..e2bf3b949c 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -905,9 +905,9 @@ struct prefix_ipv4 *prefix_ipv4_new(void)
}
/* Free prefix_ipv4 structure. */
-void prefix_ipv4_free(struct prefix_ipv4 *p)
+void prefix_ipv4_free(struct prefix_ipv4 **p)
{
- prefix_free((struct prefix *)p);
+ prefix_free((struct prefix **)p);
}
/* If given string is valid return 1 else return 0 */
@@ -1077,9 +1077,9 @@ struct prefix_ipv6 *prefix_ipv6_new(void)
}
/* Free prefix for IPv6. */
-void prefix_ipv6_free(struct prefix_ipv6 *p)
+void prefix_ipv6_free(struct prefix_ipv6 **p)
{
- prefix_free((struct prefix *)p);
+ prefix_free((struct prefix **)p);
}
/* If given string is valid return 1 else return 0 */
@@ -1484,10 +1484,18 @@ struct prefix *prefix_new(void)
return p;
}
+void prefix_free_lists(void *arg)
+{
+ struct prefix *p = arg;
+
+ prefix_free(&p);
+}
+
/* Free prefix structure. */
-void prefix_free(struct prefix *p)
+void prefix_free(struct prefix **p)
{
- XFREE(MTYPE_PREFIX, p);
+ XFREE(MTYPE_PREFIX, *p);
+ *p = NULL;
}
/* Utility function to convert ipv4 prefixes to Classful prefixes */
diff --git a/lib/prefix.h b/lib/prefix.h
index 784927616a..7a93c766a3 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -396,7 +396,11 @@ extern unsigned int prefix6_bit(const struct in6_addr *prefix,
const uint16_t prefixlen);
extern struct prefix *prefix_new(void);
-extern void prefix_free(struct prefix *);
+extern void prefix_free(struct prefix **p);
+/*
+ * Function to handle prefix_free being used as a del function.
+ */
+extern void prefix_free_lists(void *arg);
extern const char *prefix_family_str(const struct prefix *);
extern int prefix_blen(const struct prefix *);
extern int str2prefix(const char *, struct prefix *);
@@ -435,7 +439,7 @@ extern void prefix2sockunion(const struct prefix *, union sockunion *);
extern int str2prefix_eth(const char *, struct prefix_eth *);
extern struct prefix_ipv4 *prefix_ipv4_new(void);
-extern void prefix_ipv4_free(struct prefix_ipv4 *);
+extern void prefix_ipv4_free(struct prefix_ipv4 **p);
extern int str2prefix_ipv4(const char *, struct prefix_ipv4 *);
extern void apply_mask_ipv4(struct prefix_ipv4 *);
@@ -460,7 +464,7 @@ extern in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen);
extern int netmask_str2prefix_str(const char *, const char *, char *);
extern struct prefix_ipv6 *prefix_ipv6_new(void);
-extern void prefix_ipv6_free(struct prefix_ipv6 *);
+extern void prefix_ipv6_free(struct prefix_ipv6 **p);
extern int str2prefix_ipv6(const char *, struct prefix_ipv6 *);
extern void apply_mask_ipv6(struct prefix_ipv6 *);