From 78e31f4663d413a7ab18bb9c4b77e55fc8007396 Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Tue, 13 Dec 2016 02:46:52 -0800 Subject: [PATCH 01/17] tools: Fix unnecessary routing perturbations due to old style config Ticket: CM-14060 Reviewed By: Testing Done: There are two harmful problems (cause routing changes in the network) with the 2.5.x style config: one with the old style specification of "multipath as-relax", and the other with ip import-table, used by redistribute neighbor In 2.5, we had the user specify 'no-as-set' as the suffix to 'bgp bestpath as-path multipath relax' to avoid quagga's default behavior which'd cause weird routing problems. However, in 3.x, we made 'no-as-set' as the default, and so its neither required to specify it nor is it shown in the running config. This means when we do quagga reload, we remove the multipath as-relax line and add it back with the no-as-set line. This causes all BGP sessions to be reset. The problem with the "ip import-table" is that it causes us to unimport the routes and then add it back again, causing routing prefix changes throughout the network, potentially causing blackholing of traffic. This fix addresses both these issues and avoids the unnecessary routing blips. Signed-off-by: Dinesh Dutt --- tools/frr-reload.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 463784de11..e14d78d54c 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -579,6 +579,41 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): lines_to_add_to_del.append((ctx_keys, swpx_interface)) lines_to_add_to_del.append((tmp_ctx_keys, swpx_remoteas)) + ''' + In 3.0, we made bgp bestpath multipath as-relax command + automatically assume no-as-set since the lack of this option caused + weird routing problems and this problem was peculiar to this + implementation. When the running config is shown in relases after + 3.0, the no-as-set is not shown as its the default. This causes + reload to unnecessarily unapply this option to only apply it back + again, causing unnecessary session resets. Handle this. + ''' + if ctx_keys[0].startswith('router bgp') and line and 'multipath-relax' in line: + re_asrelax_new = re.search('^bgp\s+bestpath\s+as-path\s+multipath-relax$', line) + old_asrelax_cmd = 'bgp bestpath as-path multipath-relax no-as-set' + found_asrelax_old = line_exist(lines_to_add, ctx_keys, old_asrelax_cmd) + + if re_asrelax_new and found_asrelax_old: + deleted = True + lines_to_del_to_del.append((ctx_keys, line)) + lines_to_add_to_del.append((ctx_keys, old_asrelax_cmd)) + + ''' + More old-to-new config handling. ip import-table no longer accepts + distance, but we honor the old syntax. But 'show running' shows only + the new syntax. This causes an unnecessary 'no import-table' followed + by the same old 'ip import-table' which causes perturbations in + announced routes leading to traffic blackholes. Fix this issue. + ''' + re_importtbl = re.search('^ip\s+import-table\s+(\d+)$', ctx_keys[0]) + if re_importtbl: + table_num = re_importtbl.group(1) + for ctx in lines_to_add: + if ctx[0][0].startswith('ip import-table %s distance' % table_num): + deleted = True + lines_to_del_to_del.append((('ip import-table %s' % table_num,), None)) + lines_to_add_to_del.append((ctx[0], None)) + if not deleted: found_add_line = line_exist(lines_to_add, ctx_keys, line) From 3fa113f00cf15f8248db399b6da7210e8db3ceb4 Mon Sep 17 00:00:00 2001 From: radhika Date: Fri, 6 Jan 2017 12:54:25 -0800 Subject: [PATCH 02/17] bgpd, zebra: Fix for ignored non-default VRF single-hop BFD status messages in Quagga MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ticket: CM-13425 Reviewed By: Donald, Kanna Testing Done: Unit, Min tests, PTM Smoke and Nightly, BGP Smoke Issue: BFD status up/down not reflected in the Quagga for non-default VRF single-hop BFD sessions. Root Cause: PTM doesn’t keep track of VRF for Single hop BFD sessions since they are interface-based sessions. The status up/down messages to the quagga for single hop sessions do not have VRF information. In zebra daemon, the interface search based on the interface name extracted from the BFD status message is done across all VRFs. So, the search does not fail in zebra daemon. But, the interface search in bgpd/ospd is done per vrf and default VRF is used for search if no VRF is sent in the status message. So, the search fails and the BFD status changes are ignored. Fix: The VRF information is extracted from the interface if VRF is not sent in the BFD status messages in zebra daemon and passed to bgpd/ospfd. The interface search will not fail since the appropriate VRF is passed to bgpd/ospfd and BFD satus changes are not ignored. Signed-off-by: Radhika Mahankali --- bgpd/bgp_bfd.c | 8 ++++---- zebra/zebra_ptm.c | 14 +++++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index ad221d922d..4f76fd17fb 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -311,14 +311,14 @@ bgp_bfd_dest_update (int command, struct zclient *zclient, prefix2str(&dp, buf[0], sizeof(buf[0])); if (ifp) { - zlog_debug("Zebra: interface %s bfd destination %s %s", - ifp->name, buf[0], bfd_get_status_str(status)); + zlog_debug("Zebra: vrf %d interface %s bfd destination %s %s", + vrf_id, ifp->name, buf[0], bfd_get_status_str(status)); } else { prefix2str(&sp, buf[1], sizeof(buf[1])); - zlog_debug("Zebra: source %s bfd destination %s %s", - buf[1], buf[0], bfd_get_status_str(status)); + zlog_debug("Zebra: vrf %d source %s bfd destination %s %s", + vrf_id, buf[1], buf[0], bfd_get_status_str(status)); } } diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index c5223199a4..a633ce6332 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -459,6 +459,7 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp) char vrf_str[64]; struct prefix dest_prefix; struct prefix src_prefix; + vrf_id_t vrf_id; ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDSTATUS_STR, bfdst_str); @@ -491,7 +492,8 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp) } if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("%s: Recv Port [%s] bfd status [%s] vrf [%s] peer [%s] local [%s]", + zlog_debug("%s: Recv Port [%s] bfd status [%s] vrf [%s]" + " peer [%s] local [%s]", __func__, ifp ? ifp->name : "N/A", bfdst_str, vrf_str, dest_str, src_str); @@ -510,12 +512,18 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp) } } + if (!strcmp(ZEBRA_PTM_INVALID_VRF, vrf_str) && ifp) { + vrf_id = ifp->vrf_id; + } else { + vrf_id = vrf_name_to_id(vrf_str); + } + if (!strcmp (bfdst_str, ZEBRA_PTM_BFDSTATUS_DOWN_STR)) { if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_DOWN, - vrf_name_to_id(vrf_str)); + vrf_id); } else { if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_UP, - vrf_name_to_id(vrf_str)); + vrf_id); } return 0; From 4b78098d79d97abef352345221c3979efab1c373 Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Thu, 5 Jan 2017 18:49:13 -0800 Subject: [PATCH 03/17] tools: Don't overwrite Quagga.conf on reload, unless user specified. Ticket: CM-14059 Reviewed By: CCR-5524 Testing Done: the usual At some point in the 3.x release cycle, it was decided to overwrite the user's Quagga.conf configuration file with the output of running config when the user did a quagga reload. This is problematic for several reasons such as: losing user-specified comments, upsetting network automation scripts which think some thing has changed all the time from the specified config etc. This patch fixes this issue by not overwriting the Quagga.conf file unless the user specifies it via an additional option, or the file being used as input to quagga reload isn't the default configuration file (incl. path). Signed-off-by: Dinesh Dutt --- tools/frr-reload.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index e14d78d54c..729f817d63 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -732,6 +732,7 @@ if __name__ == '__main__': parser.add_argument('--debug', action='store_true', help='Enable debugs', default=False) parser.add_argument('--stdout', action='store_true', help='Log to STDOUT', default=False) parser.add_argument('filename', help='Location of new frr config file') + parser.add_argument('--overwrite', action='store_true', help='Overwrite Quagga.conf with running config output', default=False) args = parser.parse_args() # Logging @@ -939,5 +940,6 @@ if __name__ == '__main__': subprocess.call(['/usr/bin/vtysh', '-f', filename]) os.unlink(filename) - # Make these changes persistent + # Make these changes persistent + if args.overwrite or args.filename != '/etc/quagga/Quagga.conf': subprocess.call(['/usr/bin/vtysh', '-c', 'write']) From 0bf7cc2888a984883522f07ddeb897fb1fdb9621 Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Fri, 6 Jan 2017 06:50:47 -0800 Subject: [PATCH 04/17] tools: Handle lack of "seq" in prefix-list statements. Ticket: CM-14259 Reviewed By: CCR-5527 Testing Done: If users specify "ip prefix-list FOO permit 1.2.3.4/24", running config displays that line as "ip prefix-list FOO seq 5 permit 1.2.3.4/24", which causes reload to delete the running config line and add back the one in the config. This patch fixes that. Signed-off-by: Dinesh Dutt --- tools/frr-reload.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 729f817d63..e15eab4a8f 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -610,10 +610,29 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): table_num = re_importtbl.group(1) for ctx in lines_to_add: if ctx[0][0].startswith('ip import-table %s distance' % table_num): - deleted = True lines_to_del_to_del.append((('ip import-table %s' % table_num,), None)) lines_to_add_to_del.append((ctx[0], None)) - + + ''' + ip/ipv6 prefix-list can be specified without a seq number. However, + the running config always adds 'seq x', where x is a number incremented + by 5 for every element, to the prefix list. So, ignore such lines as + well. Sample prefix-list lines: + ip prefix-list PR-TABLE-2 seq 5 permit 20.8.2.0/24 le 32 + ip prefix-list PR-TABLE-2 seq 10 permit 20.8.2.0/24 le 32 + ipv6 prefix-list vrfdev6-12 permit 2000:9:2::/64 gt 64 + ''' + re_ip_pfxlst = re.search('^(ip|ipv6)(\s+prefix-list\s+)(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$', + ctx_keys[0]) + if re_ip_pfxlst: + tmpline = (re_ip_pfxlst.group(1) + re_ip_pfxlst.group(2) + + re_ip_pfxlst.group(3) + re_ip_pfxlst.group(5) + + re_ip_pfxlst.group(6)) + for ctx in lines_to_add: + if ctx[0][0] == tmpline: + lines_to_del_to_del.append((ctx_keys, None)) + lines_to_add_to_del.append(((tmpline,), None)) + if not deleted: found_add_line = line_exist(lines_to_add, ctx_keys, line) From 768bf950cf94b48576d4ddd974971c126ab68f31 Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Fri, 6 Jan 2017 14:52:25 -0800 Subject: [PATCH 05/17] tools: Handle deletes of entire interface context as deleting each line Ticket: CM-14260 Reviewed By: CCR-14260 Testing Done: quagga reload tests (quagga_service, bgp_enhe etc.) Quagga reload handles deletes of entire context by issuing a "no.." on the entire context itself instead of deleting each individual line of the context. However, this doesn't work when the context is "interface" since its not allowed to do "no interface " inside quagga. So special case this by deleting each individual line of the context. Signed-off-by: Dinesh Dutt --- tools/frr-reload.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index e15eab4a8f..57e9f026e3 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -700,6 +700,11 @@ def compare_context_objects(newconf, running): delete_bgpd = True lines_to_del.append((running_ctx_keys, None)) + # We cannot do 'no interface' in quagga, and so deal with it + elif running_ctx_keys[0].startswith('interface'): + for line in running_ctx.lines: + lines_to_del.append((running_ctx_keys, line)) + # If this is an address-family under 'router bgp' and we are already deleting the # entire 'router bgp' context then ignore this sub-context elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd: From a27647f946b1eb3b83c824942e36762038bf79f5 Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Sat, 7 Jan 2017 16:44:55 -0800 Subject: [PATCH 06/17] FRR: Add various TAGS format files to be ignored by git. Add some missing files to .gitignore Signed-off-by: Dinesh Dutt --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 30006f7e28..d592e8b3f3 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,10 @@ cscope.* *.pb.h *.pb-c.h *.pb-c.c +TAGS +tags +GTAGS +GSYMS +GRTAGS +GPATH + From 3b69fd51184da846df41c40e8ebbbdc356f3aa8a Mon Sep 17 00:00:00 2001 From: Don Slice Date: Thu, 5 Jan 2017 10:49:23 -0800 Subject: [PATCH 07/17] bgpd: do not allow prefix length on update-source A common misconfiguration that was silently accepted but wouldn't work was including the prefix length on the update-source; i.e. 10.1.1.1/32. This commit rejects this config and notifies the user. Ticket: CM-13485 Signed-off-by: Don Slice Date: Sun, 8 Jan 2017 07:08:12 -0800 Subject: [PATCH 08/17] tools: Normalize prefix-lists and IP networks for avoiding unnecessary reload Ticket: CM-14280, CM-14281, CM-14286 Reviewed By: CCR-5546 Testing Done: quagga_service_test, bgp_enhe, bgp_vrf etc. If the user specifies a network statement such as "network 1.1.1.1/24", the running config shows this as "network 1.1.1.0/24" which causes unnecessary withdrawl of the prefix and re-advertisement causing perturbations. The same thing applies to prefix-lists and of course, IPv6 addresses. IPv6 addresses were being normalized already, and so we use that same function to handle the IPv6 portion of the issue. Interestingly community strings were also getting ensnared in the normalized IPv6 function due to the presence of ':', but thats OK. quagga's running config changes 'null0' and 'blackhole' keywords into 'Null0'. For example: ip route 10.1.1.0/24 blackhole' is displayed as 'ip route 10.1.1.0/24 Null0'. Reload mistakes this and issues a delete of the Null0 route followed by an add of the "blackhole" route. Unnecessary, and results in unexpected routing perturabations. Also fix prefix-list's le/ge behavior: It always prints ge first even if the user has specified le followed by ge, and it doesn't print l3 32/128 if ge is also specified, else it prints them. Signed-off-by: Dinesh Dutt --- tools/frr-reload.py | 113 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 6 deletions(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 57e9f026e3..d26758ab17 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -38,7 +38,7 @@ import string import subprocess import sys from collections import OrderedDict -from ipaddr import IPv6Address +from ipaddr import IPv6Address, IPNetwork from pprint import pformat @@ -173,6 +173,98 @@ class Config(object): if not key: return + ''' + IP addresses specified in "network" statements, "ip prefix-lists" + etc. can differ in the host part of the specification the user + provides and what the running config displays. For example, user + can specify 11.1.1.1/24, and the running config displays this as + 11.1.1.0/24. Ensure we don't do a needless operation for such + lines. IS-IS & OSPFv3 have no "network" support. + ''' + re_key_rt = re.match(r'ip\s+route\s+([A-Fa-f:.0-9/]+)(.*)$', key[0]) + if re_key_rt: + addr = re_key_rt.group(2) + if '/' in addr: + try: + newaddr = IPNetwork(addr) + key[0] = 'ip %s %s/%s%s' % (re_key_rt.group(1), + newaddr.network, + newaddr.prefixlen, + re_key_rt.group(3)) + except ValueError: + pass + + re_key_rt = re.match( + r'(ip|ipv6)\s+prefix-list(.*)(permit|deny)\s+([A-Fa-f:.0-9/]+)(.*)$', + key[0] + ) + if re_key_rt: + addr = re_key_rt.group(4) + if '/' in addr: + try: + newaddr = '%s/%s' % (IPNetwork(addr).network, + IPNetwork(addr).prefixlen) + except ValueError: + newaddr = addr + + legestr = re_key_rt.group(5) + re_lege = re.search(r'(.*)le\s+(\d+)\s+ge\s+(\d+)(.*)', legestr) + if re_lege: + legestr = '%sge %s le %s%s' % (re_lege.group(1), + re_lege.group(3), + re_lege.group(2), + re_lege.group(4)) + re_lege = re.search(r'(.*)ge\s+(\d+)\s+le\s+(\d+)(.*)', legestr) + + if (re_lege and ((re_key_rt.group(1) == "ip" and + re_lege.group(3) == "32") or + (re_key_rt.group(1) == "ipv6" and + re_lege.group(3) == "128"))): + legestr = '%sge %s%s' % (re_lege.group(1), + re_lege.group(2), + re_lege.group(4)) + + key[0] = '%s prefix-list%s%s %s%s' % (re_key_rt.group(1), + re_key_rt.group(2), + re_key_rt.group(3), + newaddr, + legestr) + + if lines and key[0].startswith('router bgp'): + newlines = [] + for line in lines: + re_net = re.match(r'network\s+([A-Fa-f:.0-9/]+)(.*)$', line) + if re_net: + addr = re_net.group(1) + if '/' not in addr and key[0].startswith('router bgp'): + # This is most likely an error because with no + # prefixlen, BGP treats the prefixlen as 8 + addr = addr + '/8' + + try: + newaddr = IPNetwork(addr) + line = 'network %s/%s %s' % (newaddr.network, + newaddr.prefixlen, + re_net.group(2)) + newlines.append(line) + except: + # Really this should be an error. Whats a network + # without an IP Address following it ? + newlines.append(line) + else: + newlines.append(line) + lines = newlines + + ''' + More fixups in user specification and what running config shows. + "null0" in routes must be replaced by Null0, and "blackhole" must + be replaced by Null0 as well. + ''' + if (key[0].startswith('ip route') or key[0].startswith('ipv6 route') and + 'null0' in key[0] or 'blackhole' in key[0]): + key[0] = re.sub(r'\s+null0(\s*$)', ' Null0', key[0]) + key[0] = re.sub(r'\s+blackhole(\s*$)', ' Null0', key[0]) + if lines: if tuple(key) not in self.contexts: ctx = Context(tuple(key), lines) @@ -437,16 +529,25 @@ def get_normalized_ipv6_line(line): """ Return a normalized IPv6 line as produced by frr, with all letters in lower case and trailing and leading - zeros removed + zeros removed, and only the network portion present if + the IPv6 word is a network """ norm_line = "" words = line.split(' ') for word in words: if ":" in word: - try: - norm_word = str(IPv6Address(word)).lower() - except: - norm_word = word + norm_word = None + if "/" in word: + try: + v6word = IPNetwork(word) + norm_word = '%s/%s' % (v6word.network, v6word.prefixlen) + except ValueError: + pass + if not norm_word: + try: + norm_word = '%s' % IPv6Address(word) + except: + norm_word = word else: norm_word = word norm_line = norm_line + " " + norm_word From 0845b8727a90768a1a8e6ff389bfe83c2e87d2e9 Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Wed, 11 Jan 2017 11:33:15 -0800 Subject: [PATCH 09/17] tools: Fix unbound newaddr variable, fix too-broad except clauses Ticket: CM-14351 Reviewed By: dwalton Testing Done:attempts to run NCLU test failed, Daniel verified. Uninit variable bug, plus missed adding ValueError to the except clauses in a couple of places. Signed-off-by: Dinesh Dutt --- tools/frr-reload.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index d26758ab17..f6ddd35f66 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -206,6 +206,8 @@ class Config(object): IPNetwork(addr).prefixlen) except ValueError: newaddr = addr + else: + newaddr = addr legestr = re_key_rt.group(5) re_lege = re.search(r'(.*)le\s+(\d+)\s+ge\s+(\d+)(.*)', legestr) @@ -247,7 +249,7 @@ class Config(object): newaddr.prefixlen, re_net.group(2)) newlines.append(line) - except: + except ValueError: # Really this should be an error. Whats a network # without an IP Address following it ? newlines.append(line) @@ -546,7 +548,7 @@ def get_normalized_ipv6_line(line): if not norm_word: try: norm_word = '%s' % IPv6Address(word) - except: + except ValueError: norm_word = word else: norm_word = word From 1a11782c408a60afb464fe232fc2e3fa1e298436 Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Wed, 11 Jan 2017 14:33:39 -0800 Subject: [PATCH 10/17] *: Add source of route as protocol string in ip route pushed into kernel Ticket: CM-14313 Reviewed By: Testing Done: bgpmin, ospfmin, bgp_kitchen_sink_test 'ip route show' displays all routes as belonging to protocol zebra. The user has to run an additional command (in vtysh) to get the actual source of a route (bgp/ospf/static etc.). This patch addresses that by pushing the appropriate protocol string into the protocol field of the netlink route update message. Now you can see routes with the correct origin as well as filter on them (ip route show proto ospf). 'ospf' is used for both IPv4 and IPv6 routes, even though the OSPF version is different in both cases. Sample output (old): 9.9.12.13 via 69.254.2.38 dev swp3.2 proto zebra metric 20 9.9.13.3 proto zebra metric 20 nexthop via 69.254.2.30 dev swp1.2 weight 1 nexthop via 69.254.2.34 dev swp2.2 weight 1 nexthop via 69.254.2.38 dev swp3.2 weight 1 Sample output (new): 9.9.12.13 via 69.254.2.38 dev swp3.2 proto bgp metric 20 9.9.13.3 proto bgp metric 20 nexthop via 69.254.2.30 dev swp1.2 weight 1 nexthop via 69.254.2.34 dev swp2.2 weight 1 nexthop via 69.254.2.38 dev swp3.2 weight 1 Signed-off-by: Dinesh Dutt --- cumulus/etc/iproute2/rt_protos.d/frr.conf | 8 ++++ debian/frr.dirs | 1 + tools/frr | 9 ++++- zebra/kernel_netlink.c | 5 +++ zebra/rt_netlink.c | 49 +++++++++++++++++++++-- zebra/rt_netlink.h | 8 ++++ 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 cumulus/etc/iproute2/rt_protos.d/frr.conf diff --git a/cumulus/etc/iproute2/rt_protos.d/frr.conf b/cumulus/etc/iproute2/rt_protos.d/frr.conf new file mode 100644 index 0000000000..883782e4dd --- /dev/null +++ b/cumulus/etc/iproute2/rt_protos.d/frr.conf @@ -0,0 +1,8 @@ +# Additional protocol strings defined by quagga for each of its daemons + +186 bgp +187 isis +188 ospf +189 rip +190 ripng +191 static diff --git a/debian/frr.dirs b/debian/frr.dirs index 58290080d0..56699b2daa 100644 --- a/debian/frr.dirs +++ b/debian/frr.dirs @@ -1,5 +1,6 @@ etc/logrotate.d/ etc/frr/ +etc/iproute2/rt_protos.d/ usr/share/doc/frr/ usr/share/doc/frr/examples/ usr/share/lintian/overrides/ diff --git a/tools/frr b/tools/frr index 2ecaadbb53..a6d99feaf6 100755 --- a/tools/frr +++ b/tools/frr @@ -532,8 +532,15 @@ case "$1" in fi if [ -z "$dmn" -o "$dmn" = "zebra" ]; then - echo "Removing all routes made by zebra." + echo "Removing all routes made by quagga." + ip route flush proto bgp + ip route flush proto ospf + ip route flush proto static + ip route flush proto rip + ip route flush proto ripng ip route flush proto zebra + ip route flush proto isis + else [ -n "$dmn" ] && eval "${dmn/-/_}=0" start_watchfrr diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 9f9a62f384..20cb62e318 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -91,6 +91,11 @@ static const struct message rtproto_str[] = { #ifdef RTPROT_BIRD {RTPROT_BIRD, "BIRD"}, #endif /* RTPROT_BIRD */ + {RTPROT_BGP, "BGP"}, + {RTPROT_OSPF, "OSPF"}, + {RTPROT_ISIS, "IS-IS"}, + {RTPROT_RIP, "RIP"}, + {RTPROT_RIPNG, "RIPNG"}, {0, NULL} }; diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index c04f9188fa..01922e1ad5 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -92,6 +92,47 @@ struct gw_family_t union g_addr gate; }; +static inline int is_selfroute(int proto) +{ + if ((proto == RTPROT_BGP) || (proto == RTPROT_OSPF) || + (proto == RTPROT_STATIC) || (proto == RTPROT_ZEBRA) || + (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG)) { + return 1; + } + + return 0; +} + +static inline int get_rt_proto(int proto) +{ + switch (proto) { + case ZEBRA_ROUTE_BGP: + proto = RTPROT_BGP; + break; + case ZEBRA_ROUTE_OSPF: + case ZEBRA_ROUTE_OSPF6: + proto = RTPROT_OSPF; + break; + case ZEBRA_ROUTE_STATIC: + proto = RTPROT_STATIC; + break; + case ZEBRA_ROUTE_ISIS: + proto = RTPROT_ISIS; + break; + case ZEBRA_ROUTE_RIP: + proto = RTPROT_RIP; + break; + case ZEBRA_ROUTE_RIPNG: + proto = RTPROT_RIPNG; + break; + default: + proto = RTPROT_ZEBRA; + break; + } + + return proto; +} + /* Pending: create an efficient table_id (in a tree/hash) based lookup) */ @@ -181,7 +222,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, } /* Route which inserted by Zebra. */ - if (rtm->rtm_protocol == RTPROT_ZEBRA) + if (is_selfroute(rtm->rtm_protocol)) flags |= ZEBRA_FLAG_SELFROUTE; index = 0; @@ -367,9 +408,9 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, if (rtm->rtm_protocol == RTPROT_KERNEL) return 0; - if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE) + if (is_selfroute(rtm->rtm_protocol) && h->nlmsg_type == RTM_NEWROUTE) return 0; - if (rtm->rtm_protocol == RTPROT_ZEBRA) + if (is_selfroute(rtm->rtm_protocol)) SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE); if (rtm->rtm_src_len != 0) @@ -1151,7 +1192,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib, req.n.nlmsg_type = cmd; req.r.rtm_family = family; req.r.rtm_dst_len = p->prefixlen; - req.r.rtm_protocol = RTPROT_ZEBRA; + req.r.rtm_protocol = get_rt_proto(rib->type); req.r.rtm_scope = RT_SCOPE_UNIVERSE; if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index 7183525fba..d1f01bda4c 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -28,6 +28,14 @@ #define NL_DEFAULT_ROUTE_METRIC 20 +/* Additional protocol strings to push into routes */ +#define RTPROT_BGP 186 +#define RTPROT_ISIS 187 +#define RTPROT_OSPF 188 +#define RTPROT_RIP 189 +#define RTPROT_RIPNG 190 + + extern void clear_nhlfe_installed (zebra_lsp_t *lsp); extern int From cca1dda8bf5aca42aec577b2e156b5e56a2bc996 Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Mon, 16 Jan 2017 06:24:09 -0800 Subject: [PATCH 11/17] bgpd: Add decoded notification code strings to JSON output Ticket: CM-14136 Reviewed By: CCR-5585 Testing Done: bgpmin The JSON output of 'bgp neighbor show' lacked the decoded strings for the last notification error code/subcode. Decoding these strings outside quagga is painful, and then needs to match with any updates to the codes from RFCs/drafts. Further, all apps that look to understanding this need to then add their own decoders for these strings. Just add the decoded strings to the JSON output as well. JSON key name for this is 'lastNotificationReason'. Signed-off-by: Dinesh Dutt --- bgpd/bgp_vty.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 52ce1273c3..79e5a0c332 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -11917,11 +11917,19 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js tm = gmtime(&uptime); json_object_int_add(json_neigh, "lastResetTimerMsecs", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000)); json_object_string_add(json_neigh, "lastResetDueTo", peer_down_str[(int) p->last_reset]); - if (p->last_reset_cause_size) + if (p->last_reset == PEER_DOWN_NOTIFY_SEND || + p->last_reset == PEER_DOWN_NOTIFY_RECEIVED) { char errorcodesubcode_hexstr[5]; + char errorcodesubcode_str[256]; + + code_str = bgp_notify_code_str(p->notify.code); + subcode_str = bgp_notify_subcode_str(p->notify.code, p->notify.subcode); + sprintf(errorcodesubcode_hexstr, "%02X%02X", p->notify.code, p->notify.subcode); json_object_string_add(json_neigh, "lastErrorCodeSubcode", errorcodesubcode_hexstr); + snprintf(errorcodesubcode_str, 255, "%s%s", code_str, subcode_str); + json_object_string_add(json_neigh, "lastNotificationReason", errorcodesubcode_str); } } else From 5c940836ab4c5e6716cc178f976e2d1a9d386bbf Mon Sep 17 00:00:00 2001 From: radhika Date: Thu, 19 Jan 2017 14:23:21 -0800 Subject: [PATCH 12/17] bgpd: Update BFD status when de-registering with PTM Ticket: CM-14301 Reviewed By: Donald, Vivek Testing Done: Unit, Min tests, PTM and BFD Smoke, BGP Smoke Issue: BFD status is not changed from up to down for bgp peer even after the BFD session has been de-registered by bgpd. Root Cause: This issue happens when bgpd detects peer down before getting the BFD down from PTM. bgpd will send the de-reg bfd session message to ptm after detecting peer down. If ptm receives the de-reg message before it detects the peer down, then the down message will not be sent to Quagga. This causes the bfd status in bgpd to remain unchanged. Fix: Update the BFD status to down in bgpd before de-registering the session from PTM. Signed-off-by: Radhika Mahankali --- bgpd/bgp_bfd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 4f76fd17fb..3def3421a8 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -171,6 +171,9 @@ bgp_bfd_deregister_peer (struct peer *peer) if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG)) return; + bfd_info->status = BFD_STATUS_DOWN; + bfd_info->last_update = bgp_clock(); + bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER); } From 64a608dbae92eb9ec084b22004ced29efa48defd Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Fri, 20 Jan 2017 04:17:09 +0000 Subject: [PATCH 13/17] bgpd: timers config is accepted but not recorded in running config Signed-off-by: Daniel Walton Reviewed-by: Donald Sharp Ticket: CM-14463 --- bgpd/bgpd.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 244b1930b3..ef633c16e7 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -6680,26 +6680,27 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp, } /* advertisement-interval */ - if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV) - && peer->v_routeadv != BGP_DEFAULT_EBGP_ROUTEADV - && ! peer_group_active (peer)) + if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV) && + ((! peer_group_active (peer) && peer->v_routeadv != BGP_DEFAULT_EBGP_ROUTEADV) || + (peer_group_active (peer) && peer->v_routeadv != g_peer->v_routeadv))) { vty_out (vty, " neighbor %s advertisement-interval %d%s", addr, peer->v_routeadv, VTY_NEWLINE); } /* timers */ - if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER) - && (peer->keepalive != BGP_DEFAULT_KEEPALIVE || peer->holdtime != BGP_DEFAULT_HOLDTIME) - && ! peer_group_active (peer)) + if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER) && + ((! peer_group_active (peer) && (peer->keepalive != BGP_DEFAULT_KEEPALIVE || peer->holdtime != BGP_DEFAULT_HOLDTIME)) || + (peer_group_active (peer) && (peer->keepalive != g_peer->keepalive || peer->holdtime != g_peer->holdtime)))) { vty_out (vty, " neighbor %s timers %d %d%s", addr, peer->keepalive, peer->holdtime, VTY_NEWLINE); } if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT) && - peer->connect != BGP_DEFAULT_CONNECT_RETRY && - ! peer_group_active (peer)) + ((! peer_group_active (peer) && peer->connect != BGP_DEFAULT_CONNECT_RETRY) || + (peer_group_active (peer) && peer->connect != g_peer->connect))) + { vty_out (vty, " neighbor %s timers connect %d%s", addr, peer->connect, VTY_NEWLINE); From 659b52a8456ea70ee4d7a21c9cb46c58d01ea296 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Fri, 13 Jan 2017 11:23:03 -0800 Subject: [PATCH 14/17] zebra: send ipv4 singlepath delete messages to kernel without nexthop Problem reported was stale routes left in the kernel in certain cases when overlapping static routes were used and links were bounced. The problem was determined to be an issue where the nexthop was changed due to recursion as the link is going down, and the next-hop at the time of deletion doesn't match what was previously installed by the kernel. This caused the kernel to reject the deletion and the route stuck around. It was pointed out that the kernel doesn't actually require a next-hop value on the netlink deletion call. In this fix, we are eliminating the nexthop for RTM_DELROUTE messages to the kernel in the ipv4 singlepath case. This approach could also be valid for other cases but the fix as is resolved the reported failure case. More testing should be performed before similar changes are made for other cases. Testing included manual testing for the failure condition as well as complete bgp-smoke and ospf-smoke tests with no new failures. Ticket: CM-13328 Signed-off-by: Don Slice Reviewed-by: CCR-5562 --- zebra/rt_netlink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 01922e1ad5..5d1ef26487 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -777,8 +777,10 @@ _netlink_route_build_singlepath( if (nexthop->type == NEXTHOP_TYPE_IPV4 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { - _netlink_route_nl_add_gateway_info (rtmsg->rtm_family, AF_INET, nlmsg, - req_size, bytelen, nexthop); + /* Send deletes to the kernel without specifying the next-hop */ + if (cmd != RTM_DELROUTE) + _netlink_route_nl_add_gateway_info (rtmsg->rtm_family, AF_INET, nlmsg, + req_size, bytelen, nexthop); if (cmd == RTM_NEWROUTE) { From 4d760f42552b8d8abe5280f049477649a054dcdd Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Wed, 25 Jan 2017 11:55:02 -0800 Subject: [PATCH 15/17] tools: Silly typo in regex for catching ip route syntax Ticket: CM-14600 Reviewed By: CCR-5615 Testing Done: Verifying the issue with/without the fix I had intended the regexp to catch both ip and ipv6 routes, but somewhere along the way, I left out the grouping in the regexp to catch if it was ip or ipv6 at the start. This caused all the rest of the matches and replaces to be off causing the issue reported by the bug. Signed-off-by: Dinesh Dutt --- tools/frr-reload.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index f6ddd35f66..1cad55ac34 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -181,16 +181,16 @@ class Config(object): 11.1.1.0/24. Ensure we don't do a needless operation for such lines. IS-IS & OSPFv3 have no "network" support. ''' - re_key_rt = re.match(r'ip\s+route\s+([A-Fa-f:.0-9/]+)(.*)$', key[0]) + re_key_rt = re.match(r'(ip|ipv6)\s+route\s+([A-Fa-f:.0-9/]+)(.*)$', key[0]) if re_key_rt: addr = re_key_rt.group(2) if '/' in addr: try: newaddr = IPNetwork(addr) - key[0] = 'ip %s %s/%s%s' % (re_key_rt.group(1), - newaddr.network, - newaddr.prefixlen, - re_key_rt.group(3)) + key[0] = '%s route %s/%s%s' % (re_key_rt.group(1), + newaddr.network, + newaddr.prefixlen, + re_key_rt.group(3)) except ValueError: pass From 8017695fa957af91d555eb1e59bc5f775cf29a37 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Thu, 26 Jan 2017 12:49:00 -0800 Subject: [PATCH 16/17] zebra: pass correct parameters to remove static routes with tags Problem found in testing where certain "no ip route ... tag x" commands would fail. This was due to a change in tag processing where the tag value is validated and previously some of the parameters were passed incorrectly. This caused the validation to fail. This change ensures the correct parameters are passed for evaluation as tags. Manual testing completed and the previously failing test now passes. bgp and ospf smoke tests will also be performed before pushing. Ticket: CM-14605 Signed-off-by: Don Slice Reviewed-by: CCR-5627 --- zebra/zebra_vty.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 5088198624..40bf0eac78 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -791,7 +791,7 @@ ALIAS (no_ip_route, "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") -ALIAS (no_ip_route_tag, +DEFUN (no_ip_route_flags_tag, no_ip_route_flags_tag_cmd, "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>", NO_STR @@ -804,6 +804,10 @@ ALIAS (no_ip_route_tag, "Silently discard pkts when matched\n" "Tag of this route\n" "Tag value\n") +{ + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], argv[3], + NULL, NULL, NULL); +} DEFUN (no_ip_route_flags2, no_ip_route_flags2_cmd, @@ -831,7 +835,7 @@ DEFUN (no_ip_route_flags2_tag, "Tag of this route\n" "Tag value\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, NULL, argv[1], + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, NULL, argv[2], NULL, NULL, NULL); } @@ -882,7 +886,7 @@ ALIAS (no_ip_route_mask, "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") -ALIAS (no_ip_route_mask_tag, +DEFUN (no_ip_route_mask_flags_tag, no_ip_route_mask_flags_tag_cmd, "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>", NO_STR @@ -896,6 +900,10 @@ ALIAS (no_ip_route_mask_tag, "Silently discard pkts when matched\n" "Tag of this route\n" "Tag value\n") +{ + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[4], + NULL, NULL, NULL); +} DEFUN (no_ip_route_mask_flags2, no_ip_route_mask_flags2_cmd, @@ -925,7 +933,7 @@ DEFUN (no_ip_route_mask_flags2_tag, "Tag of this route\n" "Tag value\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, NULL, argv[2], + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, NULL, argv[3], NULL, NULL, NULL); } From 3cb50bf1ee8fe08a36f702c61c6b911fe0c0e6a8 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 31 Jan 2017 13:51:27 +0100 Subject: [PATCH 17/17] Revert "*: Add source of route as protocol string in ip route pushed into kernel" This reverts commit 1a11782c408a60afb464fe232fc2e3fa1e298436. The change is not suitable for stable/2.0, it's not a bugfix and has quite a visible user impact. Signed-off-by: David Lamparter Acked-by: Donald Sharp --- cumulus/etc/iproute2/rt_protos.d/frr.conf | 8 ---- debian/frr.dirs | 1 - tools/frr | 9 +---- zebra/kernel_netlink.c | 5 --- zebra/rt_netlink.c | 49 ++--------------------- zebra/rt_netlink.h | 8 ---- 6 files changed, 5 insertions(+), 75 deletions(-) delete mode 100644 cumulus/etc/iproute2/rt_protos.d/frr.conf diff --git a/cumulus/etc/iproute2/rt_protos.d/frr.conf b/cumulus/etc/iproute2/rt_protos.d/frr.conf deleted file mode 100644 index 883782e4dd..0000000000 --- a/cumulus/etc/iproute2/rt_protos.d/frr.conf +++ /dev/null @@ -1,8 +0,0 @@ -# Additional protocol strings defined by quagga for each of its daemons - -186 bgp -187 isis -188 ospf -189 rip -190 ripng -191 static diff --git a/debian/frr.dirs b/debian/frr.dirs index 56699b2daa..58290080d0 100644 --- a/debian/frr.dirs +++ b/debian/frr.dirs @@ -1,6 +1,5 @@ etc/logrotate.d/ etc/frr/ -etc/iproute2/rt_protos.d/ usr/share/doc/frr/ usr/share/doc/frr/examples/ usr/share/lintian/overrides/ diff --git a/tools/frr b/tools/frr index a6d99feaf6..2ecaadbb53 100755 --- a/tools/frr +++ b/tools/frr @@ -532,15 +532,8 @@ case "$1" in fi if [ -z "$dmn" -o "$dmn" = "zebra" ]; then - echo "Removing all routes made by quagga." - ip route flush proto bgp - ip route flush proto ospf - ip route flush proto static - ip route flush proto rip - ip route flush proto ripng + echo "Removing all routes made by zebra." ip route flush proto zebra - ip route flush proto isis - else [ -n "$dmn" ] && eval "${dmn/-/_}=0" start_watchfrr diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 20cb62e318..9f9a62f384 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -91,11 +91,6 @@ static const struct message rtproto_str[] = { #ifdef RTPROT_BIRD {RTPROT_BIRD, "BIRD"}, #endif /* RTPROT_BIRD */ - {RTPROT_BGP, "BGP"}, - {RTPROT_OSPF, "OSPF"}, - {RTPROT_ISIS, "IS-IS"}, - {RTPROT_RIP, "RIP"}, - {RTPROT_RIPNG, "RIPNG"}, {0, NULL} }; diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 5d1ef26487..4913aa878f 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -92,47 +92,6 @@ struct gw_family_t union g_addr gate; }; -static inline int is_selfroute(int proto) -{ - if ((proto == RTPROT_BGP) || (proto == RTPROT_OSPF) || - (proto == RTPROT_STATIC) || (proto == RTPROT_ZEBRA) || - (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG)) { - return 1; - } - - return 0; -} - -static inline int get_rt_proto(int proto) -{ - switch (proto) { - case ZEBRA_ROUTE_BGP: - proto = RTPROT_BGP; - break; - case ZEBRA_ROUTE_OSPF: - case ZEBRA_ROUTE_OSPF6: - proto = RTPROT_OSPF; - break; - case ZEBRA_ROUTE_STATIC: - proto = RTPROT_STATIC; - break; - case ZEBRA_ROUTE_ISIS: - proto = RTPROT_ISIS; - break; - case ZEBRA_ROUTE_RIP: - proto = RTPROT_RIP; - break; - case ZEBRA_ROUTE_RIPNG: - proto = RTPROT_RIPNG; - break; - default: - proto = RTPROT_ZEBRA; - break; - } - - return proto; -} - /* Pending: create an efficient table_id (in a tree/hash) based lookup) */ @@ -222,7 +181,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, } /* Route which inserted by Zebra. */ - if (is_selfroute(rtm->rtm_protocol)) + if (rtm->rtm_protocol == RTPROT_ZEBRA) flags |= ZEBRA_FLAG_SELFROUTE; index = 0; @@ -408,9 +367,9 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, if (rtm->rtm_protocol == RTPROT_KERNEL) return 0; - if (is_selfroute(rtm->rtm_protocol) && h->nlmsg_type == RTM_NEWROUTE) + if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE) return 0; - if (is_selfroute(rtm->rtm_protocol)) + if (rtm->rtm_protocol == RTPROT_ZEBRA) SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE); if (rtm->rtm_src_len != 0) @@ -1194,7 +1153,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib, req.n.nlmsg_type = cmd; req.r.rtm_family = family; req.r.rtm_dst_len = p->prefixlen; - req.r.rtm_protocol = get_rt_proto(rib->type); + req.r.rtm_protocol = RTPROT_ZEBRA; req.r.rtm_scope = RT_SCOPE_UNIVERSE; if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index d1f01bda4c..7183525fba 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -28,14 +28,6 @@ #define NL_DEFAULT_ROUTE_METRIC 20 -/* Additional protocol strings to push into routes */ -#define RTPROT_BGP 186 -#define RTPROT_ISIS 187 -#define RTPROT_OSPF 188 -#define RTPROT_RIP 189 -#define RTPROT_RIPNG 190 - - extern void clear_nhlfe_installed (zebra_lsp_t *lsp); extern int