summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/command.c230
-rw-r--r--lib/command.h2
-rw-r--r--lib/ipaddr.h10
-rw-r--r--lib/plist.c48
-rw-r--r--lib/plist_int.h2
-rw-r--r--lib/prefix.c128
-rw-r--r--lib/prefix.h91
-rw-r--r--lib/routemap.c14
-rw-r--r--lib/routemap.h4
-rw-r--r--lib/zclient.c50
-rw-r--r--lib/zclient.h11
11 files changed, 415 insertions, 175 deletions
diff --git a/lib/command.c b/lib/command.c
index 0720762da0..69e301fcfa 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -85,6 +85,7 @@ const char *node_names[] = {
"keychain", // KEYCHAIN_NODE,
"keychain key", // KEYCHAIN_KEY_NODE,
"logical-router", // LOGICALROUTER_NODE,
+ "static ip", // IP_NODE,
"vrf", // VRF_NODE,
"interface", // INTERFACE_NODE,
"nexthop-group", // NH_GROUP_NODE,
@@ -119,7 +120,6 @@ const char *node_names[] = {
"ldp l2vpn", // LDP_L2VPN_NODE,
"ldp", // LDP_PSEUDOWIRE_NODE,
"isis", // ISIS_NODE,
- "static ip", // IP_NODE,
"ipv4 access list", // ACCESS_NODE,
"ipv4 prefix list", // PREFIX_NODE,
"ipv6 access list", // ACCESS_IPV6_NODE,
@@ -529,87 +529,103 @@ static int config_write_host(struct vty *vty)
if (cmd_domainname_get())
vty_out(vty, "domainname %s\n", cmd_domainname_get());
- if (host.encrypt) {
- if (host.password_encrypt)
- vty_out(vty, "password 8 %s\n", host.password_encrypt);
- if (host.enable_encrypt)
- vty_out(vty, "enable password 8 %s\n",
- host.enable_encrypt);
- } else {
- if (host.password)
- vty_out(vty, "password %s\n", host.password);
- if (host.enable)
- vty_out(vty, "enable password %s\n", host.enable);
- }
+ /* The following are all configuration commands that are not sent to
+ * watchfrr. For instance watchfrr is hardcoded to log to syslog so
+ * we would always display 'log syslog informational' in the config
+ * which would cause other daemons to then switch to syslog when they
+ * parse frr.conf.
+ */
+ if (strcmp(zlog_default->protoname, "WATCHFRR")) {
+ if (host.encrypt) {
+ if (host.password_encrypt)
+ vty_out(vty, "password 8 %s\n",
+ host.password_encrypt);
+ if (host.enable_encrypt)
+ vty_out(vty, "enable password 8 %s\n",
+ host.enable_encrypt);
+ } else {
+ if (host.password)
+ vty_out(vty, "password %s\n", host.password);
+ if (host.enable)
+ vty_out(vty, "enable password %s\n",
+ host.enable);
+ }
- if (zlog_default->default_lvl != LOG_DEBUG) {
- vty_out(vty, "! N.B. The 'log trap' command is deprecated.\n");
- vty_out(vty, "log trap %s\n",
- zlog_priority[zlog_default->default_lvl]);
- }
+ if (zlog_default->default_lvl != LOG_DEBUG) {
+ vty_out(vty,
+ "! N.B. The 'log trap' command is deprecated.\n");
+ vty_out(vty, "log trap %s\n",
+ zlog_priority[zlog_default->default_lvl]);
+ }
- if (host.logfile
- && (zlog_default->maxlvl[ZLOG_DEST_FILE] != ZLOG_DISABLED)) {
- vty_out(vty, "log file %s", host.logfile);
- if (zlog_default->maxlvl[ZLOG_DEST_FILE]
- != zlog_default->default_lvl)
- vty_out(vty, " %s",
- zlog_priority
- [zlog_default->maxlvl[ZLOG_DEST_FILE]]);
- vty_out(vty, "\n");
- }
+ if (host.logfile
+ && (zlog_default->maxlvl[ZLOG_DEST_FILE]
+ != ZLOG_DISABLED)) {
+ vty_out(vty, "log file %s", host.logfile);
+ if (zlog_default->maxlvl[ZLOG_DEST_FILE]
+ != zlog_default->default_lvl)
+ vty_out(vty, " %s",
+ zlog_priority
+ [zlog_default->maxlvl
+ [ZLOG_DEST_FILE]]);
+ vty_out(vty, "\n");
+ }
- if (zlog_default->maxlvl[ZLOG_DEST_STDOUT] != ZLOG_DISABLED) {
- vty_out(vty, "log stdout");
- if (zlog_default->maxlvl[ZLOG_DEST_STDOUT]
- != zlog_default->default_lvl)
- vty_out(vty, " %s",
- zlog_priority[zlog_default->maxlvl
- [ZLOG_DEST_STDOUT]]);
- vty_out(vty, "\n");
- }
+ if (zlog_default->maxlvl[ZLOG_DEST_STDOUT] != ZLOG_DISABLED) {
+ vty_out(vty, "log stdout");
+ if (zlog_default->maxlvl[ZLOG_DEST_STDOUT]
+ != zlog_default->default_lvl)
+ vty_out(vty, " %s",
+ zlog_priority
+ [zlog_default->maxlvl
+ [ZLOG_DEST_STDOUT]]);
+ vty_out(vty, "\n");
+ }
- if (zlog_default->maxlvl[ZLOG_DEST_MONITOR] == ZLOG_DISABLED)
- vty_out(vty, "no log monitor\n");
- else if (zlog_default->maxlvl[ZLOG_DEST_MONITOR]
- != zlog_default->default_lvl)
- vty_out(vty, "log monitor %s\n",
- zlog_priority[zlog_default->maxlvl[ZLOG_DEST_MONITOR]]);
-
- if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED) {
- vty_out(vty, "log syslog");
- if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG]
- != zlog_default->default_lvl)
- vty_out(vty, " %s",
+ if (zlog_default->maxlvl[ZLOG_DEST_MONITOR] == ZLOG_DISABLED)
+ vty_out(vty, "no log monitor\n");
+ else if (zlog_default->maxlvl[ZLOG_DEST_MONITOR]
+ != zlog_default->default_lvl)
+ vty_out(vty, "log monitor %s\n",
zlog_priority[zlog_default->maxlvl
- [ZLOG_DEST_SYSLOG]]);
- vty_out(vty, "\n");
- }
+ [ZLOG_DEST_MONITOR]]);
+
+ if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED) {
+ vty_out(vty, "log syslog");
+ if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG]
+ != zlog_default->default_lvl)
+ vty_out(vty, " %s",
+ zlog_priority[zlog_default->maxlvl
+ [ZLOG_DEST_SYSLOG]]);
+ vty_out(vty, "\n");
+ }
- if (zlog_default->facility != LOG_DAEMON)
- vty_out(vty, "log facility %s\n",
- facility_name(zlog_default->facility));
+ if (zlog_default->facility != LOG_DAEMON)
+ vty_out(vty, "log facility %s\n",
+ facility_name(zlog_default->facility));
- if (zlog_default->record_priority == 1)
- vty_out(vty, "log record-priority\n");
+ if (zlog_default->record_priority == 1)
+ vty_out(vty, "log record-priority\n");
- if (zlog_default->timestamp_precision > 0)
- vty_out(vty, "log timestamp precision %d\n",
- zlog_default->timestamp_precision);
+ if (zlog_default->timestamp_precision > 0)
+ vty_out(vty, "log timestamp precision %d\n",
+ zlog_default->timestamp_precision);
- if (host.advanced)
- vty_out(vty, "service advanced-vty\n");
+ if (host.advanced)
+ vty_out(vty, "service advanced-vty\n");
- if (host.encrypt)
- vty_out(vty, "service password-encryption\n");
+ if (host.encrypt)
+ vty_out(vty, "service password-encryption\n");
- if (host.lines >= 0)
- vty_out(vty, "service terminal-length %d\n", host.lines);
+ if (host.lines >= 0)
+ vty_out(vty, "service terminal-length %d\n",
+ host.lines);
- if (host.motdfile)
- vty_out(vty, "banner motd file %s\n", host.motdfile);
- else if (!host.motd)
- vty_out(vty, "no banner motd\n");
+ if (host.motdfile)
+ vty_out(vty, "banner motd file %s\n", host.motdfile);
+ else if (!host.motd)
+ vty_out(vty, "no banner motd\n");
+ }
if (debug_memstats_at_exit)
vty_out(vty, "!\ndebug memstats-at-exit\n");
@@ -1873,7 +1889,7 @@ DEFUN (config_hostname,
{
struct cmd_token *word = argv[1];
- if (!isalpha((int)word->arg[0])) {
+ if (!isalnum((int)word->arg[0])) {
vty_out(vty, "Please specify string starting with alphabet\n");
return CMD_WARNING_CONFIG_FAILED;
}
@@ -1895,7 +1911,7 @@ DEFUN (config_no_hostname,
DEFUN (config_password,
password_cmd,
"password [(8-8)] WORD",
- "Assign the terminal connection password\n"
+ "Modify the terminal connection password\n"
"Specifies a HIDDEN password will follow\n"
"The password string\n")
{
@@ -1934,6 +1950,36 @@ DEFUN (config_password,
return CMD_SUCCESS;
}
+/* VTY interface password delete. */
+DEFUN (no_config_password,
+ no_password_cmd,
+ "no password",
+ NO_STR
+ "Modify the terminal connection password\n")
+{
+ bool warned = false;
+
+ if (host.password) {
+ vty_out(vty,
+ "Please be aware that removing the password is a security risk and "
+ "you should think twice about this command\n");
+ warned = true;
+ XFREE(MTYPE_HOST, host.password);
+ }
+ host.password = NULL;
+
+ if (host.password_encrypt) {
+ if (!warned)
+ vty_out(vty,
+ "Please be aware that removing the password is a security risk "
+ "and you should think twice about this command\n");
+ XFREE(MTYPE_HOST, host.password_encrypt);
+ }
+ host.password_encrypt = NULL;
+
+ return CMD_SUCCESS;
+}
+
/* VTY enable password set. */
DEFUN (config_enable_password,
enable_password_cmd,
@@ -1995,12 +2041,24 @@ DEFUN (no_config_enable_password,
"Modify enable password parameters\n"
"Assign the privileged level password\n")
{
- if (host.enable)
+ bool warned = false;
+
+ if (host.enable) {
+ vty_out(vty,
+ "Please be aware that removing the password is a security risk and "
+ "you should think twice about this command\n");
+ warned = true;
XFREE(MTYPE_HOST, host.enable);
+ }
host.enable = NULL;
- if (host.enable_encrypt)
+ if (host.enable_encrypt) {
+ if (!warned)
+ vty_out(vty,
+ "Please be aware that removing the password is a security risk "
+ "and you should think twice about this command\n");
XFREE(MTYPE_HOST, host.enable_encrypt);
+ }
host.enable_encrypt = NULL;
return CMD_SUCCESS;
@@ -2304,7 +2362,7 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel)
#if defined(HAVE_CUMULUS)
if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED)
- zlog_default->maxlvl[ZLOG_DEST_SYSLOG] = ZLOG_DISABLED;
+ zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
#endif
return CMD_SUCCESS;
}
@@ -2330,6 +2388,16 @@ DEFUN (config_log_file,
zlog_default->default_lvl);
}
+static void disable_log_file(void)
+{
+ zlog_reset_file();
+
+ if (host.logfile)
+ XFREE(MTYPE_HOST, host.logfile);
+
+ host.logfile = NULL;
+}
+
DEFUN (no_config_log_file,
no_config_log_file_cmd,
"no log file [FILENAME [LEVEL]]",
@@ -2339,13 +2407,7 @@ DEFUN (no_config_log_file,
"Logging file name\n"
"Logging level\n")
{
- zlog_reset_file();
-
- if (host.logfile)
- XFREE(MTYPE_HOST, host.logfile);
-
- host.logfile = NULL;
-
+ disable_log_file();
return CMD_SUCCESS;
}
@@ -2357,6 +2419,9 @@ DEFUN (config_log_syslog,
LOG_LEVEL_DESC)
{
int idx_log_levels = 2;
+
+ disable_log_file();
+
if (argc == 3) {
int level;
if ((level = level_match(argv[idx_log_levels]->arg))
@@ -2710,6 +2775,7 @@ void cmd_init(int terminal)
if (terminal > 0) {
install_element(CONFIG_NODE, &password_cmd);
+ install_element(CONFIG_NODE, &no_password_cmd);
install_element(CONFIG_NODE, &enable_password_cmd);
install_element(CONFIG_NODE, &no_enable_password_cmd);
diff --git a/lib/command.h b/lib/command.h
index f18de3417c..9ba53e0907 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -85,6 +85,7 @@ enum node_type {
KEYCHAIN_NODE, /* Key-chain node. */
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
LOGICALROUTER_NODE, /* Logical-Router node. */
+ IP_NODE, /* Static ip route node. */
VRF_NODE, /* VRF mode node. */
INTERFACE_NODE, /* Interface mode node. */
NH_GROUP_NODE, /* Nexthop-Group mode node. */
@@ -119,7 +120,6 @@ enum node_type {
LDP_L2VPN_NODE, /* LDP L2VPN node */
LDP_PSEUDOWIRE_NODE, /* LDP Pseudowire node */
ISIS_NODE, /* ISIS protocol mode */
- IP_NODE, /* Static ip route node. */
ACCESS_NODE, /* Access list node. */
PREFIX_NODE, /* Prefix list node. */
ACCESS_IPV6_NODE, /* Access list node. */
diff --git a/lib/ipaddr.h b/lib/ipaddr.h
index 33591cb4e7..7f2d06548b 100644
--- a/lib/ipaddr.h
+++ b/lib/ipaddr.h
@@ -102,4 +102,14 @@ static inline void ipv4_to_ipv4_mapped_ipv6(struct in6_addr *in6,
memcpy((char *)in6 + 12, &in, sizeof(struct in_addr));
}
+/*
+ * convert an ipv4 mapped ipv6 address back to ipv4 address
+ */
+static inline void ipv4_mapped_ipv6_to_ipv4(struct in6_addr *in6,
+ struct in_addr *in)
+{
+ memset(in, 0, sizeof(struct in_addr));
+ memcpy(in, (char *)in6 + 12, sizeof(struct in_addr));
+}
+
#endif /* __IPADDR_H__ */
diff --git a/lib/plist.c b/lib/plist.c
index 01b55f9f1d..e1dac46a90 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -73,7 +73,7 @@ struct prefix_master {
struct prefix_list_list str;
/* Whether sequential number is used. */
- int seqnum;
+ bool seqnum;
/* The latest update. */
struct prefix_list *recent;
@@ -348,7 +348,7 @@ static void prefix_list_delete(struct prefix_list *plist)
static struct prefix_list_entry *
prefix_list_entry_make(struct prefix *prefix, enum prefix_list_type type,
- int seq, int le, int ge, int any)
+ int64_t seq, int le, int ge, int any)
{
struct prefix_list_entry *pentry;
@@ -381,10 +381,10 @@ void prefix_list_delete_hook(void (*func)(struct prefix_list *plist))
}
/* Calculate new sequential number. */
-static int prefix_new_seq_get(struct prefix_list *plist)
+static int64_t prefix_new_seq_get(struct prefix_list *plist)
{
- int maxseq;
- int newseq;
+ int64_t maxseq;
+ int64_t newseq;
struct prefix_list_entry *pentry;
maxseq = newseq = 0;
@@ -401,7 +401,7 @@ static int prefix_new_seq_get(struct prefix_list *plist)
/* Return prefix list entry which has same seq number. */
static struct prefix_list_entry *prefix_seq_check(struct prefix_list *plist,
- int seq)
+ int64_t seq)
{
struct prefix_list_entry *pentry;
@@ -413,7 +413,8 @@ static struct prefix_list_entry *prefix_seq_check(struct prefix_list *plist,
static struct prefix_list_entry *
prefix_list_entry_lookup(struct prefix_list *plist, struct prefix *prefix,
- enum prefix_list_type type, int seq, int le, int ge)
+ enum prefix_list_type type, int64_t seq,
+ int le, int ge)
{
struct prefix_list_entry *pentry;
@@ -771,7 +772,7 @@ static void __attribute__((unused)) prefix_list_print(struct prefix_list *plist)
p = &pentry->prefix;
- printf(" seq %u %s %s/%d", pentry->seq,
+ printf(" seq %" PRId64 " %s %s/%d", pentry->seq,
prefix_list_type_str(pentry),
inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
p->prefixlen);
@@ -793,7 +794,7 @@ prefix_entry_dup_check(struct prefix_list *plist, struct prefix_list_entry *new)
size_t validbits = new->prefix.prefixlen;
struct pltrie_table *table;
struct prefix_list_entry *pentry;
- int seq = 0;
+ int64_t seq = 0;
if (new->seq == -1)
seq = prefix_new_seq_get(plist);
@@ -845,13 +846,13 @@ static int vty_prefix_list_install(struct vty *vty, afi_t afi, const char *name,
struct prefix_list_entry *dup;
struct prefix p, p_tmp;
int any = 0;
- int seqnum = -1;
+ int64_t seqnum = -1;
int lenum = 0;
int genum = 0;
/* Sequential number. */
if (seq)
- seqnum = atoi(seq);
+ seqnum = (int64_t)atol(seq);
/* ge and le number */
if (ge)
@@ -972,7 +973,7 @@ static int vty_prefix_list_uninstall(struct vty *vty, afi_t afi,
struct prefix_list *plist;
struct prefix_list_entry *pentry;
struct prefix p;
- int seqnum = -1;
+ int64_t seqnum = -1;
int lenum = 0;
int genum = 0;
@@ -998,7 +999,7 @@ static int vty_prefix_list_uninstall(struct vty *vty, afi_t afi,
/* Check sequence number. */
if (seq)
- seqnum = atoi(seq);
+ seqnum = (int64_t)atol(seq);
/* ge and le number */
if (ge)
@@ -1113,7 +1114,7 @@ static void vty_show_prefix_entry(struct vty *vty, afi_t afi,
vty_out(vty, " Description: %s\n", plist->desc);
vty_out(vty,
- " count: %d, range entries: %d, sequences: %u - %u\n",
+ " count: %d, range entries: %d, sequences: %" PRId64 " - %" PRId64 "\n",
plist->count, plist->rangecount,
plist->head ? plist->head->seq : 0,
plist->tail ? plist->tail->seq : 0);
@@ -1128,7 +1129,7 @@ static void vty_show_prefix_entry(struct vty *vty, afi_t afi,
vty_out(vty, " ");
if (master->seqnum)
- vty_out(vty, "seq %u ", pentry->seq);
+ vty_out(vty, "seq %" PRId64 " ", pentry->seq);
vty_out(vty, "%s ", prefix_list_type_str(pentry));
@@ -1164,14 +1165,14 @@ static int vty_show_prefix_list(struct vty *vty, afi_t afi, const char *name,
{
struct prefix_list *plist;
struct prefix_master *master;
- int seqnum = 0;
+ int64_t seqnum = 0;
master = prefix_master_get(afi, 0);
if (master == NULL)
return CMD_WARNING;
if (seq)
- seqnum = atoi(seq);
+ seqnum = (int64_t)atol(seq);
if (name) {
plist = prefix_list_lookup(afi, name);
@@ -1236,7 +1237,7 @@ static int vty_show_prefix_list_prefix(struct vty *vty, afi_t afi,
}
if (match) {
- vty_out(vty, " seq %u %s ", pentry->seq,
+ vty_out(vty, " seq %" PRId64 " %s ", pentry->seq,
prefix_list_type_str(pentry));
if (pentry->any)
@@ -1387,7 +1388,7 @@ DEFPY (ip_prefix_list_sequence_number,
PREFIX_LIST_STR
"Include/exclude sequence numbers in NVGEN\n")
{
- prefix_master_ipv4.seqnum = no ? 0 : 1;
+ prefix_master_ipv4.seqnum = no ? false : true;
return CMD_SUCCESS;
}
@@ -1581,7 +1582,7 @@ DEFPY (ipv6_prefix_list_sequence_number,
PREFIX_LIST_STR
"Include/exclude sequence numbers in NVGEN\n")
{
- prefix_master_ipv6.seqnum = no ? 0 : 1;
+ prefix_master_ipv6.seqnum = no ? false : true;
return CMD_SUCCESS;
}
@@ -1744,7 +1745,7 @@ static int config_write_prefix_afi(afi_t afi, struct vty *vty)
afi == AFI_IP ? "" : "v6", plist->name);
if (master->seqnum)
- vty_out(vty, "seq %u ", pentry->seq);
+ vty_out(vty, "seq %" PRId64 " ", pentry->seq);
vty_out(vty, "%s ", prefix_list_type_str(pentry));
@@ -1783,7 +1784,7 @@ static int config_write_prefix_afi(afi_t afi, struct vty *vty)
afi == AFI_IP ? "" : "v6", plist->name);
if (master->seqnum)
- vty_out(vty, "seq %u ", pentry->seq);
+ vty_out(vty, "seq %" PRId64 " ", pentry->seq);
vty_out(vty, "%s", prefix_list_type_str(pentry));
@@ -1959,7 +1960,8 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
struct prefix *p = &pentry->prefix;
char buf[BUFSIZ];
- vty_out(vty, " seq %u %s %s/%d", pentry->seq,
+ vty_out(vty, " seq %" PRId64 " %s %s/%d",
+ pentry->seq,
prefix_list_type_str(pentry),
inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
p->prefixlen);
diff --git a/lib/plist_int.h b/lib/plist_int.h
index aa81a3bce2..6bc2d034d6 100644
--- a/lib/plist_int.h
+++ b/lib/plist_int.h
@@ -48,7 +48,7 @@ struct prefix_list {
/* Each prefix-list's entry. */
struct prefix_list_entry {
- int seq;
+ int64_t seq;
int le;
int ge;
diff --git a/lib/prefix.c b/lib/prefix.c
index b38dd94589..05af190e9d 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -1206,54 +1206,104 @@ int str2prefix(const char *str, struct prefix *p)
return 0;
}
-static const char *prefixevpn2str(const struct prefix *p, char *str, int size)
+static const char *prefixevpn_ead2str(const struct prefix_evpn *p, char *str,
+ int size)
+{
+ snprintf(str, size, "Unsupported EVPN prefix");
+ return str;
+}
+
+static const char *prefixevpn_macip2str(const struct prefix_evpn *p, char *str,
+ int size)
{
uint8_t family;
char buf[PREFIX2STR_BUFFER];
char buf2[ETHER_ADDR_STRLEN];
- if (p->u.prefix_evpn.route_type == 2) {
- if (IS_EVPN_PREFIX_IPADDR_NONE((struct prefix_evpn *)p))
- snprintf(str, size, "[%d]:[%s]/%d",
- p->u.prefix_evpn.route_type,
- prefix_mac2str(&p->u.prefix_evpn.mac, buf2,
- sizeof(buf2)),
- p->prefixlen);
- else {
- family = IS_EVPN_PREFIX_IPADDR_V4(
- (struct prefix_evpn *)p)
- ? AF_INET
- : AF_INET6;
- snprintf(str, size, "[%d]:[%s]:[%s]/%d",
- p->u.prefix_evpn.route_type,
- prefix_mac2str(&p->u.prefix_evpn.mac, buf2,
- sizeof(buf2)),
- inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr,
- buf, PREFIX2STR_BUFFER),
- p->prefixlen);
- }
- } else if (p->u.prefix_evpn.route_type == 3) {
- family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p)
- ? AF_INET
- : AF_INET6;
- snprintf(str, size, "[%d]:[%s]/%d", p->u.prefix_evpn.route_type,
- inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr, buf,
- PREFIX2STR_BUFFER),
+ if (is_evpn_prefix_ipaddr_none(p))
+ snprintf(str, size, "[%d]:[%s]/%d",
+ p->prefix.route_type,
+ prefix_mac2str(&p->prefix.macip_addr.mac,
+ buf2, sizeof(buf2)),
p->prefixlen);
- } else if (p->u.prefix_evpn.route_type == 5) {
- family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p)
+ else {
+ family = is_evpn_prefix_ipaddr_v4(p)
? AF_INET
: AF_INET6;
- snprintf(str, size, "[%d]:[%u][%s/%d]/%d",
- p->u.prefix_evpn.route_type, p->u.prefix_evpn.eth_tag,
- inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr, buf,
- PREFIX2STR_BUFFER),
- p->u.prefix_evpn.ip_prefix_length, p->prefixlen);
- } else {
- sprintf(str, "Unsupported EVPN route type %d",
- p->u.prefix_evpn.route_type);
+ snprintf(str, size, "[%d]:[%s]:[%s]/%d",
+ p->prefix.route_type,
+ prefix_mac2str(&p->prefix.macip_addr.mac,
+ buf2, sizeof(buf2)),
+ inet_ntop(family,
+ &p->prefix.macip_addr.ip.ip.addr,
+ buf, PREFIX2STR_BUFFER),
+ p->prefixlen);
}
+ return str;
+}
+
+static const char *prefixevpn_imet2str(const struct prefix_evpn *p, char *str,
+ int size)
+{
+ uint8_t family;
+ char buf[PREFIX2STR_BUFFER];
+
+ family = is_evpn_prefix_ipaddr_v4(p)
+ ? AF_INET
+ : AF_INET6;
+ snprintf(str, size, "[%d]:[%s]/%d", p->prefix.route_type,
+ inet_ntop(family,
+ &p->prefix.imet_addr.ip.ip.addr, buf,
+ PREFIX2STR_BUFFER),
+ p->prefixlen);
+ return str;
+}
+static const char *prefixevpn_es2str(const struct prefix_evpn *p, char *str,
+ int size)
+{
+ snprintf(str, size, "Unsupported EVPN prefix");
+ return str;
+}
+
+static const char *prefixevpn_prefix2str(const struct prefix_evpn *p, char *str,
+ int size)
+{
+ uint8_t family;
+ char buf[PREFIX2STR_BUFFER];
+
+ family = is_evpn_prefix_ipaddr_v4(p)
+ ? AF_INET
+ : AF_INET6;
+ snprintf(str, size, "[%d]:[%u][%s/%d]/%d",
+ p->prefix.route_type,
+ p->prefix.prefix_addr.eth_tag,
+ inet_ntop(family,
+ &p->prefix.prefix_addr.ip.ip.addr, buf,
+ PREFIX2STR_BUFFER),
+ p->prefix.prefix_addr.ip_prefix_length,
+ p->prefixlen);
+ return str;
+}
+
+static const char *prefixevpn2str(const struct prefix_evpn *p, char *str,
+ int size)
+{
+ switch (p->prefix.route_type) {
+ case 1:
+ return prefixevpn_ead2str(p, str, size);
+ case 2:
+ return prefixevpn_macip2str(p, str, size);
+ case 3:
+ return prefixevpn_imet2str(p, str, size);
+ case 4:
+ return prefixevpn_es2str(p, str, size);
+ case 5:
+ return prefixevpn_prefix2str(p, str, size);
+ default:
+ snprintf(str, size, "Unsupported EVPN prefix");
+ break;
+ }
return str;
}
@@ -1277,7 +1327,7 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size)
break;
case AF_EVPN:
- prefixevpn2str(p, str, size);
+ prefixevpn2str((const struct prefix_evpn *)p, str, size);
break;
case AF_FLOWSPEC:
diff --git a/lib/prefix.h b/lib/prefix.h
index f01c85b811..ab3c05ae74 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -56,26 +56,56 @@ struct ethaddr {
#define PREFIX_LEN_ROUTE_TYPE_5_IPV4 (18*8)
#define PREFIX_LEN_ROUTE_TYPE_5_IPV6 (30*8)
-/* EVPN address (RFC 7432) */
-struct evpn_addr {
- uint8_t route_type;
+typedef struct esi_t_ {
+ uint8_t val[10];
+} esi_t;
+
+struct evpn_ead_addr {
+ esi_t esi;
+ uint32_t eth_tag;
+};
+
+struct evpn_macip_addr {
+ uint32_t eth_tag;
uint8_t ip_prefix_length;
struct ethaddr mac;
+ struct ipaddr ip;
+};
+
+struct evpn_imet_addr {
uint32_t eth_tag;
+ uint8_t ip_prefix_length;
struct ipaddr ip;
-#if 0
- union
- {
- uint8_t addr;
- struct in_addr v4_addr;
- struct in6_addr v6_addr;
- } ip;
-#endif
};
-#define IS_EVPN_PREFIX_IPADDR_NONE(evp) IS_IPADDR_NONE(&(evp)->prefix.ip)
-#define IS_EVPN_PREFIX_IPADDR_V4(evp) IS_IPADDR_V4(&(evp)->prefix.ip)
-#define IS_EVPN_PREFIX_IPADDR_V6(evp) IS_IPADDR_V6(&(evp)->prefix.ip)
+struct evpn_es_addr {
+ esi_t esi;
+ uint8_t ip_prefix_length;
+ struct ipaddr ip;
+};
+
+struct evpn_prefix_addr {
+ uint32_t eth_tag;
+ uint8_t ip_prefix_length;
+ struct ipaddr ip;
+};
+
+/* EVPN address (RFC 7432) */
+struct evpn_addr {
+ uint8_t route_type;
+ union {
+ struct evpn_ead_addr _ead_addr;
+ struct evpn_macip_addr _macip_addr;
+ struct evpn_imet_addr _imet_addr;
+ struct evpn_es_addr _es_addr;
+ struct evpn_prefix_addr _prefix_addr;
+ } u;
+#define ead_addr u._ead_addr
+#define macip_addr u._macip_addr
+#define imet_addr u._imet_addr
+#define es_addr u._es_addr
+#define prefix_addr u._prefix_addr
+};
/*
* A struct prefix contains an address family, a prefix length, and an
@@ -177,6 +207,39 @@ struct prefix_evpn {
struct evpn_addr prefix __attribute__((aligned(8)));
};
+static inline int is_evpn_prefix_ipaddr_none(const struct prefix_evpn *evp)
+{
+ if (evp->prefix.route_type == 2)
+ return IS_IPADDR_NONE(&(evp)->prefix.macip_addr.ip);
+ if (evp->prefix.route_type == 3)
+ return IS_IPADDR_NONE(&(evp)->prefix.imet_addr.ip);
+ if (evp->prefix.route_type == 5)
+ return IS_IPADDR_NONE(&(evp)->prefix.prefix_addr.ip);
+ return 0;
+}
+
+static inline int is_evpn_prefix_ipaddr_v4(const struct prefix_evpn *evp)
+{
+ if (evp->prefix.route_type == 2)
+ return IS_IPADDR_V4(&(evp)->prefix.macip_addr.ip);
+ if (evp->prefix.route_type == 3)
+ return IS_IPADDR_V4(&(evp)->prefix.imet_addr.ip);
+ if (evp->prefix.route_type == 5)
+ return IS_IPADDR_V4(&(evp)->prefix.prefix_addr.ip);
+ return 0;
+}
+
+static inline int is_evpn_prefix_ipaddr_v6(const struct prefix_evpn *evp)
+{
+ if (evp->prefix.route_type == 2)
+ return IS_IPADDR_V6(&(evp)->prefix.macip_addr.ip);
+ if (evp->prefix.route_type == 3)
+ return IS_IPADDR_V6(&(evp)->prefix.imet_addr.ip);
+ if (evp->prefix.route_type == 5)
+ return IS_IPADDR_V6(&(evp)->prefix.prefix_addr.ip);
+ return 0;
+}
+
/* Prefix for a generic pointer */
struct prefix_ptr {
uint8_t family;
diff --git a/lib/routemap.c b/lib/routemap.c
index ea61043a8d..892b19dac5 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -722,7 +722,7 @@ static void route_map_delete(struct route_map *map)
/* Clear all dependencies */
route_map_clear_all_references(name);
- map->deleted = 1;
+ map->deleted = true;
/* Execute deletion hook. */
if (route_map_master.delete_hook) {
(*route_map_master.delete_hook)(name);
@@ -762,19 +762,19 @@ int route_map_mark_updated(const char *name, int del_later)
map = route_map_lookup_by_name(name);
- /* If we did not find the routemap with deleted=0 try again
- * with deleted=1
+ /* If we did not find the routemap with deleted=false try again
+ * with deleted=true
*/
if (!map) {
memset(&tmp_map, 0, sizeof(struct route_map));
tmp_map.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
- tmp_map.deleted = 1;
+ tmp_map.deleted = true;
map = hash_lookup(route_map_master_hash, &tmp_map);
XFREE(MTYPE_ROUTE_MAP_NAME, tmp_map.name);
}
if (map) {
- map->to_be_processed = 1;
+ map->to_be_processed = true;
ret = 0;
}
@@ -786,7 +786,7 @@ int route_map_clear_updated(struct route_map *map)
int ret = -1;
if (map) {
- map->to_be_processed = 0;
+ map->to_be_processed = false;
if (map->deleted)
route_map_free_map(map);
}
@@ -2743,7 +2743,7 @@ void route_map_finish(void)
/* cleanup route_map */
while (route_map_master.head) {
struct route_map *map = route_map_master.head;
- map->to_be_processed = 0;
+ map->to_be_processed = false;
route_map_delete(map);
}
diff --git a/lib/routemap.h b/lib/routemap.h
index 0046b77c46..990c7fa72f 100644
--- a/lib/routemap.h
+++ b/lib/routemap.h
@@ -158,8 +158,8 @@ struct route_map {
struct route_map *prev;
/* Maintain update info */
- int to_be_processed; /* True if modification isn't acted on yet */
- int deleted; /* If 1, then this node will be deleted */
+ bool to_be_processed; /* True if modification isn't acted on yet */
+ bool deleted; /* If 1, then this node will be deleted */
QOBJ_FIELDS
};
diff --git a/lib/zclient.c b/lib/zclient.c
index dc27cbef70..05bd907589 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -975,8 +975,6 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
stream_putl(s, api->flags);
stream_putc(s, api->message);
stream_putc(s, api->safi);
- if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
- stream_put(s, &(api->rmac), sizeof(struct ethaddr));
/* Put prefix information. */
stream_putc(s, api->prefix.family);
@@ -1061,6 +1059,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
api_nh->label_num
* sizeof(mpls_label_t));
}
+
+ /* Router MAC for EVPN routes. */
+ if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
+ stream_put(s, &(api_nh->rmac),
+ sizeof(struct ethaddr));
}
}
@@ -1101,8 +1104,6 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
STREAM_GETL(s, api->flags);
STREAM_GETC(s, api->message);
STREAM_GETC(s, api->safi);
- if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
- STREAM_GET(&(api->rmac), s, sizeof(struct ethaddr));
/* Prefix. */
STREAM_GETC(s, api->prefix.family);
@@ -1212,6 +1213,11 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
api_nh->label_num
* sizeof(mpls_label_t));
}
+
+ /* Router MAC for EVPN routes. */
+ if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
+ stream_get(&(api_nh->rmac), s,
+ sizeof(struct ethaddr));
}
}
@@ -1374,6 +1380,26 @@ stream_failure:
return false;
}
+bool zapi_iptable_notify_decode(struct stream *s,
+ uint32_t *unique,
+ enum zapi_iptable_notify_owner *note)
+{
+ uint32_t uni;
+
+ STREAM_GET(note, s, sizeof(*note));
+
+ STREAM_GETL(s, uni);
+
+ if (zclient_debug)
+ zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
+ *unique = uni;
+
+ return true;
+
+stream_failure:
+ return false;
+}
+
struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
{
struct nexthop *n = nexthop_new();
@@ -2765,6 +2791,22 @@ static int zclient_read(struct thread *thread)
(*zclient->label_chunk)(command, zclient, length,
vrf_id);
break;
+ case ZEBRA_IPSET_NOTIFY_OWNER:
+ if (zclient->ipset_notify_owner)
+ (*zclient->ipset_notify_owner)(command, zclient, length,
+ vrf_id);
+ break;
+ case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
+ if (zclient->ipset_entry_notify_owner)
+ (*zclient->ipset_entry_notify_owner)(command,
+ zclient, length,
+ vrf_id);
+ break;
+ case ZEBRA_IPTABLE_NOTIFY_OWNER:
+ if (zclient->iptable_notify_owner)
+ (*zclient->iptable_notify_owner)(command,
+ zclient, length,
+ vrf_id);
default:
break;
}
diff --git a/lib/zclient.h b/lib/zclient.h
index 71f5b38384..c5eaf9c0fd 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -258,6 +258,10 @@ struct zclient {
struct zclient *zclient,
uint16_t length,
vrf_id_t vrf_id);
+ int (*iptable_notify_owner)(int command,
+ struct zclient *zclient,
+ uint16_t length,
+ vrf_id_t vrf_id);
};
/* Zebra API message flag. */
@@ -298,6 +302,8 @@ struct zapi_nexthop {
/* MPLS labels for BGP-LU or Segment Routing */
uint8_t label_num;
mpls_label_t labels[MPLS_MAX_LABELS];
+
+ struct ethaddr rmac;
};
/*
@@ -338,8 +344,6 @@ struct zapi_route {
vrf_id_t vrf_id;
uint32_t tableid;
-
- struct ethaddr rmac;
};
/* Zebra IPv4 route message API. */
@@ -680,6 +684,9 @@ bool zapi_ipset_entry_notify_decode(struct stream *s,
uint32_t *unique,
char *ipset_name,
enum zapi_ipset_entry_notify_owner *note);
+bool zapi_iptable_notify_decode(struct stream *s,
+ uint32_t *unique,
+ enum zapi_iptable_notify_owner *note);
extern struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh);
extern bool zapi_nexthop_update_decode(struct stream *s,