summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--README12
-rw-r--r--bgpd/Makefile.am6
-rw-r--r--bgpd/bgp_aspath.c3
-rw-r--r--bgpd/bgp_attr.c186
-rw-r--r--bgpd/bgp_attr.h5
-rw-r--r--bgpd/bgp_bfd.c61
-rw-r--r--bgpd/bgp_clist.c320
-rw-r--r--bgpd/bgp_clist.h18
-rw-r--r--bgpd/bgp_community.c1
-rw-r--r--bgpd/bgp_damp.c14
-rw-r--r--bgpd/bgp_debug.c153
-rw-r--r--bgpd/bgp_dump.c32
-rw-r--r--bgpd/bgp_ecommunity.c3
-rw-r--r--bgpd/bgp_encap.c187
-rw-r--r--bgpd/bgp_encap.h4
-rw-r--r--bgpd/bgp_encap_tlv.c1
-rw-r--r--bgpd/bgp_filter.c56
-rw-r--r--bgpd/bgp_fsm.c9
-rw-r--r--bgpd/bgp_lcommunity.c569
-rw-r--r--bgpd/bgp_lcommunity.h74
-rw-r--r--bgpd/bgp_main.c1
-rw-r--r--bgpd/bgp_memory.c4
-rw-r--r--bgpd/bgp_memory.h3
-rw-r--r--bgpd/bgp_mpath.c20
-rw-r--r--bgpd/bgp_mplsvpn.c648
-rw-r--r--bgpd/bgp_mplsvpn.h19
-rw-r--r--bgpd/bgp_network.c51
-rw-r--r--bgpd/bgp_nexthop.c57
-rw-r--r--bgpd/bgp_nht.c5
-rw-r--r--bgpd/bgp_open.c290
-rw-r--r--bgpd/bgp_open.h3
-rw-r--r--bgpd/bgp_packet.c116
-rw-r--r--bgpd/bgp_route.c6492
-rw-r--r--bgpd/bgp_route.h25
-rw-r--r--bgpd/bgp_routemap.c2132
-rw-r--r--bgpd/bgp_table.c1
-rw-r--r--bgpd/bgp_table.h4
-rw-r--r--bgpd/bgp_updgrp_adv.c6
-rw-r--r--bgpd/bgp_updgrp_packet.c4
-rw-r--r--bgpd/bgp_vty.c9403
-rw-r--r--bgpd/bgp_vty.h20
-rw-r--r--bgpd/bgp_zebra.c33
-rw-r--r--bgpd/bgp_zebra.h2
-rw-r--r--bgpd/bgpd.c97
-rw-r--r--bgpd/bgpd.h30
-rw-r--r--bgpd/rfapi/bgp_rfapi_cfg.c1437
-rw-r--r--bgpd/rfapi/bgp_rfapi_cfg.h23
-rw-r--r--bgpd/rfapi/rfapi.c318
-rw-r--r--bgpd/rfapi/rfapi_ap.c4
-rw-r--r--bgpd/rfapi/rfapi_backend.h9
-rw-r--r--bgpd/rfapi/rfapi_import.c24
-rw-r--r--bgpd/rfapi/rfapi_import.h8
-rw-r--r--bgpd/rfapi/rfapi_private.h15
-rw-r--r--bgpd/rfapi/rfapi_rib.c6
-rw-r--r--bgpd/rfapi/rfapi_vty.c997
-rw-r--r--bgpd/rfapi/vnc_debug.c57
-rw-r--r--bgpd/rfapi/vnc_import_bgp.c1
-rw-r--r--bgpd/rfapi/vnc_zebra.c18
-rw-r--r--bgpd/rfp-example/librfp/rfp_example.c8
-rwxr-xr-xconfigure.ac109
-rw-r--r--cumulus/start-stop-daemon.c4
-rw-r--r--debian/changelog2
-rw-r--r--debian/control2
-rw-r--r--doc/main.texi10
-rw-r--r--isisd/Makefile.am3
-rw-r--r--isisd/isis_adjacency.c10
-rw-r--r--isisd/isis_adjacency.h2
-rw-r--r--isisd/isis_bpf.c5
-rw-r--r--isisd/isis_circuit.c19
-rw-r--r--isisd/isis_circuit.h2
-rw-r--r--isisd/isis_lsp.c26
-rw-r--r--isisd/isis_pdu.c22
-rw-r--r--isisd/isis_redist.c119
-rw-r--r--isisd/isis_route.c23
-rw-r--r--isisd/isis_route.h4
-rw-r--r--isisd/isis_routemap.c311
-rw-r--r--isisd/isis_spf.c46
-rw-r--r--isisd/isis_spf.h7
-rw-r--r--isisd/isis_te.c12
-rw-r--r--isisd/isis_tlv.c8
-rw-r--r--isisd/isis_tlv.h6
-rw-r--r--isisd/isis_vty.c841
-rw-r--r--isisd/isis_zebra.c17
-rw-r--r--isisd/isisd.c124
-rw-r--r--isisd/isisd.h6
-rw-r--r--ldpd/.gitignore2
-rw-r--r--ldpd/Makefile.am10
-rw-r--r--ldpd/adjacency.c116
-rw-r--r--ldpd/hello.c18
-rw-r--r--ldpd/interface.c45
-rw-r--r--ldpd/l2vpn.c118
-rw-r--r--ldpd/lde.c234
-rw-r--r--ldpd/lde.h26
-rw-r--r--ldpd/lde_lib.c185
-rw-r--r--ldpd/ldp_debug.c4
-rw-r--r--ldpd/ldp_vty.h5
-rw-r--r--ldpd/ldp_vty.xml93
-rw-r--r--ldpd/ldp_vty_cmds.c1726
-rw-r--r--ldpd/ldp_vty_conf.c314
-rw-r--r--ldpd/ldp_vty_exec.c627
-rw-r--r--ldpd/ldp_zebra.c80
-rw-r--r--ldpd/ldpd.c466
-rw-r--r--ldpd/ldpd.h103
-rw-r--r--ldpd/ldpe.c83
-rw-r--r--ldpd/ldpe.h15
-rw-r--r--ldpd/neighbor.c29
-rw-r--r--ldpd/packet.c63
-rw-r--r--ldpd/socket.c2
-rw-r--r--lib/.gitignore6
-rw-r--r--lib/Makefile.am37
-rw-r--r--lib/bfd.c8
-rw-r--r--lib/bfd.h5
-rw-r--r--lib/command.c3480
-rw-r--r--lib/command.h445
-rw-r--r--lib/command_lex.l85
-rw-r--r--lib/command_match.c1027
-rw-r--r--lib/command_match.h113
-rw-r--r--lib/command_parse.y540
-rw-r--r--lib/csv.c18
-rw-r--r--lib/distribute.c663
-rw-r--r--lib/filter.c474
-rw-r--r--lib/filter.h3
-rw-r--r--lib/grammar_sandbox.c493
-rw-r--r--lib/grammar_sandbox_main.c64
-rw-r--r--lib/graph.c148
-rw-r--r--lib/graph.h101
-rw-r--r--lib/if.c107
-rw-r--r--lib/if.h27
-rw-r--r--lib/if_rmap.c46
-rw-r--r--lib/imsg.c3
-rw-r--r--lib/json.c20
-rw-r--r--lib/json.h8
-rw-r--r--lib/keychain.c223
-rw-r--r--lib/log.c47
-rw-r--r--lib/log.h4
-rw-r--r--lib/memory.c6
-rw-r--r--lib/monotime.h77
-rw-r--r--lib/network.c9
-rw-r--r--lib/ns.c16
-rw-r--r--lib/plist.c574
-rw-r--r--lib/prefix.c43
-rw-r--r--lib/prefix.h25
-rw-r--r--lib/ptm_lib.c2
-rw-r--r--lib/qobj.c5
-rw-r--r--lib/qobj.h2
-rwxr-xr-xlib/route_types.pl2
-rw-r--r--lib/route_types.txt2
-rw-r--r--lib/routemap.c1406
-rw-r--r--lib/routemap.h170
-rw-r--r--lib/smux.c71
-rw-r--r--lib/sockopt.c8
-rw-r--r--lib/sockopt.h7
-rw-r--r--lib/sockunion.c43
-rw-r--r--lib/sockunion.h4
-rw-r--r--lib/srcdest_table.c312
-rw-r--r--lib/srcdest_table.h101
-rw-r--r--lib/table.c36
-rw-r--r--lib/table.h6
-rw-r--r--lib/thread.c291
-rw-r--r--lib/thread.h15
-rw-r--r--lib/vector.c32
-rw-r--r--lib/vector.h5
-rw-r--r--lib/vrf.c38
-rw-r--r--lib/vrf.h8
-rw-r--r--lib/vty.c1216
-rw-r--r--lib/vty.h35
-rw-r--r--lib/wheel.c164
-rw-r--r--lib/wheel.h118
-rw-r--r--lib/workqueue.c6
-rw-r--r--lib/workqueue.h4
-rw-r--r--lib/zclient.c23
-rw-r--r--lib/zclient.h62
-rw-r--r--lib/zebra.h146
-rw-r--r--m4/ax_compare_version.m4177
-rw-r--r--m4/ax_prog_perl_modules.m477
-rw-r--r--m4/pkg.m4214
-rw-r--r--ospf6d/ospf6_abr.c2
-rw-r--r--ospf6d/ospf6_area.c251
-rw-r--r--ospf6d/ospf6_asbr.c272
-rw-r--r--ospf6d/ospf6_bfd.c20
-rw-r--r--ospf6d/ospf6_flood.c6
-rw-r--r--ospf6d/ospf6_interface.c285
-rw-r--r--ospf6d/ospf6_interface.h4
-rw-r--r--ospf6d/ospf6_intra.c10
-rw-r--r--ospf6d/ospf6_lsa.c98
-rw-r--r--ospf6d/ospf6_message.c103
-rw-r--r--ospf6d/ospf6_neighbor.c102
-rw-r--r--ospf6d/ospf6_route.c73
-rw-r--r--ospf6d/ospf6_route.h8
-rw-r--r--ospf6d/ospf6_spf.c48
-rw-r--r--ospf6d/ospf6_top.c388
-rw-r--r--ospf6d/ospf6_top.h4
-rw-r--r--ospf6d/ospf6_zebra.c88
-rw-r--r--ospf6d/ospf6d.c1020
-rw-r--r--ospf6d/ospf6d.h24
-rw-r--r--ospfd/ospf_ase.c4
-rw-r--r--ospfd/ospf_bfd.c34
-rw-r--r--ospfd/ospf_dump.c942
-rw-r--r--ospfd/ospf_flood.c9
-rw-r--r--ospfd/ospf_interface.c6
-rw-r--r--ospfd/ospf_interface.h4
-rw-r--r--ospfd/ospf_lsa.c97
-rw-r--r--ospfd/ospf_lsa.h6
-rw-r--r--ospfd/ospf_nsm.c5
-rw-r--r--ospfd/ospf_opaque.c30
-rw-r--r--ospfd/ospf_packet.c39
-rw-r--r--ospfd/ospf_ri.c54
-rw-r--r--ospfd/ospf_routemap.c390
-rw-r--r--ospfd/ospf_spf.c48
-rw-r--r--ospfd/ospf_te.c40
-rw-r--r--ospfd/ospf_te.h2
-rw-r--r--ospfd/ospf_vty.c3716
-rw-r--r--ospfd/ospf_zebra.h2
-rw-r--r--ospfd/ospfd.c11
-rw-r--r--ospfd/ospfd.h4
-rw-r--r--pimd/Makefile.am14
-rw-r--r--pimd/README81
-rw-r--r--pimd/pim_assert.c252
-rw-r--r--pimd/pim_br.c24
-rw-r--r--pimd/pim_br.h6
-rw-r--r--pimd/pim_cmd.c5179
-rw-r--r--pimd/pim_cmd.h13
-rw-r--r--pimd/pim_hello.c43
-rw-r--r--pimd/pim_iface.c502
-rw-r--r--pimd/pim_iface.h24
-rw-r--r--pimd/pim_ifchannel.c926
-rw-r--r--pimd/pim_ifchannel.h45
-rw-r--r--pimd/pim_igmp.c775
-rw-r--r--pimd/pim_igmp.h22
-rw-r--r--pimd/pim_igmpv2.c190
-rw-r--r--pimd/pim_igmpv2.h41
-rw-r--r--pimd/pim_igmpv3.c563
-rw-r--r--pimd/pim_igmpv3.h44
-rw-r--r--pimd/pim_join.c264
-rw-r--r--pimd/pim_join.h3
-rw-r--r--pimd/pim_macro.c78
-rw-r--r--pimd/pim_main.c39
-rw-r--r--pimd/pim_memory.c8
-rw-r--r--pimd/pim_memory.h8
-rw-r--r--pimd/pim_mroute.c653
-rw-r--r--pimd/pim_mroute.h8
-rw-r--r--pimd/pim_msdp.c1606
-rw-r--r--pimd/pim_msdp.h233
-rw-r--r--pimd/pim_msdp_packet.c696
-rw-r--r--pimd/pim_msdp_packet.h72
-rw-r--r--pimd/pim_msdp_socket.c227
-rw-r--r--pimd/pim_msdp_socket.h25
-rw-r--r--pimd/pim_msg.c180
-rw-r--r--pimd/pim_msg.h11
-rw-r--r--pimd/pim_neighbor.c112
-rw-r--r--pimd/pim_neighbor.h10
-rw-r--r--pimd/pim_oil.c361
-rw-r--r--pimd/pim_oil.h27
-rw-r--r--pimd/pim_pim.c481
-rw-r--r--pimd/pim_pim.h23
-rw-r--r--pimd/pim_register.c300
-rw-r--r--pimd/pim_register.h7
-rw-r--r--pimd/pim_routemap.c1
-rw-r--r--pimd/pim_rp.c786
-rw-r--r--pimd/pim_rp.h22
-rw-r--r--pimd/pim_rpf.c310
-rw-r--r--pimd/pim_rpf.h48
-rw-r--r--pimd/pim_sock.c136
-rw-r--r--pimd/pim_sock.h4
-rw-r--r--pimd/pim_ssmpingd.c48
-rw-r--r--pimd/pim_static.c62
-rw-r--r--pimd/pim_str.c55
-rw-r--r--pimd/pim_str.h14
-rw-r--r--pimd/pim_time.c19
-rw-r--r--pimd/pim_time.h1
-rw-r--r--pimd/pim_tlv.c144
-rw-r--r--pimd/pim_tlv.h7
-rw-r--r--pimd/pim_upstream.c1322
-rw-r--r--pimd/pim_upstream.h117
-rw-r--r--pimd/pim_util.c41
-rw-r--r--pimd/pim_util.h2
-rw-r--r--pimd/pim_vty.c122
-rw-r--r--pimd/pim_zebra.c564
-rw-r--r--pimd/pim_zebra.h2
-rw-r--r--pimd/pim_zlookup.c267
-rw-r--r--pimd/pim_zlookup.h11
-rw-r--r--pimd/pimd.c62
-rw-r--r--pimd/pimd.h61
-rw-r--r--redhat/.gitignore2
-rw-r--r--ripd/rip_debug.c36
-rw-r--r--ripd/rip_interface.c341
-rw-r--r--ripd/rip_offset.c30
-rw-r--r--ripd/rip_routemap.c535
-rw-r--r--ripd/rip_zebra.c176
-rw-r--r--ripd/ripd.c125
-rw-r--r--ripd/ripd.h5
-rw-r--r--ripngd/ripng_debug.c37
-rw-r--r--ripngd/ripng_interface.c52
-rw-r--r--ripngd/ripng_offset.c30
-rw-r--r--ripngd/ripng_routemap.c341
-rw-r--r--ripngd/ripng_zebra.c121
-rw-r--r--ripngd/ripngd.c73
-rw-r--r--ripngd/ripngd.h1
-rw-r--r--tests/.gitignore50
-rw-r--r--tests/Makefile.am194
-rw-r--r--tests/bgpd.tests/Makefile.am7
-rw-r--r--tests/bgpd.tests/aspathtest.exp76
-rw-r--r--tests/bgpd.tests/ecommtest.exp13
-rw-r--r--tests/bgpd.tests/testbgpcap.exp51
-rw-r--r--tests/bgpd.tests/testbgpmpath.exp12
-rw-r--r--tests/bgpd.tests/testbgpmpattr.exp38
-rw-r--r--tests/bgpd/test_aspath.c (renamed from tests/aspath_test.c)1
-rw-r--r--tests/bgpd/test_aspath.py79
-rw-r--r--tests/bgpd/test_capability.c (renamed from tests/bgp_capability_test.c)30
-rw-r--r--tests/bgpd/test_capability.py47
-rw-r--r--tests/bgpd/test_ecommunity.c (renamed from tests/ecommunity_test.c)0
-rw-r--r--tests/bgpd/test_ecommunity.py9
-rw-r--r--tests/bgpd/test_mp_attr.c (renamed from tests/bgp_mp_attr_test.c)68
-rw-r--r--tests/bgpd/test_mp_attr.py33
-rw-r--r--tests/bgpd/test_mpath.c (renamed from tests/bgp_mpath_test.c)0
-rw-r--r--tests/bgpd/test_mpath.py9
-rw-r--r--tests/config/unix.exp102
-rw-r--r--tests/global-conf.exp0
-rw-r--r--tests/helpers/c/main.c (renamed from tests/main.c)0
-rw-r--r--tests/helpers/c/prng.c (renamed from tests/prng.c)0
-rw-r--r--tests/helpers/c/prng.h (renamed from tests/prng.h)0
-rw-r--r--tests/helpers/c/tests.h (renamed from tests/tests.h)0
-rw-r--r--tests/helpers/python/frrsix.py80
-rw-r--r--tests/helpers/python/frrtest.py177
-rw-r--r--tests/lib/bgpd.exp0
-rw-r--r--tests/lib/cli/common_cli.c (renamed from tests/common-cli.c)14
-rw-r--r--tests/lib/cli/common_cli.h (renamed from tests/common-cli.h)2
-rw-r--r--tests/lib/cli/test_cli.c (renamed from tests/test-cli.c)10
-rw-r--r--tests/lib/cli/test_cli.in (renamed from tests/testcli.in)5
-rw-r--r--tests/lib/cli/test_cli.py4
-rw-r--r--tests/lib/cli/test_cli.refout (renamed from tests/testcli.refout)228
-rw-r--r--tests/lib/cli/test_commands.c (renamed from tests/test-commands.c)8
-rw-r--r--tests/lib/cli/test_commands.in (renamed from tests/testcommands.in)0
-rw-r--r--tests/lib/cli/test_commands.py8
-rw-r--r--tests/lib/cli/test_commands.refout (renamed from tests/testcommands.refout)0
-rw-r--r--tests/lib/libfrr.exp0
-rw-r--r--tests/lib/test_buffer.c (renamed from tests/test-buffer.c)0
-rw-r--r--tests/lib/test_checksum.c (renamed from tests/test-checksum.c)0
-rw-r--r--tests/lib/test_heavy.c (renamed from tests/heavy.c)2
-rw-r--r--tests/lib/test_heavy_thread.c (renamed from tests/heavy-thread.c)2
-rw-r--r--tests/lib/test_heavy_wq.c (renamed from tests/heavy-wq.c)2
-rw-r--r--tests/lib/test_memory.c (renamed from tests/test-memory.c)0
-rw-r--r--tests/lib/test_nexthop_iter.c (renamed from tests/test-nexthop-iter.c)0
-rw-r--r--tests/lib/test_nexthop_iter.py7
-rw-r--r--tests/lib/test_privs.c (renamed from tests/test-privs.c)0
-rw-r--r--tests/lib/test_segv.c (renamed from tests/test-segv.c)0
-rw-r--r--tests/lib/test_sig.c (renamed from tests/test-sig.c)0
-rw-r--r--tests/lib/test_srcdest_table.c457
-rw-r--r--tests/lib/test_srcdest_table.py6
-rw-r--r--tests/lib/test_stream.c (renamed from tests/test-stream.c)0
-rw-r--r--tests/lib/test_stream.py4
-rw-r--r--tests/lib/test_stream.refout8
-rw-r--r--tests/lib/test_table.c (renamed from tests/table_test.c)0
-rw-r--r--tests/lib/test_table.py10
-rw-r--r--tests/lib/test_timer_correctness.c (renamed from tests/test-timer-correctness.c)0
-rw-r--r--tests/lib/test_timer_correctness.py6
-rw-r--r--tests/lib/test_timer_performance.c (renamed from tests/test-timer-performance.c)6
-rw-r--r--tests/libfrr.tests/Makefile.am6
-rw-r--r--tests/libfrr.tests/tabletest.exp9
-rw-r--r--tests/libfrr.tests/test-timer-correctness.exp7
-rw-r--r--tests/libfrr.tests/testcli.exp23
-rw-r--r--tests/libfrr.tests/testcommands.exp31
-rw-r--r--tests/libfrr.tests/testnexthopiter.exp8
-rw-r--r--tests/libfrr.tests/teststream.exp28
-rw-r--r--tests/runtests.py6
-rw-r--r--tools/.gitignore4
-rw-r--r--tools/Makefile.am12
-rwxr-xr-xtools/cmd_check.py102
-rw-r--r--tools/cocci.h34
-rw-r--r--tools/permutations.c112
-rw-r--r--tools/vty_check.cocci22
-rw-r--r--tools/vty_index.cocci244
-rwxr-xr-xtools/vty_index.sh21
-rwxr-xr-xtools/xml2cli.pl34
-rw-r--r--vtysh/Makefile.am25
-rwxr-xr-xvtysh/extract.pl.in47
-rw-r--r--vtysh/vtysh.c671
-rw-r--r--vtysh/vtysh_user.c6
-rw-r--r--watchfrr/watchfrr.c2168
-rw-r--r--watchfrr/watchfrr.h2
-rw-r--r--watchfrr/watchfrr_vty.c38
-rw-r--r--zebra/Makefile.am7
-rw-r--r--zebra/client_main.c2
-rw-r--r--zebra/connected.c17
-rw-r--r--zebra/connected.h3
-rw-r--r--zebra/debug.c86
-rw-r--r--zebra/if_ioctl.c8
-rw-r--r--zebra/if_ioctl_solaris.c11
-rw-r--r--zebra/if_netlink.c55
-rw-r--r--zebra/interface.c360
-rw-r--r--zebra/ioctl.c7
-rw-r--r--zebra/ioctl.h2
-rw-r--r--zebra/ioctl_solaris.c8
-rw-r--r--zebra/ipforward.h2
-rw-r--r--zebra/ipforward_proc.c7
-rw-r--r--zebra/ipforward_solaris.c2
-rw-r--r--zebra/ipforward_sysctl.c3
-rw-r--r--zebra/irdp_interface.c161
-rw-r--r--zebra/kernel_netlink.c62
-rw-r--r--zebra/kernel_netlink.h8
-rw-r--r--zebra/kernel_null.c6
-rw-r--r--zebra/kernel_socket.c36
-rw-r--r--zebra/kernel_socket.h8
-rw-r--r--zebra/redistribute.c31
-rw-r--r--zebra/redistribute.h5
-rw-r--r--zebra/redistribute_null.c6
-rw-r--r--zebra/rib.h18
-rw-r--r--zebra/router-id.c49
-rw-r--r--zebra/rt.h4
-rw-r--r--zebra/rt_netlink.c359
-rw-r--r--zebra/rt_socket.c17
-rw-r--r--zebra/rtadv.c595
-rw-r--r--zebra/rtread_getmsg.c2
-rw-r--r--zebra/rtread_netlink.c1
-rw-r--r--zebra/test_main.c9
-rw-r--r--zebra/zebra_fpm.c48
-rw-r--r--zebra/zebra_fpm_netlink.c31
-rw-r--r--zebra/zebra_mpls.c71
-rw-r--r--zebra/zebra_mpls.h3
-rw-r--r--zebra/zebra_mpls_vty.c188
-rw-r--r--zebra/zebra_mroute.c68
-rw-r--r--zebra/zebra_mroute.h35
-rw-r--r--zebra/zebra_ptm.c47
-rw-r--r--zebra/zebra_rib.c726
-rw-r--r--zebra/zebra_rnh.c10
-rw-r--r--zebra/zebra_rnh_null.c1
-rw-r--r--zebra/zebra_routemap.c686
-rw-r--r--zebra/zebra_static.c72
-rw-r--r--zebra/zebra_static.h24
-rw-r--r--zebra/zebra_vrf.c116
-rw-r--r--zebra/zebra_vty.c4039
-rw-r--r--zebra/zserv.c142
-rw-r--r--zebra/zserv.h6
-rw-r--r--zebra/zserv_null.c1
435 files changed, 41061 insertions, 45259 deletions
diff --git a/.gitignore b/.gitignore
index d592e8b3f3..6592b34004 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@ depcomp
missing
install-sh
mkinstalldirs
+ylwrap
autom4te*.cache
configure.lineno
configure
@@ -39,6 +40,9 @@ build
*.loT
m4/*.m4
!m4/ax_sys_weak_alias.m4
+!m4/ax_compare_version.m4
+!m4/ax_prog_perl_modules.m4
+!m4/pkg.m4
debian/autoreconf.after
debian/autoreconf.before
debian/files
diff --git a/README b/README
index 4476947490..a0aa895367 100644
--- a/README
+++ b/README
@@ -1,9 +1,13 @@
-Quagga is free software that manages various IPv4 and IPv6 routing
+Free Range Routing is free software that manages various IPv4 and IPv6 routing
protocols.
-Currently Quagga supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1,
-RIPv2, RIPng, PIM-SSM and LDP as well as very early support for IS-IS.
+Currently Free Range Routing supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1,
+RIPv2, RIPng, PIM-SM/MSDP and LDP as well as very early support for IS-IS.
See the file REPORTING-BUGS to report bugs.
-Quagga is free software. See the file COPYING for copying conditions.
+Free Range Routing is free software. See the file COPYING for copying conditions.
+
+Public email discussion can be found at https://lists.nox.tf/listinfo/frr
+
+Our public slack channel is at https://freerangerouting.slack.com
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index b91d23baf6..611dbb8558 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -75,7 +75,8 @@ libbgp_a_SOURCES = \
bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \
bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \
bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
- bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_mplsvpn.c bgp_nexthop.c \
+ bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_lcommunity.c \
+ bgp_mplsvpn.c bgp_nexthop.c \
bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \
bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \
bgp_encap.c bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC)
@@ -85,7 +86,8 @@ noinst_HEADERS = \
bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \
bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
- bgp_ecommunity.h bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
+ bgp_ecommunity.h bgp_lcommunity.h \
+ bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
bgp_advertise.h bgp_snmp.h bgp_vty.h bgp_mpath.h bgp_nht.h \
bgp_updgrp.h bgp_bfd.h bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h \
$(BGP_VNC_RFAPI_HD)
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 89a529d738..2e78c9a3bf 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -27,6 +27,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "vty.h"
#include "log.h"
#include "stream.h"
+#include "command.h"
#include "jhash.h"
#include "queue.h"
#include "filter.h"
@@ -2180,7 +2181,7 @@ aspath_show_all_iterator (struct hash_backet *backet, struct vty *vty)
}
/* Print all aspath and hash information. This function is used from
- `show ip bgp paths' command. */
+ `show [ip] bgp paths' command. */
void
aspath_print_all_vty (struct vty *vty)
{
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 7741f76a75..7dc42e719f 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -32,6 +32,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "queue.h"
#include "table.h"
#include "filter.h"
+#include "command.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
@@ -41,6 +42,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_updgrp.h"
#include "bgpd/bgp_encap_types.h"
#if ENABLE_BGP_VNC
@@ -75,6 +77,7 @@ static const struct message attr_str [] =
#if ENABLE_BGP_VNC
{ BGP_ATTR_VNC, "VNC" },
#endif
+ { BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY" }
};
static const int attr_str_max = array_size(attr_str);
@@ -669,6 +672,8 @@ attrhash_key_make (void *p)
if (extra)
{
+ if (extra->lcommunity)
+ MIX(lcommunity_hash_make (extra->lcommunity));
if (extra->ecommunity)
MIX(ecommunity_hash_make (extra->ecommunity));
if (extra->cluster)
@@ -681,11 +686,9 @@ attrhash_key_make (void *p)
if (extra->vnc_subtlvs)
MIX(encap_hash_key_make (extra->vnc_subtlvs));
#endif
-#ifdef HAVE_IPV6
MIX(extra->mp_nexthop_len);
key = jhash(extra->mp_nexthop_global.s6_addr, IPV6_MAX_BYTELEN, key);
key = jhash(extra->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key);
-#endif /* HAVE_IPV6 */
}
return key;
@@ -714,13 +717,12 @@ attrhash_cmp (const void *p1, const void *p2)
&& ae1->aggregator_addr.s_addr == ae2->aggregator_addr.s_addr
&& ae1->weight == ae2->weight
&& ae1->tag == ae2->tag
-#ifdef HAVE_IPV6
&& ae1->mp_nexthop_len == ae2->mp_nexthop_len
&& IPV6_ADDR_SAME (&ae1->mp_nexthop_global, &ae2->mp_nexthop_global)
&& IPV6_ADDR_SAME (&ae1->mp_nexthop_local, &ae2->mp_nexthop_local)
-#endif /* HAVE_IPV6 */
&& IPV4_ADDR_SAME (&ae1->mp_nexthop_global_in, &ae2->mp_nexthop_global_in)
&& ae1->ecommunity == ae2->ecommunity
+ && ae1->lcommunity == ae2->lcommunity
&& ae1->cluster == ae2->cluster
&& ae1->transit == ae2->transit
&& (ae1->encap_tunneltype == ae2->encap_tunneltype)
@@ -839,6 +841,13 @@ bgp_attr_intern (struct attr *attr)
attre->ecommunity->refcnt++;
}
+ if (attre->lcommunity)
+ {
+ if (! attre->lcommunity->refcnt)
+ attre->lcommunity = lcommunity_intern (attre->lcommunity);
+ else
+ attre->lcommunity->refcnt++;
+ }
if (attre->cluster)
{
if (! attre->cluster->refcnt)
@@ -934,9 +943,7 @@ bgp_attr_default_set (struct attr *attr, u_char origin)
attr->extra->weight = BGP_ATTR_DEFAULT_WEIGHT;
attr->extra->tag = 0;
attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
-#ifdef HAVE_IPV6
attr->extra->mp_nexthop_len = IPV6_MAX_BYTELEN;
-#endif
return attr;
}
@@ -997,9 +1004,7 @@ bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin,
}
attre.weight = BGP_ATTR_DEFAULT_WEIGHT;
-#ifdef HAVE_IPV6
attre.mp_nexthop_len = IPV6_MAX_BYTELEN;
-#endif
if (! as_set || atomic_aggregate)
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
@@ -1033,7 +1038,11 @@ bgp_attr_unintern_sub (struct attr *attr)
if (attr->extra->ecommunity)
ecommunity_unintern (&attr->extra->ecommunity);
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES));
-
+
+ if (attr->extra->lcommunity)
+ lcommunity_unintern (&attr->extra->lcommunity);
+ UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
+
if (attr->extra->cluster)
cluster_unintern (attr->extra->cluster);
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST));
@@ -1103,6 +1112,8 @@ bgp_attr_flush (struct attr *attr)
if (attre->ecommunity && ! attre->ecommunity->refcnt)
ecommunity_free (&attre->ecommunity);
+ if (attre->lcommunity && ! attre->lcommunity->refcnt)
+ lcommunity_free (&attre->lcommunity);
if (attre->cluster && ! attre->cluster->refcnt)
{
cluster_free (attre->cluster);
@@ -1261,6 +1272,7 @@ const u_int8_t attr_flags_values [] = {
[BGP_ATTR_EXT_COMMUNITIES] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
[BGP_ATTR_AS4_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
[BGP_ATTR_AS4_AGGREGATOR] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
+ [BGP_ATTR_LARGE_COMMUNITIES]= BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
};
static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
@@ -1856,8 +1868,9 @@ int
bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
struct bgp_nlri *mp_update)
{
- afi_t afi;
- safi_t safi;
+ iana_afi_t pkt_afi;
+ afi_t afi;
+ safi_t pkt_safi, safi;
bgp_size_t nlri_len;
size_t start;
struct stream *s;
@@ -1881,8 +1894,20 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
}
/* Load AFI, SAFI. */
- afi = stream_getw (s);
- safi = stream_getc (s);
+ pkt_afi = stream_getw (s);
+ pkt_safi = stream_getc (s);
+
+ /* Convert AFI, SAFI to internal values, check. */
+ if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
+ {
+ /* Log if AFI or SAFI is unrecognized. This is not an error unless
+ * the attribute is otherwise malformed.
+ */
+ if (bgp_debug_update(peer, NULL, NULL, 0))
+ zlog_debug ("%s: MP_REACH received AFI %u or SAFI %u is unrecognized",
+ peer->host, pkt_afi, pkt_safi);
+ return BGP_ATTR_PARSE_ERROR;
+ }
/* Get nexthop length. */
attre->mp_nexthop_len = stream_getc (s);
@@ -1908,7 +1933,6 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
stream_getl (s); /* RD low */
stream_get (&attre->mp_nexthop_global_in, s, IPV4_MAX_BYTELEN);
break;
-#ifdef HAVE_IPV6
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL)
@@ -1948,7 +1972,6 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
attre->mp_nexthop_len = IPV6_MAX_BYTELEN;
}
break;
-#endif /* HAVE_IPV6 */
default:
zlog_info ("%s: (%s) Wrong multiprotocol next hop length: %d",
__func__, peer->host, attre->mp_nexthop_len);
@@ -1997,8 +2020,9 @@ bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
struct bgp_nlri *mp_withdraw)
{
struct stream *s;
+ iana_afi_t pkt_afi;
afi_t afi;
- safi_t safi;
+ safi_t pkt_safi, safi;
u_int16_t withdraw_len;
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
@@ -2010,9 +2034,21 @@ bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE))
return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
- afi = stream_getw (s);
- safi = stream_getc (s);
-
+ pkt_afi = stream_getw (s);
+ pkt_safi = stream_getc (s);
+
+ /* Convert AFI, SAFI to internal values, check. */
+ if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
+ {
+ /* Log if AFI or SAFI is unrecognized. This is not an error unless
+ * the attribute is otherwise malformed.
+ */
+ if (bgp_debug_update(peer, NULL, NULL, 0))
+ zlog_debug ("%s: MP_UNREACH received AFI %u or SAFI %u is unrecognized",
+ peer->host, pkt_afi, pkt_safi);
+ return BGP_ATTR_PARSE_ERROR;
+ }
+
withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
mp_withdraw->afi = afi;
@@ -2027,6 +2063,40 @@ bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
return BGP_ATTR_PARSE_PROCEED;
}
+/* Large Community attribute. */
+static bgp_attr_parse_ret_t
+bgp_attr_large_community (struct bgp_attr_parser_args *args)
+{
+ struct peer *const peer = args->peer;
+ struct attr *const attr = args->attr;
+ const bgp_size_t length = args->length;
+
+ /*
+ * Large community follows new attribute format.
+ */
+ if (length == 0)
+ {
+ if (attr->extra)
+ attr->extra->lcommunity = NULL;
+ /* Empty extcomm doesn't seem to be invalid per se */
+ return BGP_ATTR_PARSE_PROCEED;
+ }
+
+ (bgp_attr_extra_get (attr))->lcommunity =
+ lcommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
+ /* XXX: fix ecommunity_parse to use stream API */
+ stream_forward_getp (peer->ibuf, length);
+
+ if (attr->extra && !attr->extra->lcommunity)
+ return bgp_attr_malformed (args,
+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
+
+ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
+
+ return BGP_ATTR_PARSE_PROCEED;
+}
+
/* Extended Community attribute. */
static bgp_attr_parse_ret_t
bgp_attr_ext_communities (struct bgp_attr_parser_args *args)
@@ -2048,7 +2118,7 @@ bgp_attr_ext_communities (struct bgp_attr_parser_args *args)
/* XXX: fix ecommunity_parse to use stream API */
stream_forward_getp (peer->ibuf, length);
- if (!attr->extra->ecommunity)
+ if (attr->extra && !attr->extra->ecommunity)
return bgp_attr_malformed (args,
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
@@ -2464,6 +2534,9 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
case BGP_ATTR_COMMUNITIES:
ret = bgp_attr_community (&attr_args);
break;
+ case BGP_ATTR_LARGE_COMMUNITIES:
+ ret = bgp_attr_large_community (&attr_args);
+ break;
case BGP_ATTR_ORIGINATOR_ID:
ret = bgp_attr_originator_id (&attr_args);
break;
@@ -2635,6 +2708,8 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
struct attr *attr)
{
size_t sizep;
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
/* Set extended bit always to encode the attribute length as 2 bytes */
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
@@ -2642,8 +2717,12 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
sizep = stream_get_endp (s);
stream_putw (s, 0); /* Marker: Attribute length. */
- stream_putw (s, afi);
- stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
+
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
+
+ stream_putw (s, pkt_afi); /* AFI */
+ stream_putc (s, pkt_safi); /* SAFI */
if (nh_afi == AFI_MAX)
nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
@@ -2674,7 +2753,6 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
break;
}
break;
-#ifdef HAVE_IPV6
case AFI_IP6:
switch (safi)
{
@@ -2721,7 +2799,6 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
break;
}
break;
-#endif /*HAVE_IPV6*/
default:
break;
}
@@ -3085,6 +3162,28 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
stream_put (s, attr->community->val, attr->community->size * 4);
}
+ /*
+ * Large Community attribute.
+ */
+ if (attr->extra &&
+ CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY)
+ && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES)))
+ {
+ if (attr->extra->lcommunity->size * 12 > 255)
+ {
+ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
+ stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
+ stream_putw (s, attr->extra->lcommunity->size * 12);
+ }
+ else
+ {
+ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
+ stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
+ stream_putc (s, attr->extra->lcommunity->size * 12);
+ }
+ stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12);
+ }
+
/* Route Reflector. */
if (peer->sort == BGP_PEER_IBGP
&& from
@@ -3263,6 +3362,8 @@ size_t
bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi)
{
unsigned long attrlen_pnt;
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
/* Set extended bit always to encode the attribute length as 2 bytes */
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
@@ -3271,8 +3372,12 @@ bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi)
attrlen_pnt = stream_get_endp (s);
stream_putw (s, 0); /* Length of this attribute. */
- stream_putw (s, afi);
- stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
+
+ stream_putw (s, pkt_afi);
+ stream_putc (s, pkt_safi);
+
return attrlen_pnt;
}
@@ -3311,6 +3416,7 @@ bgp_attr_init (void)
attrhash_init ();
community_init ();
ecommunity_init ();
+ lcommunity_init ();
cluster_init ();
transit_init ();
encap_init ();
@@ -3323,6 +3429,7 @@ bgp_attr_finish (void)
attrhash_finish ();
community_finish ();
ecommunity_finish ();
+ lcommunity_finish ();
cluster_finish ();
transit_finish ();
encap_finish ();
@@ -3363,11 +3470,7 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr,
/* Nexthop attribute. */
/* If it's an IPv6 prefix, don't dump the IPv4 nexthop to save space */
- if(prefix != NULL
-#ifdef HAVE_IPV6
- && prefix->family != AF_INET6
-#endif /* HAVE_IPV6 */
- )
+ if(prefix != NULL && prefix->family != AF_INET6)
{
stream_putc (s, BGP_ATTR_FLAG_TRANS);
stream_putc (s, BGP_ATTR_NEXT_HOP);
@@ -3430,7 +3533,25 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr,
stream_put (s, attr->community->val, attr->community->size * 4);
}
-#ifdef HAVE_IPV6
+ /* Large Community attribute. */
+ if (attr->extra && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES))
+ {
+ if (attr->extra->lcommunity->size * 12 > 255)
+ {
+ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
+ stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
+ stream_putw (s, attr->extra->lcommunity->size * 12);
+ }
+ else
+ {
+ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
+ stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
+ stream_putc (s, attr->extra->lcommunity->size * 12);
+ }
+
+ stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12);
+ }
+
/* Add a MP_NLRI attribute to dump the IPv6 next hop */
if (prefix != NULL && prefix->family == AF_INET6 && attr->extra &&
(attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL ||
@@ -3463,7 +3584,6 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr,
/* Set MP attribute length. */
stream_putc_at (s, sizep, (stream_get_endp (s) - sizep) - 1);
}
-#endif /* HAVE_IPV6 */
/* Return total size of attribute. */
len = stream_get_endp (s) - cp - 2;
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 6e639078d6..c5799ccd0d 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -92,7 +92,10 @@ struct attr_extra
/* Extended Communities attribute. */
struct ecommunity *ecommunity;
-
+
+ /* Large Communities attribute. */
+ struct lcommunity *lcommunity;
+
/* Route-Reflector Cluster attribute */
struct cluster_list *cluster;
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c
index 3def3421a8..b8158dc31e 100644
--- a/bgpd/bgp_bfd.c
+++ b/bgpd/bgp_bfd.c
@@ -342,7 +342,6 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
if (dp.u.prefix4.s_addr != peer->su.sin.sin_addr.s_addr)
continue;
}
-#ifdef HAVE_IPV6
else if ((dp.family == AF_INET6) &&
(peer->su.sa.sa_family == AF_INET6))
{
@@ -350,7 +349,6 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
sizeof (struct in6_addr)))
continue;
}
-#endif
else
continue;
@@ -369,7 +367,6 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
if (sp.u.prefix4.s_addr != peer->su_local->sin.sin_addr.s_addr)
continue;
}
-#ifdef HAVE_IPV6
else if ((sp.family == AF_INET6) &&
(peer->su_local->sa.sa_family == AF_INET6))
{
@@ -377,7 +374,6 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
sizeof (struct in6_addr)))
continue;
}
-#endif
else
continue;
@@ -558,15 +554,16 @@ bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_obje
DEFUN (neighbor_bfd,
neighbor_bfd_cmd,
- NEIGHBOR_CMD2 "bfd",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> bfd",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Enables BFD support\n")
{
+ int idx_peer = 1;
struct peer *peer;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -581,7 +578,7 @@ DEFUN (neighbor_bfd,
DEFUN (neighbor_bfd_param,
neighbor_bfd_param_cmd,
- NEIGHBOR_CMD2 "bfd " BFD_CMD_DETECT_MULT_RANGE BFD_CMD_MIN_RX_RANGE BFD_CMD_MIN_TX_RANGE,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> bfd (2-255) (50-60000) (50-60000)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Enables BFD support\n"
@@ -589,17 +586,21 @@ DEFUN (neighbor_bfd_param,
"Required min receive interval\n"
"Desired min transmit interval\n")
{
+ int idx_peer = 1;
+ int idx_number_1 = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 5;
struct peer *peer;
u_int32_t rx_val;
u_int32_t tx_val;
u_int8_t dm_val;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING;
- if ((ret = bfd_validate_param (vty, argv[1], argv[2], argv[3], &dm_val,
+ if ((ret = bfd_validate_param (vty, argv[idx_number_1]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg, &dm_val,
&rx_val, &tx_val)) != CMD_SUCCESS)
return ret;
@@ -613,23 +614,26 @@ DEFUN (neighbor_bfd_param,
DEFUN_HIDDEN (neighbor_bfd_type,
neighbor_bfd_type_cmd,
- NEIGHBOR_CMD2 "bfd " BFD_CMD_TYPE,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> bfd <multihop|singlehop>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Enables BFD support\n"
- "Session type\n")
+ "Multihop session\n"
+ "Single hop session\n")
{
+ int idx_peer = 1;
+ int idx_hop = 3;
struct peer *peer;
enum bfd_sess_type type;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING;
- if (!strcmp(argv[1], "singlehop"))
+ if (!strcmp(argv[idx_hop]->arg, "singlehop"))
type = BFD_TYPE_SINGLEHOP;
- else if (!strcmp(argv[1], "multihop"))
+ else if (!strcmp(argv[idx_hop]->arg, "multihop"))
type = BFD_TYPE_MULTIHOP;
else
return CMD_WARNING;
@@ -643,16 +647,20 @@ DEFUN_HIDDEN (neighbor_bfd_type,
DEFUN (no_neighbor_bfd,
no_neighbor_bfd_cmd,
- NO_NEIGHBOR_CMD2 "bfd",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> bfd [(2-255) (50-60000) (50-60000)]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Disables BFD support\n")
+ "Disables BFD support\n"
+ "Detect Multiplier\n"
+ "Required min receive interval\n"
+ "Desired min transmit interval\n")
{
+ int idx_peer = 2;
struct peer *peer;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -663,30 +671,22 @@ DEFUN (no_neighbor_bfd,
return CMD_SUCCESS;
}
-ALIAS (no_neighbor_bfd,
- no_neighbor_bfd_val_cmd,
- NO_NEIGHBOR_CMD2 "bfd " BFD_CMD_DETECT_MULT_RANGE BFD_CMD_MIN_RX_RANGE BFD_CMD_MIN_TX_RANGE,
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Disables BFD support\n"
- "Detect Multiplier\n"
- "Required min receive interval\n"
- "Desired min transmit interval\n")
DEFUN_HIDDEN (no_neighbor_bfd_type,
no_neighbor_bfd_type_cmd,
- NO_NEIGHBOR_CMD2 "bfd " BFD_CMD_TYPE,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> bfd <multihop|singlehop>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Disables BFD support\n"
- "Session type\n")
+ "Multihop session\n"
+ "Singlehop session\n")
{
+ int idx_peer = 2;
struct peer *peer;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -714,6 +714,5 @@ bgp_bfd_init(void)
install_element (BGP_NODE, &neighbor_bfd_param_cmd);
install_element (BGP_NODE, &neighbor_bfd_type_cmd);
install_element (BGP_NODE, &no_neighbor_bfd_cmd);
- install_element (BGP_NODE, &no_neighbor_bfd_val_cmd);
install_element (BGP_NODE, &no_neighbor_bfd_type_cmd);
}
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index 9032b1e2f4..b37034bf29 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -29,6 +29,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgpd.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_regex.h"
#include "bgpd/bgp_clist.h"
@@ -42,9 +43,11 @@ community_list_master_lookup (struct community_list_handler *ch, int master)
switch (master)
{
case COMMUNITY_LIST_MASTER:
- return &ch->community_list;
+ return &ch->community_list;
case EXTCOMMUNITY_LIST_MASTER:
- return &ch->extcommunity_list;
+ return &ch->extcommunity_list;
+ case LARGE_COMMUNITY_LIST_MASTER:
+ return &ch->lcommunity_list;
}
return NULL;
}
@@ -66,6 +69,10 @@ community_entry_free (struct community_entry *entry)
if (entry->u.com)
community_free (entry->u.com);
break;
+ case LARGE_COMMUNITY_LIST_STANDARD:
+ if (entry->u.lcom)
+ lcommunity_free (&entry->u.lcom);
+ break;
case EXTCOMMUNITY_LIST_STANDARD:
/* In case of standard extcommunity-list, configuration string
is made by ecommunity_ecom2str(). */
@@ -76,6 +83,7 @@ community_entry_free (struct community_entry *entry)
break;
case COMMUNITY_LIST_EXPANDED:
case EXTCOMMUNITY_LIST_EXPANDED:
+ case LARGE_COMMUNITY_LIST_EXPANDED:
if (entry->config)
XFREE (MTYPE_COMMUNITY_LIST_CONFIG, entry->config);
if (entry->reg)
@@ -320,8 +328,13 @@ community_list_entry_lookup (struct community_list *list, const void *arg,
if (entry->direct == direct && ecommunity_cmp (entry->u.ecom, arg))
return entry;
break;
+ case LARGE_COMMUNITY_LIST_STANDARD:
+ if (entry->direct == direct && lcommunity_cmp (entry->u.lcom, arg))
+ return entry;
+ break;
case COMMUNITY_LIST_EXPANDED:
case EXTCOMMUNITY_LIST_EXPANDED:
+ case LARGE_COMMUNITY_LIST_EXPANDED:
if (entry->direct == direct && strcmp (entry->config, arg) == 0)
return entry;
break;
@@ -399,15 +412,14 @@ community_str_get (struct community *com, int i)
}
/* Internal function to perform regular expression match for
- * * a single community. */
+ * a single community. */
static int
community_regexp_include (regex_t * reg, struct community *com, int i)
{
char *str;
int rv;
- /* When there is no communities attribute it is treated as empty
- * string. */
+ /* When there is no communities attribute it is treated as empty string. */
if (com == NULL || com->size == 0)
str = XSTRDUP(MTYPE_COMMUNITY_STR, "");
else
@@ -447,6 +459,90 @@ community_regexp_match (struct community *com, regex_t * reg)
return 0;
}
+static char *
+lcommunity_str_get (struct lcommunity *lcom, int i)
+{
+ struct lcommunity_val lcomval;
+ u_int32_t globaladmin;
+ u_int32_t localdata1;
+ u_int32_t localdata2;
+ char *str;
+ u_char *ptr;
+ char *pnt;
+
+ ptr = lcom->val;
+ ptr += (i * LCOMMUNITY_SIZE);
+
+ memcpy (&lcomval, ptr, LCOMMUNITY_SIZE);
+
+ /* Allocate memory. 48 bytes taken off bgp_lcommunity.c */
+ str = pnt = XMALLOC (MTYPE_LCOMMUNITY_STR, 48);
+
+ ptr = (u_char *)lcomval.val;
+ globaladmin = (*ptr++ << 24);
+ globaladmin |= (*ptr++ << 16);
+ globaladmin |= (*ptr++ << 8);
+ globaladmin |= (*ptr++);
+
+ localdata1 = (*ptr++ << 24);
+ localdata1 |= (*ptr++ << 16);
+ localdata1 |= (*ptr++ << 8);
+ localdata1 |= (*ptr++);
+
+ localdata2 = (*ptr++ << 24);
+ localdata2 |= (*ptr++ << 16);
+ localdata2 |= (*ptr++ << 8);
+ localdata2 |= (*ptr++);
+
+ sprintf (pnt, "%u:%u:%u", globaladmin, localdata1, localdata2);
+ pnt += strlen (pnt);
+ *pnt = '\0';
+
+ return str;
+}
+
+/* Internal function to perform regular expression match for
+ * a single community. */
+static int
+lcommunity_regexp_include (regex_t * reg, struct lcommunity *lcom, int i)
+{
+ const char *str;
+
+ /* When there is no communities attribute it is treated as empty string. */
+ if (lcom == NULL || lcom->size == 0)
+ str = "";
+ else
+ str = lcommunity_str_get (lcom, i);
+
+ /* Regular expression match. */
+ if (regexec (reg, str, 0, NULL, 0) == 0)
+ return 1;
+
+ /* No match. */
+ return 0;
+}
+
+static int
+lcommunity_regexp_match (struct lcommunity *com, regex_t * reg)
+{
+ const char *str;
+
+ /* When there is no communities attribute it is treated as empty
+ string. */
+ if (com == NULL || com->size == 0)
+ str = "";
+ else
+ str = lcommunity_str (com);
+
+ /* Regular expression match. */
+ if (regexec (reg, str, 0, NULL, 0) == 0)
+ return 1;
+
+ /* No match. */
+ return 0;
+}
+
+
static int
ecommunity_regexp_match (struct ecommunity *ecom, regex_t * reg)
{
@@ -547,6 +643,30 @@ community_list_match (struct community *com, struct community_list *list)
}
int
+lcommunity_list_match (struct lcommunity *lcom, struct community_list *list)
+{
+ struct community_entry *entry;
+
+ for (entry = list->head; entry; entry = entry->next)
+ {
+ if (entry->any)
+ return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
+
+ if (entry->style == LARGE_COMMUNITY_LIST_STANDARD)
+ {
+ if (lcommunity_match (lcom, entry->u.lcom))
+ return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
+ }
+ else if (entry->style == LARGE_COMMUNITY_LIST_EXPANDED)
+ {
+ if (lcommunity_regexp_match (lcom, entry->reg))
+ return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
+ }
+ }
+ return 0;
+}
+
+int
ecommunity_list_match (struct ecommunity *ecom, struct community_list *list)
{
struct community_entry *entry;
@@ -694,12 +814,17 @@ community_list_dup_check (struct community_list *list,
if (community_cmp (entry->u.com, new->u.com))
return 1;
break;
+ case LARGE_COMMUNITY_LIST_STANDARD:
+ if (lcommunity_cmp (entry->u.lcom, new->u.lcom))
+ return 1;
+ break;
case EXTCOMMUNITY_LIST_STANDARD:
if (ecommunity_cmp (entry->u.ecom, new->u.ecom))
return 1;
break;
case COMMUNITY_LIST_EXPANDED:
case EXTCOMMUNITY_LIST_EXPANDED:
+ case LARGE_COMMUNITY_LIST_EXPANDED:
if (strcmp (entry->config, new->config) == 0)
return 1;
break;
@@ -817,6 +942,185 @@ community_list_unset (struct community_list_handler *ch,
return 0;
}
+/* Delete all permitted large communities in the list from com. */
+struct lcommunity *
+lcommunity_list_match_delete (struct lcommunity *lcom,
+ struct community_list *list)
+{
+ struct community_entry *entry;
+ u_int32_t com_index_to_delete[lcom->size];
+ u_char *ptr;
+ int delete_index = 0;
+ int i;
+
+ /* Loop over each lcommunity value and evaluate each against the
+ * community-list. If we need to delete a community value add its index to
+ * com_index_to_delete.
+ */
+ ptr = lcom->val;
+ for (i = 0; i < lcom->size; i++)
+ {
+ ptr += (i * LCOMMUNITY_SIZE);
+ for (entry = list->head; entry; entry = entry->next)
+ {
+ if (entry->any)
+ {
+ if (entry->direct == COMMUNITY_PERMIT)
+ {
+ com_index_to_delete[delete_index] = i;
+ delete_index++;
+ }
+ break;
+ }
+
+ else if ((entry->style == LARGE_COMMUNITY_LIST_STANDARD)
+ && lcommunity_include (entry->u.lcom, ptr) )
+ {
+ if (entry->direct == COMMUNITY_PERMIT)
+ {
+ com_index_to_delete[delete_index] = i;
+ delete_index++;
+ }
+ break;
+ }
+
+ else if ((entry->style == LARGE_COMMUNITY_LIST_STANDARD)
+ && lcommunity_regexp_include (entry->reg, lcom, i))
+ {
+ if (entry->direct == COMMUNITY_PERMIT)
+ {
+ com_index_to_delete[delete_index] = i;
+ delete_index++;
+ }
+ break;
+ }
+ }
+ }
+
+ /* Delete all of the communities we flagged for deletion */
+ ptr = lcom->val;
+ for (i = delete_index-1; i >= 0; i--)
+ {
+ ptr += (com_index_to_delete[i] * LCOMMUNITY_SIZE);
+ lcommunity_del_val (lcom, ptr);
+ }
+
+ return lcom;
+}
+
+/* Set lcommunity-list. */
+int
+lcommunity_list_set (struct community_list_handler *ch,
+ const char *name, const char *str, int direct, int style)
+{
+ struct community_entry *entry = NULL;
+ struct community_list *list;
+ struct lcommunity *lcom = NULL;
+ regex_t *regex = NULL;
+
+ /* Get community list. */
+ list = community_list_get (ch, name, LARGE_COMMUNITY_LIST_MASTER);
+
+ /* When community-list already has entry, new entry should have same
+ style. If you want to have mixed style community-list, you can
+ comment out this check. */
+ if (!community_list_empty_p (list))
+ {
+ struct community_entry *first;
+
+ first = list->head;
+
+ if (style != first->style)
+ {
+ return (first->style == COMMUNITY_LIST_STANDARD
+ ? COMMUNITY_LIST_ERR_STANDARD_CONFLICT
+ : COMMUNITY_LIST_ERR_EXPANDED_CONFLICT);
+ }
+ }
+
+ if (str)
+ {
+ if (style == LARGE_COMMUNITY_LIST_STANDARD)
+ lcom = lcommunity_str2com (str);
+ else
+ regex = bgp_regcomp (str);
+
+ if (! lcom && ! regex)
+ return COMMUNITY_LIST_ERR_MALFORMED_VAL;
+ }
+
+ entry = community_entry_new ();
+ entry->direct = direct;
+ entry->style = style;
+ entry->any = (str ? 0 : 1);
+ entry->u.lcom = lcom;
+ entry->reg = regex;
+ if (lcom)
+ entry->config = lcommunity_lcom2str (lcom, LCOMMUNITY_FORMAT_COMMUNITY_LIST);
+ else if (regex)
+ entry->config = XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str);
+ else
+ entry->config = NULL;
+
+ /* Do not put duplicated community entry. */
+ if (community_list_dup_check (list, entry))
+ community_entry_free (entry);
+ else
+ community_list_entry_add (list, entry);
+
+ return 0;
+}
+
+/* Unset community-list. When str is NULL, delete all of
+ community-list entry belongs to the specified name. */
+int
+lcommunity_list_unset (struct community_list_handler *ch,
+ const char *name, const char *str,
+ int direct, int style)
+{
+ struct community_entry *entry = NULL;
+ struct community_list *list;
+ struct lcommunity *lcom = NULL;
+ regex_t *regex = NULL;
+
+ /* Lookup community list. */
+ list = community_list_lookup (ch, name, LARGE_COMMUNITY_LIST_MASTER);
+ if (list == NULL)
+ return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
+
+ /* Delete all of entry belongs to this community-list. */
+ if (!str)
+ {
+ community_list_delete (list);
+ return 0;
+ }
+
+ if (style == LARGE_COMMUNITY_LIST_STANDARD)
+ lcom = lcommunity_str2com (str);
+ else
+ regex = bgp_regcomp (str);
+
+ if (! lcom && ! regex)
+ return COMMUNITY_LIST_ERR_MALFORMED_VAL;
+
+ if (lcom)
+ entry = community_list_entry_lookup (list, lcom, direct);
+ else
+ entry = community_list_entry_lookup (list, str, direct);
+
+ if (lcom)
+ lcommunity_free (&lcom);
+ if (regex)
+ bgp_regex_free (regex);
+
+ if (!entry)
+ return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
+
+ community_list_entry_delete (list, entry, style);
+
+ return 0;
+}
+
/* Set extcommunity-list. */
int
extcommunity_list_set (struct community_list_handler *ch,
@@ -959,6 +1263,12 @@ community_list_terminate (struct community_list_handler *ch)
while ((list = cm->str.head) != NULL)
community_list_delete (list);
+ cm = &ch->lcommunity_list;
+ while ((list = cm->num.head) != NULL)
+ community_list_delete (list);
+ while ((list = cm->str.head) != NULL)
+ community_list_delete (list);
+
cm = &ch->extcommunity_list;
while ((list = cm->num.head) != NULL)
community_list_delete (list);
diff --git a/bgpd/bgp_clist.h b/bgpd/bgp_clist.h
index 277ab7226c..68e45c8f7b 100644
--- a/bgpd/bgp_clist.h
+++ b/bgpd/bgp_clist.h
@@ -24,6 +24,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
/* Master Community-list. */
#define COMMUNITY_LIST_MASTER 0
#define EXTCOMMUNITY_LIST_MASTER 1
+#define LARGE_COMMUNITY_LIST_MASTER 2
/* Community-list deny and permit. */
#define COMMUNITY_DENY 0
@@ -38,6 +39,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#define COMMUNITY_LIST_EXPANDED 1 /* Expanded community-list. */
#define EXTCOMMUNITY_LIST_STANDARD 2 /* Standard extcommunity-list. */
#define EXTCOMMUNITY_LIST_EXPANDED 3 /* Expanded extcommunity-list. */
+#define LARGE_COMMUNITY_LIST_STANDARD 4 /* Standard Large community-list. */
+#define LARGE_COMMUNITY_LIST_EXPANDED 5 /* Expanded Large community-list. */
/* Community-list. */
struct community_list
@@ -80,6 +83,7 @@ struct community_entry
{
struct community *com;
struct ecommunity *ecom;
+ struct lcommunity *lcom;
} u;
/* Configuration string. */
@@ -112,6 +116,9 @@ struct community_list_handler
/* Exteded community-list. */
struct community_list_master extcommunity_list;
+
+ /* Large community-list. */
+ struct community_list_master lcommunity_list;
};
/* Error code of community-list. */
@@ -139,6 +146,12 @@ extern int extcommunity_list_set (struct community_list_handler *ch,
extern int extcommunity_list_unset (struct community_list_handler *ch,
const char *name, const char *str,
int direct, int style, int delete_all);
+extern int lcommunity_list_set (struct community_list_handler *ch,
+ const char *name, const char *str,
+ int direct, int style);
+extern int lcommunity_list_unset (struct community_list_handler *ch,
+ const char *name, const char *str,
+ int direct, int style);
extern struct community_list_master *
community_list_master_lookup (struct community_list_handler *, int);
@@ -148,9 +161,12 @@ community_list_lookup (struct community_list_handler *, const char *, int);
extern int community_list_match (struct community *, struct community_list *);
extern int ecommunity_list_match (struct ecommunity *, struct community_list *);
+extern int lcommunity_list_match (struct lcommunity *, struct community_list *);
extern int community_list_exact_match (struct community *,
struct community_list *);
extern struct community *
community_list_match_delete (struct community *, struct community_list *);
-
+extern struct lcommunity *
+lcommunity_list_match_delete (struct lcommunity *lcom,
+ struct community_list *list);
#endif /* _QUAGGA_BGP_CLIST_H */
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index 450cbddcfa..17a3d2fdae 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -20,6 +20,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include <zebra.h>
+#include "command.h"
#include "hash.h"
#include "memory.h"
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c
index f4a83d720b..168dbd0122 100644
--- a/bgpd/bgp_damp.c
+++ b/bgpd/bgp_damp.c
@@ -700,16 +700,16 @@ bgp_show_dampening_parameters (struct vty *vty, afi_t afi, safi_t safi)
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
{
- vty_out (vty, "Half-life time: %ld min%s",
- damp->half_life / 60, VTY_NEWLINE);
+ vty_out (vty, "Half-life time: %lld min%s",
+ (long long)damp->half_life / 60, VTY_NEWLINE);
vty_out (vty, "Reuse penalty: %d%s",
- damp->reuse_limit, VTY_NEWLINE);
+ damp->reuse_limit, VTY_NEWLINE);
vty_out (vty, "Suppress penalty: %d%s",
- damp->suppress_value, VTY_NEWLINE);
- vty_out (vty, "Max suppress time: %ld min%s",
- damp->max_suppress_time / 60, VTY_NEWLINE);
+ damp->suppress_value, VTY_NEWLINE);
+ vty_out (vty, "Max suppress time: %lld min%s",
+ (long long)damp->max_suppress_time / 60, VTY_NEWLINE);
vty_out (vty, "Max supress penalty: %u%s",
- damp->ceiling, VTY_NEWLINE);
+ damp->ceiling, VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
}
else
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 46d3afbf79..ab05878210 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -182,12 +182,14 @@ const char *bgp_origin_long_str[] = {"IGP","EGP","incomplete"};
static struct peer *
bgp_find_peer (struct vty *vty, const char *peer_str)
{
+ struct bgp *bgp = VTY_GET_CONTEXT(bgp);
int ret;
union sockunion su;
- struct bgp *bgp;
struct peer *peer;
- bgp = vty->index;
+ if (!bgp) {
+ return NULL;
+ }
ret = str2sockunion (peer_str, &su);
/* 'swpX' string */
@@ -390,7 +392,6 @@ bgp_dump_attr (struct peer *peer, struct attr *attr, char *buf, size_t size)
snprintf (buf + strlen (buf), size - strlen (buf), ", origin %s",
bgp_origin_str[attr->origin]);
-#ifdef HAVE_IPV6
if (attr->extra)
{
char addrbuf[BUFSIZ];
@@ -407,7 +408,6 @@ bgp_dump_attr (struct peer *peer, struct attr *attr, char *buf, size_t size)
inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
addrbuf, BUFSIZ));
}
-#endif /* HAVE_IPV6 */
if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
snprintf (buf + strlen (buf), size - strlen (buf), ", localpref %u",
@@ -621,7 +621,7 @@ DEFUN (debug_bgp_neighbor_events,
DEFUN (debug_bgp_neighbor_events_peer,
debug_bgp_neighbor_events_peer_cmd,
- "debug bgp neighbor-events (A.B.C.D|X:X::X:X|WORD)",
+ "debug bgp neighbor-events <A.B.C.D|X:X::X:X|WORD>",
DEBUG_STR
BGP_STR
"BGP Neighbor Events\n"
@@ -629,7 +629,8 @@ DEFUN (debug_bgp_neighbor_events_peer,
"BGP IPv6 neighbor to debug\n"
"BGP neighbor on interface to debug\n")
{
- const char *host = argv[0];
+ int idx_peer = 3;
+ const char *host = argv[idx_peer]->arg;
if (!bgp_debug_neighbor_events_peers)
bgp_debug_neighbor_events_peers = list_new ();
@@ -674,7 +675,7 @@ DEFUN (no_debug_bgp_neighbor_events,
DEFUN (no_debug_bgp_neighbor_events_peer,
no_debug_bgp_neighbor_events_peer_cmd,
- "no debug bgp neighbor-events (A.B.C.D|X:X::X:X|WORD)",
+ "no debug bgp neighbor-events <A.B.C.D|X:X::X:X|WORD>",
NO_STR
DEBUG_STR
BGP_STR
@@ -683,8 +684,9 @@ DEFUN (no_debug_bgp_neighbor_events_peer,
"BGP IPv6 neighbor to debug\n"
"BGP neighbor on interface to debug\n")
{
+ int idx_peer = 4;
int found_peer = 0;
- const char *host = argv[0];
+ const char *host = argv[idx_peer]->arg;
if (bgp_debug_neighbor_events_peers && !list_isempty(bgp_debug_neighbor_events_peers))
{
@@ -765,7 +767,7 @@ DEFUN (debug_bgp_keepalive,
DEFUN (debug_bgp_keepalive_peer,
debug_bgp_keepalive_peer_cmd,
- "debug bgp keepalives (A.B.C.D|X:X::X:X|WORD)",
+ "debug bgp keepalives <A.B.C.D|X:X::X:X|WORD>",
DEBUG_STR
BGP_STR
"BGP Neighbor Events\n"
@@ -773,7 +775,8 @@ DEFUN (debug_bgp_keepalive_peer,
"BGP IPv6 neighbor to debug\n"
"BGP neighbor on interface to debug\n")
{
- const char *host = argv[0];
+ int idx_peer = 3;
+ const char *host = argv[idx_peer]->arg;
if (!bgp_debug_keepalive_peers)
bgp_debug_keepalive_peers = list_new ();
@@ -818,7 +821,7 @@ DEFUN (no_debug_bgp_keepalive,
DEFUN (no_debug_bgp_keepalive_peer,
no_debug_bgp_keepalive_peer_cmd,
- "no debug bgp keepalives (A.B.C.D|X:X::X:X|WORD)",
+ "no debug bgp keepalives <A.B.C.D|X:X::X:X|WORD>",
NO_STR
DEBUG_STR
BGP_STR
@@ -827,8 +830,9 @@ DEFUN (no_debug_bgp_keepalive_peer,
"BGP IPv6 neighbor to debug\n"
"BGP neighbor on interface to debug\n")
{
+ int idx_peer = 4;
int found_peer = 0;
- const char *host = argv[0];
+ const char *host = argv[idx_peer]->arg;
if (bgp_debug_keepalive_peers && !list_isempty(bgp_debug_keepalive_peers))
{
@@ -854,19 +858,20 @@ DEFUN (no_debug_bgp_keepalive_peer,
/* debug bgp bestpath */
DEFUN (debug_bgp_bestpath_prefix,
debug_bgp_bestpath_prefix_cmd,
- "debug bgp bestpath (A.B.C.D/M|X:X::X:X/M)",
+ "debug bgp bestpath <A.B.C.D/M|X:X::X:X/M>",
DEBUG_STR
BGP_STR
"BGP bestpath\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "IPv6 prefix <network>/<length>\n")
+ "IPv4 prefix\n"
+ "IPv6 prefix\n")
{
+ int idx_ipv4_ipv6_prefixlen = 3;
struct prefix *argv_p;
int ret;
argv_p = prefix_new();
- ret = str2prefix (argv[0], argv_p);
+ ret = str2prefix (argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
if (!ret)
{
prefix_free(argv_p);
@@ -880,7 +885,7 @@ DEFUN (debug_bgp_bestpath_prefix,
if (bgp_debug_list_has_entry(bgp_debug_bestpath_prefixes, NULL, argv_p))
{
- vty_out (vty, "BGP bestptah debugging is already enabled for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP bestptah debugging is already enabled for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -893,7 +898,7 @@ DEFUN (debug_bgp_bestpath_prefix,
else
{
TERM_DEBUG_ON (bestpath, BESTPATH);
- vty_out (vty, "BGP bestpath debugging is on for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP bestpath debugging is on for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
}
return CMD_SUCCESS;
@@ -901,21 +906,22 @@ DEFUN (debug_bgp_bestpath_prefix,
DEFUN (no_debug_bgp_bestpath_prefix,
no_debug_bgp_bestpath_prefix_cmd,
- "no debug bgp bestpath (A.B.C.D/M|X:X::X:X/M)",
+ "no debug bgp bestpath <A.B.C.D/M|X:X::X:X/M>",
NO_STR
DEBUG_STR
BGP_STR
"BGP bestpath\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "IPv6 prefix <network>/<length>\n")
+ "IPv4 prefix\n"
+ "IPv6 prefix\n")
{
+ int idx_ipv4_ipv6_prefixlen = 4;
struct prefix *argv_p;
int found_prefix = 0;
int ret;
argv_p = prefix_new();
- ret = str2prefix (argv[0], argv_p);
+ ret = str2prefix (argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
if (!ret)
{
prefix_free(argv_p);
@@ -942,9 +948,9 @@ DEFUN (no_debug_bgp_bestpath_prefix,
}
if (found_prefix)
- vty_out (vty, "BGP bestpath debugging is off for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP bestpath debugging is off for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
else
- vty_out (vty, "BGP bestpath debugging was not enabled for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP bestpath debugging was not enabled for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -997,29 +1003,30 @@ DEFUN (debug_bgp_update,
DEFUN (debug_bgp_update_direct,
debug_bgp_update_direct_cmd,
- "debug bgp updates (in|out)",
+ "debug bgp updates <in|out>",
DEBUG_STR
BGP_STR
"BGP updates\n"
"Inbound updates\n"
"Outbound updates\n")
{
+ int idx_in_out = 3;
- if (strncmp ("i", argv[0], 1) == 0)
+ if (strncmp ("i", argv[idx_in_out]->arg, 1) == 0)
bgp_debug_list_free(bgp_debug_update_in_peers);
else
bgp_debug_list_free(bgp_debug_update_out_peers);
if (vty->node == CONFIG_NODE)
{
- if (strncmp ("i", argv[0], 1) == 0)
+ if (strncmp ("i", argv[idx_in_out]->arg, 1) == 0)
DEBUG_ON (update, UPDATE_IN);
else
DEBUG_ON (update, UPDATE_OUT);
}
else
{
- if (strncmp ("i", argv[0], 1) == 0)
+ if (strncmp ("i", argv[idx_in_out]->arg, 1) == 0)
{
TERM_DEBUG_ON (update, UPDATE_IN);
vty_out (vty, "BGP updates debugging is on (inbound)%s", VTY_NEWLINE);
@@ -1035,7 +1042,7 @@ DEFUN (debug_bgp_update_direct,
DEFUN (debug_bgp_update_direct_peer,
debug_bgp_update_direct_peer_cmd,
- "debug bgp updates (in|out) (A.B.C.D|X:X::X:X|WORD)",
+ "debug bgp updates <in|out> <A.B.C.D|X:X::X:X|WORD>",
DEBUG_STR
BGP_STR
"BGP updates\n"
@@ -1045,7 +1052,9 @@ DEFUN (debug_bgp_update_direct_peer,
"BGP IPv6 neighbor to debug\n"
"BGP neighbor on interface to debug\n")
{
- const char *host = argv[1];
+ int idx_in_out = 3;
+ int idx_peer = 4;
+ const char *host = argv[idx_peer]->arg;
int inbound;
if (!bgp_debug_update_in_peers)
@@ -1054,7 +1063,7 @@ DEFUN (debug_bgp_update_direct_peer,
if (!bgp_debug_update_out_peers)
bgp_debug_update_out_peers = list_new ();
- if (strncmp ("i", argv[0], 1) == 0)
+ if (strncmp ("i", argv[idx_in_out]->arg, 1) == 0)
inbound = 1;
else
inbound = 0;
@@ -1116,12 +1125,12 @@ DEFUN (debug_bgp_update_direct_peer,
if (inbound)
{
TERM_DEBUG_ON (update, UPDATE_IN);
- vty_out (vty, "BGP updates debugging is on (inbound) for %s%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "BGP updates debugging is on (inbound) for %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
}
else
{
TERM_DEBUG_ON (update, UPDATE_OUT);
- vty_out (vty, "BGP updates debugging is on (outbound) for %s%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "BGP updates debugging is on (outbound) for %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
}
}
return CMD_SUCCESS;
@@ -1129,7 +1138,7 @@ DEFUN (debug_bgp_update_direct_peer,
DEFUN (no_debug_bgp_update_direct,
no_debug_bgp_update_direct_cmd,
- "no debug bgp updates (in|out)",
+ "no debug bgp updates <in|out>",
NO_STR
DEBUG_STR
BGP_STR
@@ -1137,7 +1146,8 @@ DEFUN (no_debug_bgp_update_direct,
"Inbound updates\n"
"Outbound updates\n")
{
- if (strncmp ("i", argv[0], 1) == 0)
+ int idx_in_out = 4;
+ if (strncmp ("i", argv[idx_in_out]->arg, 1) == 0)
{
bgp_debug_list_free(bgp_debug_update_in_peers);
@@ -1171,7 +1181,7 @@ DEFUN (no_debug_bgp_update_direct,
DEFUN (no_debug_bgp_update_direct_peer,
no_debug_bgp_update_direct_peer_cmd,
- "no debug bgp updates (in|out) (A.B.C.D|X:X::X:X|WORD)",
+ "no debug bgp updates <in|out> <A.B.C.D|X:X::X:X|WORD>",
NO_STR
DEBUG_STR
BGP_STR
@@ -1182,11 +1192,13 @@ DEFUN (no_debug_bgp_update_direct_peer,
"BGP IPv6 neighbor to debug\n"
"BGP neighbor on interface to debug\n")
{
+ int idx_in_out = 4;
+ int idx_peer = 5;
int inbound;
int found_peer = 0;
- const char *host = argv[1];
+ const char *host = argv[idx_peer]->arg;
- if (strncmp ("i", argv[0], 1) == 0)
+ if (strncmp ("i", argv[idx_in_out]->arg, 1) == 0)
inbound = 1;
else
inbound = 0;
@@ -1261,20 +1273,21 @@ DEFUN (no_debug_bgp_update_direct_peer,
DEFUN (debug_bgp_update_prefix,
debug_bgp_update_prefix_cmd,
- "debug bgp updates prefix (A.B.C.D/M|X:X::X:X/M)",
+ "debug bgp updates prefix <A.B.C.D/M|X:X::X:X/M>",
DEBUG_STR
BGP_STR
"BGP updates\n"
"Specify a prefix to debug\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "IPv6 prefix <network>/<length>\n")
+ "IPv4 prefix\n"
+ "IPv6 prefix\n")
{
+ int idx_ipv4_ipv6_prefixlen = 4;
struct prefix *argv_p;
int ret;
argv_p = prefix_new();
- ret = str2prefix (argv[0], argv_p);
+ ret = str2prefix (argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
if (!ret)
{
prefix_free(argv_p);
@@ -1288,7 +1301,7 @@ DEFUN (debug_bgp_update_prefix,
if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, argv_p))
{
- vty_out (vty, "BGP updates debugging is already enabled for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP updates debugging is already enabled for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1301,7 +1314,7 @@ DEFUN (debug_bgp_update_prefix,
else
{
TERM_DEBUG_ON (update, UPDATE_PREFIX);
- vty_out (vty, "BGP updates debugging is on for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP updates debugging is on for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
}
return CMD_SUCCESS;
@@ -1309,22 +1322,23 @@ DEFUN (debug_bgp_update_prefix,
DEFUN (no_debug_bgp_update_prefix,
no_debug_bgp_update_prefix_cmd,
- "no debug bgp updates prefix (A.B.C.D/M|X:X::X:X/M)",
+ "no debug bgp updates prefix <A.B.C.D/M|X:X::X:X/M>",
NO_STR
DEBUG_STR
BGP_STR
"BGP updates\n"
"Specify a prefix to debug\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "IPv6 prefix <network>/<length>\n")
+ "IPv4 prefix\n"
+ "IPv6 prefix\n")
{
+ int idx_ipv4_ipv6_prefixlen = 5;
struct prefix *argv_p;
int found_prefix = 0;
int ret;
argv_p = prefix_new();
- ret = str2prefix (argv[0], argv_p);
+ ret = str2prefix (argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
if (!ret)
{
prefix_free(argv_p);
@@ -1351,9 +1365,9 @@ DEFUN (no_debug_bgp_update_prefix,
}
if (found_prefix)
- vty_out (vty, "BGP updates debugging is off for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP updates debugging is off for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
else
- vty_out (vty, "BGP updates debugging was not enabled for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP updates debugging was not enabled for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1366,11 +1380,12 @@ DEFUN (no_debug_bgp_update,
BGP_STR
"BGP updates\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_debug_list_free(bgp_debug_update_in_peers);
bgp_debug_list_free(bgp_debug_update_out_peers);
bgp_debug_list_free(bgp_debug_update_prefixes);
- bgp_debug_clear_updgrp_update_dbg(vty->index);
+ bgp_debug_clear_updgrp_update_dbg(bgp);
if (vty->node == CONFIG_NODE)
{
@@ -1408,20 +1423,21 @@ DEFUN (debug_bgp_zebra,
DEFUN (debug_bgp_zebra_prefix,
debug_bgp_zebra_prefix_cmd,
- "debug bgp zebra prefix (A.B.C.D/M|X:X::X:X/M)",
+ "debug bgp zebra prefix <A.B.C.D/M|X:X::X:X/M>",
DEBUG_STR
BGP_STR
"BGP Zebra messages\n"
"Specify a prefix to debug\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "IPv6 prefix <network>/<length>\n")
+ "IPv4 prefix\n"
+ "IPv6 prefix\n")
{
+ int idx_ipv4_ipv6_prefixlen = 4;
struct prefix *argv_p;
int ret;
argv_p = prefix_new();
- ret = str2prefix (argv[0], argv_p);
+ ret = str2prefix (argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
if (!ret)
{
prefix_free(argv_p);
@@ -1434,7 +1450,7 @@ DEFUN (debug_bgp_zebra_prefix,
if (bgp_debug_list_has_entry(bgp_debug_zebra_prefixes, NULL, argv_p))
{
- vty_out (vty, "BGP zebra debugging is already enabled for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP zebra debugging is already enabled for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1445,7 +1461,7 @@ DEFUN (debug_bgp_zebra_prefix,
else
{
TERM_DEBUG_ON (zebra, ZEBRA);
- vty_out (vty, "BGP zebra debugging is on for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP zebra debugging is on for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
}
return CMD_SUCCESS;
@@ -1473,22 +1489,23 @@ DEFUN (no_debug_bgp_zebra,
DEFUN (no_debug_bgp_zebra_prefix,
no_debug_bgp_zebra_prefix_cmd,
- "no debug bgp zebra prefix (A.B.C.D/M|X:X::X:X/M)",
+ "no debug bgp zebra prefix <A.B.C.D/M|X:X::X:X/M>",
NO_STR
DEBUG_STR
BGP_STR
"BGP Zebra messages\n"
"Specify a prefix to debug\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "IPv6 prefix <network>/<length>\n")
+ "IPv4 prefix\n"
+ "IPv6 prefix\n")
{
+ int idx_ipv4_ipv6_prefixlen = 5;
struct prefix *argv_p;
int found_prefix = 0;
int ret;
argv_p = prefix_new();
- ret = str2prefix (argv[0], argv_p);
+ ret = str2prefix (argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
if (!ret)
{
prefix_free(argv_p);
@@ -1513,9 +1530,9 @@ DEFUN (no_debug_bgp_zebra_prefix,
}
if (found_prefix)
- vty_out (vty, "BGP zebra debugging is off for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP zebra debugging is off for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
else
- vty_out (vty, "BGP zebra debugging was not enabled for %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "BGP zebra debugging was not enabled for %s%s", argv[idx_ipv4_ipv6_prefixlen]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1555,12 +1572,6 @@ DEFUN (no_debug_bgp_allow_martians,
return CMD_SUCCESS;
}
-ALIAS (no_debug_bgp_allow_martians,
- undebug_bgp_allow_martians_cmd,
- "undebug bgp allow-martians",
- UNDEBUG_STR
- BGP_STR
- "BGP allow martian next hops\n")
/* debug bgp update-groups */
DEFUN (debug_bgp_update_groups,
@@ -1605,6 +1616,7 @@ DEFUN (no_debug_bgp,
DEBUG_STR
BGP_STR)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_debug_list_free(bgp_debug_neighbor_events_peers);
bgp_debug_list_free(bgp_debug_keepalive_peers);
bgp_debug_list_free(bgp_debug_update_in_peers);
@@ -1613,7 +1625,7 @@ DEFUN (no_debug_bgp,
bgp_debug_list_free(bgp_debug_bestpath_prefixes);
bgp_debug_list_free(bgp_debug_zebra_prefixes);
- bgp_debug_clear_updgrp_update_dbg(vty->index);
+ bgp_debug_clear_updgrp_update_dbg(bgp);
TERM_DEBUG_OFF (keepalive, KEEPALIVE);
TERM_DEBUG_OFF (update, UPDATE_IN);
@@ -1905,7 +1917,6 @@ bgp_debug_init (void)
install_element (ENABLE_NODE, &no_debug_bgp_zebra_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_zebra_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_allow_martians_cmd);
- install_element (ENABLE_NODE, &undebug_bgp_allow_martians_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_allow_martians_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_update_groups_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_update_groups_cmd);
diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c
index a8c9dad843..84ece48850 100644
--- a/bgpd/bgp_dump.c
+++ b/bgpd/bgp_dump.c
@@ -364,11 +364,7 @@ bgp_dump_route_node_record (int afi, struct bgp_node *rn,
stream_putw (obuf, info->peer->table_dump_index);
/* Originated */
-#ifdef HAVE_CLOCK_MONOTONIC
stream_putl (obuf, time(NULL) - (bgp_clock() - info->uptime));
-#else
- stream_putl (obuf, info->uptime);
-#endif /* HAVE_CLOCK_MONOTONIC */
/* Dump attribute. */
/* Skip prefix & AFI/SAFI for MP_NLRI */
@@ -737,7 +733,7 @@ bgp_dump_unset (struct bgp_dump *bgp_dump)
DEFUN (dump_bgp_all,
dump_bgp_all_cmd,
- "dump bgp (all|all-et|updates|updates-et|routes-mrt) PATH [INTERVAL]",
+ "dump bgp <all|all-et|updates|updates-et|routes-mrt> PATH [INTERVAL]",
"Dump packet\n"
"BGP packet dump\n"
"Dump all BGP packets\nDump all BGP packets (Extended Timestamp Header)\n"
@@ -746,13 +742,16 @@ DEFUN (dump_bgp_all,
"Output filename\n"
"Interval of output\n")
{
+ int idx_dump_routes = 2;
+ int idx_path = 3;
+ int idx_interval = 4;
int bgp_dump_type = 0;
const char *interval = NULL;
struct bgp_dump *bgp_dump_struct = NULL;
const struct bgp_dump_type_map *map = NULL;
for (map = bgp_dump_type_map; map->str; map++)
- if (strcmp(argv[0], map->str) == 0)
+ if (strcmp(argv[idx_dump_routes]->arg, map->str) == 0)
bgp_dump_type = map->type;
switch (bgp_dump_type)
@@ -772,16 +771,16 @@ DEFUN (dump_bgp_all,
}
/* When an interval is given */
- if (argc == 3)
- interval = argv[2];
+ if (argc == idx_interval + 1)
+ interval = argv[idx_interval]->arg;
return bgp_dump_set (vty, bgp_dump_struct, bgp_dump_type,
- argv[1], interval);
+ argv[idx_path]->arg, interval);
}
DEFUN (no_dump_bgp_all,
no_dump_bgp_all_cmd,
- "no dump bgp (all|all-et|updates|updates-et|routes-mrt) [PATH] [INTERVAL]",
+ "no dump bgp <all|all-et|updates|updates-et|routes-mrt> [PATH [INTERVAL]]",
NO_STR
"Stop dump packet\n"
"Stop BGP packet dump\n"
@@ -789,14 +788,17 @@ DEFUN (no_dump_bgp_all,
"Stop dump process all-et\n"
"Stop dump process updates\n"
"Stop dump process updates-et\n"
- "Stop dump process route-mrt\n")
+ "Stop dump process route-mrt\n"
+ "Output filename\n"
+ "Interval of output\n")
{
+ int idx_dump_routes = 3;
int bgp_dump_type = 0;
const struct bgp_dump_type_map *map = NULL;
struct bgp_dump *bgp_dump_struct = NULL;
for (map = bgp_dump_type_map; map->str; map++)
- if (strcmp(argv[0], map->str) == 0)
+ if (strcmp(argv[idx_dump_routes]->arg, map->str) == 0)
bgp_dump_type = map->type;
switch (bgp_dump_type)
@@ -880,7 +882,7 @@ config_write_bgp_dump (struct vty *vty)
bgp_dump_updates.filename, bgp_dump_updates.interval_str,
VTY_NEWLINE);
else
- vty_out (vty, "dump bgp updates %s%s",
+ vty_out (vty, "dump bgp %s %s%s", type_str,
bgp_dump_updates.filename, VTY_NEWLINE);
}
if (bgp_dump_routes.filename)
@@ -889,6 +891,10 @@ config_write_bgp_dump (struct vty *vty)
vty_out (vty, "dump bgp routes-mrt %s %s%s",
bgp_dump_routes.filename, bgp_dump_routes.interval_str,
VTY_NEWLINE);
+ else
+ vty_out (vty, "dump bgp routes-mrt %s%s",
+ bgp_dump_routes.filename, VTY_NEWLINE);
+
}
return 0;
}
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index 65415dcee2..6689883d94 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -29,6 +29,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_aspath.h"
/* Hash of community attribute. */
@@ -592,7 +593,7 @@ ecommunity_str2com (const char *str, int type, int keyword_included)
extcommunity-list
"rt 100:1 rt 100:2 soo 100:3"
- "show ip bgp" and extcommunity-list regular expression matching
+ "show [ip] bgp" and extcommunity-list regular expression matching
"RT:100:1 RT:100:2 SoO:100:3"
For each formath please use below definition for format:
diff --git a/bgpd/bgp_encap.c b/bgpd/bgp_encap.c
index 282815a596..4ec45108b4 100644
--- a/bgpd/bgp_encap.c
+++ b/bgpd/bgp_encap.c
@@ -41,6 +41,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_encap.h"
@@ -209,13 +210,16 @@ DEFUN (encap_network,
encap_network_cmd,
"network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
"Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "IPv4 prefix\n"
"Specify Route Distinguisher\n"
"ENCAP Route Distinguisher\n"
"BGP tag\n"
"tag value\n")
{
- return bgp_static_set_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2], NULL);
+ int idx_ipv4 = 1;
+ int idx_rd = 3;
+ int idx_word = 5;
+ return bgp_static_set_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg, NULL);
}
/* For testing purpose, static route of ENCAP. */
@@ -224,13 +228,16 @@ DEFUN (no_encap_network,
"no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
NO_STR
"Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "IPv4 prefix\n"
"Specify Route Distinguisher\n"
"ENCAP Route Distinguisher\n"
"BGP tag\n"
"tag value\n")
{
- return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2]);
+ int idx_ipv4 = 2;
+ int idx_rd = 4;
+ int idx_word = 6;
+ return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg);
}
static int
@@ -318,23 +325,7 @@ show_adj_route_encap (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
return CMD_SUCCESS;
}
-enum bgp_show_type
-{
- bgp_show_type_normal,
- bgp_show_type_regexp,
- bgp_show_type_prefix_list,
- bgp_show_type_filter_list,
- bgp_show_type_neighbor,
- bgp_show_type_cidr_only,
- bgp_show_type_prefix_longer,
- bgp_show_type_community_all,
- bgp_show_type_community,
- bgp_show_type_community_exact,
- bgp_show_type_community_list,
- bgp_show_type_community_list_exact
-};
-
-static int
+int
bgp_show_encap (
struct vty *vty,
afi_t afi,
@@ -459,43 +450,22 @@ bgp_show_encap (
return CMD_SUCCESS;
}
-DEFUN (show_bgp_ipv4_encap,
- show_bgp_ipv4_encap_cmd,
- "show bgp ipv4 encap",
- SHOW_STR
- BGP_STR
- "Address Family\n"
- "Display ENCAP NLRI specific information\n")
-{
- return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0);
-}
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_ipv6_encap,
- show_bgp_ipv6_encap_cmd,
- "show bgp ipv6 encap",
- SHOW_STR
- BGP_STR
- "Address Family\n"
- "Display ENCAP NLRI specific information\n")
-{
- return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0);
-}
-#endif
-
DEFUN (show_bgp_ipv4_encap_rd,
show_bgp_ipv4_encap_rd_cmd,
- "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn",
+ "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
"Display information for a route distinguisher\n"
"ENCAP Route Distinguisher\n")
{
+ int idx_rd = 5;
int ret;
struct prefix_rd prd;
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
@@ -503,11 +473,12 @@ DEFUN (show_bgp_ipv4_encap_rd,
}
return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0);
}
-#ifdef HAVE_IPV6
+
DEFUN (show_bgp_ipv6_encap_rd,
show_bgp_ipv6_encap_rd_cmd,
- "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn",
+ "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -515,10 +486,11 @@ DEFUN (show_bgp_ipv6_encap_rd,
"ENCAP Route Distinguisher\n"
"Display BGP tags for prefixes\n")
{
+ int idx_rd = 5;
int ret;
struct prefix_rd prd;
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
@@ -526,12 +498,12 @@ DEFUN (show_bgp_ipv6_encap_rd,
}
return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0);
}
-#endif
DEFUN (show_bgp_ipv4_encap_tags,
show_bgp_ipv4_encap_tags_cmd,
- "show bgp ipv4 encap tags",
+ "show [ip] bgp ipv4 encap tags",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -539,11 +511,12 @@ DEFUN (show_bgp_ipv4_encap_tags,
{
return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 1);
}
-#ifdef HAVE_IPV6
+
DEFUN (show_bgp_ipv6_encap_tags,
show_bgp_ipv6_encap_tags_cmd,
- "show bgp ipv6 encap tags",
+ "show [ip] bgp ipv6 encap tags",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -551,12 +524,12 @@ DEFUN (show_bgp_ipv6_encap_tags,
{
return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 1);
}
-#endif
DEFUN (show_bgp_ipv4_encap_rd_tags,
show_bgp_ipv4_encap_rd_tags_cmd,
- "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn tags",
+ "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn tags",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -564,10 +537,11 @@ DEFUN (show_bgp_ipv4_encap_rd_tags,
"ENCAP Route Distinguisher\n"
"Display BGP tags for prefixes\n")
{
+ int idx_rd = 5;
int ret;
struct prefix_rd prd;
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
@@ -575,11 +549,12 @@ DEFUN (show_bgp_ipv4_encap_rd_tags,
}
return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 1);
}
-#ifdef HAVE_IPV6
+
DEFUN (show_bgp_ipv6_encap_rd_tags,
show_bgp_ipv6_encap_rd_tags_cmd,
- "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn tags",
+ "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn tags",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -587,10 +562,11 @@ DEFUN (show_bgp_ipv6_encap_rd_tags,
"ENCAP Route Distinguisher\n"
"Display BGP tags for prefixes\n")
{
+ int idx_rd = 5;
int ret;
struct prefix_rd prd;
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
@@ -598,12 +574,12 @@ DEFUN (show_bgp_ipv6_encap_rd_tags,
}
return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 1);
}
-#endif
DEFUN (show_bgp_ipv4_encap_neighbor_routes,
show_bgp_ipv4_encap_neighbor_routes_cmd,
- "show bgp ipv4 encap neighbors A.B.C.D routes",
+ "show [ip] bgp ipv4 encap neighbors A.B.C.D routes",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -611,12 +587,13 @@ DEFUN (show_bgp_ipv4_encap_neighbor_routes,
"Neighbor to display information about\n"
"Display routes learned from neighbor\n")
{
+ int idx_peer = 5;
union sockunion su;
struct peer *peer;
- if (str2sockunion(argv[0], &su))
+ if (sockunion_str2su (argv[idx_peer]->arg))
{
- vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -629,11 +606,12 @@ DEFUN (show_bgp_ipv4_encap_neighbor_routes,
return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0);
}
-#ifdef HAVE_IPV6
+
DEFUN (show_bgp_ipv6_encap_neighbor_routes,
show_bgp_ipv6_encap_neighbor_routes_cmd,
- "show bgp ipv6 encap neighbors A.B.C.D routes",
+ "show [ip] bgp ipv6 encap neighbors A.B.C.D routes",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -641,12 +619,13 @@ DEFUN (show_bgp_ipv6_encap_neighbor_routes,
"Neighbor to display information about\n"
"Display routes learned from neighbor\n")
{
+ int idx_peer = 5;
union sockunion su;
struct peer *peer;
- if (str2sockunion(argv[0], &su))
+ if (str2sockunion(argv[idx_peer]->arg, &su))
{
- vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -659,12 +638,12 @@ DEFUN (show_bgp_ipv6_encap_neighbor_routes,
return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_neighbor, &su, 0);
}
-#endif
DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes,
show_bgp_ipv4_encap_rd_neighbor_routes_cmd,
- "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
+ "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> routes",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -675,21 +654,23 @@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes,
"Neighbor to display information about\n"
"Display routes learned from neighbor\n")
{
+ int idx_rd = 5;
+ int idx_peer = 7;
int ret;
union sockunion su;
struct peer *peer;
struct prefix_rd prd;
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (str2sockunion(argv[1], &su))
+ if (str2sockunion(argv[idx_peer]->arg, &su))
{
- vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -702,11 +683,12 @@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes,
return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_neighbor, &su, 0);
}
-#ifdef HAVE_IPV6
+
DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes,
show_bgp_ipv6_encap_rd_neighbor_routes_cmd,
- "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
+ "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> routes",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -717,21 +699,23 @@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes,
"Neighbor to display information about\n"
"Display routes learned from neighbor\n")
{
+ int idx_rd = 5;
+ int idx_peer = 7;
int ret;
union sockunion su;
struct peer *peer;
struct prefix_rd prd;
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (str2sockunion(argv[1], &su))
+ if (str2sockunion(argv[idx_peer]->arg, &su))
{
- vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -744,12 +728,12 @@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes,
return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_neighbor, &su, 0);
}
-#endif
DEFUN (show_bgp_ipv4_encap_neighbor_advertised_routes,
show_bgp_ipv4_encap_neighbor_advertised_routes_cmd,
- "show bgp ipv4 encap neighbors A.B.C.D advertised-routes",
+ "show [ip] bgp ipv4 encap neighbors A.B.C.D advertised-routes",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -757,14 +741,15 @@ DEFUN (show_bgp_ipv4_encap_neighbor_advertised_routes,
"Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n")
{
+ int idx_peer = 5;
int ret;
struct peer *peer;
union sockunion su;
- ret = str2sockunion (argv[0], &su);
+ ret = str2sockunion (argv[idx_peer]->arg, &su);
if (ret < 0)
{
- vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
peer = peer_lookup (NULL, &su);
@@ -776,11 +761,12 @@ DEFUN (show_bgp_ipv4_encap_neighbor_advertised_routes,
return show_adj_route_encap (vty, peer, NULL);
}
-#ifdef HAVE_IPV6
+
DEFUN (show_bgp_ipv6_encap_neighbor_advertised_routes,
show_bgp_ipv6_encap_neighbor_advertised_routes_cmd,
- "show bgp ipv6 encap neighbors A.B.C.D advertised-routes",
+ "show [ip] bgp ipv6 encap neighbors A.B.C.D advertised-routes",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -788,14 +774,15 @@ DEFUN (show_bgp_ipv6_encap_neighbor_advertised_routes,
"Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n")
{
+ int idx_peer = 5;
int ret;
struct peer *peer;
union sockunion su;
- ret = str2sockunion (argv[0], &su);
+ ret = str2sockunion (argv[idx_peer]->arg, &su);
if (ret < 0)
{
- vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
peer = peer_lookup (NULL, &su);
@@ -807,12 +794,12 @@ DEFUN (show_bgp_ipv6_encap_neighbor_advertised_routes,
return show_adj_route_encap (vty, peer, NULL);
}
-#endif
DEFUN (show_bgp_ipv4_encap_rd_neighbor_advertised_routes,
show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd,
- "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
+ "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> advertised-routes",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -823,15 +810,17 @@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_advertised_routes,
"Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n")
{
+ int idx_rd = 5;
+ int idx_peer = 7;
int ret;
struct peer *peer;
struct prefix_rd prd;
union sockunion su;
- ret = str2sockunion (argv[1], &su);
+ ret = str2sockunion (argv[idx_peer]->arg, &su);
if (ret < 0)
{
- vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "%% Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
peer = peer_lookup (NULL, &su);
@@ -841,7 +830,7 @@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_advertised_routes,
return CMD_WARNING;
}
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
@@ -850,11 +839,12 @@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_advertised_routes,
return show_adj_route_encap (vty, peer, &prd);
}
-#ifdef HAVE_IPV6
+
DEFUN (show_bgp_ipv6_encap_rd_neighbor_advertised_routes,
show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd,
- "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
+ "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> advertised-routes",
SHOW_STR
+ IP_STR
BGP_STR
"Address Family\n"
"Display ENCAP NLRI specific information\n"
@@ -865,15 +855,17 @@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_advertised_routes,
"Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n")
{
+ int idx_rd = 5;
+ int idx_peer = 7;
int ret;
struct peer *peer;
struct prefix_rd prd;
union sockunion su;
- ret = str2sockunion (argv[1], &su);
+ ret = str2sockunion (argv[idx_peer]->arg, &su);
if (ret < 0)
{
- vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "%% Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
peer = peer_lookup (NULL, &su);
@@ -883,7 +875,7 @@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_advertised_routes,
return CMD_WARNING;
}
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
@@ -892,7 +884,6 @@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_advertised_routes,
return show_adj_route_encap (vty, peer, &prd);
}
-#endif
void
bgp_encap_init (void)
@@ -900,7 +891,6 @@ bgp_encap_init (void)
install_element (BGP_ENCAP_NODE, &encap_network_cmd);
install_element (BGP_ENCAP_NODE, &no_encap_network_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_encap_cmd);
install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_cmd);
install_element (VIEW_NODE, &show_bgp_ipv4_encap_tags_cmd);
install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_tags_cmd);
@@ -909,8 +899,6 @@ bgp_encap_init (void)
install_element (VIEW_NODE, &show_bgp_ipv4_encap_neighbor_advertised_routes_cmd);
install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd);
-#ifdef HAVE_IPV6
- install_element (VIEW_NODE, &show_bgp_ipv6_encap_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_encap_tags_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_tags_cmd);
@@ -918,5 +906,4 @@ bgp_encap_init (void)
install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_neighbor_routes_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_encap_neighbor_advertised_routes_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd);
-#endif
}
diff --git a/bgpd/bgp_encap.h b/bgpd/bgp_encap.h
index 7442c73c47..4d57fca79d 100644
--- a/bgpd/bgp_encap.h
+++ b/bgpd/bgp_encap.h
@@ -21,9 +21,11 @@
#ifndef _QUAGGA_BGP_ENCAP_H
#define _QUAGGA_BGP_ENCAP_H
+#include "bgpd/bgp_route.h"
extern void bgp_encap_init (void);
extern int bgp_nlri_parse_encap (struct peer *, struct attr *, struct bgp_nlri *);
-
+extern int bgp_show_encap (struct vty *vty, afi_t afi, struct prefix_rd *prd,
+ enum bgp_show_type type, void *output_arg, int tags);
#include "bgp_encap_types.h"
#endif /* _QUAGGA_BGP_ENCAP_H */
diff --git a/bgpd/bgp_encap_tlv.c b/bgpd/bgp_encap_tlv.c
index c554ade27e..5c18629aa6 100644
--- a/bgpd/bgp_encap_tlv.c
+++ b/bgpd/bgp_encap_tlv.c
@@ -19,6 +19,7 @@
#include <zebra.h>
+#include "command.h"
#include "memory.h"
#include "prefix.h"
#include "vty.h"
diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c
index a95a7564ec..0de2663dd4 100644
--- a/bgpd/bgp_filter.c
+++ b/bgpd/bgp_filter.c
@@ -426,8 +426,9 @@ as_list_dup_check (struct as_list *aslist, struct as_filter *new)
return 0;
}
-DEFUN (ip_as_path, ip_as_path_cmd,
- "ip as-path access-list WORD (deny|permit) .LINE",
+DEFUN (ip_as_path,
+ ip_as_path_cmd,
+ "ip as-path access-list WORD <deny|permit> LINE...",
IP_STR
"BGP autonomous system path filter\n"
"Specify an access list name\n"
@@ -436,32 +437,28 @@ DEFUN (ip_as_path, ip_as_path_cmd,
"Specify packets to forward\n"
"A regular-expression to match the BGP AS paths\n")
{
+ int idx = 0;
enum as_filter_type type;
struct as_filter *asfilter;
struct as_list *aslist;
regex_t *regex;
char *regstr;
+ /* Retrieve access list name */
+ char *alname = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
+
/* Check the filter type. */
- if (strncmp (argv[1], "p", 1) == 0)
- type = AS_FILTER_PERMIT;
- else if (strncmp (argv[1], "d", 1) == 0)
- type = AS_FILTER_DENY;
- else
- {
- vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ type = argv_find (argv, argc, "deny", &idx) ? AS_FILTER_DENY : AS_FILTER_PERMIT;
/* Check AS path regex. */
- regstr = argv_concat(argv, argc, 2);
+ argv_find (argv, argc, "LINE", &idx);
+ regstr = argv_concat(argv, argc, idx);
regex = bgp_regcomp (regstr);
if (!regex)
{
+ vty_out (vty, "can't compile regexp %s%s", regstr, VTY_NEWLINE);
XFREE (MTYPE_TMP, regstr);
- vty_out (vty, "can't compile regexp %s%s", argv[0],
- VTY_NEWLINE);
return CMD_WARNING;
}
@@ -470,7 +467,7 @@ DEFUN (ip_as_path, ip_as_path_cmd,
XFREE (MTYPE_TMP, regstr);
/* Install new filter to the access_list. */
- aslist = as_list_get (argv[0]);
+ aslist = as_list_get (alname);
/* Duplicate insertion check. */;
if (as_list_dup_check (aslist, asfilter))
@@ -483,7 +480,7 @@ DEFUN (ip_as_path, ip_as_path_cmd,
DEFUN (no_ip_as_path,
no_ip_as_path_cmd,
- "no ip as-path access-list WORD (deny|permit) .LINE",
+ "no ip as-path access-list WORD <deny|permit> LINE...",
NO_STR
IP_STR
"BGP autonomous system path filter\n"
@@ -493,25 +490,28 @@ DEFUN (no_ip_as_path,
"Specify packets to forward\n"
"A regular-expression to match the BGP AS paths\n")
{
+ int idx = 0;
enum as_filter_type type;
struct as_filter *asfilter;
struct as_list *aslist;
char *regstr;
regex_t *regex;
+ char *aslistname = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
+
/* Lookup AS list from AS path list. */
- aslist = as_list_lookup (argv[0]);
+ aslist = as_list_lookup (aslistname);
if (aslist == NULL)
{
- vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[0],
+ vty_out (vty, "ip as-path access-list %s doesn't exist%s", aslistname,
VTY_NEWLINE);
return CMD_WARNING;
}
/* Check the filter type. */
- if (strncmp (argv[1], "p", 1) == 0)
+ if (argv_find (argv, argc, "permit", &idx))
type = AS_FILTER_PERMIT;
- else if (strncmp (argv[1], "d", 1) == 0)
+ else if (argv_find (argv, argc, "deny", &idx))
type = AS_FILTER_DENY;
else
{
@@ -520,14 +520,14 @@ DEFUN (no_ip_as_path,
}
/* Compile AS path. */
- regstr = argv_concat(argv, argc, 2);
+ argv_find (argv, argc, "LINE", &idx);
+ regstr = argv_concat(argv, argc, idx);
regex = bgp_regcomp (regstr);
if (!regex)
{
+ vty_out (vty, "can't compile regexp %s%s", regstr, VTY_NEWLINE);
XFREE (MTYPE_TMP, regstr);
- vty_out (vty, "can't compile regexp %s%s", argv[0],
- VTY_NEWLINE);
return CMD_WARNING;
}
@@ -557,12 +557,13 @@ DEFUN (no_ip_as_path_all,
"Specify an access list name\n"
"Regular expression access list name\n")
{
+ int idx_word = 4;
struct as_list *aslist;
- aslist = as_list_lookup (argv[0]);
+ aslist = as_list_lookup (argv[idx_word]->arg);
if (aslist == NULL)
{
- vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[0],
+ vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[idx_word]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -571,7 +572,7 @@ DEFUN (no_ip_as_path_all,
/* Run hook function. */
if (as_list_master.delete_hook)
- (*as_list_master.delete_hook) (argv[0]);
+ (*as_list_master.delete_hook) (argv[idx_word]->arg);
return CMD_SUCCESS;
}
@@ -627,9 +628,10 @@ DEFUN (show_ip_as_path_access_list,
"List AS path access lists\n"
"AS path access list name\n")
{
+ int idx_word = 3;
struct as_list *aslist;
- aslist = as_list_lookup (argv[0]);
+ aslist = as_list_lookup (argv[idx_word]->arg);
if (aslist)
as_list_show (vty, aslist);
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index e669b4f9b7..a71364381e 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -33,6 +33,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "workqueue.h"
#include "queue.h"
#include "filter.h"
+#include "command.h"
#include "lib/json.h"
#include "bgpd/bgpd.h"
@@ -508,7 +509,7 @@ bgp_graceful_restart_timer_expire (struct thread *thread)
/* NSF delete stale route */
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
- for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
+ for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++)
if (peer->nsf[afi][safi])
bgp_clear_stale_route (peer, afi, safi);
@@ -541,7 +542,7 @@ bgp_graceful_stale_timer_expire (struct thread *thread)
/* NSF delete stale route */
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
- for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
+ for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++)
if (peer->nsf[afi][safi])
bgp_clear_stale_route (peer, afi, safi);
@@ -1050,7 +1051,7 @@ bgp_stop (struct peer *peer)
UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
- for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
+ for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++)
peer->nsf[afi][safi] = 0;
}
@@ -1467,7 +1468,7 @@ bgp_establish (struct peer *peer)
/* graceful restart */
UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
- for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
+ for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++)
{
if (peer->afc_nego[afi][safi]
&& CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)
diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c
new file mode 100644
index 0000000000..549a2ebad8
--- /dev/null
+++ b/bgpd/bgp_lcommunity.c
@@ -0,0 +1,569 @@
+/* BGP Large Communities Attribute
+ *
+ * Copyright (C) 2016 Keyur Patel <keyur@arrcus.com>
+ *
+ * This file is part of FreeRangeRouting (FRR).
+ *
+ * FRR is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2, or (at your option) any later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FRR; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "hash.h"
+#include "memory.h"
+#include "prefix.h"
+#include "command.h"
+#include "filter.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_lcommunity.h"
+#include "bgpd/bgp_aspath.h"
+
+/* Hash of community attribute. */
+static struct hash *lcomhash;
+
+/* Allocate a new lcommunities. */
+static struct lcommunity *
+lcommunity_new (void)
+{
+ return (struct lcommunity *) XCALLOC (MTYPE_LCOMMUNITY,
+ sizeof (struct lcommunity));
+}
+
+/* Allocate lcommunities. */
+void
+lcommunity_free (struct lcommunity **lcom)
+{
+ if ((*lcom)->val)
+ XFREE (MTYPE_LCOMMUNITY_VAL, (*lcom)->val);
+ if ((*lcom)->str)
+ XFREE (MTYPE_LCOMMUNITY_STR, (*lcom)->str);
+ XFREE (MTYPE_LCOMMUNITY, *lcom);
+ lcom = NULL;
+}
+
+static void
+lcommunity_hash_free (struct lcommunity *lcom)
+{
+ lcommunity_free (&lcom);
+}
+
+/* Add a new Large Communities value to Large Communities
+ Attribute structure. When the value is already exists in the
+ structure, we don't add the value. Newly added value is sorted by
+ numerical order. When the value is added to the structure return 1
+ else return 0. */
+static int
+lcommunity_add_val (struct lcommunity *lcom, struct lcommunity_val *lval)
+{
+ u_int8_t *p;
+ int ret;
+ int c;
+
+ /* When this is fist value, just add it. */
+ if (lcom->val == NULL)
+ {
+ lcom->size++;
+ lcom->val = XMALLOC (MTYPE_LCOMMUNITY_VAL, lcom_length (lcom));
+ memcpy (lcom->val, lval->val, LCOMMUNITY_SIZE);
+ return 1;
+ }
+
+ /* If the value already exists in the structure return 0. */
+ c = 0;
+ for (p = lcom->val; c < lcom->size; p += LCOMMUNITY_SIZE, c++)
+ {
+ ret = memcmp (p, lval->val, LCOMMUNITY_SIZE);
+ if (ret == 0)
+ return 0;
+ if (ret > 0)
+ break;
+ }
+
+ /* Add the value to the structure with numerical sorting. */
+ lcom->size++;
+ lcom->val = XREALLOC (MTYPE_LCOMMUNITY_VAL, lcom->val, lcom_length (lcom));
+
+ memmove (lcom->val + (c + 1) * LCOMMUNITY_SIZE,
+ lcom->val + c * LCOMMUNITY_SIZE,
+ (lcom->size - 1 - c) * LCOMMUNITY_SIZE);
+ memcpy (lcom->val + c * LCOMMUNITY_SIZE, lval->val, LCOMMUNITY_SIZE);
+
+ return 1;
+}
+
+/* This function takes pointer to Large Communites strucutre then
+ create a new Large Communities structure by uniq and sort each
+ Large Communities value. */
+struct lcommunity *
+lcommunity_uniq_sort (struct lcommunity *lcom)
+{
+ int i;
+ struct lcommunity *new;
+ struct lcommunity_val *lval;
+
+ if (! lcom)
+ return NULL;
+
+ new = lcommunity_new ();
+
+ for (i = 0; i < lcom->size; i++)
+ {
+ lval = (struct lcommunity_val *) (lcom->val + (i * LCOMMUNITY_SIZE));
+ lcommunity_add_val (new, lval);
+ }
+ return new;
+}
+
+/* Parse Large Communites Attribute in BGP packet. */
+struct lcommunity *
+lcommunity_parse (u_int8_t *pnt, u_short length)
+{
+ struct lcommunity tmp;
+ struct lcommunity *new;
+
+ /* Length check. */
+ if (length % LCOMMUNITY_SIZE)
+ return NULL;
+
+ /* Prepare tmporary structure for making a new Large Communities
+ Attribute. */
+ tmp.size = length / LCOMMUNITY_SIZE;
+ tmp.val = pnt;
+
+ /* Create a new Large Communities Attribute by uniq and sort each
+ Large Communities value */
+ new = lcommunity_uniq_sort (&tmp);
+
+ return lcommunity_intern (new);
+}
+
+/* Duplicate the Large Communities Attribute structure. */
+struct lcommunity *
+lcommunity_dup (struct lcommunity *lcom)
+{
+ struct lcommunity *new;
+
+ new = XCALLOC (MTYPE_LCOMMUNITY, sizeof (struct lcommunity));
+ new->size = lcom->size;
+ if (new->size)
+ {
+ new->val = XMALLOC (MTYPE_LCOMMUNITY_VAL, lcom->size * LCOMMUNITY_SIZE);
+ memcpy (new->val, lcom->val, lcom->size * LCOMMUNITY_SIZE);
+ }
+ else
+ new->val = NULL;
+ return new;
+}
+
+/* Retrun string representation of communities attribute. */
+char *
+lcommunity_str (struct lcommunity *lcom)
+{
+ if (! lcom->str)
+ lcom->str = lcommunity_lcom2str (lcom, LCOMMUNITY_FORMAT_DISPLAY);
+ return lcom->str;
+}
+
+/* Merge two Large Communities Attribute structure. */
+struct lcommunity *
+lcommunity_merge (struct lcommunity *lcom1, struct lcommunity *lcom2)
+{
+ if (lcom1->val)
+ lcom1->val = XREALLOC (MTYPE_LCOMMUNITY_VAL, lcom1->val,
+ (lcom1->size + lcom2->size) * LCOMMUNITY_SIZE);
+ else
+ lcom1->val = XMALLOC (MTYPE_LCOMMUNITY_VAL,
+ (lcom1->size + lcom2->size) * LCOMMUNITY_SIZE);
+
+ memcpy (lcom1->val + (lcom1->size * LCOMMUNITY_SIZE),
+ lcom2->val, lcom2->size * LCOMMUNITY_SIZE);
+ lcom1->size += lcom2->size;
+
+ return lcom1;
+}
+
+/* Intern Large Communities Attribute. */
+struct lcommunity *
+lcommunity_intern (struct lcommunity *lcom)
+{
+ struct lcommunity *find;
+
+ assert (lcom->refcnt == 0);
+
+ find = (struct lcommunity *) hash_get (lcomhash, lcom, hash_alloc_intern);
+
+ if (find != lcom)
+ lcommunity_free (&lcom);
+
+ find->refcnt++;
+
+ if (! find->str)
+ find->str = lcommunity_lcom2str (find, LCOMMUNITY_FORMAT_DISPLAY);
+
+ return find;
+}
+
+/* Unintern Large Communities Attribute. */
+void
+lcommunity_unintern (struct lcommunity **lcom)
+{
+ struct lcommunity *ret;
+
+ if ((*lcom)->refcnt)
+ (*lcom)->refcnt--;
+
+ /* Pull off from hash. */
+ if ((*lcom)->refcnt == 0)
+ {
+ /* Large community must be in the hash. */
+ ret = (struct lcommunity *) hash_release (lcomhash, *lcom);
+ assert (ret != NULL);
+
+ lcommunity_free (lcom);
+ }
+}
+
+/* Utility function to make hash key. */
+unsigned int
+lcommunity_hash_make (void *arg)
+{
+ const struct lcommunity *lcom = arg;
+ int size = lcom->size * LCOMMUNITY_SIZE;
+ u_int8_t *pnt = lcom->val;
+ unsigned int key = 0;
+ int c;
+
+ for (c = 0; c < size; c += LCOMMUNITY_SIZE)
+ {
+ key += pnt[c];
+ key += pnt[c + 1];
+ key += pnt[c + 2];
+ key += pnt[c + 3];
+ key += pnt[c + 4];
+ key += pnt[c + 5];
+ key += pnt[c + 6];
+ key += pnt[c + 7];
+ key += pnt[c + 8];
+ key += pnt[c + 9];
+ key += pnt[c + 10];
+ key += pnt[c + 11];
+ }
+
+ return key;
+}
+
+/* Compare two Large Communities Attribute structure. */
+int
+lcommunity_cmp (const void *arg1, const void *arg2)
+{
+ const struct lcommunity *lcom1 = arg1;
+ const struct lcommunity *lcom2 = arg2;
+
+ return (lcom1->size == lcom2->size
+ && memcmp (lcom1->val, lcom2->val, lcom1->size * LCOMMUNITY_SIZE) == 0);
+}
+
+/* Return communities hash. */
+struct hash *
+lcommunity_hash (void)
+{
+ return lcomhash;
+}
+
+/* Initialize Large Comminities related hash. */
+void
+lcommunity_init (void)
+{
+ lcomhash = hash_create (lcommunity_hash_make, lcommunity_cmp);
+}
+
+void
+lcommunity_finish (void)
+{
+ hash_clean (lcomhash, (void (*)(void *))lcommunity_hash_free);
+ hash_free (lcomhash);
+ lcomhash = NULL;
+}
+
+/* Large Communities token enum. */
+enum lcommunity_token
+{
+ lcommunity_token_unknown = 0,
+ lcommunity_token_val,
+};
+
+/* Get next Large Communities token from the string. */
+static const char *
+lcommunity_gettoken (const char *str, struct lcommunity_val *lval,
+ enum lcommunity_token *token)
+{
+ const char *p = str;
+
+ /* Skip white space. */
+ while (isspace ((int) *p))
+ {
+ p++;
+ str++;
+ }
+
+ /* Check the end of the line. */
+ if (*p == '\0')
+ return NULL;
+
+ /* Community value. */
+ if (isdigit ((int) *p))
+ {
+ int separator = 0;
+ int digit = 0;
+ u_int32_t globaladmin = 0;
+ u_int32_t localdata1 = 0;
+ u_int32_t localdata2 = 0;
+
+ while (isdigit ((int) *p) || *p == ':')
+ {
+ if (*p == ':')
+ {
+ if (separator == 2)
+ {
+ *token = lcommunity_token_unknown;
+ return NULL;
+ }
+ else
+ {
+ separator++;
+ digit = 0;
+ if (separator == 1) {
+ globaladmin = localdata2;
+ } else {
+ localdata1 = localdata2;
+ }
+ localdata2 = 0;
+ }
+ }
+ else
+ {
+ digit = 1;
+ localdata2 *= 10;
+ localdata2 += (*p - '0');
+ }
+ p++;
+ }
+ if (! digit)
+ {
+ *token = lcommunity_token_unknown;
+ return NULL;
+ }
+
+ /*
+ * Copy the large comm.
+ */
+ lval->val[0] = (globaladmin >> 24) & 0xff;
+ lval->val[1] = (globaladmin >> 16) & 0xff;
+ lval->val[2] = (globaladmin >> 8) & 0xff;
+ lval->val[3] = globaladmin & 0xff;
+ lval->val[4] = (localdata1 >> 24) & 0xff;
+ lval->val[5] = (localdata1 >> 16) & 0xff;
+ lval->val[6] = (localdata1 >> 8) & 0xff;
+ lval->val[7] = localdata1 & 0xff;
+ lval->val[8] = (localdata2 >> 24) & 0xff;
+ lval->val[9] = (localdata2 >> 16) & 0xff;
+ lval->val[10] = (localdata2 >> 8) & 0xff;
+ lval->val[11] = localdata2 & 0xff;
+
+ *token = lcommunity_token_val;
+ return p;
+ }
+ *token = lcommunity_token_unknown;
+ return p;
+}
+
+/*
+ Convert string to large community attribute.
+ When type is already known, please specify both str and type.
+
+ When string includes keyword for each large community value.
+ Please specify keyword_included as non-zero value.
+*/
+struct lcommunity *
+lcommunity_str2com (const char *str)
+{
+ struct lcommunity *lcom = NULL;
+ enum lcommunity_token token = lcommunity_token_unknown;
+ struct lcommunity_val lval;
+
+ while ((str = lcommunity_gettoken (str, &lval, &token)))
+ {
+ switch (token)
+ {
+ case lcommunity_token_val:
+ if (lcom == NULL)
+ lcom = lcommunity_new ();
+ lcommunity_add_val (lcom, &lval);
+ break;
+ case lcommunity_token_unknown:
+ default:
+ if (lcom)
+ lcommunity_free (&lcom);
+ return NULL;
+ }
+ }
+ return lcom;
+}
+
+int
+lcommunity_include (struct lcommunity *lcom, u_char *ptr)
+{
+ int i;
+ u_char *lcom_ptr;
+
+ lcom_ptr = lcom->val;
+ for (i = 0; i < lcom->size; i++) {
+ lcom_ptr += (i * LCOMMUNITY_SIZE);
+ if (memcmp (ptr, lcom_ptr, LCOMMUNITY_SIZE) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+/* Convert large community attribute to string.
+ The large coms will be in 65535:65531:0 format.
+*/
+char *
+lcommunity_lcom2str (struct lcommunity *lcom, int format)
+{
+ int i;
+ u_int8_t *pnt;
+#define LCOMMUNITY_STR_DEFAULT_LEN 40
+ int str_size;
+ int str_pnt;
+ char *str_buf;
+ int len = 0;
+ int first = 1;
+ u_int32_t globaladmin, localdata1, localdata2;
+
+ if (lcom->size == 0)
+ {
+ str_buf = XMALLOC (MTYPE_LCOMMUNITY_STR, 1);
+ str_buf[0] = '\0';
+ return str_buf;
+ }
+
+ /* Prepare buffer. */
+ str_buf = XMALLOC (MTYPE_LCOMMUNITY_STR, LCOMMUNITY_STR_DEFAULT_LEN + 1);
+ str_size = LCOMMUNITY_STR_DEFAULT_LEN + 1;
+ str_pnt = 0;
+
+ for (i = 0; i < lcom->size; i++)
+ {
+ /* Make it sure size is enough. */
+ while (str_pnt + LCOMMUNITY_STR_DEFAULT_LEN >= str_size)
+ {
+ str_size *= 2;
+ str_buf = XREALLOC (MTYPE_LCOMMUNITY_STR, str_buf, str_size);
+ }
+
+ /* Space between each value. */
+ if (! first)
+ str_buf[str_pnt++] = ' ';
+
+ pnt = lcom->val + (i * 12);
+
+ globaladmin = (*pnt++ << 24);
+ globaladmin |= (*pnt++ << 16);
+ globaladmin |= (*pnt++ << 8);
+ globaladmin |= (*pnt++);
+
+ localdata1 = (*pnt++ << 24);
+ localdata1 |= (*pnt++ << 16);
+ localdata1 |= (*pnt++ << 8);
+ localdata1 |= (*pnt++);
+
+ localdata2 = (*pnt++ << 24);
+ localdata2 |= (*pnt++ << 16);
+ localdata2 |= (*pnt++ << 8);
+ localdata2 |= (*pnt++);
+
+ len = sprintf( str_buf + str_pnt, "%u:%u:%u", globaladmin,
+ localdata1, localdata2);
+ str_pnt += len;
+ first = 0;
+ }
+ return str_buf;
+}
+
+int
+lcommunity_match (const struct lcommunity *lcom1,
+ const struct lcommunity *lcom2)
+{
+ int i = 0;
+ int j = 0;
+
+ if (lcom1 == NULL && lcom2 == NULL)
+ return 1;
+
+ if (lcom1 == NULL || lcom2 == NULL)
+ return 0;
+
+ if (lcom1->size < lcom2->size)
+ return 0;
+
+ /* Every community on com2 needs to be on com1 for this to match */
+ while (i < lcom1->size && j < lcom2->size)
+ {
+ if (memcmp (lcom1->val + (i*12), lcom2->val + (j*12), LCOMMUNITY_SIZE) == 0)
+ j++;
+ i++;
+ }
+
+ if (j == lcom2->size)
+ return 1;
+ else
+ return 0;
+}
+
+/* Delete one lcommunity. */
+void
+lcommunity_del_val (struct lcommunity *lcom, u_char *ptr)
+{
+ int i = 0;
+ int c = 0;
+
+ if (! lcom->val)
+ return;
+
+ while (i < lcom->size)
+ {
+ if (memcmp (lcom->val + i*LCOMMUNITY_SIZE, ptr, LCOMMUNITY_SIZE) == 0)
+ {
+ c = lcom->size -i -1;
+
+ if (c > 0)
+ memmove (lcom->val + i*LCOMMUNITY_SIZE, lcom->val + (i + 1)*LCOMMUNITY_SIZE, c * LCOMMUNITY_SIZE);
+
+ lcom->size--;
+
+ if (lcom->size > 0)
+ lcom->val = XREALLOC (MTYPE_COMMUNITY_VAL, lcom->val,
+ lcom_length (lcom));
+ else
+ {
+ XFREE (MTYPE_COMMUNITY_VAL, lcom->val);
+ lcom->val = NULL;
+ }
+ return;
+ }
+ i++;
+ }
+}
diff --git a/bgpd/bgp_lcommunity.h b/bgpd/bgp_lcommunity.h
new file mode 100644
index 0000000000..de3697f477
--- /dev/null
+++ b/bgpd/bgp_lcommunity.h
@@ -0,0 +1,74 @@
+/* BGP Large Communities Attribute.
+ *
+ * Copyright (C) 2016 Keyur Patel <keyur@arrcus.com>
+ *
+ * This file is part of FreeRangeRouting (FRR).
+ *
+ * FRR is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2, or (at your option) any later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FRR; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _QUAGGA_BGP_LCOMMUNITY_H
+#define _QUAGGA_BGP_LCOMMUNITY_H
+
+/* Extended communities attribute string format. */
+#define LCOMMUNITY_FORMAT_ROUTE_MAP 0
+#define LCOMMUNITY_FORMAT_COMMUNITY_LIST 1
+#define LCOMMUNITY_FORMAT_DISPLAY 2
+
+/* Large Communities value is twelve octets long. */
+#define LCOMMUNITY_SIZE 12
+
+/* Large Communities attribute. */
+struct lcommunity
+{
+ /* Reference counter. */
+ unsigned long refcnt;
+
+ /* Size of Extended Communities attribute. */
+ int size;
+
+ /* Extended Communities value. */
+ u_int8_t *val;
+
+ /* Human readable format string. */
+ char *str;
+};
+
+/* Extended community value is eight octet. */
+struct lcommunity_val
+{
+ char val[LCOMMUNITY_SIZE];
+};
+
+#define lcom_length(X) ((X)->size * LCOMMUNITY_SIZE)
+
+extern void lcommunity_init (void);
+extern void lcommunity_finish (void);
+extern void lcommunity_free (struct lcommunity **);
+extern struct lcommunity *lcommunity_parse (u_int8_t *, u_short);
+extern struct lcommunity *lcommunity_dup (struct lcommunity *);
+extern struct lcommunity *lcommunity_merge (struct lcommunity *, struct lcommunity *);
+extern struct lcommunity *lcommunity_uniq_sort (struct lcommunity *);
+extern struct lcommunity *lcommunity_intern (struct lcommunity *);
+extern int lcommunity_cmp (const void *, const void *);
+extern void lcommunity_unintern (struct lcommunity **);
+extern unsigned int lcommunity_hash_make (void *);
+extern struct hash *lcommunity_hash (void);
+extern struct lcommunity *lcommunity_str2com (const char *);
+extern char *lcommunity_lcom2str (struct lcommunity *, int);
+extern int lcommunity_match (const struct lcommunity *, const struct lcommunity *);
+extern char *lcommunity_str (struct lcommunity *);
+extern int lcommunity_include (struct lcommunity *lcom, u_char *ptr);
+extern void lcommunity_del_val (struct lcommunity *lcom, u_char *ptr);
+#endif /* _QUAGGA_BGP_LCOMMUNITY_H */
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 979471dc49..9607d381d9 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -44,6 +44,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_route.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_dump.h"
diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c
index 72c0311c17..85e32645ee 100644
--- a/bgpd/bgp_memory.c
+++ b/bgpd/bgp_memory.c
@@ -111,3 +111,7 @@ DEFINE_MTYPE(BGPD, ENCAP_TLV, "ENCAP TLV")
DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS, "BGP TEA Options")
DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS_VALUE, "BGP TEA Options Value")
+
+DEFINE_MTYPE(BGPD, LCOMMUNITY, "Large Community")
+DEFINE_MTYPE(BGPD, LCOMMUNITY_STR, "Large Community display string")
+DEFINE_MTYPE(BGPD, LCOMMUNITY_VAL, "Large Community value")
diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h
index a4ce8b891b..341fb235d0 100644
--- a/bgpd/bgp_memory.h
+++ b/bgpd/bgp_memory.h
@@ -108,4 +108,7 @@ DECLARE_MTYPE(ENCAP_TLV)
DECLARE_MTYPE(BGP_TEA_OPTIONS)
DECLARE_MTYPE(BGP_TEA_OPTIONS_VALUE)
+DECLARE_MTYPE(LCOMMUNITY)
+DECLARE_MTYPE(LCOMMUNITY_STR)
+DECLARE_MTYPE(LCOMMUNITY_VAL)
#endif /* _QUAGGA_BGP_MEMORY_H */
diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index dc8904ced2..f564ff1691 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -38,6 +38,7 @@
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_mpath.h"
/*
@@ -124,7 +125,6 @@ bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2)
compare = IPV4_ADDR_CMP (&ae1->mp_nexthop_global_in,
&ae2->mp_nexthop_global_in);
break;
-#ifdef HAVE_IPV6
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global,
@@ -137,11 +137,9 @@ bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2)
compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_local,
&ae2->mp_nexthop_local);
break;
-#endif /* HAVE_IPV6 */
}
}
-#ifdef HAVE_IPV6
/* This can happen if one IPv6 peer sends you global and link-local
* nexthops but another IPv6 peer only sends you global
*/
@@ -158,7 +156,6 @@ bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2)
compare = 1;
}
}
-#endif /* HAVE_IPV6 */
}
return compare;
@@ -666,6 +663,7 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
u_char origin;
struct community *community, *commerge;
struct ecommunity *ecomm, *ecommerge;
+ struct lcommunity *lcomm, *lcommerge;
struct attr_extra *ae;
struct attr attr = { 0 };
@@ -702,6 +700,7 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
community = attr.community ? community_dup (attr.community) : NULL;
ae = attr.extra;
ecomm = (ae && ae->ecommunity) ? ecommunity_dup (ae->ecommunity) : NULL;
+ lcomm = (ae && ae->lcommunity) ? lcommunity_dup (ae->lcommunity) : NULL;
for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
mpinfo = bgp_info_mpath_next (mpinfo))
@@ -737,6 +736,17 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
else
ecomm = ecommunity_dup (ae->ecommunity);
}
+ if (ae && ae->lcommunity)
+ {
+ if (lcomm)
+ {
+ lcommerge = lcommunity_merge (lcomm, ae->lcommunity);
+ lcomm = lcommunity_uniq_sort (lcommerge);
+ lcommunity_free (&lcommerge);
+ }
+ else
+ lcomm = lcommunity_dup (ae->lcommunity);
+ }
}
attr.aspath = aspath;
@@ -755,10 +765,8 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
/* Zap multipath attr nexthop so we set nexthop to self */
attr.nexthop.s_addr = 0;
-#ifdef HAVE_IPV6
if (attr.extra)
memset (&attr.extra->mp_nexthop_global, 0, sizeof (struct in6_addr));
-#endif /* HAVE_IPV6 */
/* TODO: should we set ATOMIC_AGGREGATE and AGGREGATOR? */
}
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index deb187abd2..cfdb9f3ce6 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -41,6 +41,25 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/rfapi/rfapi_backend.h"
#endif
+extern int
+argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi)
+{
+ int ret = 0;
+ if (argv_find (argv, argc, "vpnv4", index))
+ {
+ ret = 1;
+ if (afi)
+ *afi = AFI_IP;
+ }
+ else if (argv_find (argv, argc, "vpnv6", index))
+ {
+ ret = 1;
+ if (afi)
+ *afi = AFI_IP6;
+ }
+ return ret;
+}
+
u_int16_t
decode_rd_type (u_char *pnt)
{
@@ -442,20 +461,23 @@ DEFUN (vpnv4_network,
vpnv4_network_cmd,
"network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
"Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "IPv4 prefix\n"
"Specify Route Distinguisher\n"
"VPN Route Distinguisher\n"
"BGP tag\n"
"tag value\n")
{
- return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
+ int idx_ipv4_prefixlen = 1;
+ int idx_ext_community = 3;
+ int idx_word = 5;
+ return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, NULL);
}
DEFUN (vpnv4_network_route_map,
vpnv4_network_route_map_cmd,
"network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
"Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "IPv4 prefix\n"
"Specify Route Distinguisher\n"
"VPN Route Distinguisher\n"
"BGP tag\n"
@@ -463,7 +485,11 @@ DEFUN (vpnv4_network_route_map,
"route map\n"
"route map name\n")
{
- return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
+ int idx_ipv4_prefixlen = 1;
+ int idx_ext_community = 3;
+ int idx_word = 5;
+ int idx_word_2 = 7;
+ return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, argv[idx_word_2]->arg);
}
/* For testing purpose, static route of MPLS-VPN. */
@@ -472,17 +498,61 @@ DEFUN (no_vpnv4_network,
"no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
NO_STR
"Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "IPv4 prefix\n"
"Specify Route Distinguisher\n"
"VPN Route Distinguisher\n"
"BGP tag\n"
"tag value\n")
{
- return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
+ int idx_ipv4_prefixlen = 2;
+ int idx_ext_community = 4;
+ int idx_word = 6;
+ return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg);
+}
+
+DEFUN (vpnv6_network,
+ vpnv6_network_cmd,
+ "network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD [route-map WORD]",
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
+ "Specify Route Distinguisher\n"
+ "VPN Route Distinguisher\n"
+ "BGP tag\n"
+ "tag value\n"
+ "route map\n"
+ "route map name\n")
+{
+ int idx_ipv6_prefix = 1;
+ int idx_ext_community = 3;
+ int idx_word = 5;
+ int idx_word_2 = 7;
+ if (argv[idx_word_2])
+ return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, argv[idx_word_2]->arg);
+ else
+ return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, NULL);
}
+/* For testing purpose, static route of MPLS-VPN. */
+DEFUN (no_vpnv6_network,
+ no_vpnv6_network_cmd,
+ "no network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
+ "Specify Route Distinguisher\n"
+ "VPN Route Distinguisher\n"
+ "BGP tag\n"
+ "tag value\n")
+{
+ int idx_ipv6_prefix = 2;
+ int idx_ext_community = 4;
+ int idx_word = 6;
+ return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg);
+}
+
+#if defined(KEEP_OLD_VPN_COMMANDS)
static int
-show_adj_route_vpn (struct vty *vty, struct peer *peer, afi_t afi, struct prefix_rd *prd, u_char use_json)
+show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u_char use_json, afi_t afi)
{
struct bgp *bgp;
struct bgp_table *table;
@@ -647,24 +717,9 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, afi_t afi, struct prefix
}
return CMD_SUCCESS;
}
+#endif
-enum bgp_show_type
-{
- bgp_show_type_normal,
- bgp_show_type_regexp,
- bgp_show_type_prefix_list,
- bgp_show_type_filter_list,
- bgp_show_type_neighbor,
- bgp_show_type_cidr_only,
- bgp_show_type_prefix_longer,
- bgp_show_type_community_all,
- bgp_show_type_community,
- bgp_show_type_community_exact,
- bgp_show_type_community_list,
- bgp_show_type_community_list_exact
-};
-
-static int
+int
bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
enum bgp_show_type type, void *output_arg, int tags, u_char use_json)
{
@@ -882,398 +937,434 @@ bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
return CMD_SUCCESS;
}
-DEFUN (show_bgp_ivp4_vpn,
- show_bgp_ipv4_vpn_cmd,
- "show bgp ipv4 vpn {json}",
+#ifdef KEEP_OLD_VPN_COMMANDS
+DEFUN (show_ip_bgp_vpn_all,
+ show_ip_bgp_vpn_all_cmd,
+ "show [ip] bgp <vpnv4|vpnv6>",
SHOW_STR
+ IP_STR
BGP_STR
- "Address Family\n"
- "Display VPN NLRI specific information\n")
+ BGP_VPNVX_HELP_STR)
{
- return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
-}
+ afi_t afi;
+ int idx = 0;
-DEFUN (show_bgp_ipv6_vpn,
- show_bgp_ipv6_vpn_cmd,
- "show bgp ipv6 vpn {json}",
- SHOW_STR
- BGP_STR
- "Address Family\n"
- "Display VPN NLRI specific information\n")
-{
- return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
+ return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, 0);
+
+ return CMD_SUCCESS;
}
+#endif
-DEFUN (show_bgp_ipv4_vpn_rd,
- show_bgp_ipv4_vpn_rd_cmd,
- "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn {json}",
+DEFUN (show_bgp_ip_vpn_all_rd,
+ show_bgp_ip_vpn_all_rd_cmd,
+ "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:nn_or_IP-address:nn] [json]",
SHOW_STR
+ IP_STR
BGP_STR
- "Address Family\n"
+ BGP_VPNVX_HELP_STR
"Display VPN NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
JSON_STR)
{
+ int idx_rd = 5;
int ret;
struct prefix_rd prd;
+ afi_t afi;
+ int idx = 0;
- ret = str2prefix_rd (argv[0], &prd);
- if (! ret)
+ if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
{
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
+ if (argc >= 7 && argv[idx_rd]->arg)
+ {
+ ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
+ }
+ else
+ {
+ return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
+ }
}
- return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
+ return CMD_SUCCESS;
}
-DEFUN (show_bgp_ipv6_vpn_rd,
- show_bgp_ipv6_vpn_rd_cmd,
- "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn {json}",
+DEFUN (show_ip_bgp_vpn_rd,
+ show_ip_bgp_vpn_rd_cmd,
+ "show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn",
SHOW_STR
+ IP_STR
BGP_STR
- "Address Family\n"
- "Display VPN NLRI specific information\n"
+ BGP_AFI_HELP_STR
+ "Address Family modifier\n"
"Display information for a route distinguisher\n"
- "VPN Route Distinguisher\n"
- JSON_STR)
+ "VPN Route Distinguisher\n")
{
+ int idx_ext_community = argc-1;
int ret;
struct prefix_rd prd;
+ afi_t afi;
+ int idx = 0;
- ret = str2prefix_rd (argv[0], &prd);
- if (!ret)
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
{
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
+ ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 0, 0);
}
+ return CMD_SUCCESS;
+ }
- return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
-}
-
-DEFUN (show_bgp_ip_vpn_all,
- show_bgp_ip_vpn_all_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn all",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_AFI_HELP_STR
- "Display information about all VPN NLRIs\n")
-{
- return bgp_show_mpls_vpn (vty, bgp_vty_afi_from_arg(argv[0]), NULL, bgp_show_type_normal, NULL, 0, 0);
-}
-
-DEFUN (show_bgp_ip_vpn_rd,
- show_bgp_ip_vpn_rd_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn",
+#ifdef KEEP_OLD_VPN_COMMANDS
+DEFUN (show_ip_bgp_vpn_all,
+ show_ip_bgp_vpn_all_cmd,
+ "show [ip] bgp <vpnv4|vpnv6>",
SHOW_STR
IP_STR
BGP_STR
- BGP_AFI_HELP_STR
- "Display information for a route distinguisher\n"
- "VPN Route Distinguisher\n")
+ BGP_VPNVX_HELP_STR)
{
- int ret;
- struct prefix_rd prd;
+ afi_t afi;
+ int idx = 0;
- ret = str2prefix_rd (argv[0], &prd);
- if (! ret)
- {
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show_mpls_vpn (vty, bgp_vty_afi_from_arg(argv[0]), &prd, bgp_show_type_normal, NULL, 0, 0);
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
+ return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, 0);
+ return CMD_SUCCESS;
}
-DEFUN (show_bgp_ip_vpn_all_tags,
- show_bgp_ip_vpn_all_tags_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn all tags",
+DEFUN (show_ip_bgp_vpn_all_tags,
+ show_ip_bgp_vpn_all_tags_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> all tags",
SHOW_STR
IP_STR
BGP_STR
- BGP_AFI_HELP_STR
- "Display information about all VPNv4 NLRIs\n"
+ BGP_VPNVX_HELP_STR
+ "Display information about all VPNv4/VPNV6 NLRIs\n"
"Display BGP tags for prefixes\n")
{
- return bgp_show_mpls_vpn (vty, bgp_vty_afi_from_arg(argv[0]), NULL, bgp_show_type_normal, NULL, 1, 0);
+ afi_t afi;
+ int idx = 0;
+
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
+ return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 1, 0);
+ return CMD_SUCCESS;
}
-DEFUN (show_bgp_ip_vpn_rd_tags,
- show_bgp_ip_vpn_rd_tags_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn tags",
+DEFUN (show_ip_bgp_vpn_rd_tags,
+ show_ip_bgp_vpn_rd_tags_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn tags",
SHOW_STR
IP_STR
BGP_STR
- BGP_AFI_HELP_STR
+ BGP_VPNVX_HELP_STR
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
"Display BGP tags for prefixes\n")
{
+ int idx_ext_community = 5;
int ret;
struct prefix_rd prd;
+ afi_t afi;
+ int idx = 0;
- ret = str2prefix_rd (argv[1], &prd);
- if (! ret)
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
{
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
+ ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 1, 0);
}
- return bgp_show_mpls_vpn (vty, bgp_vty_afi_from_arg(argv[0]), &prd, bgp_show_type_normal, NULL, 1, 0);
+ return CMD_SUCCESS;
}
-DEFUN (show_bgp_ip_vpn_all_neighbor_routes,
- show_bgp_ip_vpn_all_neighbor_routes_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn all neighbors (A.B.C.D|X:X::X:X) routes {json}",
+DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
+ show_ip_bgp_vpn_all_neighbor_routes_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
SHOW_STR
IP_STR
BGP_STR
- BGP_AFI_HELP_STR
- "Display information about all VPNv4 NLRIs\n"
+ BGP_VPNVX_HELP_STR
+ "Display information about all VPNv4/VPNv6 NLRIs\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
- "Neighbor to display information about\n"
"Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_ipv4 = 6;
union sockunion su;
struct peer *peer;
int ret;
u_char uj = use_json(argc, argv);
- afi_t afi = bgp_vty_afi_from_arg(argv[0]);
+ afi_t afi;
+ int idx = 0;
- ret = str2sockunion (argv[1], &su);
- if (ret < 0)
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
{
- if (uj)
+ ret = str2sockunion (argv[idx_ipv4]->arg, &su);
+ if (ret < 0)
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed address");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "Malformed address");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
- peer = peer_lookup (NULL, &su);
- if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
- {
- if (uj)
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "No such neighbor or address family");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "No such neighbor or address family");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_neighbor, &su, 0, uj);
+ return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_neighbor, &su, 0, uj);
+ }
+ return CMD_SUCCESS;
}
-DEFUN (show_bgp_ip_vpn_rd_neighbor_routes,
- show_bgp_ip_vpn_rd_neighbor_routes_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes {json}",
+DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
+ show_ip_bgp_vpn_rd_neighbor_routes_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
SHOW_STR
IP_STR
BGP_STR
- BGP_AFI_HELP_STR
+ BGP_VPNVX_HELP_STR
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
- "Neighbor to display information about\n"
"Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_ext_community = 5;
+ int idx_ipv4 = 7;
int ret;
union sockunion su;
struct peer *peer;
struct prefix_rd prd;
u_char uj = use_json(argc, argv);
- afi_t afi = bgp_vty_afi_from_arg(argv[0]);
+ afi_t afi;
+ int idx = 0;
- ret = str2prefix_rd (argv[1], &prd);
- if (! ret)
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
{
- if (uj)
+ ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
+ if (! ret)
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- ret = str2sockunion (argv[2], &su);
- if (ret < 0)
- {
- if (uj)
+ ret = str2sockunion (argv[idx_ipv4]->arg, &su);
+ if (ret < 0)
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed address");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "Malformed address");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
- peer = peer_lookup (NULL, &su);
- if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
- {
- if (uj)
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "No such neighbor or address family");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "No such neighbor or address family");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_neighbor, &su, 0, uj);
+ return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_neighbor, &su, 0, uj);
+ }
+ return CMD_SUCCESS;
}
-DEFUN (show_bgp_ip_vpn_all_neighbor_advertised_routes,
- show_bgp_ip_vpn_all_neighbor_advertised_routes_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn all neighbors (A.B.C.D|X:X::X:X) advertised-routes {json}",
+DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
+ show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
SHOW_STR
IP_STR
BGP_STR
- BGP_AFI_HELP_STR
- "Display information about all VPN NLRIs\n"
+ BGP_VPNVX_HELP_STR
+ "Display information about all VPNv4/VPNv6 NLRIs\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
- "Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_ipv4 = 6;
int ret;
struct peer *peer;
union sockunion su;
u_char uj = use_json(argc, argv);
- afi_t afi = bgp_vty_afi_from_arg(argv[0]);
+ afi_t afi;
+ int idx = 0;
- ret = str2sockunion (argv[1], &su);
- if (ret < 0)
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
{
- if (uj)
+ ret = str2sockunion (argv[idx_ipv4]->arg, &su);
+ if (ret < 0)
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed address");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "Malformed address");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
- peer = peer_lookup (NULL, &su);
- if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
- {
- if (uj)
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "No such neighbor or address family");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "No such neighbor or address family");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return show_adj_route_vpn (vty, peer, afi, NULL, uj);
+ return show_adj_route_vpn (vty, peer, NULL, uj, afi);
+ }
+ return CMD_SUCCESS;
}
-DEFUN (show_bgp_ip_vpn_rd_neighbor_advertised_routes,
- show_bgp_ip_vpn_rd_neighbor_advertised_routes_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes {json}",
+DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
+ show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
SHOW_STR
IP_STR
BGP_STR
- BGP_AFI_HELP_STR
+ BGP_VPNVX_HELP_STR
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
- "Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_ext_community = 5;
+ int idx_ipv4 = 7;
int ret;
struct peer *peer;
struct prefix_rd prd;
union sockunion su;
u_char uj = use_json(argc, argv);
- afi_t afi = bgp_vty_afi_from_arg(argv[0]);
+ afi_t afi;
+ int idx = 0;
- ret = str2sockunion (argv[2], &su);
- if (ret < 0)
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
{
- if (uj)
+ ret = str2sockunion (argv[idx_ipv4]->arg, &su);
+ if (ret < 0)
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed address");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "Malformed address");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "Malformed address: %s%s", argv[2], VTY_NEWLINE);
- return CMD_WARNING;
- }
- peer = peer_lookup (NULL, &su);
- if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
- {
- if (uj)
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "No such neighbor or address family");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "No such neighbor or address family");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- ret = str2prefix_rd (argv[1], &prd);
- if (! ret)
- {
- if (uj)
+ ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
+ if (! ret)
{
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
- else
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return show_adj_route_vpn (vty, peer, afi, &prd, uj);
+ return show_adj_route_vpn (vty, peer, &prd, uj, afi);
+ }
+ return CMD_SUCCESS;
}
+#endif /* KEEP_OLD_VPN_COMMANDS */
void
bgp_mplsvpn_init (void)
@@ -1282,16 +1373,19 @@ bgp_mplsvpn_init (void)
install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_vpn_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_vpn_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_cmd);
- install_element (VIEW_NODE, &show_bgp_ip_vpn_all_cmd);
- install_element (VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
- install_element (VIEW_NODE, &show_bgp_ip_vpn_all_tags_cmd);
- install_element (VIEW_NODE, &show_bgp_ip_vpn_rd_tags_cmd);
- install_element (VIEW_NODE, &show_bgp_ip_vpn_all_neighbor_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_ip_vpn_rd_neighbor_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_ip_vpn_all_neighbor_advertised_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_ip_vpn_rd_neighbor_advertised_routes_cmd);
+ install_element (BGP_VPNV6_NODE, &vpnv6_network_cmd);
+ install_element (BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
+
+ install_element (VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
}
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index f75b989057..148e5946f1 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -21,6 +21,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGP_MPLSVPN_H
#define _QUAGGA_BGP_MPLSVPN_H
+#include "bgpd/bgp_route.h"
+
#define RD_TYPE_AS 0
#define RD_TYPE_IP 1
#define RD_TYPE_AS4 2
@@ -30,6 +32,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#define RD_ADDRSTRLEN 28
+#ifdef MPLS_LABEL_MAX
+# undef MPLS_LABEL_MAX
+#endif
+
typedef enum {
MPLS_LABEL_IPV4_EXPLICIT_NULL = 0, /* [RFC3032] */
MPLS_LABEL_ROUTER_ALERT = 1, /* [RFC3032] */
@@ -45,7 +51,9 @@ typedef enum {
MPLS_LABEL_UNASSIGNED11 = 11,
MPLS_LABEL_GAL = 13, /* [RFC5586] */
MPLS_LABEL_OAM_ALERT = 14, /* [RFC3429] */
- MPLS_LABEL_EXTENSION = 15 /* [RFC7274] */
+ MPLS_LABEL_EXTENSION = 15, /* [RFC7274] */
+ MPLS_LABEL_MAX = 1048575,
+ MPLS_LABEL_ILLEGAL = 0xFFFFFFFF /* for internal use only */
} mpls_special_label_t;
#define MPLS_LABEL_IS_SPECIAL(label) \
@@ -55,6 +63,10 @@ typedef enum {
(label) == MPLS_LABEL_IPV6_EXPLICIT_NULL || \
(label) == MPLS_LABEL_IMPLICIT_NULL)
+#define BGP_VPNVX_HELP_STR \
+ "Address Family\n" \
+ "Address Family\n"
+
struct rd_as
{
u_int16_t type;
@@ -94,4 +106,9 @@ extern int str2prefix_rd (const char *, struct prefix_rd *);
extern int str2tag (const char *, u_char *);
extern char *prefix_rd2str (struct prefix_rd *, char *, size_t);
+extern int
+argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi);
+extern int bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
+ enum bgp_show_type type, void *output_arg, int tags, u_char use_json);
+
#endif /* _QUAGGA_BGP_MPLSVPN_H */
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 9a49051a96..1358ebc5ef 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -598,10 +598,8 @@ bgp_connect (struct peer *peer)
zlog_err ("%s: could not raise privs", __func__);
if (sockunion_family (&peer->su) == AF_INET)
setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);
-# ifdef HAVE_IPV6
else if (sockunion_family (&peer->su) == AF_INET6)
setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL);
-# endif
if (bgpd_privs.change (ZPRIVS_LOWER))
zlog_err ("%s: could not lower privs", __func__);
#endif
@@ -618,10 +616,8 @@ bgp_connect (struct peer *peer)
return connect_error;
}
-#ifdef HAVE_IPV6
if (peer->conf_if || peer->ifname)
ifindex = ifname2ifindex (peer->conf_if ? peer->conf_if : peer->ifname);
-#endif /* HAVE_IPV6 */
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s [Event] Connect start to %s fd %d",
@@ -681,10 +677,8 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
#ifdef IPTOS_PREC_INTERNETCONTROL
if (sa->sa_family == AF_INET)
setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL);
-# ifdef HAVE_IPV6
else if (sa->sa_family == AF_INET6)
setsockopt_ipv6_tclass (sock, IPTOS_PREC_INTERNETCONTROL);
-# endif
#endif
sockopt_v6only (sa->sa_family, sock);
@@ -717,7 +711,6 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
}
/* IPv6 supported version of BGP server socket setup. */
-#ifdef HAVE_IPV6
int
bgp_socket (unsigned short port, const char *address)
{
@@ -774,50 +767,6 @@ bgp_socket (unsigned short port, const char *address)
return 0;
}
-#else
-/* Traditional IPv4 only version. */
-int
-bgp_socket (unsigned short port, const char *address)
-{
- int sock;
- int socklen;
- struct sockaddr_in sin;
- int ret;
-
- sock = socket (AF_INET, SOCK_STREAM, 0);
- if (sock < 0)
- {
- zlog_err ("socket: %s", safe_strerror (errno));
- return sock;
- }
-
- /* if we intend to implement ttl-security, this socket needs ttl=255 */
- sockopt_ttl (AF_INET, sock, MAXTTL);
-
- memset (&sin, 0, sizeof (struct sockaddr_in));
- sin.sin_family = AF_INET;
- sin.sin_port = htons (port);
- socklen = sizeof (struct sockaddr_in);
-
- if (address && ((ret = inet_aton(address, &sin.sin_addr)) < 1))
- {
- zlog_err("bgp_socket: could not parse ip address %s: %s",
- address, safe_strerror (errno));
- return ret;
- }
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- sin.sin_len = socklen;
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
-
- ret = bgp_listener (sock, (struct sockaddr *) &sin, socklen);
- if (ret < 0)
- {
- close (sock);
- return ret;
- }
- return sock;
-}
-#endif /* HAVE_IPV6 */
void
bgp_close (void)
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 2d3d8e6a65..0cf96101c2 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -243,7 +243,6 @@ bgp_connected_add (struct bgp *bgp, struct connected *ifc)
}
}
}
-#ifdef HAVE_IPV6
else if (addr->family == AF_INET6)
{
apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
@@ -267,7 +266,6 @@ bgp_connected_add (struct bgp *bgp, struct connected *ifc)
rn->info = bc;
}
}
-#endif /* HAVE_IPV6 */
}
void
@@ -304,7 +302,6 @@ bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
bgp_unlock_node (rn);
bgp_unlock_node (rn);
}
-#ifdef HAVE_IPV6
else if (addr->family == AF_INET6)
{
apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
@@ -329,7 +326,6 @@ bgp_connected_delete (struct bgp *bgp, struct connected *ifc)
bgp_unlock_node (rn);
bgp_unlock_node (rn);
}
-#endif /* HAVE_IPV6 */
}
int
@@ -450,12 +446,8 @@ bgp_show_nexthops (struct vty *vty, struct bgp *bgp, int detail)
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
vty_out (vty, " Must be Connected%s", VTY_NEWLINE);
}
-#ifdef HAVE_CLOCK_MONOTONIC
tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
vty_out (vty, " Last update: %s", ctime(&tbuf));
-#else
- vty_out (vty, " Last update: %s", ctime(&bnc->uptime));
-#endif /* HAVE_CLOCK_MONOTONIC */
vty_out(vty, "%s", VTY_NEWLINE);
}
}
@@ -500,41 +492,23 @@ bgp_show_all_instances_nexthops_vty (struct vty *vty)
DEFUN (show_ip_bgp_nexthop,
show_ip_bgp_nexthop_cmd,
- "show ip bgp nexthop",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP nexthop table\n")
-{
- return show_ip_bgp_nexthop_table (vty, NULL, 0);
-}
-
-DEFUN (show_ip_bgp_nexthop_detail,
- show_ip_bgp_nexthop_detail_cmd,
- "show ip bgp nexthop detail",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP nexthop table\n")
-{
- return show_ip_bgp_nexthop_table (vty, NULL, 1);
-}
-
-DEFUN (show_ip_bgp_instance_nexthop,
- show_ip_bgp_instance_nexthop_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " nexthop",
+ "show [ip] bgp [<view|vrf> WORD] nexthop [detail]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "BGP nexthop table\n")
+ "BGP nexthop table\n"
+ "Show detailed information\n")
{
- return show_ip_bgp_nexthop_table (vty, argv[1], 0);
+ int idx = 0;
+ char *vrf = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
+ int detail = argv_find (argv, argc, "detail", &idx) ? 1 : 0;
+ return show_ip_bgp_nexthop_table (vty, vrf, detail);
}
DEFUN (show_ip_bgp_instance_all_nexthop,
show_ip_bgp_instance_all_nexthop_cmd,
- "show ip bgp " BGP_INSTANCE_ALL_CMD " nexthop",
+ "show [ip] bgp <view|vrf> all nexthop",
SHOW_STR
IP_STR
BGP_STR
@@ -545,18 +519,6 @@ DEFUN (show_ip_bgp_instance_all_nexthop,
return CMD_SUCCESS;
}
-DEFUN (show_ip_bgp_instance_nexthop_detail,
- show_ip_bgp_instance_nexthop_detail_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " nexthop detail",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP nexthop table\n")
-{
- return show_ip_bgp_nexthop_table (vty, argv[1], 1);
-}
-
void
bgp_scan_init (struct bgp *bgp)
{
@@ -574,10 +536,7 @@ void
bgp_scan_vty_init (void)
{
install_element (VIEW_NODE, &show_ip_bgp_nexthop_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_nexthop_detail_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_nexthop_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_all_nexthop_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_nexthop_detail_cmd);
}
void
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 4c4fbc09b5..e1204f55a1 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -395,6 +395,7 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
bgp_unlock_node (rn);
bnc->last_update = bgp_clock();
bnc->change_flags = 0;
+ stream_getc (s); // Distance but not currently used
metric = stream_getl (s);
nexthop_num = stream_getc (s);
@@ -527,7 +528,6 @@ make_prefix (int afi, struct bgp_info *ri, struct prefix *p)
p->prefixlen = IPV4_MAX_BITLEN;
}
break;
-#ifdef HAVE_IPV6
case AFI_IP6:
/* We don't register link local NH */
if (ri->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL
@@ -547,7 +547,6 @@ make_prefix (int afi, struct bgp_info *ri, struct prefix *p)
p->prefixlen = IPV6_MAX_BITLEN;
}
break;
-#endif
default:
if (BGP_DEBUG(nht, NHT))
{
@@ -600,11 +599,9 @@ sendmsg_zebra_rnh (struct bgp_nexthop_cache *bnc, int command)
case AF_INET:
stream_put_in_addr (s, &p->u.prefix4);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
stream_put(s, &(p->u.prefix6), 16);
break;
-#endif
default:
break;
}
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 02026a004a..7dbb439be1 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -79,9 +79,13 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
if (hdr->code == CAPABILITY_CODE_MP)
{
+ afi_t afi;
+ safi_t safi;
+
+ bgp_map_afi_safi_iana2int (ntohs(mpc.afi), mpc.safi, &afi, &safi);
if (use_json)
{
- switch (ntohs (mpc.afi))
+ switch (afi)
{
case AFI_IP:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolAfi", "IPv4");
@@ -93,7 +97,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
json_object_int_add(json_cap, "capabilityErrorMultiProtocolAfiUnknown", ntohs (mpc.afi));
break;
}
- switch (mpc.safi)
+ switch (safi)
{
case SAFI_UNICAST:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "unicast");
@@ -101,7 +105,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
case SAFI_MULTICAST:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "multicast");
break;
- case SAFI_MPLS_LABELED_VPN:
+ case SAFI_MPLS_VPN:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "MPLS-labeled VPN");
break;
case SAFI_ENCAP:
@@ -115,7 +119,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
else
{
vty_out (vty, " Capability error for: Multi protocol ");
- switch (ntohs (mpc.afi))
+ switch (afi)
{
case AFI_IP:
vty_out (vty, "AFI IPv4, ");
@@ -127,7 +131,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
break;
}
- switch (mpc.safi)
+ switch (safi)
{
case SAFI_UNICAST:
vty_out (vty, "SAFI Unicast");
@@ -135,7 +139,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
case SAFI_MULTICAST:
vty_out (vty, "SAFI Multicast");
break;
- case SAFI_MPLS_LABELED_VPN:
+ case SAFI_MPLS_VPN:
vty_out (vty, "SAFI MPLS-labeled VPN");
break;
case SAFI_ENCAP:
@@ -178,42 +182,15 @@ bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
mpc->safi = stream_getc (s);
}
-int
-bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
-{
- switch (afi)
- {
- case AFI_IP:
- case AFI_IP6:
- switch (*safi)
- {
- /* BGP MPLS-labeled VPN SAFI isn't contigious with others, remap */
- case SAFI_MPLS_LABELED_VPN:
- *safi = SAFI_MPLS_VPN;
- case SAFI_UNICAST:
- case SAFI_MULTICAST:
- case SAFI_MPLS_VPN:
- case SAFI_ENCAP:
- return 1;
- }
- break;
- case AFI_ETHER:
- default:
- break;
- }
-
- zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
-
- return 0;
-}
-
/* Set negotiated capability value. */
static int
bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
{
struct capability_mp_data mpc;
struct stream *s = BGP_INPUT (peer);
-
+ afi_t afi;
+ safi_t safi;
+
/* Verify length is 4 */
if (hdr->length != 4)
{
@@ -228,14 +205,15 @@ bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
peer->host, mpc.afi, mpc.safi);
- if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi))
+ /* Convert AFI, SAFI to internal values, check. */
+ if (bgp_map_afi_safi_iana2int (mpc.afi, mpc.safi, &afi, &safi))
return -1;
/* Now safi remapped, and afi/safi are valid array indices */
- peer->afc_recv[mpc.afi][mpc.safi] = 1;
+ peer->afc_recv[afi][safi] = 1;
- if (peer->afc[mpc.afi][mpc.safi])
- peer->afc_nego[mpc.afi][mpc.safi] = 1;
+ if (peer->afc[afi][safi])
+ peer->afc_nego[afi][safi] = 1;
else
return -1;
@@ -243,7 +221,7 @@ bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
}
static void
-bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
+bgp_capability_orf_not_support (struct peer *peer, iana_afi_t afi, safi_t safi,
u_char type, u_char mode)
{
if (bgp_debug_neighbor_events(peer))
@@ -271,8 +249,9 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
{
struct stream *s = BGP_INPUT (peer);
struct capability_orf_entry entry;
+ iana_afi_t pkt_afi;
afi_t afi;
- safi_t safi;
+ safi_t pkt_safi, safi;
u_char type;
u_char mode;
u_int16_t sm_cap = 0; /* capability send-mode receive */
@@ -282,22 +261,25 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
/* ORF Entry header */
bgp_capability_mp_data (s, &entry.mpc);
entry.num = stream_getc (s);
- afi = entry.mpc.afi;
- safi = entry.mpc.safi;
+ pkt_afi = entry.mpc.afi;
+ pkt_safi = entry.mpc.safi;
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u",
peer->host, entry.mpc.afi, entry.mpc.safi);
- /* Check AFI and SAFI. */
- if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi))
+ /* Convert AFI, SAFI to internal values, check. */
+ if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
zlog_info ("%s Addr-family %d/%d not supported."
" Ignoring the ORF capability",
- peer->host, entry.mpc.afi, entry.mpc.safi);
+ peer->host, pkt_afi, pkt_safi);
return 0;
}
+ entry.mpc.afi = pkt_afi;
+ entry.mpc.safi = safi;
+
/* validate number field */
if (CAPABILITY_CODE_ORF_LEN + (entry.num * 2) > hdr->length)
{
@@ -321,7 +303,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
case ORF_MODE_RECEIVE:
break;
default:
- bgp_capability_orf_not_support (peer, afi, safi, type, mode);
+ bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
/* ORF Type and afi/safi error checks */
@@ -334,7 +316,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
case ORF_TYPE_PREFIX:
break;
default:
- bgp_capability_orf_not_support (peer, afi, safi, type, mode);
+ bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
break;
@@ -344,12 +326,12 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
case ORF_TYPE_PREFIX_OLD:
break;
default:
- bgp_capability_orf_not_support (peer, afi, safi, type, mode);
+ bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
break;
default:
- bgp_capability_orf_not_support (peer, afi, safi, type, mode);
+ bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
@@ -358,7 +340,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
|| (afi == AFI_IP && safi == SAFI_MULTICAST)
|| (afi == AFI_IP6 && safi == SAFI_UNICAST)))
{
- bgp_capability_orf_not_support (peer, afi, safi, type, mode);
+ bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
@@ -367,7 +349,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
" as %s for afi/safi: %d/%d",
peer->host, LOOKUP (orf_type_str, type),
LOOKUP (orf_mode_str, mode),
- entry.mpc.afi, safi);
+ pkt_afi, pkt_safi);
if (hdr->code == CAPABILITY_CODE_ORF)
{
@@ -381,7 +363,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
}
else
{
- bgp_capability_orf_not_support (peer, afi, safi, type, mode);
+ bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
@@ -437,23 +419,26 @@ bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
while (stream_get_getp (s) + 4 <= end)
{
- afi_t afi = stream_getw (s);
- safi_t safi = stream_getc (s);
+ afi_t afi;
+ safi_t safi;
+ iana_afi_t pkt_afi = stream_getw (s);
+ safi_t pkt_safi = stream_getc (s);
u_char flag = stream_getc (s);
- if (!bgp_afi_safi_valid_indices (afi, &safi))
+ /* Convert AFI, SAFI to internal values, check. */
+ if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
" Ignore the Graceful Restart capability for this AFI/SAFI",
- peer->host, afi, safi);
+ peer->host, pkt_afi, pkt_safi);
}
else if (!peer->afc[afi][safi])
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
" Ignore the Graceful Restart capability",
- peer->host, afi, safi);
+ peer->host, pkt_afi, pkt_safi);
}
else
{
@@ -512,22 +497,25 @@ bgp_capability_addpath (struct peer *peer, struct capability_header *hdr)
while (stream_get_getp (s) + 4 <= end)
{
- afi_t afi = stream_getw (s);
- safi_t safi = stream_getc (s);
+ afi_t afi;
+ safi_t safi;
+ iana_afi_t pkt_afi = stream_getw (s);
+ safi_t pkt_safi = stream_getc (s);
u_char send_receive = stream_getc (s);
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s",
- peer->host, afi, safi,
+ peer->host, pkt_afi, pkt_safi,
(send_receive & BGP_ADDPATH_RX) ? ", receive" : "",
(send_receive & BGP_ADDPATH_TX) ? ", transmit" : "");
- if (!bgp_afi_safi_valid_indices (afi, &safi))
+ /* Convert AFI, SAFI to internal values, check. */
+ if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
" Ignore the Addpath Attribute for this AFI/SAFI",
- peer->host, afi, safi);
+ peer->host, pkt_afi, pkt_safi);
continue;
}
else if (!peer->afc[afi][safi])
@@ -535,7 +523,7 @@ bgp_capability_addpath (struct peer *peer, struct capability_header *hdr)
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
" Ignore the AddPath capability for this AFI/SAFI",
- peer->host, afi, safi);
+ peer->host, pkt_afi, pkt_safi);
continue;
}
@@ -565,20 +553,23 @@ bgp_capability_enhe (struct peer *peer, struct capability_header *hdr)
while (stream_get_getp (s) + 6 <= end)
{
- afi_t afi = stream_getw (s);
- safi_t safi = stream_getw (s);
- afi_t nh_afi = stream_getw (s);
+ iana_afi_t pkt_afi = stream_getw (s);
+ afi_t afi;
+ safi_t safi, pkt_safi = stream_getw (s);
+ iana_afi_t pkt_nh_afi = stream_getw (s);
+ afi_t nh_afi;
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Received with afi/safi/next-hop afi: %u/%u/%u",
- peer->host, afi, safi, nh_afi);
+ peer->host, pkt_afi, pkt_safi, pkt_nh_afi);
- if (!bgp_afi_safi_valid_indices (afi, &safi))
+ /* Convert AFI, SAFI to internal values, check. */
+ if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
" Ignore the ENHE Attribute for this AFI/SAFI",
- peer->host, afi, safi);
+ peer->host, pkt_afi, pkt_safi);
continue;
}
@@ -587,11 +578,13 @@ bgp_capability_enhe (struct peer *peer, struct capability_header *hdr)
* possibilities, so we ignore other values with a log. Also, only
* Unicast SAFI is currently supported (and expected).
*/
+ nh_afi = afi_iana2int (pkt_nh_afi);
+
if (afi != AFI_IP || safi != SAFI_UNICAST || nh_afi != AFI_IP6)
{
zlog_warn ("%s Unexpected afi/safi/next-hop afi: %u/%u/%u "
"in Extended Next-hop capability, ignoring",
- peer->host, afi, safi, nh_afi);
+ peer->host, pkt_afi, pkt_safi, pkt_nh_afi);
continue;
}
@@ -1174,9 +1167,11 @@ bgp_open_capability_orf (struct stream *s, struct peer *peer,
unsigned long orfp;
unsigned long numberp;
int number_of_orfs = 0;
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
- if (safi == SAFI_MPLS_VPN)
- safi = SAFI_MPLS_LABELED_VPN;
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
stream_putc (s, BGP_OPEN_OPT_CAP);
capp = stream_get_endp (s); /* Set Capability Len Pointer */
@@ -1184,9 +1179,9 @@ bgp_open_capability_orf (struct stream *s, struct peer *peer,
stream_putc (s, code); /* Capability Code */
orfp = stream_get_endp (s); /* Set ORF Len Pointer */
stream_putc (s, 0); /* ORF Length */
- stream_putw (s, afi);
+ stream_putw (s, pkt_afi);
stream_putc (s, 0);
- stream_putc (s, safi);
+ stream_putc (s, pkt_safi);
numberp = stream_get_endp (s); /* Set Number Pointer */
stream_putc (s, 0); /* Number of ORFs */
@@ -1235,8 +1230,9 @@ bgp_open_capability (struct stream *s, struct peer *peer)
{
u_char len;
unsigned long cp, capp, rcapp;
+ iana_afi_t pkt_afi;
afi_t afi;
- safi_t safi;
+ safi_t safi, pkt_safi;
as_t local_as;
u_int32_t restart_time;
u_char afi_safi_count = 0;
@@ -1254,56 +1250,29 @@ bgp_open_capability (struct stream *s, struct peer *peer)
|| CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
return;
- /* IPv4 unicast. */
- if (peer->afc[AFI_IP][SAFI_UNICAST])
- {
- peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_MP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN);
- stream_putw (s, AFI_IP);
- stream_putc (s, 0);
- stream_putc (s, SAFI_UNICAST);
- }
- /* IPv4 multicast. */
- if (peer->afc[AFI_IP][SAFI_MULTICAST])
- {
- peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_MP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN);
- stream_putw (s, AFI_IP);
- stream_putc (s, 0);
- stream_putc (s, SAFI_MULTICAST);
- }
- /* IPv4 VPN */
- if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
- {
- peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_MP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN);
- stream_putw (s, AFI_IP);
- stream_putc (s, 0);
- stream_putc (s, SAFI_MPLS_LABELED_VPN);
- }
- /* ENCAP */
- if (peer->afc[AFI_IP][SAFI_ENCAP])
- {
- peer->afc_adv[AFI_IP][SAFI_ENCAP] = 1;
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_MP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN);
- stream_putw (s, AFI_IP);
- stream_putc (s, 0);
- stream_putc (s, SAFI_ENCAP);
- }
-#ifdef HAVE_IPV6
- /* Currently supporting RFC-5549 for Link-Local peering only */
+ /* MP capability for configured AFI, SAFI */
+ for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
+ for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
+ {
+ if (peer->afc[afi][safi])
+ {
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
+
+ peer->afc_adv[afi][safi] = 1;
+ stream_putc (s, BGP_OPEN_OPT_CAP);
+ stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
+ stream_putc (s, CAPABILITY_CODE_MP);
+ stream_putc (s, CAPABILITY_CODE_MP_LEN);
+ stream_putw (s, pkt_afi);
+ stream_putc (s, 0);
+ stream_putc (s, pkt_safi);
+ }
+ }
+
+ /* Extended nexthop capability - currently supporting RFC-5549 for
+ * Link-Local peering only
+ */
if (CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE) &&
peer->su.sa.sa_family == AF_INET6 &&
IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr))
@@ -1323,55 +1292,6 @@ bgp_open_capability (struct stream *s, struct peer *peer)
if (CHECK_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_RCV))
SET_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_NEGO);
}
- /* IPv6 unicast. */
- if (peer->afc[AFI_IP6][SAFI_UNICAST])
- {
- peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_MP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN);
- stream_putw (s, AFI_IP6);
- stream_putc (s, 0);
- stream_putc (s, SAFI_UNICAST);
- }
- /* IPv6 multicast. */
- if (peer->afc[AFI_IP6][SAFI_MULTICAST])
- {
- peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_MP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN);
- stream_putw (s, AFI_IP6);
- stream_putc (s, 0);
- stream_putc (s, SAFI_MULTICAST);
- }
- /* IPv6 VPN. */
- if (peer->afc[AFI_IP6][SAFI_MPLS_VPN])
- {
- peer->afc_adv[AFI_IP6][SAFI_MPLS_VPN] = 1;
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_MP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN);
- stream_putw (s, AFI_IP6);
- stream_putc (s, 0);
- stream_putc (s, SAFI_MPLS_LABELED_VPN);
- }
- /* IPv6 ENCAP. */
- if (peer->afc[AFI_IP6][SAFI_ENCAP])
- {
- peer->afc_adv[AFI_IP6][SAFI_ENCAP] = 1;
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_MP);
- stream_putc (s, CAPABILITY_CODE_MP_LEN);
- stream_putw (s, AFI_IP6);
- stream_putc (s, 0);
- stream_putc (s, SAFI_ENCAP);
- }
-#endif /* HAVE_IPV6 */
/* Route refresh. */
SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
@@ -1420,8 +1340,11 @@ bgp_open_capability (struct stream *s, struct peer *peer)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
if (peer->afc[afi][safi])
{
- stream_putw (s, afi);
- stream_putc (s, safi);
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
+
+ stream_putw (s, pkt_afi);
+ stream_putc (s, pkt_safi);
if (adv_addpath_tx)
{
@@ -1535,9 +1458,14 @@ bgp_open_capability (struct stream *s, struct peer *peer)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
if (peer->afc[afi][safi])
{
- stream_putw (s, afi);
- stream_putc (s, safi);
- stream_putc (s, 0); //Forwarding is not retained as of now.
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
+ stream_putw (s, pkt_afi);
+ stream_putc (s, pkt_safi);
+ if (bgp_flag_check(peer->bgp, BGP_FLAG_GR_PRESERVE_FWD))
+ stream_putc (s, RESTART_F_BIT);
+ else
+ stream_putc (s, 0);
}
}
diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h
index 8ec0a5416b..9275b3a101 100644
--- a/bgpd/bgp_open.h
+++ b/bgpd/bgp_open.h
@@ -31,7 +31,7 @@ struct capability_header
/* Generic MP capability data */
struct capability_mp_data
{
- afi_t afi;
+ iana_afi_t afi;
u_char reserved;
safi_t safi;
};
@@ -115,6 +115,5 @@ extern int bgp_open_option_parse (struct peer *, u_char, int *);
extern void bgp_open_capability (struct stream *, struct peer *);
extern void bgp_capability_vty_out (struct vty *, struct peer *, u_char, json_object *);
extern as_t peek_for_as4_capability (struct peer *, u_char);
-extern int bgp_afi_safi_valid_indices (afi_t, safi_t *);
#endif /* _QUAGGA_BGP_OPEN_H */
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 796a57f054..2df22ab568 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -46,6 +46,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_network.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_encap.h"
@@ -147,6 +148,8 @@ static struct stream *
bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
{
struct stream *s;
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
if (DISABLE_BGP_ANNOUNCE)
return NULL;
@@ -169,13 +172,16 @@ bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
}
else
{
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
+
/* Total Path Attribute Length */
stream_putw (s, 6);
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
stream_putc (s, 3);
- stream_putw (s, afi);
- stream_putc (s, safi);
+ stream_putw (s, pkt_afi);
+ stream_putc (s, pkt_safi);
}
bgp_packet_set_size (s);
@@ -240,8 +246,7 @@ bgp_write_packet (struct peer *peer)
if (!(PAF_SUBGRP(paf))->t_coalesce &&
peer->afc_nego[afi][safi] && peer->synctime
&& ! CHECK_FLAG (peer->af_sflags[afi][safi],
- PEER_STATUS_EOR_SEND)
- && safi != SAFI_MPLS_VPN)
+ PEER_STATUS_EOR_SEND))
{
SET_FLAG (peer->af_sflags[afi][safi],
PEER_STATUS_EOR_SEND);
@@ -691,15 +696,16 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
struct stream *s;
struct bgp_filter *filter;
int orf_refresh = 0;
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
if (DISABLE_BGP_ANNOUNCE)
return;
filter = &peer->filter[afi][safi];
- /* Adjust safi code. */
- if (safi == SAFI_MPLS_VPN)
- safi = SAFI_MPLS_LABELED_VPN;
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
s = stream_new (BGP_MAX_PACKET_SIZE);
@@ -710,9 +716,9 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
/* Encode Route Refresh message. */
- stream_putw (s, afi);
+ stream_putw (s, pkt_afi);
stream_putc (s, 0);
- stream_putc (s, safi);
+ stream_putc (s, pkt_safi);
if (orf_type == ORF_TYPE_PREFIX
|| orf_type == ORF_TYPE_PREFIX_OLD)
@@ -735,7 +741,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
peer->host, orf_type,
(when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
- afi, safi);
+ pkt_afi, pkt_safi);
}
else
{
@@ -747,7 +753,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
peer->host, orf_type,
(when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
- afi, safi);
+ pkt_afi, pkt_safi);
}
/* Total ORF Entry Len. */
@@ -762,7 +768,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
{
if (! orf_refresh)
zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
- peer->host, afi, safi);
+ peer->host, pkt_afi, pkt_safi);
}
/* Add packet to the peer. */
@@ -777,10 +783,11 @@ bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
int capability_code, int action)
{
struct stream *s;
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
- /* Adjust safi code. */
- if (safi == SAFI_MPLS_VPN)
- safi = SAFI_MPLS_LABELED_VPN;
+ /* Convert AFI, SAFI to values for packet. */
+ bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
s = stream_new (BGP_MAX_PACKET_SIZE);
@@ -793,14 +800,14 @@ bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
stream_putc (s, action);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
- stream_putw (s, afi);
+ stream_putw (s, pkt_afi);
stream_putc (s, 0);
- stream_putc (s, safi);
+ stream_putc (s, pkt_safi);
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
peer->host, action == CAPABILITY_ACTION_SET ?
- "Advertising" : "Removing", afi, safi);
+ "Advertising" : "Removing", pkt_afi, pkt_safi);
}
/* Set packet size. */
@@ -1330,7 +1337,6 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
case SAFI_MULTICAST:
return bgp_nlri_parse_ip (peer, attr, packet);
case SAFI_MPLS_VPN:
- case SAFI_MPLS_LABELED_VPN:
return bgp_nlri_parse_vpn (peer, attr, packet);
case SAFI_ENCAP:
return bgp_nlri_parse_encap (peer, attr, packet);
@@ -1509,26 +1515,6 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
if (!nlris[i].nlri)
continue;
- /* We use afi and safi as indices into tables and what not. It would
- * be impossible, at this time, to support unknown afi/safis. And
- * anyway, the peer needs to be configured to enable the afi/safi
- * explicitly which requires UI support.
- *
- * Ignore unknown afi/safi NLRIs.
- *
- * Note: This means nlri[x].afi/safi still can not be trusted for
- * indexing later in this function!
- *
- * Note2: This will also remap the wire code-point for VPN safi to the
- * internal safi_t point, as needs be.
- */
- if(!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
- {
- zlog_info ("%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
- peer->host, nlris[i].afi, nlris[i].safi);
- continue;
- }
-
/* NLRI is processed iff the peer if configured for the specific afi/safi */
if (!peer->afc[nlris[i].afi][nlris[i].safi])
{
@@ -1587,9 +1573,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
safi = SAFI_UNICAST;
}
else if (attr.flag & ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI)
- && nlris[NLRI_MP_WITHDRAW].length == 0
- && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
- &nlris[NLRI_MP_WITHDRAW].safi))
+ && nlris[NLRI_MP_WITHDRAW].length == 0)
{
afi = nlris[NLRI_MP_WITHDRAW].afi;
safi = nlris[NLRI_MP_WITHDRAW].safi;
@@ -1728,8 +1712,9 @@ bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
static void
bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
{
+ iana_afi_t pkt_afi;
afi_t afi;
- safi_t safi;
+ safi_t pkt_safi, safi;
struct stream *s;
struct peer_af *paf;
struct update_group *updgrp;
@@ -1758,28 +1743,22 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
s = peer->ibuf;
/* Parse packet. */
- afi = stream_getw (s);
+ pkt_afi = stream_getw (s);
(void)stream_getc (s);
- safi = stream_getc (s);
+ pkt_safi = stream_getc (s);
if (bgp_debug_update(peer, NULL, NULL, 0))
zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
- peer->host, afi, safi);
+ peer->host, pkt_afi, pkt_safi);
- /* Check AFI and SAFI. */
- if ((afi != AFI_IP && afi != AFI_IP6)
- || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
- && safi != SAFI_MPLS_LABELED_VPN))
+ /* Convert AFI, SAFI to internal values and check. */
+ if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
zlog_info ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
- peer->host, afi, safi);
+ peer->host, pkt_afi, pkt_safi);
return;
}
- /* Adjust safi code. */
- if (safi == SAFI_MPLS_LABELED_VPN)
- safi = SAFI_MPLS_VPN;
-
if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
{
u_char *end;
@@ -1955,8 +1934,9 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
struct capability_mp_data mpc;
struct capability_header *hdr;
u_char action;
+ iana_afi_t pkt_afi;
afi_t afi;
- safi_t safi;
+ safi_t pkt_safi, safi;
end = pnt + length;
@@ -2000,18 +1980,19 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
/* We know MP Capability Code. */
if (hdr->code == CAPABILITY_CODE_MP)
{
- afi = ntohs (mpc.afi);
- safi = mpc.safi;
+ pkt_afi = ntohs (mpc.afi);
+ pkt_safi = mpc.safi;
/* Ignore capability when override-capability is set. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
continue;
- if (!bgp_afi_safi_valid_indices (afi, &safi))
+ /* Convert AFI, SAFI to internal values. */
+ if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
- "(%u/%u)", peer->host, afi, safi);
+ "(%u/%u)", peer->host, pkt_afi, pkt_safi);
continue;
}
@@ -2021,7 +2002,7 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
peer->host,
action == CAPABILITY_ACTION_SET
? "Advertising" : "Removing",
- ntohs(mpc.afi) , mpc.safi);
+ pkt_afi, pkt_safi);
if (action == CAPABILITY_ACTION_SET)
{
@@ -2175,15 +2156,6 @@ bgp_marker_all_one (struct stream *s, int length)
return 1;
}
-/* Recent thread time.
- On same clock base as bgp_clock (MONOTONIC)
- but can be time of last context switch to bgp_read thread. */
-static time_t
-bgp_recent_clock (void)
-{
- return recent_relative_time().tv_sec;
-}
-
/* Starting point of packet process function. */
int
bgp_read (struct thread *thread)
@@ -2310,14 +2282,14 @@ bgp_read (struct thread *thread)
bgp_open_receive (peer, size); /* XXX return value ignored! */
break;
case BGP_MSG_UPDATE:
- peer->readtime = bgp_recent_clock ();
+ peer->readtime = monotime (NULL);
bgp_update_receive (peer, size);
break;
case BGP_MSG_NOTIFY:
bgp_notify_receive (peer, size);
break;
case BGP_MSG_KEEPALIVE:
- peer->readtime = bgp_recent_clock ();
+ peer->readtime = monotime (NULL);
bgp_keepalive_receive (peer, size);
break;
case BGP_MSG_ROUTE_REFRESH_NEW:
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 3e5251a7ff..0123ed17ea 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1,5 +1,6 @@
/* BGP routing information
Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
+ Copyright (C) 2016 Job Snijders <job@instituut.net>
This file is part of GNU Zebra.
@@ -20,7 +21,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include <zebra.h>
-#include "lib/json.h"
#include "prefix.h"
#include "linklist.h"
#include "memory.h"
@@ -36,6 +36,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "workqueue.h"
#include "queue.h"
#include "memory.h"
+#include "lib/json.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@@ -46,11 +47,13 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_regex.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_clist.h"
#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_filter.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_mplsvpn.h"
+#include "bgpd/bgp_encap.h"
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_damp.h"
#include "bgpd/bgp_advertise.h"
@@ -59,7 +62,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_mpath.h"
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_updgrp.h"
-#include "bgpd/bgp_vty.h"
#if ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h"
@@ -1173,10 +1175,8 @@ subgroup_announce_reset_nhop (u_char family, struct attr *attr)
{
if (family == AF_INET)
attr->nexthop.s_addr = 0;
-#ifdef HAVE_IPV6
if (family == AF_INET6)
memset (&attr->extra->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
-#endif
}
int
@@ -1267,10 +1267,8 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
{
if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
return 0;
-#ifdef HAVE_IPV6
else if (p->family == AF_INET6 && p->prefixlen == 0)
return 0;
-#endif /* HAVE_IPV6 */
}
/* Transparency check. */
@@ -1433,7 +1431,6 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
if (reflect)
SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
-#ifdef HAVE_IPV6
#define NEXTHOP_IS_V6 (\
(safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
(p->family == AF_INET6 || peer_cap_enhe(peer))) || \
@@ -1465,7 +1462,6 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
memset (&attr->extra->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
}
-#endif /* HAVE_IPV6 */
bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
bgp_peer_as_override(bgp, afi, safi, peer, attr);
@@ -1930,7 +1926,7 @@ bgp_process_main (struct work_queue *wq, void *data)
vnc_import_bgp_add_route(bgp, p, old_select);
vnc_import_bgp_exterior_add_route(bgp, p, old_select);
#endif
- bgp_zebra_announce (p, old_select, bgp, afi, safi);
+ bgp_zebra_announce (p, old_select, bgp, afi, safi);
}
UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
bgp_zebra_clear_route_change_flags (rn);
@@ -2118,9 +2114,12 @@ bgp_maximum_prefix_restart_timer (struct thread *thread)
}
int
-bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
+bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
safi_t safi, int always)
{
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
+
if (!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
return 0;
@@ -2138,15 +2137,15 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
return 0;
+ /* Convert AFI, SAFI to values for packet. */
+ pkt_afi = afi_int2iana (afi);
+ pkt_safi = safi_int2iana (safi);
{
u_int8_t ndata[7];
- if (safi == SAFI_MPLS_VPN)
- safi = SAFI_MPLS_LABELED_VPN;
-
- ndata[0] = (afi >> 8);
- ndata[1] = afi;
- ndata[2] = safi;
+ ndata[0] = (pkt_afi >> 8);
+ ndata[1] = pkt_afi;
+ ndata[2] = pkt_safi;
ndata[3] = (peer->pmax[afi][safi] >> 24);
ndata[4] = (peer->pmax[afi][safi] >> 16);
ndata[5] = (peer->pmax[afi][safi] >> 8);
@@ -2227,7 +2226,7 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
return;
}
-
+
#if ENABLE_BGP_VNC
if (safi == SAFI_MPLS_VPN) {
struct bgp_node *prn = NULL;
@@ -2319,7 +2318,6 @@ bgp_update_martian_nexthop (struct bgp *bgp, afi_t afi, safi_t safi, struct attr
IPV4_CLASS_DE (ntohl (attre->mp_nexthop_global_in.s_addr)));
break;
-#ifdef HAVE_IPV6
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
@@ -2327,7 +2325,6 @@ bgp_update_martian_nexthop (struct bgp *bgp, afi_t afi, safi_t safi, struct attr
IN6_IS_ADDR_LOOPBACK(&attre->mp_nexthop_global) ||
IN6_IS_ADDR_MULTICAST(&attre->mp_nexthop_global));
break;
-#endif /* HAVE_IPV6 */
default:
ret = 1;
@@ -3359,17 +3356,37 @@ bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi)
struct bgp_info *ri;
struct bgp_table *table;
- table = peer->bgp->rib[afi][safi];
+ if ( safi == SAFI_MPLS_VPN)
+ {
+ for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn))
+ {
+ struct bgp_node *rm;
+ struct bgp_info *ri;
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ /* look for neighbor in tables */
+ if ((table = rn->info) != NULL)
+ {
+ for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
+ for (ri = rm->info; ri; ri = ri->next)
+ if (ri->peer == peer)
+ {
+ if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
+ bgp_rib_remove (rm, ri, peer, afi, safi);
+ break;
+ }
+ }
+ }
+ }
+ else
{
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer)
- {
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- bgp_rib_remove (rn, ri, peer, afi, safi);
- break;
- }
+ for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn))
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == peer)
+ {
+ if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
+ bgp_rib_remove (rn, ri, peer, afi, safi);
+ break;
+ }
}
}
@@ -3394,7 +3411,7 @@ bgp_cleanup_table(struct bgp_table *table, safi_t safi)
vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri);
#endif
bgp_zebra_withdraw (&rn->p, ri, safi);
- bgp_info_reap (rn, ri);
+ bgp_info_reap (rn, ri);
}
}
}
@@ -3554,7 +3571,6 @@ bgp_nlri_parse_ip (struct peer *peer, struct attr *attr,
}
}
-#ifdef HAVE_IPV6
/* Check address. */
if (afi == AFI_IP6 && safi == SAFI_UNICAST)
{
@@ -3577,7 +3593,6 @@ bgp_nlri_parse_ip (struct peer *peer, struct attr *attr,
continue;
}
}
-#endif /* HAVE_IPV6 */
/* Normal process. */
if (attr)
@@ -4043,9 +4058,10 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
/* Configure static BGP network. When user don't run zebra, static
route should be installed as valid. */
static int
-bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
+bgp_static_set (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi, const char *rmap, int backdoor)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
struct prefix p;
struct bgp_static *bgp_static;
@@ -4059,14 +4075,12 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
return CMD_WARNING;
}
-#ifdef HAVE_IPV6
if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
{
vty_out (vty, "%% Malformed prefix (link-local address)%s",
VTY_NEWLINE);
return CMD_WARNING;
}
-#endif /* HAVE_IPV6 */
apply_mask (&p);
@@ -4132,9 +4146,10 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
/* Configure static BGP network. */
static int
-bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str,
+bgp_static_unset (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
struct prefix p;
struct bgp_static *bgp_static;
@@ -4147,14 +4162,12 @@ bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str,
vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
return CMD_WARNING;
}
-#ifdef HAVE_IPV6
if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
{
vty_out (vty, "%% Malformed prefix (link-local address)%s",
VTY_NEWLINE);
return CMD_WARNING;
}
-#endif /* HAVE_IPV6 */
apply_mask (&p);
@@ -4330,17 +4343,16 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,
const char *rd_str, const char *tag_str,
const char *rmap_str)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
struct prefix p;
struct prefix_rd prd;
- struct bgp *bgp;
struct bgp_node *prn;
struct bgp_node *rn;
struct bgp_table *table;
struct bgp_static *bgp_static;
u_char tag[3];
-
- bgp = vty->index;
+ afi_t afi;
ret = str2prefix (ip_str, &p);
if (! ret)
@@ -4363,11 +4375,19 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,
vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
return CMD_WARNING;
}
-
- prn = bgp_node_get (bgp->route[AFI_IP][safi],
+ if (p.family == AF_INET)
+ afi = AFI_IP;
+ else if (p.family == AF_INET6)
+ afi = AFI_IP6;
+ else
+ {
+ vty_out (vty, "%% Non Supported prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ prn = bgp_node_get (bgp->route[afi][safi],
(struct prefix *)&prd);
if (prn->info == NULL)
- prn->info = bgp_table_init (AFI_IP, safi);
+ prn->info = bgp_table_init (afi, safi);
else
bgp_unlock_node (prn);
table = prn->info;
@@ -4400,7 +4420,7 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,
rn->info = bgp_static;
bgp_static->valid = 1;
- bgp_static_update_safi (bgp, &p, bgp_static, AFI_IP, safi);
+ bgp_static_update_safi (bgp, &p, bgp_static, afi, safi);
}
return CMD_SUCCESS;
@@ -4411,8 +4431,8 @@ int
bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,
const char *rd_str, const char *tag_str)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
- struct bgp *bgp;
struct prefix p;
struct prefix_rd prd;
struct bgp_node *prn;
@@ -4421,8 +4441,6 @@ bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,
struct bgp_static *bgp_static;
u_char tag[3];
- bgp = vty->index;
-
/* Convert IP prefix string to struct prefix. */
ret = str2prefix (ip_str, &p);
if (! ret)
@@ -4473,9 +4491,10 @@ bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,
}
static int
-bgp_table_map_set (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
+bgp_table_map_set (struct vty *vty, afi_t afi, safi_t safi,
const char *rmap_name)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct bgp_rmap *rmap;
rmap = &bgp->table_map[afi][safi];
@@ -4500,9 +4519,10 @@ bgp_table_map_set (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
}
static int
-bgp_table_map_unset (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
+bgp_table_map_unset (struct vty *vty, afi_t afi, safi_t safi,
const char *rmap_name)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct bgp_rmap *rmap;
rmap = &bgp->table_map[afi][safi];
@@ -4536,26 +4556,30 @@ DEFUN (bgp_table_map,
"BGP table to RIB route download filter\n"
"Name of the route map\n")
{
- return bgp_table_map_set (vty, vty->index,
- bgp_node_afi (vty), bgp_node_safi (vty), argv[0]);
+ int idx_word = 1;
+ return bgp_table_map_set (vty,
+ bgp_node_afi (vty), bgp_node_safi (vty), argv[idx_word]->arg);
}
DEFUN (no_bgp_table_map,
no_bgp_table_map_cmd,
"no table-map WORD",
+ NO_STR
"BGP table to RIB route download filter\n"
"Name of the route map\n")
{
- return bgp_table_map_unset (vty, vty->index,
- bgp_node_afi (vty), bgp_node_safi (vty), argv[0]);
+ int idx_word = 2;
+ return bgp_table_map_unset (vty,
+ bgp_node_afi (vty), bgp_node_safi (vty), argv[idx_word]->arg);
}
DEFUN (bgp_network,
bgp_network_cmd,
"network A.B.C.D/M",
"Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+ "IPv4 prefix\n")
{
- return bgp_static_set (vty, vty->index, argv[0],
+ int idx_ipv4_prefixlen = 1;
+ return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
AFI_IP, bgp_node_safi (vty), NULL, 0);
}
@@ -4563,22 +4587,25 @@ DEFUN (bgp_network_route_map,
bgp_network_route_map_cmd,
"network A.B.C.D/M route-map WORD",
"Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "IPv4 prefix\n"
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- return bgp_static_set (vty, vty->index, argv[0],
- AFI_IP, bgp_node_safi (vty), argv[1], 0);
+ int idx_ipv4_prefixlen = 1;
+ int idx_word = 3;
+ return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
+ AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
}
DEFUN (bgp_network_backdoor,
bgp_network_backdoor_cmd,
"network A.B.C.D/M backdoor",
"Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "IPv4 prefix\n"
"Specify a BGP backdoor route\n")
{
- return bgp_static_set (vty, vty->index, argv[0], AFI_IP, SAFI_UNICAST,
+ int idx_ipv4_prefixlen = 1;
+ return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP, SAFI_UNICAST,
NULL, 1);
}
@@ -4590,17 +4617,19 @@ DEFUN (bgp_network_mask,
"Network mask\n"
"Network mask\n")
{
+ int idx_ipv4 = 1;
+ int idx_ipv4_2 = 3;
int ret;
char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
if (! ret)
{
vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_static_set (vty, vty->index, prefix_str,
+ return bgp_static_set (vty, prefix_str,
AFI_IP, bgp_node_safi (vty), NULL, 0);
}
@@ -4614,18 +4643,21 @@ DEFUN (bgp_network_mask_route_map,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
+ int idx_ipv4 = 1;
+ int idx_ipv4_2 = 3;
+ int idx_word = 5;
int ret;
char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
if (! ret)
{
vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[2], 0);
+ return bgp_static_set (vty, prefix_str,
+ AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
}
DEFUN (bgp_network_mask_backdoor,
@@ -4637,17 +4669,19 @@ DEFUN (bgp_network_mask_backdoor,
"Network mask\n"
"Specify a BGP backdoor route\n")
{
+ int idx_ipv4 = 1;
+ int idx_ipv4_2 = 3;
int ret;
char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
if (! ret)
{
vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
+ return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
NULL, 1);
}
@@ -4657,17 +4691,18 @@ DEFUN (bgp_network_mask_natural,
"Specify a network to announce via BGP\n"
"Network number\n")
{
+ int idx_ipv4 = 1;
int ret;
char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
+ ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
if (! ret)
{
vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_static_set (vty, vty->index, prefix_str,
+ return bgp_static_set (vty, prefix_str,
AFI_IP, bgp_node_safi (vty), NULL, 0);
}
@@ -4679,18 +4714,20 @@ DEFUN (bgp_network_mask_natural_route_map,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
+ int idx_ipv4 = 1;
+ int idx_word = 3;
int ret;
char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
+ ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
if (! ret)
{
vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[1], 0);
+ return bgp_static_set (vty, prefix_str,
+ AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
}
DEFUN (bgp_network_mask_natural_backdoor,
@@ -4700,138 +4737,97 @@ DEFUN (bgp_network_mask_natural_backdoor,
"Network number\n"
"Specify a BGP backdoor route\n")
{
+ int idx_ipv4 = 1;
int ret;
char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
+ ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
if (! ret)
{
vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
+ return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
NULL, 1);
}
DEFUN (no_bgp_network,
no_bgp_network_cmd,
- "no network A.B.C.D/M",
+ "no network A.B.C.D/M [<backdoor|route-map WORD>]",
NO_STR
"Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+ "IPv4 prefix\n"
+ "Specify a BGP backdoor route\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
{
- return bgp_static_unset (vty, vty->index, argv[0], AFI_IP,
+ int idx_ipv4_prefixlen = 2;
+ return bgp_static_unset (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
bgp_node_safi (vty));
}
-ALIAS (no_bgp_network,
- no_bgp_network_route_map_cmd,
- "no network A.B.C.D/M route-map WORD",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
-
-ALIAS (no_bgp_network,
- no_bgp_network_backdoor_cmd,
- "no network A.B.C.D/M backdoor",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Specify a BGP backdoor route\n")
-
DEFUN (no_bgp_network_mask,
no_bgp_network_mask_cmd,
- "no network A.B.C.D mask A.B.C.D",
+ "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
NO_STR
"Specify a network to announce via BGP\n"
"Network number\n"
"Network mask\n"
- "Network mask\n")
+ "Network mask\n"
+ "Specify a BGP backdoor route\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
{
+ int idx_ipv4 = 2;
+ int idx_ipv4_2 = 4;
int ret;
char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
if (! ret)
{
vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
+ return bgp_static_unset (vty, prefix_str, AFI_IP,
bgp_node_safi (vty));
}
-ALIAS (no_bgp_network_mask,
- no_bgp_network_mask_route_map_cmd,
- "no network A.B.C.D mask A.B.C.D route-map WORD",
+DEFUN (no_bgp_network_mask_natural,
+ no_bgp_network_mask_natural_cmd,
+ "no network A.B.C.D [<backdoor|route-map WORD>]",
NO_STR
"Specify a network to announce via BGP\n"
"Network number\n"
- "Network mask\n"
- "Network mask\n"
+ "Specify a BGP backdoor route\n"
"Route-map to modify the attributes\n"
"Name of the route map\n")
-
-ALIAS (no_bgp_network_mask,
- no_bgp_network_mask_backdoor_cmd,
- "no network A.B.C.D mask A.B.C.D backdoor",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Specify a BGP backdoor route\n")
-
-DEFUN (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_cmd,
- "no network A.B.C.D",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n")
{
+ int idx_ipv4 = 2;
int ret;
char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
+ ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
if (! ret)
{
vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
+ return bgp_static_unset (vty, prefix_str, AFI_IP,
bgp_node_safi (vty));
}
-ALIAS (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_route_map_cmd,
- "no network A.B.C.D route-map WORD",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
-
-ALIAS (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_backdoor_cmd,
- "no network A.B.C.D backdoor",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Specify a BGP backdoor route\n")
-
-#ifdef HAVE_IPV6
DEFUN (ipv6_bgp_network,
ipv6_bgp_network_cmd,
"network X:X::X:X/M",
"Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n")
+ "IPv6 prefix\n")
{
- return bgp_static_set (vty, vty->index, argv[0], AFI_IP6, bgp_node_safi(vty),
+ int idx_ipv6_prefixlen = 1;
+ return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty),
NULL, 0);
}
@@ -4839,50 +4835,28 @@ DEFUN (ipv6_bgp_network_route_map,
ipv6_bgp_network_route_map_cmd,
"network X:X::X:X/M route-map WORD",
"Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n"
+ "IPv6 prefix\n"
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- return bgp_static_set (vty, vty->index, argv[0], AFI_IP6,
- bgp_node_safi (vty), argv[1], 0);
+ int idx_ipv6_prefixlen = 1;
+ int idx_word = 3;
+ return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
+ bgp_node_safi (vty), argv[idx_word]->arg, 0);
}
DEFUN (no_ipv6_bgp_network,
no_ipv6_bgp_network_cmd,
- "no network X:X::X:X/M",
+ "no network X:X::X:X/M [route-map WORD]",
NO_STR
"Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n")
-{
- return bgp_static_unset (vty, vty->index, argv[0], AFI_IP6, bgp_node_safi(vty));
-}
-
-ALIAS (no_ipv6_bgp_network,
- no_ipv6_bgp_network_route_map_cmd,
- "no network X:X::X:X/M route-map WORD",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n"
+ "IPv6 prefix\n"
"Route-map to modify the attributes\n"
"Name of the route map\n")
-
-ALIAS (ipv6_bgp_network,
- old_ipv6_bgp_network_cmd,
- "ipv6 bgp network X:X::X:X/M",
- IPV6_STR
- BGP_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
-
-ALIAS (no_ipv6_bgp_network,
- old_no_ipv6_bgp_network_cmd,
- "no ipv6 bgp network X:X::X:X/M",
- NO_STR
- IPV6_STR
- BGP_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
-#endif /* HAVE_IPV6 */
+{
+ int idx_ipv6_prefixlen = 2;
+ return bgp_static_unset (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty));
+}
/* Aggreagete address:
@@ -5388,10 +5362,10 @@ static int
bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
afi_t afi, safi_t safi)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
struct prefix p;
struct bgp_node *rn;
- struct bgp *bgp;
struct bgp_aggregate *aggregate;
/* Convert string to prefix structure. */
@@ -5403,9 +5377,6 @@ bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
}
apply_mask (&p);
- /* Get BGP structure. */
- bgp = vty->index;
-
/* Old configuration check. */
rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
if (! rn)
@@ -5435,10 +5406,10 @@ bgp_aggregate_set (struct vty *vty, const char *prefix_str,
afi_t afi, safi_t safi,
u_char summary_only, u_char as_set)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
struct prefix p;
struct bgp_node *rn;
- struct bgp *bgp;
struct bgp_aggregate *aggregate;
/* Convert string to prefix structure. */
@@ -5450,9 +5421,6 @@ bgp_aggregate_set (struct vty *vty, const char *prefix_str,
}
apply_mask (&p);
- /* Get BGP structure. */
- bgp = vty->index;
-
/* Old configuration check. */
rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
@@ -5487,137 +5455,46 @@ bgp_aggregate_set (struct vty *vty, const char *prefix_str,
DEFUN (aggregate_address,
aggregate_address_cmd,
- "aggregate-address A.B.C.D/M",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
-{
- return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty), 0, 0);
-}
-
-DEFUN (aggregate_address_mask,
- aggregate_address_mask_cmd,
- "aggregate-address A.B.C.D A.B.C.D",
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n")
-{
- int ret;
- char prefix_str[BUFSIZ];
-
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
-
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
- 0, 0);
-}
-
-DEFUN (aggregate_address_summary_only,
- aggregate_address_summary_only_cmd,
- "aggregate-address A.B.C.D/M summary-only",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
-{
- return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
- AGGREGATE_SUMMARY_ONLY, 0);
-}
-
-DEFUN (aggregate_address_mask_summary_only,
- aggregate_address_mask_summary_only_cmd,
- "aggregate-address A.B.C.D A.B.C.D summary-only",
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Filter more specific routes from updates\n")
-{
- int ret;
- char prefix_str[BUFSIZ];
-
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
-
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
- AGGREGATE_SUMMARY_ONLY, 0);
-}
-
-DEFUN (aggregate_address_as_set,
- aggregate_address_as_set_cmd,
- "aggregate-address A.B.C.D/M as-set",
+ "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
+ "Generate AS set path information\n"
+ "Filter more specific routes from updates\n"
+ "Filter more specific routes from updates\n"
"Generate AS set path information\n")
{
- return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
- 0, AGGREGATE_AS_SET);
+ int idx = 0;
+ argv_find (argv, argc, "A.B.C.D/M", &idx);
+ char *prefix = argv[idx]->arg;
+ int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
+ idx = 0;
+ int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
+
+ return bgp_aggregate_set (vty, prefix, AFI_IP, bgp_node_safi (vty), summary_only, as_set);
}
-DEFUN (aggregate_address_mask_as_set,
- aggregate_address_mask_as_set_cmd,
- "aggregate-address A.B.C.D A.B.C.D as-set",
+DEFUN (aggregate_address_mask,
+ aggregate_address_mask_cmd,
+ "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
"Configure BGP aggregate entries\n"
"Aggregate address\n"
"Aggregate mask\n"
- "Generate AS set path information\n")
-{
- int ret;
- char prefix_str[BUFSIZ];
-
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
-
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
- 0, AGGREGATE_AS_SET);
-}
-
-
-DEFUN (aggregate_address_as_set_summary,
- aggregate_address_as_set_summary_cmd,
- "aggregate-address A.B.C.D/M as-set summary-only",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
"Generate AS set path information\n"
- "Filter more specific routes from updates\n")
-{
- return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
- AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
-}
-
-ALIAS (aggregate_address_as_set_summary,
- aggregate_address_summary_as_set_cmd,
- "aggregate-address A.B.C.D/M summary-only as-set",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
+ "Filter more specific routes from updates\n"
"Filter more specific routes from updates\n"
"Generate AS set path information\n")
-
-DEFUN (aggregate_address_mask_as_set_summary,
- aggregate_address_mask_as_set_summary_cmd,
- "aggregate-address A.B.C.D A.B.C.D as-set summary-only",
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Generate AS set path information\n"
- "Filter more specific routes from updates\n")
{
- int ret;
- char prefix_str[BUFSIZ];
+ int idx = 0;
+ argv_find (argv, argc, "A.B.C.D", &idx);
+ char *prefix = argv[idx++]->arg;
+ argv_find (argv, argc, "A.B.C.D", &idx);
+ char *mask = argv[idx]->arg;
+ int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
+ idx = 0;
+ int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ char prefix_str[BUFSIZ];
+ int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
if (! ret)
{
@@ -5625,75 +5502,46 @@ DEFUN (aggregate_address_mask_as_set_summary,
return CMD_WARNING;
}
- return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
- AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
+ return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty), summary_only, as_set);
}
-ALIAS (aggregate_address_mask_as_set_summary,
- aggregate_address_mask_summary_as_set_cmd,
- "aggregate-address A.B.C.D A.B.C.D summary-only as-set",
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Filter more specific routes from updates\n"
- "Generate AS set path information\n")
-
DEFUN (no_aggregate_address,
no_aggregate_address_cmd,
- "no aggregate-address A.B.C.D/M",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
-{
- return bgp_aggregate_unset (vty, argv[0], AFI_IP, bgp_node_safi (vty));
-}
-
-ALIAS (no_aggregate_address,
- no_aggregate_address_summary_only_cmd,
- "no aggregate-address A.B.C.D/M summary-only",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
-
-ALIAS (no_aggregate_address,
- no_aggregate_address_as_set_cmd,
- "no aggregate-address A.B.C.D/M as-set",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Generate AS set path information\n")
-
-ALIAS (no_aggregate_address,
- no_aggregate_address_as_set_summary_cmd,
- "no aggregate-address A.B.C.D/M as-set summary-only",
+ "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
"Generate AS set path information\n"
- "Filter more specific routes from updates\n")
-
-ALIAS (no_aggregate_address,
- no_aggregate_address_summary_as_set_cmd,
- "no aggregate-address A.B.C.D/M summary-only as-set",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
+ "Filter more specific routes from updates\n"
"Filter more specific routes from updates\n"
"Generate AS set path information\n")
+{
+ int idx = 0;
+ argv_find (argv, argc, "A.B.C.D/M", &idx);
+ char *prefix = argv[idx]->arg;
+ return bgp_aggregate_unset (vty, prefix, AFI_IP, bgp_node_safi (vty));
+}
DEFUN (no_aggregate_address_mask,
no_aggregate_address_mask_cmd,
- "no aggregate-address A.B.C.D A.B.C.D",
+ "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate address\n"
- "Aggregate mask\n")
+ "Aggregate mask\n"
+ "Generate AS set path information\n"
+ "Filter more specific routes from updates\n"
+ "Filter more specific routes from updates\n"
+ "Generate AS set path information\n")
{
- int ret;
- char prefix_str[BUFSIZ];
+ int idx = 0;
+ argv_find (argv, argc, "A.B.C.D", &idx);
+ char *prefix = argv[idx++]->arg;
+ argv_find (argv, argc, "A.B.C.D", &idx);
+ char *mask = argv[idx]->arg;
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ char prefix_str[BUFSIZ];
+ int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
if (! ret)
{
@@ -5704,123 +5552,34 @@ DEFUN (no_aggregate_address_mask,
return bgp_aggregate_unset (vty, prefix_str, AFI_IP, bgp_node_safi (vty));
}
-ALIAS (no_aggregate_address_mask,
- no_aggregate_address_mask_summary_only_cmd,
- "no aggregate-address A.B.C.D A.B.C.D summary-only",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Filter more specific routes from updates\n")
-
-ALIAS (no_aggregate_address_mask,
- no_aggregate_address_mask_as_set_cmd,
- "no aggregate-address A.B.C.D A.B.C.D as-set",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Generate AS set path information\n")
-
-ALIAS (no_aggregate_address_mask,
- no_aggregate_address_mask_as_set_summary_cmd,
- "no aggregate-address A.B.C.D A.B.C.D as-set summary-only",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Generate AS set path information\n"
- "Filter more specific routes from updates\n")
-
-ALIAS (no_aggregate_address_mask,
- no_aggregate_address_mask_summary_as_set_cmd,
- "no aggregate-address A.B.C.D A.B.C.D summary-only as-set",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Filter more specific routes from updates\n"
- "Generate AS set path information\n")
-
-#ifdef HAVE_IPV6
DEFUN (ipv6_aggregate_address,
ipv6_aggregate_address_cmd,
- "aggregate-address X:X::X:X/M",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
-{
- return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST, 0, 0);
-}
-
-DEFUN (ipv6_aggregate_address_summary_only,
- ipv6_aggregate_address_summary_only_cmd,
- "aggregate-address X:X::X:X/M summary-only",
+ "aggregate-address X:X::X:X/M [summary-only]",
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
"Filter more specific routes from updates\n")
{
- return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST,
- AGGREGATE_SUMMARY_ONLY, 0);
+ int idx = 0;
+ argv_find (argv, argc, "X:X::X:X/M", &idx);
+ char *prefix = argv[idx]->arg;
+ int sum_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
+ return bgp_aggregate_set (vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only, 0);
}
DEFUN (no_ipv6_aggregate_address,
no_ipv6_aggregate_address_cmd,
- "no aggregate-address X:X::X:X/M",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
-{
- return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
-}
-
-DEFUN (no_ipv6_aggregate_address_summary_only,
- no_ipv6_aggregate_address_summary_only_cmd,
- "no aggregate-address X:X::X:X/M summary-only",
+ "no aggregate-address X:X::X:X/M [summary-only]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
"Filter more specific routes from updates\n")
{
- return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
+ int idx = 0;
+ argv_find (argv, argc, "X:X::X:X/M", &idx);
+ char *prefix = argv[idx]->arg;
+ return bgp_aggregate_unset (vty, prefix, AFI_IP6, SAFI_UNICAST);
}
-ALIAS (ipv6_aggregate_address,
- old_ipv6_aggregate_address_cmd,
- "ipv6 bgp aggregate-address X:X::X:X/M",
- IPV6_STR
- BGP_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
-
-ALIAS (ipv6_aggregate_address_summary_only,
- old_ipv6_aggregate_address_summary_only_cmd,
- "ipv6 bgp aggregate-address X:X::X:X/M summary-only",
- IPV6_STR
- BGP_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
-
-ALIAS (no_ipv6_aggregate_address,
- old_no_ipv6_aggregate_address_cmd,
- "no ipv6 bgp aggregate-address X:X::X:X/M",
- NO_STR
- IPV6_STR
- BGP_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
-
-ALIAS (no_ipv6_aggregate_address_summary_only,
- old_no_ipv6_aggregate_address_summary_only_cmd,
- "no ipv6 bgp aggregate-address X:X::X:X/M summary-only",
- NO_STR
- IPV6_STR
- BGP_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
-#endif /* HAVE_IPV6 */
-
/* Redistribute route treatment. */
void
bgp_redistribute_add (struct bgp *bgp, struct prefix *p, const struct in_addr *nexthop,
@@ -5843,14 +5602,12 @@ bgp_redistribute_add (struct bgp *bgp, struct prefix *p, const struct in_addr *n
attr.nexthop = *nexthop;
attr.nh_ifindex = ifindex;
-#ifdef HAVE_IPV6
if (nexthop6)
{
struct attr_extra *extra = bgp_attr_extra_get(&attr);
extra->mp_nexthop_global = *nexthop6;
extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
}
-#endif
attr.med = metric;
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
@@ -6124,7 +5881,8 @@ route_vty_short_status_out (struct vty *vty, struct bgp_info *binfo,
vty_out (vty, " ");
/* Internal route. */
- if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
+ if (binfo->peer &&
+ (binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
vty_out (vty, "i");
else
vty_out (vty, " ");
@@ -6179,12 +5937,10 @@ route_vty_out (struct vty *vty, struct prefix *p,
vty_out (vty, "%s", inet_ntop(af,
&attr->extra->mp_nexthop_global_in, buf, BUFSIZ));
break;
-#if HAVE_IPV6
case AF_INET6:
vty_out (vty, "%s", inet_ntop(af,
&attr->extra->mp_nexthop_global, buf, BUFSIZ));
break;
-#endif
default:
vty_out(vty, "?");
break;
@@ -6380,7 +6136,7 @@ route_vty_out (struct vty *vty, struct prefix *p,
}
else
{
- vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "%s", VTY_NEWLINE);
#if ENABLE_BGP_VNC
/* prints an additional line, indented, with VNC info, if present */
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
@@ -6431,7 +6187,6 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t
else
json_object_string_add(json_net, "nextHop", inet_ntoa (attr->nexthop));
}
-#ifdef HAVE_IPV6
else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
{
char buf[BUFSIZ];
@@ -6439,7 +6194,6 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t
json_object_string_add(json_net, "netHopGloabal", inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
buf, BUFSIZ));
}
-#endif /* HAVE_IPV6 */
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
json_object_int_add(json_net, "metric", attr->med);
@@ -6466,33 +6220,28 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t
safi == SAFI_ENCAP ||
!BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
{
- if (attr->extra &&
- (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
vty_out (vty, "%-16s",
inet_ntoa (attr->extra->mp_nexthop_global_in));
else
vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
}
-#ifdef HAVE_IPV6
else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
{
int len;
char buf[BUFSIZ];
- if (attr->extra)
- {
- len = vty_out (vty, "%s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, BUFSIZ));
- len = 16 - len;
- }
- else
- len = 0;
+
+ assert (attr->extra);
+
+ len = vty_out (vty, "%s",
+ inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
+ buf, BUFSIZ));
+ len = 16 - len;
if (len < 1)
vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
else
vty_out (vty, "%*s", len, " ");
}
-#endif /* HAVE_IPV6 */
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
vty_out (vty, "%10u", attr->med);
else
@@ -6573,7 +6322,6 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
}
}
-#ifdef HAVE_IPV6
else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
{
assert (attr->extra);
@@ -6610,7 +6358,6 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
}
}
-#endif /* HAVE_IPV6 */
}
label = decode_label (binfo->extra->tag);
@@ -6852,9 +6599,7 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
char buf1[BUFSIZ];
struct attr *attr;
int sockunion_vty_out (struct vty *, union sockunion *);
-#ifdef HAVE_CLOCK_MONOTONIC
time_t tbuf;
-#endif
json_object *json_bestpath = NULL;
json_object *json_cluster_list = NULL;
json_object *json_cluster_list_list = NULL;
@@ -7367,7 +7112,12 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
}
}
- /* Line 6 display Originator, Cluster-id */
+ /* Line 6 display Large community */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
+ vty_out (vty, " Large Community: %s%s",
+ attr->extra->lcommunity->str, VTY_NEWLINE);
+
+ /* Line 7 display Originator, Cluster-id */
if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)))
{
@@ -7423,7 +7173,7 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
if (binfo->extra && binfo->extra->damp_info)
bgp_damp_info_vty (vty, binfo, json_path);
- /* Line 7 display Addpath IDs */
+ /* Line 8 display Addpath IDs */
if (binfo->addpath_rx_id || binfo->addpath_tx_id)
{
if (json_paths)
@@ -7478,8 +7228,7 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
}
}
- /* Line 8 display Uptime */
-#ifdef HAVE_CLOCK_MONOTONIC
+ /* Line 9 display Uptime */
tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
if (json_paths)
{
@@ -7490,17 +7239,6 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
}
else
vty_out (vty, " Last update: %s", ctime(&tbuf));
-#else
- if (json_paths)
- {
- json_last_update = json_object_new_object();
- json_object_int_add(json_last_update, "epoch", tbuf);
- json_object_string_add(json_last_update, "string", ctime(&binfo->uptime));
- json_object_object_add(json_path, "lastUpdate", json_last_update);
- }
- else
- vty_out (vty, " Last update: %s", ctime(&binfo->uptime));
-#endif /* HAVE_CLOCK_MONOTONIC */
}
/* We've constructed the json object for this path, add it to the json
@@ -7532,55 +7270,32 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
#define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
#define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
-enum bgp_show_type
-{
- bgp_show_type_normal,
- bgp_show_type_regexp,
- bgp_show_type_prefix_list,
- bgp_show_type_filter_list,
- bgp_show_type_route_map,
- bgp_show_type_neighbor,
- bgp_show_type_cidr_only,
- bgp_show_type_prefix_longer,
- bgp_show_type_community_all,
- bgp_show_type_community,
- bgp_show_type_community_exact,
- bgp_show_type_community_list,
- bgp_show_type_community_list_exact,
- bgp_show_type_flap_statistics,
- bgp_show_type_flap_address,
- bgp_show_type_flap_prefix,
- bgp_show_type_flap_cidr_only,
- bgp_show_type_flap_regexp,
- bgp_show_type_flap_filter_list,
- bgp_show_type_flap_prefix_list,
- bgp_show_type_flap_prefix_longer,
- bgp_show_type_flap_route_map,
- bgp_show_type_flap_neighbor,
- bgp_show_type_dampend_paths,
- bgp_show_type_damp_neighbor
-};
-
static int
-bgp_show_prefix_list (struct vty *vty, const char *name,
+bgp_show_prefix_list (struct vty *vty, struct bgp *bgp,
const char *prefix_list_str, afi_t afi,
safi_t safi, enum bgp_show_type type);
static int
-bgp_show_filter_list (struct vty *vty, const char *name,
+bgp_show_filter_list (struct vty *vty, struct bgp *bgp,
const char *filter, afi_t afi,
safi_t safi, enum bgp_show_type type);
static int
-bgp_show_route_map (struct vty *vty, const char *name,
+bgp_show_route_map (struct vty *vty, struct bgp *bgp,
const char *rmap_str, afi_t afi,
safi_t safi, enum bgp_show_type type);
static int
-bgp_show_community_list (struct vty *vty, const char *name,
+bgp_show_community_list (struct vty *vty, struct bgp *bgp,
const char *com, int exact,
afi_t afi, safi_t safi);
static int
-bgp_show_prefix_longer (struct vty *vty, const char *name,
+bgp_show_prefix_longer (struct vty *vty, struct bgp *bgp,
const char *prefix, afi_t afi,
safi_t safi, enum bgp_show_type type);
+static int
+bgp_show_regexp (struct vty *vty, const char *regstr, afi_t afi,
+ safi_t safi, enum bgp_show_type type);
+static int
+bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
+ struct cmd_token **argv, int exact, afi_t afi, safi_t safi);
static int
bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
@@ -7629,14 +7344,6 @@ bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
{
total_count++;
if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_address
- || type == bgp_show_type_flap_prefix
- || type == bgp_show_type_flap_cidr_only
- || type == bgp_show_type_flap_regexp
- || type == bgp_show_type_flap_filter_list
- || type == bgp_show_type_flap_prefix_list
- || type == bgp_show_type_flap_prefix_longer
- || type == bgp_show_type_flap_route_map
|| type == bgp_show_type_flap_neighbor
|| type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor)
@@ -7644,32 +7351,28 @@ bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
if (!(ri->extra && ri->extra->damp_info))
continue;
}
- if (type == bgp_show_type_regexp
- || type == bgp_show_type_flap_regexp)
+ if (type == bgp_show_type_regexp)
{
regex_t *regex = output_arg;
if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
continue;
}
- if (type == bgp_show_type_prefix_list
- || type == bgp_show_type_flap_prefix_list)
+ if (type == bgp_show_type_prefix_list)
{
struct prefix_list *plist = output_arg;
if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
continue;
}
- if (type == bgp_show_type_filter_list
- || type == bgp_show_type_flap_filter_list)
+ if (type == bgp_show_type_filter_list)
{
struct as_list *as_list = output_arg;
if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
continue;
}
- if (type == bgp_show_type_route_map
- || type == bgp_show_type_flap_route_map)
+ if (type == bgp_show_type_route_map)
{
struct route_map *rmap = output_arg;
struct bgp_info binfo;
@@ -7693,11 +7396,11 @@ bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
{
union sockunion *su = output_arg;
- if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
+ if (ri->peer == NULL ||
+ ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
continue;
}
- if (type == bgp_show_type_cidr_only
- || type == bgp_show_type_flap_cidr_only)
+ if (type == bgp_show_type_cidr_only)
{
u_int32_t destination;
@@ -7709,8 +7412,7 @@ bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
continue;
}
- if (type == bgp_show_type_prefix_longer
- || type == bgp_show_type_flap_prefix_longer)
+ if (type == bgp_show_type_prefix_longer)
{
struct prefix *p = output_arg;
@@ -7752,17 +7454,26 @@ bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
if (! community_list_exact_match (ri->attr->community, list))
continue;
}
- if (type == bgp_show_type_flap_address
- || type == bgp_show_type_flap_prefix)
+ if (type == bgp_show_type_lcommunity)
{
- struct prefix *p = output_arg;
+ struct lcommunity *lcom = output_arg;
- if (! prefix_match (&rn->p, p))
+ if (! ri->attr->extra || ! ri->attr->extra->lcommunity ||
+ ! lcommunity_match (ri->attr->extra->lcommunity, lcom))
continue;
+ }
+ if (type == bgp_show_type_lcommunity_list)
+ {
+ struct community_list *list = output_arg;
- if (type == bgp_show_type_flap_prefix)
- if (p->prefixlen != rn->p.prefixlen)
- continue;
+ if (! ri->attr->extra ||
+ ! lcommunity_list_match (ri->attr->extra->lcommunity, list))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity_all)
+ {
+ if (! ri->attr->extra || ! ri->attr->extra->lcommunity)
+ continue;
}
if (type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor)
@@ -7781,14 +7492,6 @@ bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
|| type == bgp_show_type_damp_neighbor)
vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE);
else if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_address
- || type == bgp_show_type_flap_prefix
- || type == bgp_show_type_flap_cidr_only
- || type == bgp_show_type_flap_regexp
- || type == bgp_show_type_flap_filter_list
- || type == bgp_show_type_flap_prefix_list
- || type == bgp_show_type_flap_prefix_longer
- || type == bgp_show_type_flap_route_map
|| type == bgp_show_type_flap_neighbor)
vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE);
else
@@ -7800,14 +7503,6 @@ bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
|| type == bgp_show_type_damp_neighbor)
damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, use_json, json_paths);
else if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_address
- || type == bgp_show_type_flap_prefix
- || type == bgp_show_type_flap_cidr_only
- || type == bgp_show_type_flap_regexp
- || type == bgp_show_type_flap_filter_list
- || type == bgp_show_type_flap_prefix_list
- || type == bgp_show_type_flap_prefix_longer
- || type == bgp_show_type_flap_route_map
|| type == bgp_show_type_flap_neighbor)
flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, use_json, json_paths);
else
@@ -7869,6 +7564,18 @@ bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
+ /* use MPLS and ENCAP specific shows until they are merged */
+ if (safi == SAFI_MPLS_VPN)
+ {
+ return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg,
+ 0, use_json);
+ }
+ if (safi == SAFI_ENCAP)
+ {
+ return bgp_show_encap(vty, afi, NULL, type, output_arg,
+ 0);
+ }
+
table = bgp->rib[afi][safi];
@@ -8164,1101 +7871,458 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
/* Display specified route of Main RIB */
static int
-bgp_show_route (struct vty *vty, const char *view_name, const char *ip_str,
+bgp_show_route (struct vty *vty, struct bgp *bgp, const char *ip_str,
afi_t afi, safi_t safi, struct prefix_rd *prd,
int prefix_check, enum bgp_path_type pathtype,
u_char use_json)
{
- struct bgp *bgp;
+ if (!bgp)
+ bgp = bgp_get_default ();
- /* BGP structure lookup. */
- if (view_name)
- {
- bgp = bgp_lookup_by_name (view_name);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP instance %s%s", view_name, VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- else
- {
- bgp = bgp_get_default ();
- if (bgp == NULL)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
return bgp_show_route_in_table (vty, bgp, bgp->rib[afi][safi], ip_str,
afi, safi, prd, prefix_check, pathtype,
use_json);
}
-/* BGP route print out function. */
-DEFUN (show_ip_bgp,
- show_ip_bgp_cmd,
- "show ip bgp {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "JavaScript Object Notation\n")
-{
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL, use_json(argc, argv));
-}
-
-ALIAS (show_ip_bgp,
- show_bgp_ipv4_cmd,
- "show bgp ipv4 {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_ip_bgp_ipv4,
- show_ip_bgp_ipv4_cmd,
- "show ip bgp ipv4 (unicast|multicast) {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
-
- return bgp_show (vty, NULL, AFI_IP,
- bgp_vty_safi_from_arg(argv[0]),
- bgp_show_type_normal, NULL, uj);
-}
-
-ALIAS (show_ip_bgp_ipv4,
- show_bgp_ipv4_safi_cmd,
- "show bgp ipv4 (unicast|multicast) {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_ip_bgp_route,
- show_ip_bgp_route_cmd,
- "show ip bgp A.B.C.D {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Network in the BGP routing table to display\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
-}
-
-DEFUN (show_ip_bgp_route_pathtype,
- show_ip_bgp_route_pathtype_cmd,
- "show ip bgp A.B.C.D (bestpath|multipath) {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
-
- if (strncmp (argv[1], "b", 1) == 0)
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_BESTPATH, uj);
- else
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_MULTIPATH, uj);
-}
-
-DEFUN (show_bgp_ipv4_safi_route_pathtype,
- show_bgp_ipv4_safi_route_pathtype_cmd,
- "show bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
-
- if (strncmp (argv[2], "b", 1) == 0)
- return bgp_show_route (vty, NULL, argv[1], AFI_IP,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 0, BGP_PATH_BESTPATH, uj);
- else
- return bgp_show_route (vty, NULL, argv[1], AFI_IP,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 0, BGP_PATH_MULTIPATH, uj);
-}
-
-DEFUN (show_bgp_ipv4_prefix,
- show_bgp_ipv4_prefix_cmd,
- "show bgp ipv4 A.B.C.D/M {json}",
- SHOW_STR
- BGP_STR
- IP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- JSON_STR)
-{
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json (argc, argv));
-}
-
-DEFUN (show_bgp_ipv6_route,
- show_bgp_ipv6_route_cmd,
- "show bgp ipv6 X:X::X:X {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Network in the BGP routing table to display\n"
- JSON_STR)
-{
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json (argc, argv));
-}
-
-DEFUN (show_bgp_ipv6_prefix,
- show_bgp_ipv6_prefix_cmd,
- "show bgp ipv6 X:X::X:X/M {json}",
- SHOW_STR
- BGP_STR
- IP_STR
- "IPv6 prefix <network>/<length>\n"
- JSON_STR)
-{
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json (argc,argv));
-}
-
-DEFUN (show_ip_bgp_ipv4_route,
- show_ip_bgp_ipv4_route_cmd,
- "show ip bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "Network in the BGP routing table to display\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
-
- return bgp_show_route (vty, NULL, argv[1], AFI_IP,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 0, BGP_PATH_ALL, uj);
-}
-
-ALIAS (show_ip_bgp_ipv4_route,
- show_bgp_ipv4_safi_route_cmd,
- "show bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D {json}",
- SHOW_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "Network in the BGP routing table to display\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_bgp_ipv4_safi_rd_route,
- show_bgp_ipv4_safi_rd_route_cmd,
- "show bgp ipv4 (encap|vpn) rd ASN:nn_or_IP-address:nn A.B.C.D {json}",
- SHOW_STR
- BGP_STR
- "Address Family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- "Display information for a route distinguisher\n"
- "ENCAP Route Distinguisher\n"
- "Network in the BGP routing table to display\n")
+static int
+bgp_show_lcommunity (struct vty *vty, struct bgp *bgp, int argc,
+ struct cmd_token **argv, afi_t afi, safi_t safi, u_char uj)
{
- int ret;
- struct prefix_rd prd;
- safi_t safi;
+ struct lcommunity *lcom;
+ struct buffer *b;
+ int i;
+ char *str;
+ int first = 0;
- if (bgp_parse_safi(argv[0], &safi)) {
- vty_out (vty, "Error: Bad SAFI: %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
- ret = str2prefix_rd (argv[1], &prd);
- if (! ret)
+ b = buffer_new (1024);
+ for (i = 0; i < argc; i++)
{
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
+ if (first)
+ buffer_putc (b, ' ');
+ else
+ {
+ if (strmatch (argv[i]->text, "<AA:BB:CC>"))
+ {
+ first = 1;
+ buffer_putstr (b, argv[i]->arg);
+ }
+ }
}
- return bgp_show_route (vty, NULL, argv[2], AFI_IP, safi, &prd, 0, BGP_PATH_ALL, use_json (argc, argv));
-}
+ buffer_putc (b, '\0');
-DEFUN (show_bgp_ipv6_safi_rd_route,
- show_bgp_ipv6_safi_rd_route_cmd,
- "show bgp ipv6 (encap|vpn) rd ASN:nn_or_IP-address:nn X:X::X:X {json}",
- SHOW_STR
- BGP_STR
- "Address Family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- "Display information for a route distinguisher\n"
- "ENCAP Route Distinguisher\n"
- "Network in the BGP routing table to display\n")
-{
- int ret;
- struct prefix_rd prd;
- safi_t safi;
+ str = buffer_getstr (b);
+ buffer_free (b);
- if (bgp_parse_safi(argv[0], &safi)) {
- vty_out (vty, "Error: Bad SAFI: %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
- ret = str2prefix_rd (argv[1], &prd);
- if (! ret)
+ lcom = lcommunity_str2com (str);
+ XFREE (MTYPE_TMP, str);
+ if (! lcom)
{
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ vty_out (vty, "%% Large-community malformed: %s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_show_route (vty, NULL, argv[2], AFI_IP6, SAFI_ENCAP, &prd, 0, BGP_PATH_ALL, use_json (argc, argv));
-}
-
-DEFUN (show_bgp_ipv4_safi_rd_prefix,
- show_bgp_ipv4_safi_rd_prefix_cmd,
- "show bgp ipv4 (encap|vpn) rd ASN:nn_or_IP-address:nn A.B.C.D/M {json}",
- SHOW_STR
- BGP_STR
- "Address Family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- "Display information for a route distinguisher\n"
- "ENCAP Route Distinguisher\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
-{
- int ret;
- struct prefix_rd prd;
- safi_t safi;
-
- if (bgp_parse_safi(argv[0], &safi)) {
- vty_out (vty, "Error: Bad SAFI: %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ret = str2prefix_rd (argv[1], &prd);
- if (! ret)
- {
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show_route (vty, NULL, argv[2], AFI_IP, safi, &prd, 1, BGP_PATH_ALL, use_json (argc, argv));
+ return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom, uj);
}
-DEFUN (show_bgp_ipv6_safi_rd_prefix,
- show_bgp_ipv6_safi_rd_prefix_cmd,
- "show bgp ipv6 (encap|vpn) rd ASN:nn_or_IP-address:nn X:X::X:X/M {json}",
- SHOW_STR
- BGP_STR
- "Address Family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- "Display information for a route distinguisher\n"
- "ENCAP Route Distinguisher\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+static int
+bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom,
+ afi_t afi, safi_t safi, u_char uj)
{
- int ret;
- struct prefix_rd prd;
- safi_t safi;
-
- if (bgp_parse_safi(argv[0], &safi)) {
- vty_out (vty, "Error: Bad SAFI: %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
+ struct community_list *list;
- ret = str2prefix_rd (argv[1], &prd);
- if (! ret)
+ list = community_list_lookup (bgp_clist, lcom, LARGE_COMMUNITY_LIST_MASTER);
+ if (list == NULL)
{
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ vty_out (vty, "%% %s is not a valid large-community-list name%s", lcom,
+ VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_show_route (vty, NULL, argv[2], AFI_IP6, safi, &prd, 1, BGP_PATH_ALL, use_json (argc, argv));
-}
-
-DEFUN (show_ip_bgp_prefix,
- show_ip_bgp_prefix_cmd,
- "show ip bgp A.B.C.D/M {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json(argc, argv));
-}
-DEFUN (show_ip_bgp_prefix_pathtype,
- show_ip_bgp_prefix_pathtype_cmd,
- "show ip bgp A.B.C.D/M (bestpath|multipath) {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- if (strncmp (argv[1], "b", 1) == 0)
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_BESTPATH, uj);
- else
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_MULTIPATH, uj);
-}
-
-DEFUN (show_ip_bgp_ipv4_prefix,
- show_ip_bgp_ipv4_prefix_cmd,
- "show ip bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D/M {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
-
- return bgp_show_route (vty, NULL, argv[1], AFI_IP,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 1, BGP_PATH_ALL, uj);
+ return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_list, list, uj);
}
-ALIAS (show_ip_bgp_ipv4_prefix,
- show_bgp_ipv4_safi_prefix_cmd,
- "show bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D/M {json}",
- SHOW_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_ip_bgp_ipv4_prefix_pathtype,
- show_ip_bgp_ipv4_prefix_pathtype_cmd,
- "show ip bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D/M (bestpath|multipath) {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
-
- if (strncmp (argv[2], "b", 1) == 0)
- return bgp_show_route (vty, NULL, argv[1], AFI_IP,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 1, BGP_PATH_BESTPATH, uj);
- else
- return bgp_show_route (vty, NULL, argv[1], AFI_IP,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 1, BGP_PATH_MULTIPATH, uj);
-}
-
-ALIAS (show_ip_bgp_ipv4_prefix_pathtype,
- show_bgp_ipv4_safi_prefix_pathtype_cmd,
- "show bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D/M (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-
-
-DEFUN (show_ip_bgp_view,
- show_ip_bgp_instance_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " {json}",
+DEFUN (show_ip_bgp_large_community_list,
+ show_ip_bgp_large_community_list_cmd,
+ "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community-list <(1-500)|WORD> [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "JavaScript Object Notation\n")
+ "Address Family\n"
+ "Address Family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the large-community-list\n"
+ "large-community-list number\n"
+ "large-community-list name\n"
+ JSON_STR)
{
- struct bgp *bgp;
+ char *vrf = NULL;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ int idx = 0;
+
+ if (argv_find (argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
+ vrf = argv[++idx]->arg;
+ if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
+ {
+ afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
+ if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
+ safi = bgp_vty_safi_from_arg (argv[idx]->text);
+ }
- /* BGP structure lookup. */
- bgp = bgp_lookup_by_name (argv[1]);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP instance %s%s", argv[1], VTY_NEWLINE);
- return CMD_WARNING;
- }
+ int uj = use_json (argc, argv);
- return bgp_show (vty, bgp, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL, use_json(argc, argv));
-}
-
-DEFUN (show_ip_bgp_instance_all,
- show_ip_bgp_instance_all_cmd,
- "show ip bgp " BGP_INSTANCE_ALL_CMD " {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_ALL_HELP_STR
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
+ struct bgp *bgp = bgp_lookup_by_name (vrf);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- bgp_show_all_instances_routes_vty (vty, AFI_IP, SAFI_UNICAST, uj);
- return CMD_SUCCESS;
+ argv_find (argv, argc, "large-community-list", &idx);
+ return bgp_show_lcommunity_list (vty, bgp, argv[idx+1]->arg, afi, safi, uj);
}
-
-DEFUN (show_ip_bgp_instance_route,
- show_ip_bgp_instance_route_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " A.B.C.D {json}",
+DEFUN (show_ip_bgp_large_community,
+ show_ip_bgp_large_community_cmd,
+ "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community [AA:BB:CC] [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "Network in the BGP routing table to display\n"
- "JavaScript Object Notation\n")
+ "Address Family\n"
+ "Address Family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Display routes matching the large-communities\n"
+ "List of large-community numbers\n"
+ JSON_STR)
{
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
-}
+ char *vrf = NULL;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ int idx = 0;
+
+ if (argv_find (argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
+ vrf = argv[++idx]->arg;
+ if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
+ {
+ afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
+ if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
+ safi = bgp_vty_safi_from_arg (argv[idx]->text);
+ }
-DEFUN (show_ip_bgp_instance_route_pathtype,
- show_ip_bgp_instance_route_pathtype_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " A.B.C.D (bestpath|multipath) {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Network in the BGP routing table to display\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
+ int uj = use_json (argc, argv);
+
+ struct bgp *bgp = bgp_lookup_by_name (vrf);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- if (strncmp (argv[3], "b", 1) == 0)
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_BESTPATH, uj);
+ argv_find (argv, argc, "large-community", &idx);
+ if (strmatch(argv[idx+1]->text, "AA:BB:CC"))
+ return bgp_show_lcommunity (vty, bgp, argc, argv, afi, safi, uj);
else
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_MULTIPATH, uj);
+ return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_all, NULL, uj);
}
-DEFUN (show_ip_bgp_instance_prefix,
- show_ip_bgp_instance_prefix_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " A.B.C.D/M {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json(argc, argv));
-}
+static int bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi);
-DEFUN (show_ip_bgp_instance_prefix_pathtype,
- show_ip_bgp_instance_prefix_pathtype_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " A.B.C.D/M (bestpath|multipath) {json}",
+/* BGP route print out function. */
+DEFUN (show_ip_bgp,
+ show_ip_bgp_cmd,
+ "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]\
+ [<\
+ cidr-only\
+ |dampening <flap-statistics|dampened-paths|parameters>\
+ |route-map WORD\
+ |prefix-list WORD\
+ |filter-list WORD\
+ |statistics\
+ |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
+ |community-list <(1-500)|WORD> [exact-match]\
+ |A.B.C.D/M longer-prefixes\
+ |X:X::X:X/M longer-prefixes>\
+ ] [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
+ BGP_AFI_HELP_STR
+ BGP_SAFI_HELP_STR
+ "Display only routes with non-natural netmasks\n"
+ "Display detailed information about dampening\n"
+ "Display flap statistics of routes\n"
+ "Display paths suppressed due to dampening\n"
+ "Display detail of configured dampening parameters\n"
+ "Display routes matching the route-map\n"
+ "A route-map to match on\n"
+ "Display routes conforming to the prefix-list\n"
+ "Prefix-list name\n"
+ "Display routes conforming to the filter-list\n"
+ "Regular expression access list name\n"
+ "BGP RIB advertisement statistics\n"
+ "Display routes matching the communities\n"
+ COMMUNITY_AANN_STR
+ "Do not send outside local AS (well-known community)\n"
+ "Do not advertise to any peer (well-known community)\n"
+ "Do not export to next AS (well-known community)\n"
+ "Exact match of the communities\n"
+ "Display routes matching the community-list\n"
+ "community-list number\n"
+ "community-list name\n"
+ "Exact match of the communities\n"
+ "IPv4 prefix\n"
+ "Display route and more specific routes\n"
+ "IPv6 prefix\n"
+ "Display route and more specific routes\n"
+ JSON_STR)
{
- u_char uj = use_json(argc, argv);
- if (strncmp (argv[3], "b", 1) == 0)
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_BESTPATH, uj);
- else
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_MULTIPATH, uj);
-}
+ vrf_id_t vrf = VRF_DEFAULT;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ int exact_match = 0;
+ enum bgp_show_type sh_type = bgp_show_type_normal;
+ struct bgp *bgp = NULL;
+ int idx = 0;
-#ifdef HAVE_IPV6
-DEFUN (show_bgp,
- show_bgp_cmd,
- "show bgp {json}",
- SHOW_STR
- BGP_STR
- "JavaScript Object Notation\n")
-{
- return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal,
- NULL, use_json(argc, argv));
-}
+ bgp_vty_find_and_parse_afi_safi_vrf (vty, argv, argc, &idx, &afi, &safi, &vrf);
+ if (!idx)
+ return CMD_WARNING;
-ALIAS (show_bgp,
- show_bgp_ipv6_cmd,
- "show bgp ipv6 {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "JavaScript Object Notation\n")
+ int uj = use_json (argc, argv);
+ if (uj) argc--;
-DEFUN (show_bgp_ipv6_safi,
- show_bgp_ipv6_safi_cmd,
- "show bgp ipv6 (unicast|multicast) {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
+ bgp = bgp_lookup_by_vrf_id (vrf);
+ if (bgp == NULL)
+ {
+ if (vrf == VRF_DEFAULT)
+ vty_out (vty, "Can't find BGP instance (default)%s", VTY_NEWLINE);
+ else
+ vty_out (vty, "Can't find BGP instance %d%s", vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_show (vty, NULL, AFI_IP6,
- bgp_vty_safi_from_arg(argv[0]),
- bgp_show_type_normal, NULL, uj);
-}
+ if (argv_find(argv, argc, "cidr-only", &idx))
+ return bgp_show (vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj);
-static void
-bgp_show_ipv6_bgp_deprecate_warning (struct vty *vty)
-{
- vty_out (vty, "WARNING: The 'show ipv6 bgp' parse tree will be deprecated in our"
- " next release%sPlese use 'show bgp ipv6' instead%s%s",
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
-}
+ if (argv_find(argv, argc, "dampening", &idx))
+ {
+ if (argv_find (argv, argc, "dampened-paths", &idx))
+ return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj);
+ else if (argv_find (argv, argc, "flap-statistics", &idx))
+ return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj);
+ else if (argv_find (argv, argc, "parameters", &idx))
+ return bgp_show_dampening_parameters (vty, afi, safi);
+ }
-/* old command */
-DEFUN (show_ipv6_bgp,
- show_ipv6_bgp_cmd,
- "show ipv6 bgp {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "JavaScript Object Notation\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal,
- NULL, use_json(argc, argv));
-}
+ if (argv_find(argv, argc, "prefix-list", &idx))
+ return bgp_show_prefix_list (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_list);
-DEFUN (show_bgp_route,
- show_bgp_route_cmd,
- "show bgp X:X::X:X {json}",
- SHOW_STR
- BGP_STR
- "Network in the BGP routing table to display\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
-}
+ if (argv_find(argv, argc, "filter-list", &idx))
+ return bgp_show_filter_list (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_filter_list);
-DEFUN (show_bgp_ipv6_safi_route,
- show_bgp_ipv6_safi_route_cmd,
- "show bgp ipv6 "BGP_SAFI_CMD_STR" X:X::X:X {json}",
- SHOW_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "Network in the BGP routing table to display\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
+ if (argv_find(argv, argc, "statistics", &idx))
+ return bgp_table_stats (vty, bgp, afi, safi);
- return bgp_show_route (vty, NULL, argv[1], AFI_IP6,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 0, BGP_PATH_ALL, uj);
-}
+ if (argv_find(argv, argc, "route-map", &idx))
+ return bgp_show_route_map (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_route_map);
-DEFUN (show_bgp_route_pathtype,
- show_bgp_route_pathtype_cmd,
- "show bgp X:X::X:X (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- "Network in the BGP routing table to display\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- if (strncmp (argv[1], "b", 1) == 0)
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_BESTPATH, uj);
- else
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_MULTIPATH, uj);
-}
+ if (argv_find(argv, argc, "community", &idx))
+ {
+ /* show a specific community */
+ if (argv_find (argv, argc, "local-AS", &idx) ||
+ argv_find (argv, argc, "no-advertise", &idx) ||
+ argv_find (argv, argc, "no-export", &idx))
+ {
+ if (argv_find (argv, argc, "exact_match", &idx))
+ exact_match = 1;
+ return bgp_show_community (vty, bgp, argc, argv, exact_match, afi, safi);
+ }
+ /* show all communities */
+ else
+ return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL, uj);
+ }
-ALIAS (show_bgp_route_pathtype,
- show_bgp_ipv6_route_pathtype_cmd,
- "show bgp ipv6 X:X::X:X (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Network in the BGP routing table to display\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
+ if (argv_find(argv, argc, "community-list", &idx))
+ {
+ const char *clist_number_or_name = argv[++idx]->arg;
+ if (++idx < argc && strmatch (argv[idx]->text, "exact-match"))
+ exact_match = 1;
+ return bgp_show_community_list (vty, bgp, clist_number_or_name, exact_match, afi, safi);
+ }
+ /* prefix-longer */
+ if (argv_find(argv, argc, "A.B.C.D/M", &idx) || argv_find(argv, argc, "X:X::X:X/M", &idx))
+ return bgp_show_prefix_longer (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_longer);
-DEFUN (show_bgp_ipv6_safi_route_pathtype,
- show_bgp_ipv6_safi_route_pathtype_cmd,
- "show bgp ipv6 "BGP_SAFI_CMD_STR" X:X::X:X (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "Network in the BGP routing table to display\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- if (strncmp (argv[2], "b", 1) == 0)
- return bgp_show_route (vty, NULL, argv[1], AFI_IP6,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 0, BGP_PATH_BESTPATH, uj);
+ if (safi == SAFI_MPLS_VPN)
+ return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, uj);
+ else if (safi == SAFI_ENCAP)
+ return bgp_show_encap (vty, afi, NULL, bgp_show_type_normal, NULL, 0);
else
- return bgp_show_route (vty, NULL, argv[1], AFI_IP6,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 0, BGP_PATH_MULTIPATH, uj);
+ return bgp_show (vty, bgp, afi, safi, sh_type, NULL, uj);
}
-/* old command */
-DEFUN (show_ipv6_bgp_route,
- show_ipv6_bgp_route_cmd,
- "show ipv6 bgp X:X::X:X {json}",
+DEFUN (show_ip_bgp_route,
+ show_ip_bgp_route_cmd,
+ "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]"
+ "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
SHOW_STR
IP_STR
BGP_STR
+ BGP_INSTANCE_HELP_STR
+ BGP_AFI_HELP_STR
+ BGP_SAFI_HELP_STR
"Network in the BGP routing table to display\n"
- "JavaScript Object Notation\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
-}
-
-DEFUN (show_bgp_prefix,
- show_bgp_prefix_cmd,
- "show bgp X:X::X:X/M {json}",
- SHOW_STR
- BGP_STR
- "IPv6 prefix <network>/<length>\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json(argc, argv));
-}
-
-DEFUN (show_bgp_ipv6_safi_prefix,
- show_bgp_ipv6_safi_prefix_cmd,
- "show bgp ipv6 "BGP_SAFI_CMD_STR" X:X::X:X/M {json}",
- SHOW_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
-
- return bgp_show_route (vty, NULL, argv[1], AFI_IP6,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 1, BGP_PATH_ALL, uj);
-}
-
-DEFUN (show_bgp_prefix_pathtype,
- show_bgp_prefix_pathtype_cmd,
- "show bgp X:X::X:X/M (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- "IPv6 prefix <network>/<length>\n"
+ "IPv4 prefix\n"
+ "Network in the BGP routing table to display\n"
+ "IPv6 prefix\n"
"Display only the bestpath\n"
"Display only multipaths\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
- u_char uj = use_json(argc, argv);
- if (strncmp (argv[1], "b", 1) == 0)
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_BESTPATH, uj);
- else
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_MULTIPATH, uj);
-}
-
-ALIAS (show_bgp_prefix_pathtype,
- show_bgp_ipv6_prefix_pathtype_cmd,
- "show bgp ipv6 X:X::X:X/M (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "IPv6 prefix <network>/<length>\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
+ int prefix_check = 0;
-DEFUN (show_bgp_ipv6_safi_prefix_pathtype,
- show_bgp_ipv6_safi_prefix_pathtype_cmd,
- "show bgp ipv6 "BGP_SAFI_CMD_STR" X:X::X:X/M (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ vrf_id_t vrf = VRF_DEFAULT;;
+ char *prefix = NULL;
+ struct bgp *bgp = NULL;
+ enum bgp_path_type path_type;
u_char uj = use_json(argc, argv);
- if (strncmp (argv[2], "b", 1) == 0)
- return bgp_show_route (vty, NULL, argv[1], AFI_IP6,
- bgp_vty_safi_from_arg(argv[0]),
- NULL, 1, BGP_PATH_BESTPATH, uj);
- else
- return bgp_show_route (vty, NULL, argv[1], AFI_IP6,
- bgp_vty_safi_from_arg(argv[0]), NULL, 1, BGP_PATH_MULTIPATH, uj);
-}
-/* old command */
-DEFUN (show_ipv6_bgp_prefix,
- show_ipv6_bgp_prefix_cmd,
- "show ipv6 bgp X:X::X:X/M {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
- "JavaScript Object Notation\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json(argc, argv));
-}
+ int idx = 0;
-DEFUN (show_bgp_view,
- show_bgp_instance_cmd,
- "show bgp " BGP_INSTANCE_CMD " {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "JavaScript Object Notation\n")
-{
- struct bgp *bgp;
+ bgp_vty_find_and_parse_afi_safi_vrf (vty, argv, argc, &idx, &afi, &safi, &vrf);
+ if (!idx)
+ return CMD_WARNING;
- /* BGP structure lookup. */
- bgp = bgp_lookup_by_name (argv[1]);
- if (bgp == NULL)
+ if (vrf != VRF_ALL)
{
- vty_out (vty, "Can't find BGP instance %s%s", argv[1], VTY_NEWLINE);
+ bgp = bgp_lookup_by_vrf_id (vrf);
+ if (bgp == NULL)
+ {
+ vty_out (vty, "Can't find BGP instance %s%s", argv[5]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ {
+ vty_out (vty, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_show (vty, bgp, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal, NULL, use_json(argc, argv));
-}
-
-DEFUN (show_bgp_instance_all,
- show_bgp_instance_all_cmd,
- "show bgp " BGP_INSTANCE_ALL_CMD " {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_ALL_HELP_STR
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
+ /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
+ if (argv_find (argv, argc, "A.B.C.D", &idx) || argv_find (argv, argc, "X:X::X:X", &idx))
+ prefix_check = 0;
+ else if (argv_find (argv, argc, "A.B.C.D/M", &idx) || argv_find (argv, argc, "X:X::X:X/M", &idx))
+ prefix_check = 1;
- bgp_show_all_instances_routes_vty (vty, AFI_IP6, SAFI_UNICAST, uj);
- return CMD_SUCCESS;
-}
-
-ALIAS (show_bgp_view,
- show_bgp_instance_ipv6_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_bgp_instance_route,
- show_bgp_instance_route_cmd,
- "show bgp " BGP_INSTANCE_CMD " X:X::X:X {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Network in the BGP routing table to display\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
-}
+ if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN) && afi != AFI_IP6)
+ {
+ vty_out (vty, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN) && afi != AFI_IP)
+ {
+ vty_out (vty, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
-ALIAS (show_bgp_instance_route,
- show_bgp_instance_ipv6_route_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 X:X::X:X {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Network in the BGP routing table to display\n"
- "JavaScript Object Notation\n")
+ prefix = argv[idx]->arg;
-DEFUN (show_bgp_instance_route_pathtype,
- show_bgp_instance_route_pathtype_cmd,
- "show bgp " BGP_INSTANCE_CMD " X:X::X:X (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Network in the BGP routing table to display\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- if (strncmp (argv[3], "b", 1) == 0)
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_BESTPATH, uj);
+ /* [<bestpath|multipath>] */
+ if (argv_find (argv, argc, "bestpath", &idx))
+ path_type = BGP_PATH_BESTPATH;
+ else if (argv_find (argv, argc, "multipath", &idx))
+ path_type = BGP_PATH_MULTIPATH;
else
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_MULTIPATH, uj);
-}
+ path_type = BGP_PATH_ALL;
-ALIAS (show_bgp_instance_route_pathtype,
- show_bgp_instance_ipv6_route_pathtype_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 X:X::X:X (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Network in the BGP routing table to display\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_bgp_instance_prefix,
- show_bgp_instance_prefix_cmd,
- "show bgp " BGP_INSTANCE_CMD " X:X::X:X/M {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "IPv6 prefix <network>/<length>\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json(argc, argv));
+ return bgp_show_route (vty, bgp, prefix, afi, safi, NULL, prefix_check, path_type, uj);
}
-ALIAS (show_bgp_instance_prefix,
- show_bgp_instance_ipv6_prefix_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 X:X::X:X/M {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "IPv6 prefix <network>/<length>\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_bgp_instance_prefix_pathtype,
- show_bgp_instance_prefix_pathtype_cmd,
- "show bgp " BGP_INSTANCE_CMD " X:X::X:X/M (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "IPv6 prefix <network>/<length>\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- if (strncmp (argv[3], "b", 1) == 0)
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_BESTPATH, uj);
- else
- return bgp_show_route (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_MULTIPATH, uj);
-}
-
-ALIAS (show_bgp_instance_prefix_pathtype,
- show_bgp_instance_ipv6_prefix_pathtype_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 X:X::X:X/M (bestpath|multipath) {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "IPv6 prefix <network>/<length>\n"
- "Display only the bestpath\n"
- "Display only multipaths\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_bgp_instance_prefix_list,
- show_bgp_instance_prefix_list_cmd,
- "show bgp " BGP_INSTANCE_CMD " prefix-list WORD",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Display routes conforming to the prefix-list\n"
- "IPv6 prefix-list name\n")
-{
- return bgp_show_prefix_list (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_list);
-}
-
-ALIAS (show_bgp_instance_prefix_list,
- show_bgp_instance_ipv6_prefix_list_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 prefix-list WORD",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Display routes conforming to the prefix-list\n"
- "IPv6 prefix-list name\n")
-
-DEFUN (show_bgp_instance_filter_list,
- show_bgp_instance_filter_list_cmd,
- "show bgp " BGP_INSTANCE_CMD " filter-list WORD",
+DEFUN (show_ip_bgp_regexp,
+ show_ip_bgp_regexp_cmd,
+ "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] regexp REGEX...",
SHOW_STR
+ IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
+ BGP_AFI_HELP_STR
+ BGP_SAFI_HELP_STR
+ "Display routes matching the AS path regular expression\n"
+ "A regular-expression to match the BGP AS paths\n")
{
- return bgp_show_filter_list (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_filter_list);
-}
+ vrf_id_t vrf = VRF_DEFAULT;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
-ALIAS (show_bgp_instance_filter_list,
- show_bgp_instance_ipv6_filter_list_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 filter-list WORD",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
+ int idx = 0;
+ bgp_vty_find_and_parse_afi_safi_vrf (vty, argv, argc, &idx, &afi, &safi, &vrf);
+ if (!idx)
+ return CMD_WARNING;
-DEFUN (show_bgp_instance_route_map,
- show_bgp_instance_route_map_cmd,
- "show bgp " BGP_INSTANCE_CMD " route-map WORD",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
-{
- return bgp_show_route_map (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_route_map);
-}
+ // get index of regex
+ argv_find (argv, argc, "regexp", &idx);
+ idx++;
-ALIAS (show_bgp_instance_route_map,
- show_bgp_instance_ipv6_route_map_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 route-map WORD",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
-
-DEFUN (show_bgp_instance_community_list,
- show_bgp_instance_community_list_cmd,
- "show bgp " BGP_INSTANCE_CMD " community-list (<1-500>|WORD)",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
-{
- return bgp_show_community_list (vty, argv[1], argv[2], 0, AFI_IP6, SAFI_UNICAST);
+ char *regstr = argv_concat (argv, argc, idx);
+ int rc = bgp_show_regexp (vty, (const char *) regstr, afi, safi, bgp_show_type_regexp);
+ XFREE (MTYPE_TMP, regstr);
+ return rc;
}
-ALIAS (show_bgp_instance_community_list,
- show_bgp_instance_ipv6_community_list_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 community-list (<1-500>|WORD)",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
-
-DEFUN (show_bgp_instance_prefix_longer,
- show_bgp_instance_prefix_longer_cmd,
- "show bgp " BGP_INSTANCE_CMD " X:X::X:X/M longer-prefixes",
+DEFUN (show_ip_bgp_instance_all,
+ show_ip_bgp_instance_all_cmd,
+ "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] [json]",
SHOW_STR
+ IP_STR
BGP_STR
- BGP_INSTANCE_HELP_STR
- "IPv6 prefix <network>/<length>\n"
- "Display route and more specific routes\n")
+ BGP_INSTANCE_ALL_HELP_STR
+ BGP_AFI_HELP_STR
+ BGP_SAFI_HELP_STR
+ JSON_STR)
{
- return bgp_show_prefix_longer (vty, argv[1], argv[2], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_longer);
-}
+ vrf_id_t vrf = VRF_DEFAULT;
+ afi_t afi = AFI_IP;
+ safi_t safi = SAFI_UNICAST;
-ALIAS (show_bgp_instance_prefix_longer,
- show_bgp_instance_ipv6_prefix_longer_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 X:X::X:X/M longer-prefixes",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "IPv6 prefix <network>/<length>\n"
- "Display route and more specific routes\n")
-
-/* old command */
-DEFUN (show_ipv6_mbgp,
- show_ipv6_mbgp_cmd,
- "show ipv6 mbgp {json}",
- SHOW_STR
- IP_STR
- MBGP_STR
- "JavaScript Object Notation\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal,
- NULL, use_json(argc, argv));
-}
+ int idx = 0;
+ bgp_vty_find_and_parse_afi_safi_vrf (vty, argv, argc, &idx, &afi, &safi, &vrf);
+ if (!idx)
+ return CMD_WARNING;
-/* old command */
-DEFUN (show_ipv6_mbgp_route,
- show_ipv6_mbgp_route_cmd,
- "show ipv6 mbgp X:X::X:X {json}",
- SHOW_STR
- IP_STR
- MBGP_STR
- "Network in the MBGP routing table to display\n"
- "JavaScript Object Notation\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
-}
+ int uj = use_json (argc, argv);
+ if (uj) argc--;
-/* old command */
-DEFUN (show_ipv6_mbgp_prefix,
- show_ipv6_mbgp_prefix_cmd,
- "show ipv6 mbgp X:X::X:X/M {json}",
- SHOW_STR
- IP_STR
- MBGP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
- "JavaScript Object Notation\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 1, BGP_PATH_ALL, use_json(argc, argv));
+ bgp_show_all_instances_routes_vty (vty, afi, safi, uj);
+ return CMD_SUCCESS;
}
-#endif
-
static int
-bgp_show_regexp (struct vty *vty, int argc, const char **argv, afi_t afi,
+bgp_show_regexp (struct vty *vty, const char *regstr, afi_t afi,
safi_t safi, enum bgp_show_type type)
{
- int i;
- struct buffer *b;
- char *regstr;
- int first;
+ return CMD_SUCCESS;
+
regex_t *regex;
int rc;
- first = 0;
- b = buffer_new (1024);
- for (i = 0; i < argc; i++)
- {
- if (first)
- buffer_putc (b, ' ');
- else
- {
- if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
- continue;
- first = 1;
- }
-
- buffer_putstr (b, argv[i]);
- }
- buffer_putc (b, '\0');
-
- regstr = buffer_getstr (b);
- buffer_free (b);
-
regex = bgp_regcomp (regstr);
- XFREE(MTYPE_TMP, regstr);
if (! regex)
{
- vty_out (vty, "Can't compile regexp %s%s", argv[0],
- VTY_NEWLINE);
+ vty_out (vty, "Can't compile regexp %s%s", regstr, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -9267,128 +8331,12 @@ bgp_show_regexp (struct vty *vty, int argc, const char **argv, afi_t afi,
return rc;
}
-DEFUN (show_ip_bgp_regexp,
- show_ip_bgp_regexp_cmd,
- "show ip bgp regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
-{
- return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
- bgp_show_type_regexp);
-}
-
-DEFUN (show_ip_bgp_flap_regexp,
- show_ip_bgp_flap_regexp_cmd,
- "show ip bgp flap-statistics regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
-{
- return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_regexp);
-}
-
-ALIAS (show_ip_bgp_flap_regexp,
- show_ip_bgp_damp_flap_regexp_cmd,
- "show ip bgp dampening flap-statistics regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
-
-DEFUN (show_ip_bgp_ipv4_regexp,
- show_ip_bgp_ipv4_regexp_cmd,
- "show ip bgp ipv4 (unicast|multicast) regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_regexp (vty, argc, argv, AFI_IP, safi,
- bgp_show_type_regexp);
-}
-
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_regexp,
- show_bgp_regexp_cmd,
- "show bgp regexp .LINE",
- SHOW_STR
- BGP_STR
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
-{
- return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_regexp);
-}
-
-ALIAS (show_bgp_regexp,
- show_bgp_ipv6_regexp_cmd,
- "show bgp ipv6 regexp .LINE",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
-
-/* old command */
-DEFUN (show_ipv6_bgp_regexp,
- show_ipv6_bgp_regexp_cmd,
- "show ipv6 bgp regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_regexp);
-}
-
-/* old command */
-DEFUN (show_ipv6_mbgp_regexp,
- show_ipv6_mbgp_regexp_cmd,
- "show ipv6 mbgp regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the MBGP AS paths\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_regexp);
-}
-#endif /* HAVE_IPV6 */
-
static int
-bgp_show_prefix_list (struct vty *vty, const char *name,
+bgp_show_prefix_list (struct vty *vty, struct bgp *bgp,
const char *prefix_list_str, afi_t afi,
safi_t safi, enum bgp_show_type type)
{
struct prefix_list *plist;
- struct bgp *bgp = NULL;
-
- if (name && !(bgp = bgp_lookup_by_name(name)))
- {
- vty_out (vty, "%% No such BGP instance exists%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
plist = prefix_list_lookup (afi, prefix_list_str);
if (plist == NULL)
@@ -9401,142 +8349,12 @@ bgp_show_prefix_list (struct vty *vty, const char *name,
return bgp_show (vty, bgp, afi, safi, type, plist, 0);
}
-DEFUN (show_ip_bgp_prefix_list,
- show_ip_bgp_prefix_list_cmd,
- "show ip bgp prefix-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes conforming to the prefix-list\n"
- "IP prefix-list name\n")
-{
- return bgp_show_prefix_list (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_prefix_list);
-}
-
-DEFUN (show_ip_bgp_instance_prefix_list,
- show_ip_bgp_instance_prefix_list_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " prefix-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Display routes conforming to the prefix-list\n"
- "IP prefix-list name\n")
-{
- return bgp_show_prefix_list (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST,
- bgp_show_type_prefix_list);
-}
-
-DEFUN (show_ip_bgp_flap_prefix_list,
- show_ip_bgp_flap_prefix_list_cmd,
- "show ip bgp flap-statistics prefix-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display routes conforming to the prefix-list\n"
- "IP prefix-list name\n")
-{
- return bgp_show_prefix_list (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_prefix_list);
-}
-
-ALIAS (show_ip_bgp_flap_prefix_list,
- show_ip_bgp_damp_flap_prefix_list_cmd,
- "show ip bgp dampening flap-statistics prefix-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "Display routes conforming to the prefix-list\n"
- "IP prefix-list name\n")
-
-DEFUN (show_ip_bgp_ipv4_prefix_list,
- show_ip_bgp_ipv4_prefix_list_cmd,
- "show ip bgp ipv4 (unicast|multicast) prefix-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes conforming to the prefix-list\n"
- "IP prefix-list name\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_prefix_list (vty, NULL, argv[1], AFI_IP, safi,
- bgp_show_type_prefix_list);
-}
-
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_prefix_list,
- show_bgp_prefix_list_cmd,
- "show bgp prefix-list WORD",
- SHOW_STR
- BGP_STR
- "Display routes conforming to the prefix-list\n"
- "IPv6 prefix-list name\n")
-{
- return bgp_show_prefix_list (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_list);
-}
-
-ALIAS (show_bgp_prefix_list,
- show_bgp_ipv6_prefix_list_cmd,
- "show bgp ipv6 prefix-list WORD",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes conforming to the prefix-list\n"
- "IPv6 prefix-list name\n")
-
-/* old command */
-DEFUN (show_ipv6_bgp_prefix_list,
- show_ipv6_bgp_prefix_list_cmd,
- "show ipv6 bgp prefix-list WORD",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the prefix-list\n"
- "IPv6 prefix-list name\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_prefix_list (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_list);
-}
-
-/* old command */
-DEFUN (show_ipv6_mbgp_prefix_list,
- show_ipv6_mbgp_prefix_list_cmd,
- "show ipv6 mbgp prefix-list WORD",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the prefix-list\n"
- "IPv6 prefix-list name\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_prefix_list (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_prefix_list);
-}
-#endif /* HAVE_IPV6 */
-
static int
-bgp_show_filter_list (struct vty *vty, const char *name,
+bgp_show_filter_list (struct vty *vty, struct bgp *bgp,
const char *filter, afi_t afi,
safi_t safi, enum bgp_show_type type)
{
struct as_list *as_list;
- struct bgp *bgp = NULL;
-
- if (name && !(bgp = bgp_lookup_by_name(name)))
- {
- vty_out (vty, "%% No such BGP instance exists%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
as_list = as_list_lookup (filter);
if (as_list == NULL)
@@ -9548,209 +8366,12 @@ bgp_show_filter_list (struct vty *vty, const char *name,
return bgp_show (vty, bgp, afi, safi, type, as_list, 0);
}
-DEFUN (show_ip_bgp_filter_list,
- show_ip_bgp_filter_list_cmd,
- "show ip bgp filter-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
-{
- return bgp_show_filter_list (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_filter_list);
-}
-
-DEFUN (show_ip_bgp_instance_filter_list,
- show_ip_bgp_instance_filter_list_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " filter-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
-{
- return bgp_show_filter_list (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST,
- bgp_show_type_filter_list);
-}
-
-DEFUN (show_ip_bgp_flap_filter_list,
- show_ip_bgp_flap_filter_list_cmd,
- "show ip bgp flap-statistics filter-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
-{
- return bgp_show_filter_list (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_filter_list);
-}
-
-ALIAS (show_ip_bgp_flap_filter_list,
- show_ip_bgp_damp_flap_filter_list_cmd,
- "show ip bgp dampening flap-statistics filter-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
-
-DEFUN (show_ip_bgp_ipv4_filter_list,
- show_ip_bgp_ipv4_filter_list_cmd,
- "show ip bgp ipv4 (unicast|multicast) filter-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_filter_list (vty, NULL, argv[1], AFI_IP, safi,
- bgp_show_type_filter_list);
-}
-
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_filter_list,
- show_bgp_filter_list_cmd,
- "show bgp filter-list WORD",
- SHOW_STR
- BGP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
-{
- return bgp_show_filter_list (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_filter_list);
-}
-
-ALIAS (show_bgp_filter_list,
- show_bgp_ipv6_filter_list_cmd,
- "show bgp ipv6 filter-list WORD",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
-
-/* old command */
-DEFUN (show_ipv6_bgp_filter_list,
- show_ipv6_bgp_filter_list_cmd,
- "show ipv6 bgp filter-list WORD",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_filter_list (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_filter_list);
-}
-
-/* old command */
-DEFUN (show_ipv6_mbgp_filter_list,
- show_ipv6_mbgp_filter_list_cmd,
- "show ipv6 mbgp filter-list WORD",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_filter_list (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_filter_list);
-}
-#endif /* HAVE_IPV6 */
-
-DEFUN (show_ip_bgp_dampening_info,
- show_ip_bgp_dampening_params_cmd,
- "show ip bgp dampening parameters",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display detail of configured dampening parameters\n")
-{
- return bgp_show_dampening_parameters (vty, AFI_IP, SAFI_UNICAST);
-}
-
-
-DEFUN (show_ip_bgp_ipv4_dampening_parameters,
- show_ip_bgp_ipv4_dampening_parameters_cmd,
- "show ip bgp ipv4 (unicast|multicast) dampening parameters",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display detailed information about dampening\n"
- "Display detail of configured dampening parameters\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_dampening_parameters (vty, AFI_IP, safi);
-}
-
-
-DEFUN (show_ip_bgp_ipv4_dampening_flap_stats,
- show_ip_bgp_ipv4_dampening_flap_stats_cmd,
- "show ip bgp ipv4 (unicast|multicast) dampening flap-statistics",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show (vty, NULL, AFI_IP, safi,
- bgp_show_type_flap_statistics, NULL, 0);
-}
-
-DEFUN (show_ip_bgp_ipv4_dampening_dampd_paths,
- show_ip_bgp_ipv4_dampening_dampd_paths_cmd,
- "show ip bgp ipv4 (unicast|multicast) dampening dampened-paths",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display detailed information about dampening\n"
- "Display paths suppressed due to dampening\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show (vty, NULL, AFI_IP, safi,
- bgp_show_type_dampend_paths, NULL, 0);
-}
-
static int
-bgp_show_route_map (struct vty *vty, const char *name,
+bgp_show_route_map (struct vty *vty, struct bgp *bgp,
const char *rmap_str, afi_t afi,
safi_t safi, enum bgp_show_type type)
{
struct route_map *rmap;
- struct bgp *bgp = NULL;
-
- if (name && !(bgp = bgp_lookup_by_name(name)))
- {
- vty_out (vty, "%% No such BGP instance exists%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
rmap = route_map_lookup_by_name (rmap_str);
if (! rmap)
@@ -9763,258 +8384,16 @@ bgp_show_route_map (struct vty *vty, const char *name,
return bgp_show (vty, bgp, afi, safi, type, rmap, 0);
}
-DEFUN (show_ip_bgp_route_map,
- show_ip_bgp_route_map_cmd,
- "show ip bgp route-map WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
-{
- return bgp_show_route_map (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_route_map);
-}
-
-DEFUN (show_ip_bgp_instance_route_map,
- show_ip_bgp_instance_route_map_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " route-map WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
-{
- return bgp_show_route_map (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST,
- bgp_show_type_route_map);
-}
-
-DEFUN (show_ip_bgp_flap_route_map,
- show_ip_bgp_flap_route_map_cmd,
- "show ip bgp flap-statistics route-map WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
-{
- return bgp_show_route_map (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_route_map);
-}
-
-ALIAS (show_ip_bgp_flap_route_map,
- show_ip_bgp_damp_flap_route_map_cmd,
- "show ip bgp dampening flap-statistics route-map WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
-
-DEFUN (show_ip_bgp_ipv4_route_map,
- show_ip_bgp_ipv4_route_map_cmd,
- "show ip bgp ipv4 (unicast|multicast) route-map WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_route_map (vty, NULL, argv[1], AFI_IP, safi,
- bgp_show_type_route_map);
-}
-
-DEFUN (show_bgp_route_map,
- show_bgp_route_map_cmd,
- "show bgp route-map WORD",
- SHOW_STR
- BGP_STR
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
-{
- return bgp_show_route_map (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_route_map);
-}
-
-ALIAS (show_bgp_route_map,
- show_bgp_ipv6_route_map_cmd,
- "show bgp ipv6 route-map WORD",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
-
-DEFUN (show_ip_bgp_cidr_only,
- show_ip_bgp_cidr_only_cmd,
- "show ip bgp cidr-only",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display only routes with non-natural netmasks\n")
-{
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
- bgp_show_type_cidr_only, NULL, 0);
-}
-
-DEFUN (show_ip_bgp_flap_cidr_only,
- show_ip_bgp_flap_cidr_only_cmd,
- "show ip bgp flap-statistics cidr-only",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display only routes with non-natural netmasks\n")
-{
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_cidr_only, NULL, 0);
-}
-
-ALIAS (show_ip_bgp_flap_cidr_only,
- show_ip_bgp_damp_flap_cidr_only_cmd,
- "show ip bgp dampening flap-statistics cidr-only",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "Display only routes with non-natural netmasks\n")
-
-DEFUN (show_ip_bgp_ipv4_cidr_only,
- show_ip_bgp_ipv4_cidr_only_cmd,
- "show ip bgp ipv4 (unicast|multicast) cidr-only",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display only routes with non-natural netmasks\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show (vty, NULL, AFI_IP, safi,
- bgp_show_type_cidr_only, NULL, 0);
-}
-
-DEFUN (show_ip_bgp_community_all,
- show_ip_bgp_community_all_cmd,
- "show ip bgp community",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n")
-{
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
- bgp_show_type_community_all, NULL, 0);
-}
-
-DEFUN (show_ip_bgp_ipv4_community_all,
- show_ip_bgp_ipv4_community_all_cmd,
- "show ip bgp ipv4 (unicast|multicast) community",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show (vty, NULL, AFI_IP, safi,
- bgp_show_type_community_all, NULL, 0);
-}
-
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_community_all,
- show_bgp_community_all_cmd,
- "show bgp community",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n")
-{
- return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_community_all, NULL, 0);
-}
-
-ALIAS (show_bgp_community_all,
- show_bgp_ipv6_community_all_cmd,
- "show bgp ipv6 community",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n")
-
-/* old command */
-DEFUN (show_ipv6_bgp_community_all,
- show_ipv6_bgp_community_all_cmd,
- "show ipv6 bgp community",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_community_all, NULL, 0);
-}
-
-/* old command */
-DEFUN (show_ipv6_mbgp_community_all,
- show_ipv6_mbgp_community_all_cmd,
- "show ipv6 mbgp community",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_community_all, NULL, 0);
-}
-#endif /* HAVE_IPV6 */
-
static int
-bgp_show_community (struct vty *vty, const char *view_name, int argc,
- const char **argv, int exact, afi_t afi, safi_t safi)
+bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
+ struct cmd_token **argv, int exact, afi_t afi, safi_t safi)
{
struct community *com;
struct buffer *b;
- struct bgp *bgp;
int i;
char *str;
int first = 0;
- /* BGP structure lookup */
- if (view_name)
- {
- bgp = bgp_lookup_by_name (view_name);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP instance %s%s", view_name, VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- else
- {
- bgp = bgp_get_default ();
- if (bgp == NULL)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
b = buffer_new (1024);
for (i = 0; i < argc; i++)
{
@@ -10022,12 +8401,12 @@ bgp_show_community (struct vty *vty, const char *view_name, int argc,
buffer_putc (b, ' ');
else
{
- if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
+ if ((strcmp (argv[i]->arg, "unicast") == 0) || (strcmp (argv[i]->arg, "multicast") == 0))
continue;
first = 1;
}
- buffer_putstr (b, argv[i]);
+ buffer_putstr (b, argv[i]->arg);
}
buffer_putc (b, '\0');
@@ -10047,1104 +8426,12 @@ bgp_show_community (struct vty *vty, const char *view_name, int argc,
bgp_show_type_community), com, 0);
}
-DEFUN (show_ip_bgp_community,
- show_ip_bgp_community_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-{
- return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST);
-}
-
-ALIAS (show_ip_bgp_community,
- show_ip_bgp_community2_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_ip_bgp_community,
- show_ip_bgp_community3_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_ip_bgp_community,
- show_ip_bgp_community4_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-DEFUN (show_ip_bgp_ipv4_community,
- show_ip_bgp_ipv4_community_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, safi);
-}
-
-ALIAS (show_ip_bgp_ipv4_community,
- show_ip_bgp_ipv4_community2_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_ip_bgp_ipv4_community,
- show_ip_bgp_ipv4_community3_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_ip_bgp_ipv4_community,
- show_ip_bgp_ipv4_community4_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-DEFUN (show_bgp_instance_afi_safi_community_all,
- show_bgp_instance_afi_safi_community_all_cmd,
- "show bgp " BGP_INSTANCE_CMD " (ipv4|ipv6) (unicast|multicast) community",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n")
-{
- int afi;
- int safi;
- struct bgp *bgp;
-
- /* BGP structure lookup. */
- bgp = bgp_lookup_by_name (argv[1]);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP instance %s%s", argv[1], VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- afi = bgp_vty_safi_from_arg(argv[2]);
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL, 0);
-}
-
-DEFUN (show_bgp_instance_afi_safi_community,
- show_bgp_instance_afi_safi_community_cmd,
- "show bgp " BGP_INSTANCE_CMD " (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Address family\n"
- "Address family modifier\n"
- "Address family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-{
- int afi;
- int safi;
-
- afi = bgp_vty_safi_from_arg(argv[2]);
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_show_community (vty, argv[1], argc-4, &argv[4], 0, afi, safi);
-}
-
-ALIAS (show_bgp_instance_afi_safi_community,
- show_bgp_instance_afi_safi_community2_cmd,
- "show bgp " BGP_INSTANCE_CMD " (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Address family\n"
- "Address family modifier\n"
- "Address family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_bgp_instance_afi_safi_community,
- show_bgp_instance_afi_safi_community3_cmd,
- "show bgp " BGP_INSTANCE_CMD " (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Address family\n"
- "Address family modifier\n"
- "Address family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_bgp_instance_afi_safi_community,
- show_bgp_instance_afi_safi_community4_cmd,
- "show bgp " BGP_INSTANCE_CMD " (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Address family\n"
- "Address family modifier\n"
- "Address family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-DEFUN (show_ip_bgp_community_exact,
- show_ip_bgp_community_exact_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-{
- return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST);
-}
-
-ALIAS (show_ip_bgp_community_exact,
- show_ip_bgp_community2_exact_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_ip_bgp_community_exact,
- show_ip_bgp_community3_exact_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_ip_bgp_community_exact,
- show_ip_bgp_community4_exact_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-DEFUN (show_ip_bgp_ipv4_community_exact,
- show_ip_bgp_ipv4_community_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, safi);
-}
-
-ALIAS (show_ip_bgp_ipv4_community_exact,
- show_ip_bgp_ipv4_community2_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_ip_bgp_ipv4_community_exact,
- show_ip_bgp_ipv4_community3_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_ip_bgp_ipv4_community_exact,
- show_ip_bgp_ipv4_community4_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_community,
- show_bgp_community_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-{
- return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
-}
-
-ALIAS (show_bgp_community,
- show_bgp_ipv6_community_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_bgp_community,
- show_bgp_community2_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_bgp_community,
- show_bgp_ipv6_community2_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_bgp_community,
- show_bgp_community3_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_bgp_community,
- show_bgp_ipv6_community3_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_bgp_community,
- show_bgp_community4_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-ALIAS (show_bgp_community,
- show_bgp_ipv6_community4_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-/* old command */
-DEFUN (show_ipv6_bgp_community,
- show_ipv6_bgp_community_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
-}
-
-/* old command */
-ALIAS (show_ipv6_bgp_community,
- show_ipv6_bgp_community2_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-/* old command */
-ALIAS (show_ipv6_bgp_community,
- show_ipv6_bgp_community3_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-/* old command */
-ALIAS (show_ipv6_bgp_community,
- show_ipv6_bgp_community4_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-DEFUN (show_bgp_community_exact,
- show_bgp_community_exact_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-{
- return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
-}
-
-ALIAS (show_bgp_community_exact,
- show_bgp_ipv6_community_exact_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_bgp_community_exact,
- show_bgp_community2_exact_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_bgp_community_exact,
- show_bgp_ipv6_community2_exact_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_bgp_community_exact,
- show_bgp_community3_exact_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_bgp_community_exact,
- show_bgp_ipv6_community3_exact_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_bgp_community_exact,
- show_bgp_community4_exact_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-ALIAS (show_bgp_community_exact,
- show_bgp_ipv6_community4_exact_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-/* old command */
-DEFUN (show_ipv6_bgp_community_exact,
- show_ipv6_bgp_community_exact_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
-}
-
-/* old command */
-ALIAS (show_ipv6_bgp_community_exact,
- show_ipv6_bgp_community2_exact_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-/* old command */
-ALIAS (show_ipv6_bgp_community_exact,
- show_ipv6_bgp_community3_exact_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-/* old command */
-ALIAS (show_ipv6_bgp_community_exact,
- show_ipv6_bgp_community4_exact_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-/* old command */
-DEFUN (show_ipv6_mbgp_community,
- show_ipv6_mbgp_community_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_MULTICAST);
-}
-
-/* old command */
-ALIAS (show_ipv6_mbgp_community,
- show_ipv6_mbgp_community2_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-/* old command */
-ALIAS (show_ipv6_mbgp_community,
- show_ipv6_mbgp_community3_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-/* old command */
-ALIAS (show_ipv6_mbgp_community,
- show_ipv6_mbgp_community4_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
-/* old command */
-DEFUN (show_ipv6_mbgp_community_exact,
- show_ipv6_mbgp_community_exact_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_MULTICAST);
-}
-
-/* old command */
-ALIAS (show_ipv6_mbgp_community_exact,
- show_ipv6_mbgp_community2_exact_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-/* old command */
-ALIAS (show_ipv6_mbgp_community_exact,
- show_ipv6_mbgp_community3_exact_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
-/* old command */
-ALIAS (show_ipv6_mbgp_community_exact,
- show_ipv6_mbgp_community4_exact_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- COMMUNITY_AANN_STR
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-#endif /* HAVE_IPV6 */
-
static int
-bgp_show_community_list (struct vty *vty, const char *name,
+bgp_show_community_list (struct vty *vty, struct bgp *bgp,
const char *com, int exact,
afi_t afi, safi_t safi)
{
struct community_list *list;
- struct bgp *bgp = NULL;
-
- if (name && !(bgp = bgp_lookup_by_name(name)))
- {
- vty_out (vty, "%% No such BGP instance exists%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
list = community_list_lookup (bgp_clist, com, COMMUNITY_LIST_MASTER);
if (list == NULL)
@@ -11159,204 +8446,13 @@ bgp_show_community_list (struct vty *vty, const char *name,
bgp_show_type_community_list), list, 0);
}
-DEFUN (show_ip_bgp_community_list,
- show_ip_bgp_community_list_cmd,
- "show ip bgp community-list (<1-500>|WORD)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
-{
- return bgp_show_community_list (vty, NULL, argv[0], 0, AFI_IP, SAFI_UNICAST);
-}
-
-DEFUN (show_ip_bgp_instance_community_list,
- show_ip_bgp_instance_community_list_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " community-list (<1-500>|WORD)",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
-{
- return bgp_show_community_list (vty, argv[1], argv[2], 0, AFI_IP, SAFI_UNICAST);
-}
-
-DEFUN (show_ip_bgp_ipv4_community_list,
- show_ip_bgp_ipv4_community_list_cmd,
- "show ip bgp ipv4 (unicast|multicast) community-list (<1-500>|WORD)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_community_list (vty, NULL, argv[1], 0, AFI_IP, safi);
-}
-
-DEFUN (show_ip_bgp_community_list_exact,
- show_ip_bgp_community_list_exact_cmd,
- "show ip bgp community-list (<1-500>|WORD) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n"
- "Exact match of the communities\n")
-{
- return bgp_show_community_list (vty, NULL, argv[0], 1, AFI_IP, SAFI_UNICAST);
-}
-
-DEFUN (show_ip_bgp_ipv4_community_list_exact,
- show_ip_bgp_ipv4_community_list_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community-list (<1-500>|WORD) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n"
- "Exact match of the communities\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_community_list (vty, NULL, argv[1], 1, AFI_IP, safi);
-}
-
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_community_list,
- show_bgp_community_list_cmd,
- "show bgp community-list (<1-500>|WORD)",
- SHOW_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
-{
- return bgp_show_community_list (vty, NULL, argv[0], 0, AFI_IP6, SAFI_UNICAST);
-}
-
-ALIAS (show_bgp_community_list,
- show_bgp_ipv6_community_list_cmd,
- "show bgp ipv6 community-list (<1-500>|WORD)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
-
-/* old command */
-DEFUN (show_ipv6_bgp_community_list,
- show_ipv6_bgp_community_list_cmd,
- "show ipv6 bgp community-list WORD",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list name\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_community_list (vty, NULL, argv[0], 0, AFI_IP6, SAFI_UNICAST);
-}
-
-/* old command */
-DEFUN (show_ipv6_mbgp_community_list,
- show_ipv6_mbgp_community_list_cmd,
- "show ipv6 mbgp community-list WORD",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the community-list\n"
- "community-list name\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_community_list (vty, NULL, argv[0], 0, AFI_IP6, SAFI_MULTICAST);
-}
-
-DEFUN (show_bgp_community_list_exact,
- show_bgp_community_list_exact_cmd,
- "show bgp community-list (<1-500>|WORD) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n"
- "Exact match of the communities\n")
-{
- return bgp_show_community_list (vty, NULL, argv[0], 1, AFI_IP6, SAFI_UNICAST);
-}
-
-ALIAS (show_bgp_community_list_exact,
- show_bgp_ipv6_community_list_exact_cmd,
- "show bgp ipv6 community-list (<1-500>|WORD) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n"
- "Exact match of the communities\n")
-
-/* old command */
-DEFUN (show_ipv6_bgp_community_list_exact,
- show_ipv6_bgp_community_list_exact_cmd,
- "show ipv6 bgp community-list WORD exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list name\n"
- "Exact match of the communities\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_community_list (vty, NULL, argv[0], 1, AFI_IP6, SAFI_UNICAST);
-}
-
-/* old command */
-DEFUN (show_ipv6_mbgp_community_list_exact,
- show_ipv6_mbgp_community_list_exact_cmd,
- "show ipv6 mbgp community-list WORD exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the community-list\n"
- "community-list name\n"
- "Exact match of the communities\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_community_list (vty, NULL, argv[0], 1, AFI_IP6, SAFI_MULTICAST);
-}
-#endif /* HAVE_IPV6 */
-
static int
-bgp_show_prefix_longer (struct vty *vty, const char *name,
+bgp_show_prefix_longer (struct vty *vty, struct bgp *bgp,
const char *prefix, afi_t afi,
safi_t safi, enum bgp_show_type type)
{
int ret;
struct prefix *p;
- struct bgp *bgp = NULL;
-
- if (name && !(bgp = bgp_lookup_by_name(name)))
- {
- vty_out (vty, "%% No such BGP instance exists%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
p = prefix_new();
@@ -11372,222 +8468,14 @@ bgp_show_prefix_longer (struct vty *vty, const char *name,
return ret;
}
-DEFUN (show_ip_bgp_prefix_longer,
- show_ip_bgp_prefix_longer_cmd,
- "show ip bgp A.B.C.D/M longer-prefixes",
- SHOW_STR
- IP_STR
- BGP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display route and more specific routes\n")
-{
- return bgp_show_prefix_longer (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_prefix_longer);
-}
-
-DEFUN (show_ip_bgp_instance_prefix_longer,
- show_ip_bgp_instance_prefix_longer_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " A.B.C.D/M longer-prefixes",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display route and more specific routes\n")
-{
- return bgp_show_prefix_longer (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST,
- bgp_show_type_prefix_longer);
-}
-
-DEFUN (show_ip_bgp_flap_prefix_longer,
- show_ip_bgp_flap_prefix_longer_cmd,
- "show ip bgp flap-statistics A.B.C.D/M longer-prefixes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display route and more specific routes\n")
-{
- return bgp_show_prefix_longer (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_prefix_longer);
-}
-
-ALIAS (show_ip_bgp_flap_prefix_longer,
- show_ip_bgp_damp_flap_prefix_longer_cmd,
- "show ip bgp dampening flap-statistics A.B.C.D/M longer-prefixes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display route and more specific routes\n")
-
-DEFUN (show_ip_bgp_ipv4_prefix_longer,
- show_ip_bgp_ipv4_prefix_longer_cmd,
- "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M longer-prefixes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display route and more specific routes\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_prefix_longer (vty, NULL, argv[1], AFI_IP, safi,
- bgp_show_type_prefix_longer);
-}
-
-DEFUN (show_ip_bgp_flap_address,
- show_ip_bgp_flap_address_cmd,
- "show ip bgp flap-statistics A.B.C.D",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Network in the BGP routing table to display\n")
-{
- return bgp_show_prefix_longer (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_address);
-}
-
-ALIAS (show_ip_bgp_flap_address,
- show_ip_bgp_damp_flap_address_cmd,
- "show ip bgp dampening flap-statistics A.B.C.D",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "Network in the BGP routing table to display\n")
-
-DEFUN (show_ip_bgp_flap_prefix,
- show_ip_bgp_flap_prefix_cmd,
- "show ip bgp flap-statistics A.B.C.D/M",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
-{
- return bgp_show_prefix_longer (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_prefix);
-}
-
-ALIAS (show_ip_bgp_flap_prefix,
- show_ip_bgp_damp_flap_prefix_cmd,
- "show ip bgp dampening flap-statistics A.B.C.D/M",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
-
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_prefix_longer,
- show_bgp_prefix_longer_cmd,
- "show bgp X:X::X:X/M longer-prefixes",
- SHOW_STR
- BGP_STR
- "IPv6 prefix <network>/<length>\n"
- "Display route and more specific routes\n")
-{
- return bgp_show_prefix_longer (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_longer);
-}
-
-ALIAS (show_bgp_prefix_longer,
- show_bgp_ipv6_prefix_longer_cmd,
- "show bgp ipv6 X:X::X:X/M longer-prefixes",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "IPv6 prefix <network>/<length>\n"
- "Display route and more specific routes\n")
-
-/* old command */
-DEFUN (show_ipv6_bgp_prefix_longer,
- show_ipv6_bgp_prefix_longer_cmd,
- "show ipv6 bgp X:X::X:X/M longer-prefixes",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
- "Display route and more specific routes\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_prefix_longer (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_longer);
-}
-
-/* old command */
-DEFUN (show_ipv6_mbgp_prefix_longer,
- show_ipv6_mbgp_prefix_longer_cmd,
- "show ipv6 mbgp X:X::X:X/M longer-prefixes",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
- "Display route and more specific routes\n")
-{
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_prefix_longer (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_prefix_longer);
-}
-#endif /* HAVE_IPV6 */
-
static struct peer *
-peer_lookup_in_view (struct vty *vty, const char *view_name,
+peer_lookup_in_view (struct vty *vty, struct bgp *bgp,
const char *ip_str, u_char use_json)
{
int ret;
- struct bgp *bgp;
struct peer *peer;
union sockunion su;
- /* BGP structure lookup. */
- if (view_name)
- {
- bgp = bgp_lookup_by_name (view_name);
- if (! bgp)
- {
- if (use_json)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Can't find BGP view");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "Can't find BGP instance %s%s", view_name, VTY_NEWLINE);
- return NULL;
- }
- }
- else
- {
- bgp = bgp_get_default ();
- if (! bgp)
- {
- if (use_json)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "No BGP process configured");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return NULL;
- }
- }
-
/* Get peer sockunion. */
ret = str2sockunion (ip_str, &su);
if (ret < 0)
@@ -11806,7 +8694,7 @@ bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
if (!bgp->rib[afi][safi])
{
- vty_out (vty, "%% No RIB exists for the AFI(%d)/SAFI(%d)%s",
+ vty_out (vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
afi, safi, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -11883,65 +8771,6 @@ bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
return CMD_SUCCESS;
}
-static int
-bgp_table_stats_vty (struct vty *vty, const char *name,
- const char *afi_str, const char *safi_str)
-{
- struct bgp *bgp;
- afi_t afi;
- safi_t safi;
-
- if (name)
- bgp = bgp_lookup_by_name (name);
- else
- bgp = bgp_get_default ();
-
- if (!bgp)
- {
- vty_out (vty, "%% No such BGP instance exists%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- afi = bgp_vty_afi_from_arg(afi_str);
- if (afi == AFI_MAX)
- {
- vty_out (vty, "%% Invalid address family \"%s\"%s",
- afi_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
- safi = bgp_vty_safi_from_arg(safi_str);
- if (safi == SAFI_MAX)
- {
- vty_out (vty, "%% Invalid subsequent address family %s%s",
- safi_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return bgp_table_stats (vty, bgp, afi, safi);
-}
-
-DEFUN (show_bgp_statistics,
- show_bgp_statistics_cmd,
- "show bgp "BGP_AFI_SAFI_CMD_STR" statistics",
- SHOW_STR
- BGP_STR
- BGP_AFI_SAFI_HELP_STR
- "BGP RIB advertisement statistics\n")
-{
- return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]);
-}
-
-DEFUN (show_bgp_statistics_view,
- show_bgp_statistics_view_cmd,
- "show bgp " BGP_INSTANCE_CMD " "BGP_AFI_SAFI_CMD_STR" statistics",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- BGP_AFI_SAFI_HELP_STR
- "BGP RIB advertisement statistics\n")
-{
- return bgp_table_stats_vty (vty, NULL, argv[1], argv[2]);
-}
-
enum bgp_pcounts
{
PCOUNT_ADJ_IN = 0,
@@ -12061,7 +8890,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_c
if (use_json)
{
json_object_string_add(json, "warning", "No such neighbor or address family");
- vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
json_object_free(json);
}
else
@@ -12096,7 +8925,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_c
json_object_string_add(json, "pfxctDriftFor", peer->host);
json_object_string_add(json, "recommended", "Please report this bug, with the above command output");
}
- vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
json_object_free(json);
}
else
@@ -12133,127 +8962,122 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_c
return CMD_SUCCESS;
}
-DEFUN (show_ip_bgp_neighbor_prefix_counts,
- show_ip_bgp_neighbor_prefix_counts_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display detailed prefix count information\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, uj);
-}
-
DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
show_ip_bgp_instance_neighbor_prefix_counts_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {json}",
+ "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] "
+ "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
+ "Address Family\n"
+ "Address Family\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
+ "Address Family modifier\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
+ "Neighbor on BGP configured interface\n"
"Display detailed prefix count information\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ vrf_id_t vrf = VRF_DEFAULT;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
struct peer *peer;
- u_char uj = use_json(argc, argv);
+ int idx = 0;
+ struct bgp *bgp = NULL;
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
- if (! peer)
+ bgp_vty_find_and_parse_afi_safi_vrf (vty, argv, argc, &idx, &afi, &safi, &vrf);
+ if (!idx)
return CMD_WARNING;
- return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, uj);
-}
+ int uj = use_json (argc, argv);
+ if (uj) argc--;
-DEFUN (show_bgp_ipv6_neighbor_prefix_counts,
- show_bgp_ipv6_neighbor_prefix_counts_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display detailed prefix count information\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
+ if (vrf != VRF_ALL)
+ {
+ bgp = bgp_lookup_by_vrf_id (vrf);
+ if (bgp == NULL)
+ {
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "Can't find BGP view");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "Can't find BGP instance %s%s", argv[5]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else
+ bgp = NULL;
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
- if (! peer)
+ argv_find (argv, argc, "neighbors", &idx);
+ peer = peer_lookup_in_view (vty, bgp, argv[idx+1]->arg, uj);
+ if (! peer)
return CMD_WARNING;
-
- return bgp_peer_counts (vty, peer, AFI_IP6, SAFI_UNICAST, uj);
+
+ return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, uj);
}
-DEFUN (show_bgp_instance_ipv6_neighbor_prefix_counts,
- show_bgp_instance_ipv6_neighbor_prefix_counts_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {json}",
+#ifdef KEEP_OLD_VPN_COMMANDS
+DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
+ show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
SHOW_STR
+ IP_STR
BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
+ BGP_VPNVX_HELP_STR
+ "Display information about all VPNv4 NLRIs\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
+ "Neighbor on BGP configured interface\n"
"Display detailed prefix count information\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_peer = 6;
struct peer *peer;
u_char uj = use_json(argc, argv);
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
+ peer = peer_lookup_in_view (vty, NULL, argv[idx_peer]->arg, uj);
if (! peer)
return CMD_WARNING;
-
- return bgp_peer_counts (vty, peer, AFI_IP6, SAFI_UNICAST, uj);
+
+ return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
}
-DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts,
- show_ip_bgp_ipv4_neighbor_prefix_counts_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {json}",
+DEFUN (show_ip_bgp_vpn_all_route_prefix,
+ show_ip_bgp_vpn_all_route_prefix_cmd,
+ "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
SHOW_STR
IP_STR
BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display detailed prefix count information\n"
- "JavaScript Object Notation\n")
+ BGP_VPNVX_HELP_STR
+ "Display information about all VPNv4 NLRIs\n"
+ "Network in the BGP routing table to display\n"
+ "Network in the BGP routing table to display\n"
+ JSON_STR)
{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
- if (! peer)
- return CMD_WARNING;
-
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_peer_counts (vty, peer, AFI_IP, safi, uj);
+ int idx = 0;
+ char *network = NULL;
+ struct bgp *bgp = bgp_get_default();
+ if (!bgp)
+ {
+ vty_out (vty, "Can't find default instance%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ network = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
+ network = argv_find (argv, argc, "A.B.C.D/M", &idx) ? argv[idx]->arg : NULL;
+ return bgp_show_route (vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
}
+#endif /* KEEP_OLD_VPN_COMMANDS */
static void
show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
@@ -12306,7 +9130,7 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
if (use_json)
{
json_object_string_add(json, "alert", "no BGP");
- vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
json_object_free(json);
}
else
@@ -12447,7 +9271,7 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
}
if (use_json)
{
- vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
json_object_free(json);
}
@@ -12467,7 +9291,7 @@ peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
if (use_json)
{
json_object_string_add(json, "warning", "No such neighbor or address family");
- vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
json_object_free(json);
}
else
@@ -12481,7 +9305,7 @@ peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
if (use_json)
{
json_object_string_add(json, "warning", "Inbound soft reconfiguration not enabled");
- vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
json_object_free(json);
}
else
@@ -12497,723 +9321,128 @@ peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
show_ip_bgp_instance_neighbor_advertised_route_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- if (argc == 4 || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0))
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
- else
- peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
-
- if (! peer)
- return CMD_WARNING;
-
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0, NULL, uj);
-}
-
-DEFUN (show_ip_bgp_neighbor_advertised_route,
- show_ip_bgp_neighbor_advertised_route_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-
-{
- struct peer *peer;
- const char *rmap_name = NULL;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
-
- if (! peer)
- return CMD_WARNING;
-
- if ((argc == 2 && argv[1] && strcmp(argv[1], "json") != 0)
- || (argc == 3))
- rmap_name = argv[1];
-
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0, rmap_name, uj);
-}
-
-ALIAS (show_ip_bgp_neighbor_advertised_route,
- show_ip_bgp_neighbor_advertised_route_rmap_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes route-map WORD {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-
-ALIAS (show_ip_bgp_instance_neighbor_advertised_route,
- show_ip_bgp_instance_neighbor_advertised_route_rmap_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes route-map WORD {json}",
+ "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
+ "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
+ BGP_AFI_HELP_STR
+ BGP_SAFI_HELP_STR
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route,
- show_ip_bgp_ipv4_neighbor_advertised_route_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- const char *rmap_name = NULL;
- safi_t safi;
-
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
- if (! peer)
- return CMD_WARNING;
-
- if ((argc == 4) || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0))
- rmap_name = argv[2];
-
- safi = bgp_vty_safi_from_arg(argv[0]);
- return peer_adj_routes (vty, peer, AFI_IP, safi, 0, rmap_name, uj);
-}
-
-ALIAS (show_ip_bgp_ipv4_neighbor_advertised_route,
- show_ip_bgp_ipv4_neighbor_advertised_route_rmap_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes route-map WORD {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "Route-map to control what is displayed\n"
- "JavaScript Object Notation\n")
-
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_instance_neighbor_advertised_route,
- show_bgp_instance_neighbor_advertised_route_cmd,
- "show bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- if (argc == 4 || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0))
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
- else
- peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
-
- if (! peer)
- return CMD_WARNING;
-
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 0, NULL, uj);
-}
-
-ALIAS (show_bgp_instance_neighbor_advertised_route,
- show_bgp_instance_ipv6_neighbor_advertised_route_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_bgp_neighbor_advertised_route,
- show_bgp_neighbor_advertised_route_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-
-{
- struct peer *peer;
- const char *rmap_name = NULL;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
-
- if (!peer)
- return CMD_WARNING;
-
- if (argc == 3 || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0))
- rmap_name = argv[1];
-
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 0, rmap_name, uj);
-}
-
-ALIAS (show_bgp_neighbor_advertised_route,
- show_bgp_ipv6_neighbor_advertised_route_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-
-/* old command */
-ALIAS (show_bgp_neighbor_advertised_route,
- ipv6_bgp_neighbor_advertised_route_cmd,
- "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-
-/* old command */
-DEFUN (ipv6_mbgp_neighbor_advertised_route,
- ipv6_mbgp_neighbor_advertised_route_cmd,
- "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Neighbor on bgp configured interface\n"
- "Display the routes advertised to a BGP neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
- if (! peer)
- return CMD_WARNING;
-
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 0, NULL, uj);
-}
-#endif /* HAVE_IPV6 */
-
-DEFUN (show_bgp_instance_neighbor_received_routes,
- show_bgp_instance_neighbor_received_routes_cmd,
- "show bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
+ "Neighbor on BGP configured interface\n"
"Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
+ "Display the routes advertised to a BGP neighbor\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n"
+ JSON_STR)
{
+ vrf_id_t vrf = VRF_DEFAULT;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ char *rmap_name = NULL;
+ char *peerstr = NULL;
+ int rcvd = 0;
+ struct bgp *bgp = NULL;
struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
- if (! peer)
- return CMD_WARNING;
-
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 1, NULL, uj);
-}
-DEFUN (show_ip_bgp_instance_neighbor_received_routes,
- show_ip_bgp_instance_neighbor_received_routes_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
+ int idx = 0;
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
- if (! peer)
+ bgp_vty_find_and_parse_afi_safi_vrf (vty, argv, argc, &idx, &afi, &safi, &vrf);
+ if (!idx)
return CMD_WARNING;
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1, NULL, uj);
-}
-
-ALIAS (show_bgp_instance_neighbor_received_routes,
- show_bgp_instance_ipv6_neighbor_received_routes_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_ip_bgp_neighbor_received_routes,
- show_ip_bgp_neighbor_received_routes_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-
-{
- struct peer *peer;
- const char *rmap_name = NULL;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
-
- if (! peer)
- return CMD_WARNING;
-
- if (argc == 3 || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0))
- rmap_name = argv[1];
-
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1, rmap_name, uj);
-}
-
-ALIAS (show_ip_bgp_neighbor_received_routes,
- show_ip_bgp_neighbor_received_routes_rmap_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes route-map WORD {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-
-ALIAS (show_ip_bgp_instance_neighbor_received_routes,
- show_ip_bgp_instance_neighbor_received_routes_rmap_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) received-routes route-map WORD {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_ip_bgp_ipv4_neighbor_received_routes,
- show_ip_bgp_ipv4_neighbor_received_routes_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- const char *rmap_name = NULL;
- safi_t safi;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
- if (! peer)
- return CMD_WARNING;
-
- if (argc == 4 || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0))
- rmap_name = argv[2];
-
- safi = bgp_vty_safi_from_arg(argv[0]);
- return peer_adj_routes (vty, peer, AFI_IP, safi, 1, rmap_name, uj);
-}
-
-ALIAS (show_ip_bgp_ipv4_neighbor_received_routes,
- show_ip_bgp_ipv4_neighbor_received_routes_rmap_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received-routes route-map WORD {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
+ int uj = use_json (argc, argv);
+ if (uj) argc--;
-DEFUN (show_bgp_instance_afi_safi_neighbor_adv_recd_routes,
- show_bgp_instance_afi_safi_neighbor_adv_recd_routes_cmd,
- "show bgp " BGP_INSTANCE_CMD " (ipv4|ipv6) (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) (advertised-routes|received-routes) {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Address family\n"
- "Address family modifier\n"
- "Address family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the advertised routes to neighbor\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-{
- int afi;
- int safi;
- int in;
- struct peer *peer;
- u_char uj = use_json(argc, argv);
+ bgp = bgp_lookup_by_vrf_id (vrf);
+ if (bgp == NULL)
+ {
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "Can't find BGP view");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "Can't find BGP instance %s%s", argv[5]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- peer = peer_lookup_in_view (vty, argv[1], argv[4], uj);
+ /* neighbors <A.B.C.D|X:X::X:X|WORD> */
+ argv_find (argv, argc, "neighbors", &idx);
+ peerstr = argv[++idx]->arg;
- if (! peer)
+ peer = peer_lookup_in_view (vty, bgp, peerstr, uj);
+ if (! peer)
return CMD_WARNING;
- afi = bgp_vty_safi_from_arg(argv[2]);
- safi = bgp_vty_safi_from_arg(argv[3]);
- in = (strncmp (argv[5], "r", 1) == 0) ? 1 : 0;
+ if (argv_find (argv, argc, "received-routes", &idx))
+ rcvd = 1;
+ if (argv_find (argv, argc, "advertised-routes", &idx))
+ rcvd = 0;
+ if (argv_find (argv, argc, "route-map", &idx))
+ rmap_name = argv[++idx]->arg;
- return peer_adj_routes (vty, peer, afi, safi, in, NULL, uj);
+ return peer_adj_routes (vty, peer, afi, safi, rcvd, rmap_name, uj);
}
DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
show_ip_bgp_neighbor_received_prefix_filter_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}",
+ "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
SHOW_STR
IP_STR
BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n"
- "JavaScript Object Notation\n")
-{
- char name[BUFSIZ];
- union sockunion su;
- struct peer *peer;
- int count, ret;
- u_char uj = use_json(argc, argv);
-
- ret = str2sockunion (argv[0], &su);
- if (ret < 0)
- {
- peer = peer_lookup_by_conf_if (NULL, argv[0]);
- if (! peer)
- {
- if (uj)
- {
- json_object *json_no = NULL;
- json_object *json_sub = NULL;
- json_no = json_object_new_object();
- json_sub = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed address or name");
- json_object_string_add(json_sub, "warningCause", argv[0]);
- json_object_object_add(json_no, "detail", json_sub);
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "%% Malformed address or name: %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- else
- {
- peer = peer_lookup (NULL, &su);
- if (! peer)
- {
- if (uj)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Peer not found");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "No peer%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST);
- count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name, uj);
- if (count)
- {
- if (!uj)
- vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, AFI_IP, name, uj);
- }
- else
- {
- if (uj)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_boolean_true_add(json_no, "noFuntionalOutput");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "No functional output%s", VTY_NEWLINE);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter,
- show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
+ "Address Family\n"
+ "Address Family\n"
"Address Family modifier\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
+ "Neighbor on BGP configured interface\n"
"Display information received from a BGP neighbor\n"
"Display the prefixlist filter\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ char *peerstr = NULL;
+
char name[BUFSIZ];
union sockunion su;
struct peer *peer;
int count, ret;
- u_char uj = use_json(argc, argv);
-
- ret = str2sockunion (argv[1], &su);
- if (ret < 0)
- {
- peer = peer_lookup_by_conf_if (NULL, argv[1]);
- if (! peer)
- {
- if (uj)
- {
- json_object *json_no = NULL;
- json_object *json_sub = NULL;
- json_no = json_object_new_object();
- json_sub = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed address or name");
- json_object_string_add(json_sub, "warningCause", argv[1]);
- json_object_object_add(json_no, "detail", json_sub);
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "%% Malformed address or name: %s%s", argv[1], VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- else
- {
- peer = peer_lookup (NULL, &su);
- if (! peer)
- {
- if (uj)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Peer not found");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "No peer%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- {
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- sprintf (name, "%s.%d.%d", peer->host, AFI_IP, safi);
- count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name, uj);
- if (count)
- {
- if (!uj)
- vty_out (vty, "Address family: %s%s",
- afi_safi_print (AFI_IP, safi), VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, AFI_IP, name, uj);
- }
- else
- {
- if (uj)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_boolean_true_add(json_no, "noFuntionalOutput");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "No functional output%s", VTY_NEWLINE);
- }
- }
+ int idx = 0;
- return CMD_SUCCESS;
-}
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_neighbor_received_routes,
- show_bgp_neighbor_received_routes_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- const char *rmap_name = NULL;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
+ /* show [ip] bgp */
+ if (argv_find (argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ /* [<ipv4|ipv6> [unicast]] */
+ if (argv_find (argv, argc, "ipv4", &idx))
+ afi = AFI_IP;
+ if (argv_find (argv, argc, "ipv6", &idx))
+ afi = AFI_IP6;
+ /* neighbors <A.B.C.D|X:X::X:X|WORD> */
+ argv_find (argv, argc, "neighbors", &idx);
+ peerstr = argv[++idx]->arg;
- if (! peer)
- return CMD_WARNING;
-
- if (argc == 3 || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0))
- rmap_name = argv[1];
-
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 1, rmap_name, uj);
-}
-
-ALIAS (show_bgp_neighbor_received_routes,
- show_bgp_ipv6_neighbor_received_routes_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_bgp_neighbor_received_prefix_filter,
- show_bgp_neighbor_received_prefix_filter_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n"
- "JavaScript Object Notation\n")
-{
- char name[BUFSIZ];
- union sockunion su;
- struct peer *peer;
- int count, ret;
u_char uj = use_json(argc, argv);
- ret = str2sockunion (argv[0], &su);
+ ret = str2sockunion (peerstr, &su);
if (ret < 0)
{
- peer = peer_lookup_by_conf_if (NULL, argv[0]);
+ peer = peer_lookup_by_conf_if (NULL, peerstr);
if (! peer)
{
if (uj)
- {
- json_object *json_no = NULL;
- json_object *json_sub = NULL;
- json_no = json_object_new_object();
- json_sub = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed address or name");
- json_object_string_add(json_sub, "warningCause", argv[0]);
- json_object_object_add(json_no, "detail", json_sub);
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
+ vty_out (vty, "{}%s", VTY_NEWLINE);
else
- vty_out (vty, "%% Malformed address or name: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Malformed address or name: %s%s", peerstr, VTY_NEWLINE);
return CMD_WARNING;
}
}
@@ -13223,37 +9452,25 @@ DEFUN (show_bgp_neighbor_received_prefix_filter,
if (! peer)
{
if (uj)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "No Peer");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
+ vty_out (vty, "{}%s", VTY_NEWLINE);
else
vty_out (vty, "No peer%s", VTY_NEWLINE);
return CMD_WARNING;
}
}
- sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST);
- count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name, uj);
+ sprintf (name, "%s.%d.%d", peer->host, afi, safi);
+ count = prefix_bgp_show_prefix_list (NULL, afi, name, uj);
if (count)
{
if (!uj)
- vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, AFI_IP6, name, uj);
+ vty_out (vty, "Address Family: %s%s", afi_safi_print(afi, safi), VTY_NEWLINE);
+ prefix_bgp_show_prefix_list (vty, afi, name, uj);
}
else
{
if (uj)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_boolean_true_add(json_no, "noFuntionalOutput");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
+ vty_out (vty, "{}%s", VTY_NEWLINE);
else
vty_out (vty, "No functional output%s", VTY_NEWLINE);
}
@@ -13261,167 +9478,6 @@ DEFUN (show_bgp_neighbor_received_prefix_filter,
return CMD_SUCCESS;
}
-ALIAS (show_bgp_neighbor_received_prefix_filter,
- show_bgp_ipv6_neighbor_received_prefix_filter_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n"
- "JavaScript Object Notation\n")
-
-/* old command */
-ALIAS (show_bgp_neighbor_received_routes,
- ipv6_bgp_neighbor_received_routes_cmd,
- "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-
-/* old command */
-DEFUN (ipv6_mbgp_neighbor_received_routes,
- ipv6_mbgp_neighbor_received_routes_cmd,
- "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the received routes from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
- if (! peer)
- return CMD_WARNING;
-
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 1, NULL, uj);
-}
-
-DEFUN (show_bgp_instance_neighbor_received_prefix_filter,
- show_bgp_instance_neighbor_received_prefix_filter_cmd,
- "show bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n"
- "JavaScript Object Notation\n")
-{
- char name[BUFSIZ];
- union sockunion su;
- struct peer *peer;
- struct bgp *bgp;
- int count, ret;
- u_char uj = use_json(argc, argv);
-
- /* BGP structure lookup. */
- bgp = bgp_lookup_by_name (argv[1]);
- if (bgp == NULL)
- {
- if (uj)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "Can't find BGP view");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "Can't find BGP instance %s%s", argv[1], VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ret = str2sockunion (argv[2], &su);
- if (ret < 0)
- {
- peer = peer_lookup_by_conf_if (bgp, argv[2]);
- if (! peer)
- {
- if (uj)
- {
- json_object *json_no = NULL;
- json_object *json_sub = NULL;
- json_no = json_object_new_object();
- json_sub = json_object_new_object();
- json_object_string_add(json_no, "warning", "Malformed address or name");
- json_object_string_add(json_sub, "warningCause", argv[2]);
- json_object_object_add(json_no, "detail", json_sub);
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "%% Malformed address or name: %s%s", argv[2], VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- else
- {
- peer = peer_lookup (bgp, &su);
- if (! peer)
- {
- if (uj)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_boolean_true_add(json_no, "noPeer");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "No peer%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- }
-
- sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST);
- count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name, uj);
- if (count)
- {
- if (!uj)
- vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, AFI_IP6, name, uj);
- }
-
- return CMD_SUCCESS;
-}
-ALIAS (show_bgp_instance_neighbor_received_prefix_filter,
- show_bgp_instance_ipv6_neighbor_received_prefix_filter_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n"
- "JavaScript Object NOtation\n")
-#endif /* HAVE_IPV6 */
-
static int
bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
safi_t safi, enum bgp_show_type type, u_char use_json)
@@ -13446,384 +9502,82 @@ bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
DEFUN (show_ip_bgp_neighbor_routes,
show_ip_bgp_neighbor_routes_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
- bgp_show_type_neighbor, uj);
-}
-
-DEFUN (show_ip_bgp_instance_neighbor_routes,
- show_ip_bgp_instance_neighbor_routes_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}",
+ "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
+ "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
+ BGP_AFI_HELP_STR
+ BGP_SAFI_HELP_STR
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
- bgp_show_type_neighbor, uj);
-}
-
-DEFUN (show_ip_bgp_neighbor_flap,
- show_ip_bgp_neighbor_flap_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
+ "Neighbor on BGP configured interface\n"
"Display flap statistics of the routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_neighbor, uj);
-}
-
-DEFUN (show_ip_bgp_neighbor_damp,
- show_ip_bgp_neighbor_damp_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
"Display the dampened routes received from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
- bgp_show_type_damp_neighbor, uj);
-}
-
-DEFUN (show_ip_bgp_ipv4_neighbor_routes,
- show_ip_bgp_ipv4_neighbor_routes_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- safi_t safi;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
- if (! peer)
- return CMD_WARNING;
-
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_show_neighbor_route (vty, peer, AFI_IP, safi,
- bgp_show_type_neighbor, uj);
-}
-
-#ifdef HAVE_IPV6
-DEFUN (show_bgp_instance_neighbor_routes,
- show_bgp_instance_neighbor_routes_cmd,
- "show bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
"Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_neighbor, uj);
-}
-
-ALIAS (show_bgp_instance_neighbor_routes,
- show_bgp_instance_ipv6_neighbor_routes_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_bgp_instance_neighbor_damp,
- show_bgp_instance_neighbor_damp_cmd,
- "show bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the dampened routes received from neighbor\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ vrf_id_t vrf = VRF_DEFAULT;
+ char *peerstr = NULL;
+ struct bgp *bgp = NULL;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
struct peer *peer;
- u_char uj = use_json(argc, argv);
+ enum bgp_show_type sh_type = bgp_show_type_neighbor;
- if ((argc == 4 && argv[3] && strcmp(argv[3], "json") == 0)
- || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0))
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
- else
- peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
+ int idx = 0;
- if (! peer)
+ bgp_vty_find_and_parse_afi_safi_vrf (vty, argv, argc, &idx, &afi, &safi, &vrf);
+ if (!idx)
return CMD_WARNING;
- return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_damp_neighbor, uj);
-}
-
-ALIAS (show_bgp_instance_neighbor_damp,
- show_bgp_instance_ipv6_neighbor_damp_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the dampened routes received from neighbor\n"
- "JavaScript Object Notation\n")
+ int uj = use_json (argc, argv);
+ if (uj) argc--;
-DEFUN (show_bgp_instance_neighbor_flap,
- show_bgp_instance_neighbor_flap_cmd,
- "show bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display flap statistics of the routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- if ((argc == 4 && argv[3] && strcmp(argv[3], "json") == 0)
- || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0))
- peer = peer_lookup_in_view (vty, argv[1], argv[2], uj);
+ if (vrf != VRF_ALL)
+ {
+ bgp = bgp_lookup_by_vrf_id (vrf);
+ if (bgp == NULL)
+ {
+ if (uj)
+ {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning", "Can't find BGP view");
+ vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
+ json_object_free(json_no);
+ }
+ else
+ vty_out (vty, "Can't find BGP instance %s%s", argv[5]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
else
- peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
-
- if (! peer)
- return CMD_WARNING;
+ bgp = NULL;
- return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_flap_neighbor, uj);
-}
+ /* neighbors <A.B.C.D|X:X::X:X|WORD> */
+ argv_find (argv, argc, "neighbors", &idx);
+ peerstr = argv[++idx]->arg;
-ALIAS (show_bgp_instance_neighbor_flap,
- show_bgp_instance_ipv6_neighbor_flap_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display flap statistics of the routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_bgp_neighbor_routes,
- show_bgp_neighbor_routes_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
+ peer = peer_lookup_in_view (vty, bgp, peerstr, uj);
if (! peer)
- return CMD_WARNING;
-
- return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_neighbor, uj);
-}
-
-
-ALIAS (show_bgp_neighbor_routes,
- show_bgp_ipv6_neighbor_routes_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
+ {
+ vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
-/* old command */
-ALIAS (show_bgp_neighbor_routes,
- ipv6_bgp_neighbor_routes_cmd,
- "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
+ if (argv_find (argv, argc, "flap-statistics", &idx))
+ sh_type = bgp_show_type_flap_neighbor;
+ else if (argv_find (argv, argc, "dampened-routes", &idx))
+ sh_type = bgp_show_type_damp_neighbor;
+ else if (argv_find (argv, argc, "routes", &idx))
+ sh_type = bgp_show_type_neighbor;
-/* old command */
-DEFUN (ipv6_mbgp_neighbor_routes,
- ipv6_mbgp_neighbor_routes_cmd,
- "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-{
- struct peer *peer;
- u_char uj = use_json(argc, argv);
-
- peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
- if (! peer)
- return CMD_WARNING;
-
- bgp_show_ipv6_bgp_deprecate_warning(vty);
- return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_neighbor, uj);
+ return bgp_show_neighbor_route (vty, peer, afi, safi, sh_type, uj);
}
-ALIAS (show_bgp_instance_neighbor_flap,
- show_bgp_neighbor_flap_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display flap statistics of the routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-
-ALIAS (show_bgp_instance_neighbor_flap,
- show_bgp_ipv6_neighbor_flap_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display flap statistics of the routes learned from neighbor\n"
- "JavaScript Object Notation\n")
-
-ALIAS (show_bgp_instance_neighbor_damp,
- show_bgp_neighbor_damp_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the dampened routes received from neighbor\n"
- "JavaScript Object Notation\n")
-
-ALIAS (show_bgp_instance_neighbor_damp,
- show_bgp_ipv6_neighbor_damp_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "Display the dampened routes received from neighbor\n"
- "JavaScript Object Notation\n")
-
-#endif /* HAVE_IPV6 */
-
struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
struct bgp_distance
@@ -13835,6 +9589,34 @@ struct bgp_distance
char *access_list;
};
+DEFUN (show_bgp_afi_vpn_rd_route,
+ show_bgp_afi_vpn_rd_route_cmd,
+ "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn <A.B.C.D/M|X:X::X:X/M> [json]",
+ SHOW_STR
+ BGP_STR
+ BGP_AFI_HELP_STR
+ "Address Family modifier\n"
+ "Display information for a route distinguisher\n"
+ "Route Distinguisher\n"
+ "Network in the BGP routing table to display\n"
+ "Network in the BGP routing table to display\n"
+ JSON_STR)
+{
+ int ret;
+ struct prefix_rd prd;
+ afi_t afi = AFI_MAX;
+ int idx = 0;
+
+ argv_find_and_parse_afi (argv, argc, &idx, &afi);
+ ret = str2prefix_rd (argv[5]->arg, &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_route (vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, use_json (argc, argv));
+}
+
static struct bgp_distance *
bgp_distance_new (void)
{
@@ -14015,30 +9797,32 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, afi_t afi,
DEFUN (bgp_distance,
bgp_distance_cmd,
- "distance bgp <1-255> <1-255> <1-255>",
+ "distance bgp (1-255) (1-255) (1-255)",
"Define an administrative distance\n"
"BGP distance\n"
"Distance for routes external to the AS\n"
"Distance for routes internal to the AS\n"
"Distance for local routes\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 2;
+ int idx_number_2 = 3;
+ int idx_number_3 = 4;
afi_t afi;
safi_t safi;
- bgp = vty->index;
afi = bgp_node_afi (vty);
safi = bgp_node_safi (vty);
- bgp->distance_ebgp[afi][safi] = atoi (argv[0]);
- bgp->distance_ibgp[afi][safi] = atoi (argv[1]);
- bgp->distance_local[afi][safi] = atoi (argv[2]);
+ bgp->distance_ebgp[afi][safi] = atoi (argv[idx_number]->arg);
+ bgp->distance_ibgp[afi][safi] = atoi (argv[idx_number_2]->arg);
+ bgp->distance_local[afi][safi] = atoi (argv[idx_number_3]->arg);
return CMD_SUCCESS;
}
DEFUN (no_bgp_distance,
no_bgp_distance_cmd,
- "no distance bgp <1-255> <1-255> <1-255>",
+ "no distance bgp [(1-255) (1-255) (1-255)]",
NO_STR
"Define an administrative distance\n"
"BGP distance\n"
@@ -14046,11 +9830,10 @@ DEFUN (no_bgp_distance,
"Distance for routes internal to the AS\n"
"Distance for local routes\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
afi_t afi;
safi_t safi;
- bgp = vty->index;
afi = bgp_node_afi (vty);
safi = bgp_node_safi (vty);
@@ -14060,112 +9843,116 @@ DEFUN (no_bgp_distance,
return CMD_SUCCESS;
}
-ALIAS (no_bgp_distance,
- no_bgp_distance2_cmd,
- "no distance bgp",
- NO_STR
- "Define an administrative distance\n"
- "BGP distance\n")
DEFUN (bgp_distance_source,
bgp_distance_source_cmd,
- "distance <1-255> A.B.C.D/M",
+ "distance (1-255) A.B.C.D/M",
"Define an administrative distance\n"
"Administrative distance\n"
"IP source prefix\n")
{
- bgp_distance_set (vty, argv[0], argv[1], NULL);
+ int idx_number = 1;
+ int idx_ipv4_prefixlen = 2;
+ bgp_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
return CMD_SUCCESS;
}
DEFUN (no_bgp_distance_source,
no_bgp_distance_source_cmd,
- "no distance <1-255> A.B.C.D/M",
+ "no distance (1-255) A.B.C.D/M",
NO_STR
"Define an administrative distance\n"
"Administrative distance\n"
"IP source prefix\n")
{
- bgp_distance_unset (vty, argv[0], argv[1], NULL);
+ int idx_number = 2;
+ int idx_ipv4_prefixlen = 3;
+ bgp_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
return CMD_SUCCESS;
}
DEFUN (bgp_distance_source_access_list,
bgp_distance_source_access_list_cmd,
- "distance <1-255> A.B.C.D/M WORD",
+ "distance (1-255) A.B.C.D/M WORD",
"Define an administrative distance\n"
"Administrative distance\n"
"IP source prefix\n"
"Access list name\n")
{
- bgp_distance_set (vty, argv[0], argv[1], argv[2]);
+ int idx_number = 1;
+ int idx_ipv4_prefixlen = 2;
+ int idx_word = 3;
+ bgp_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
return CMD_SUCCESS;
}
DEFUN (no_bgp_distance_source_access_list,
no_bgp_distance_source_access_list_cmd,
- "no distance <1-255> A.B.C.D/M WORD",
+ "no distance (1-255) A.B.C.D/M WORD",
NO_STR
"Define an administrative distance\n"
"Administrative distance\n"
"IP source prefix\n"
"Access list name\n")
{
- bgp_distance_unset (vty, argv[0], argv[1], argv[2]);
+ int idx_number = 2;
+ int idx_ipv4_prefixlen = 3;
+ int idx_word = 4;
+ bgp_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
return CMD_SUCCESS;
}
DEFUN (ipv6_bgp_distance_source,
ipv6_bgp_distance_source_cmd,
- "distance <1-255> X:X::X:X/M",
+ "distance (1-255) X:X::X:X/M",
"Define an administrative distance\n"
"Administrative distance\n"
"IP source prefix\n")
{
- bgp_distance_set (vty, argv[0], argv[1], NULL);
+ bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, NULL);
return CMD_SUCCESS;
}
DEFUN (no_ipv6_bgp_distance_source,
no_ipv6_bgp_distance_source_cmd,
- "no distance <1-255> X:X::X:X/M",
+ "no distance (1-255) X:X::X:X/M",
NO_STR
"Define an administrative distance\n"
"Administrative distance\n"
"IP source prefix\n")
{
- bgp_distance_unset (vty, argv[0], argv[1], NULL);
+ bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, NULL);
return CMD_SUCCESS;
}
DEFUN (ipv6_bgp_distance_source_access_list,
ipv6_bgp_distance_source_access_list_cmd,
- "distance <1-255> X:X::X:X/M WORD",
+ "distance (1-255) X:X::X:X/M WORD",
"Define an administrative distance\n"
"Administrative distance\n"
"IP source prefix\n"
"Access list name\n")
{
- bgp_distance_set (vty, argv[0], argv[1], argv[2]);
+ bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
return CMD_SUCCESS;
}
DEFUN (no_ipv6_bgp_distance_source_access_list,
no_ipv6_bgp_distance_source_access_list_cmd,
- "no distance <1-255> X:X::X:X/M WORD",
+ "no distance (1-255) X:X::X:X/M WORD",
NO_STR
"Define an administrative distance\n"
"Administrative distance\n"
"IP source prefix\n"
"Access list name\n")
{
- bgp_distance_unset (vty, argv[0], argv[1], argv[2]);
+ bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
return CMD_SUCCESS;
}
DEFUN (bgp_damp_set,
bgp_damp_set_cmd,
- "bgp dampening <1-45> <1-20000> <1-20000> <1-255>",
+ "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
"BGP Specific commands\n"
"Enable route-flap dampening\n"
"Half-life time for the penalty\n"
@@ -14173,27 +9960,29 @@ DEFUN (bgp_damp_set,
"Value to start suppressing a route\n"
"Maximum duration to suppress a stable route\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_half_life = 2;
+ int idx_reuse = 3;
+ int idx_suppress = 4;
+ int idx_max_suppress = 5;
int half = DEFAULT_HALF_LIFE * 60;
int reuse = DEFAULT_REUSE;
int suppress = DEFAULT_SUPPRESS;
int max = 4 * half;
- if (argc == 4)
+ if (argc == 6)
{
- half = atoi (argv[0]) * 60;
- reuse = atoi (argv[1]);
- suppress = atoi (argv[2]);
- max = atoi (argv[3]) * 60;
+ half = atoi (argv[idx_half_life]->arg) * 60;
+ reuse = atoi (argv[idx_reuse]->arg);
+ suppress = atoi (argv[idx_suppress]->arg);
+ max = atoi (argv[idx_max_suppress]->arg) * 60;
}
- else if (argc == 1)
+ else if (argc == 3)
{
- half = atoi (argv[0]) * 60;
+ half = atoi (argv[idx_half_life]->arg) * 60;
max = 4 * half;
}
- bgp = vty->index;
-
if (suppress < reuse)
{
vty_out (vty, "Suppress value cannot be less than reuse value %s",
@@ -14205,35 +9994,9 @@ DEFUN (bgp_damp_set,
half, reuse, suppress, max);
}
-ALIAS (bgp_damp_set,
- bgp_damp_set2_cmd,
- "bgp dampening <1-45>",
- "BGP Specific commands\n"
- "Enable route-flap dampening\n"
- "Half-life time for the penalty\n")
-
-ALIAS (bgp_damp_set,
- bgp_damp_set3_cmd,
- "bgp dampening",
- "BGP Specific commands\n"
- "Enable route-flap dampening\n")
-
DEFUN (bgp_damp_unset,
bgp_damp_unset_cmd,
- "no bgp dampening",
- NO_STR
- "BGP Specific commands\n"
- "Enable route-flap dampening\n")
-{
- struct bgp *bgp;
-
- bgp = vty->index;
- return bgp_damp_disable (bgp, bgp_node_afi (vty), bgp_node_safi (vty));
-}
-
-ALIAS (bgp_damp_unset,
- bgp_damp_unset2_cmd,
- "no bgp dampening <1-45> <1-20000> <1-20000> <1-255>",
+ "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
NO_STR
"BGP Specific commands\n"
"Enable route-flap dampening\n"
@@ -14241,57 +10004,11 @@ ALIAS (bgp_damp_unset,
"Value to start reusing a route\n"
"Value to start suppressing a route\n"
"Maximum duration to suppress a stable route\n")
-
-ALIAS (bgp_damp_unset,
- bgp_damp_unset3_cmd,
- "no bgp dampening <1-45>",
- NO_STR
- "BGP Specific commands\n"
- "Enable route-flap dampening\n"
- "Half-life time for the penalty\n")
-
-DEFUN (show_ip_bgp_dampened_paths,
- show_ip_bgp_dampened_paths_cmd,
- "show ip bgp dampened-paths",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display paths suppressed due to dampening\n")
-{
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_dampend_paths,
- NULL, 0);
-}
-
-ALIAS (show_ip_bgp_dampened_paths,
- show_ip_bgp_damp_dampened_paths_cmd,
- "show ip bgp dampening dampened-paths",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display paths suppressed due to dampening\n")
-
-DEFUN (show_ip_bgp_flap_statistics,
- show_ip_bgp_flap_statistics_cmd,
- "show ip bgp flap-statistics",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n")
{
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_statistics, NULL, 0);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ return bgp_damp_disable (bgp, bgp_node_afi (vty), bgp_node_safi (vty));
}
-ALIAS (show_ip_bgp_flap_statistics,
- show_ip_bgp_damp_flap_statistics_cmd,
- "show ip bgp dampening flap-statistics",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display detailed information about dampening\n"
- "Display flap statistics of routes\n")
-
/* Display specified route of BGP table. */
static int
bgp_clear_damp_route (struct vty *vty, const char *view_name,
@@ -14413,9 +10130,10 @@ DEFUN (clear_ip_bgp_dampening_prefix,
IP_STR
BGP_STR
"Clear route flap dampening information\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+ "IPv4 prefix\n")
{
- return bgp_clear_damp_route (vty, NULL, argv[0], AFI_IP,
+ int idx_ipv4_prefixlen = 4;
+ return bgp_clear_damp_route (vty, NULL, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
SAFI_UNICAST, NULL, 1);
}
@@ -14428,7 +10146,8 @@ DEFUN (clear_ip_bgp_dampening_address,
"Clear route flap dampening information\n"
"Network to clear damping information\n")
{
- return bgp_clear_damp_route (vty, NULL, argv[0], AFI_IP,
+ int idx_ipv4 = 4;
+ return bgp_clear_damp_route (vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
SAFI_UNICAST, NULL, 0);
}
@@ -14442,10 +10161,12 @@ DEFUN (clear_ip_bgp_dampening_address_mask,
"Network to clear damping information\n"
"Network mask\n")
{
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
int ret;
char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
+ ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
if (! ret)
{
vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
@@ -14458,7 +10179,7 @@ DEFUN (clear_ip_bgp_dampening_address_mask,
/* also used for encap safi */
static int
-bgp_config_write_network_vpnv4 (struct vty *vty, struct bgp *bgp,
+bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp,
afi_t afi, safi_t safi, int *write)
{
struct bgp_node *prn;
@@ -14508,8 +10229,8 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
struct bgp_aggregate *bgp_aggregate;
char buf[SU_ADDRSTRLEN];
- if (afi == AFI_IP && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)))
- return bgp_config_write_network_vpnv4 (vty, bgp, afi, safi, write);
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
+ return bgp_config_write_network_vpn (vty, bgp, afi, safi, write);
/* Network configuration. */
for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
@@ -14660,33 +10381,11 @@ bgp_route_init (void)
install_element (BGP_NODE, &no_bgp_network_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_natural_cmd);
- install_element (BGP_NODE, &no_bgp_network_route_map_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_route_map_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_natural_route_map_cmd);
- install_element (BGP_NODE, &no_bgp_network_backdoor_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_backdoor_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_cmd);
install_element (BGP_NODE, &aggregate_address_cmd);
install_element (BGP_NODE, &aggregate_address_mask_cmd);
- install_element (BGP_NODE, &aggregate_address_summary_only_cmd);
- install_element (BGP_NODE, &aggregate_address_mask_summary_only_cmd);
- install_element (BGP_NODE, &aggregate_address_as_set_cmd);
- install_element (BGP_NODE, &aggregate_address_mask_as_set_cmd);
- install_element (BGP_NODE, &aggregate_address_as_set_summary_cmd);
- install_element (BGP_NODE, &aggregate_address_mask_as_set_summary_cmd);
- install_element (BGP_NODE, &aggregate_address_summary_as_set_cmd);
- install_element (BGP_NODE, &aggregate_address_mask_summary_as_set_cmd);
install_element (BGP_NODE, &no_aggregate_address_cmd);
- install_element (BGP_NODE, &no_aggregate_address_summary_only_cmd);
- install_element (BGP_NODE, &no_aggregate_address_as_set_cmd);
- install_element (BGP_NODE, &no_aggregate_address_as_set_summary_cmd);
- install_element (BGP_NODE, &no_aggregate_address_summary_as_set_cmd);
install_element (BGP_NODE, &no_aggregate_address_mask_cmd);
- install_element (BGP_NODE, &no_aggregate_address_mask_summary_only_cmd);
- install_element (BGP_NODE, &no_aggregate_address_mask_as_set_cmd);
- install_element (BGP_NODE, &no_aggregate_address_mask_as_set_summary_cmd);
- install_element (BGP_NODE, &no_aggregate_address_mask_summary_as_set_cmd);
/* IPv4 unicast configuration. */
install_element (BGP_IPV4_NODE, &bgp_table_map_cmd);
@@ -14700,30 +10399,11 @@ bgp_route_init (void)
install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_route_map_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_mask_route_map_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_route_map_cmd);
install_element (BGP_IPV4_NODE, &aggregate_address_cmd);
install_element (BGP_IPV4_NODE, &aggregate_address_mask_cmd);
- install_element (BGP_IPV4_NODE, &aggregate_address_summary_only_cmd);
- install_element (BGP_IPV4_NODE, &aggregate_address_mask_summary_only_cmd);
- install_element (BGP_IPV4_NODE, &aggregate_address_as_set_cmd);
- install_element (BGP_IPV4_NODE, &aggregate_address_mask_as_set_cmd);
- install_element (BGP_IPV4_NODE, &aggregate_address_as_set_summary_cmd);
- install_element (BGP_IPV4_NODE, &aggregate_address_mask_as_set_summary_cmd);
- install_element (BGP_IPV4_NODE, &aggregate_address_summary_as_set_cmd);
- install_element (BGP_IPV4_NODE, &aggregate_address_mask_summary_as_set_cmd);
install_element (BGP_IPV4_NODE, &no_aggregate_address_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_summary_only_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_as_set_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_as_set_summary_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_summary_as_set_cmd);
install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_summary_only_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_as_set_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_as_set_summary_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_summary_as_set_cmd);
/* IPv4 multicast configuration. */
install_element (BGP_IPV4M_NODE, &bgp_table_map_cmd);
@@ -14737,158 +10417,36 @@ bgp_route_init (void)
install_element (BGP_IPV4M_NODE, &no_bgp_network_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_route_map_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_route_map_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_route_map_cmd);
install_element (BGP_IPV4M_NODE, &aggregate_address_cmd);
install_element (BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_summary_only_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_mask_summary_only_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_as_set_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_mask_as_set_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_as_set_summary_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_mask_as_set_summary_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_summary_as_set_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_mask_summary_as_set_cmd);
install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_summary_only_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_as_set_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_as_set_summary_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_summary_as_set_cmd);
install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_summary_only_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_as_set_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_as_set_summary_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_summary_as_set_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_safi_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_cmd);
install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_route_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_route_pathtype_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_route_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_safi_route_pathtype_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_safi_route_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_prefix_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_safi_prefix_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_safi_prefix_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_prefix_pathtype_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_pathtype_cmd);
-
install_element (VIEW_NODE, &show_ip_bgp_regexp_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_regexp_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_prefix_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_filter_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_filter_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_filter_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_route_map_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_route_map_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_map_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_cidr_only_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_cidr_only_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community_all_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_all_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community2_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community3_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community4_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community_all_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community2_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community3_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community4_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community2_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community3_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community4_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_community_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_community_list_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_list_exact_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_neighbor_advertised_route_cmd);
+
install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_neighbor_advertised_route_rmap_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_rmap_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_rmap_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_received_routes_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_rmap_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_received_routes_rmap_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_rmap_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_afi_safi_neighbor_adv_recd_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_routes_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_dampened_paths_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_dampd_paths_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_flap_stats_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_damp_dampened_paths_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_flap_statistics_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_damp_flap_statistics_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_flap_address_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_damp_flap_address_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_flap_cidr_only_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_damp_flap_cidr_only_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_flap_regexp_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_flap_filter_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_damp_flap_filter_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_damp_flap_prefix_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_damp_flap_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_flap_route_map_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_damp_flap_route_map_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_neighbor_flap_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_neighbor_damp_cmd);
-
- install_element (VIEW_NODE, &show_bgp_ipv4_prefix_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_safi_rd_route_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_safi_rd_route_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_safi_rd_prefix_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_safi_rd_prefix_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
+ install_element (VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
+ install_element (VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
/* BGP dampening clear commands */
install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
install_element (ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
+
install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
/* prefix count */
- install_element (ENABLE_NODE, &show_ip_bgp_neighbor_prefix_counts_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
- install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_prefix_counts_cmd);
-#ifdef HAVE_IPV6
- install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_prefix_counts_cmd);
- install_element (ENABLE_NODE, &show_bgp_instance_ipv6_neighbor_prefix_counts_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
+ install_element (ENABLE_NODE, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
/* New config IPv6 BGP commands. */
install_element (BGP_IPV6_NODE, &bgp_table_map_cmd);
@@ -14896,230 +10454,56 @@ bgp_route_init (void)
install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
- install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_route_map_cmd);
install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
- install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_summary_only_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
- install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_summary_only_cmd);
install_element (BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
- /* Old config IPv6 BGP commands. */
- install_element (BGP_NODE, &old_ipv6_bgp_network_cmd);
- install_element (BGP_NODE, &old_no_ipv6_bgp_network_cmd);
-
- install_element (BGP_NODE, &old_ipv6_aggregate_address_cmd);
- install_element (BGP_NODE, &old_ipv6_aggregate_address_summary_only_cmd);
- install_element (BGP_NODE, &old_no_ipv6_aggregate_address_cmd);
- install_element (BGP_NODE, &old_no_ipv6_aggregate_address_summary_only_cmd);
-
- install_element (VIEW_NODE, &show_bgp_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_safi_cmd);
- install_element (VIEW_NODE, &show_bgp_route_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_route_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_safi_route_cmd);
- install_element (VIEW_NODE, &show_bgp_route_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_route_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_safi_route_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_prefix_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_prefix_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_safi_prefix_cmd);
- install_element (VIEW_NODE, &show_bgp_prefix_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_prefix_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_safi_prefix_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_regexp_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_regexp_cmd);
- install_element (VIEW_NODE, &show_bgp_prefix_list_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_prefix_list_cmd);
- install_element (VIEW_NODE, &show_bgp_filter_list_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_filter_list_cmd);
- install_element (VIEW_NODE, &show_bgp_route_map_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_route_map_cmd);
- install_element (VIEW_NODE, &show_bgp_community_all_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community_all_cmd);
- install_element (VIEW_NODE, &show_bgp_community_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community_cmd);
- install_element (VIEW_NODE, &show_bgp_community2_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community2_cmd);
- install_element (VIEW_NODE, &show_bgp_community3_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community3_cmd);
- install_element (VIEW_NODE, &show_bgp_community4_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community4_cmd);
- install_element (VIEW_NODE, &show_bgp_community_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_community2_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community2_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_community3_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community3_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_community4_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community4_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_community_list_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community_list_cmd);
- install_element (VIEW_NODE, &show_bgp_community_list_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_community_list_exact_cmd);
- install_element (VIEW_NODE, &show_bgp_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_bgp_neighbor_advertised_route_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_advertised_route_cmd);
- install_element (VIEW_NODE, &show_bgp_neighbor_received_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_received_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_neighbor_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_neighbor_received_prefix_filter_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_received_prefix_filter_cmd);
- install_element (VIEW_NODE, &show_bgp_neighbor_flap_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_flap_cmd);
- install_element (VIEW_NODE, &show_bgp_neighbor_damp_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_damp_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_all_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_route_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_route_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_route_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_route_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_prefix_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_prefix_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_prefix_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_prefix_pathtype_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_prefix_list_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_prefix_list_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_filter_list_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_filter_list_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_route_map_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_route_map_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_community_list_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_community_list_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_neighbor_advertised_route_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbor_advertised_route_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_neighbor_received_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbor_received_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_neighbor_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbor_routes_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_neighbor_received_prefix_filter_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbor_received_prefix_filter_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_neighbor_flap_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbor_flap_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_neighbor_damp_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbor_damp_cmd);
-
- /* Statistics */
- install_element (ENABLE_NODE, &show_bgp_statistics_cmd);
- //install_element (ENABLE_NODE, &show_bgp_statistics_vpnv4_cmd);
- install_element (ENABLE_NODE, &show_bgp_statistics_view_cmd);
- //install_element (ENABLE_NODE, &show_bgp_statistics_view_vpnv4_cmd);
-
- /* old command */
- install_element (VIEW_NODE, &show_ipv6_bgp_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_route_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_prefix_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_regexp_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_prefix_list_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_filter_list_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community_all_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community2_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community3_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community4_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community2_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community3_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community4_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community_list_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_community_list_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_bgp_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_route_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_prefix_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_regexp_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_prefix_list_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_filter_list_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community_all_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community2_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community3_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community4_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community2_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community3_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community4_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community_list_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_community_list_exact_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_prefix_longer_cmd);
-
- /* old command */
- install_element (VIEW_NODE, &ipv6_bgp_neighbor_advertised_route_cmd);
- install_element (VIEW_NODE, &ipv6_mbgp_neighbor_advertised_route_cmd);
-
- /* old command */
- install_element (VIEW_NODE, &ipv6_bgp_neighbor_received_routes_cmd);
- install_element (VIEW_NODE, &ipv6_mbgp_neighbor_received_routes_cmd);
-
- /* old command */
- install_element (VIEW_NODE, &ipv6_bgp_neighbor_routes_cmd);
- install_element (VIEW_NODE, &ipv6_mbgp_neighbor_routes_cmd);
-#endif /* HAVE_IPV6 */
-
install_element (BGP_NODE, &bgp_distance_cmd);
install_element (BGP_NODE, &no_bgp_distance_cmd);
- install_element (BGP_NODE, &no_bgp_distance2_cmd);
install_element (BGP_NODE, &bgp_distance_source_cmd);
install_element (BGP_NODE, &no_bgp_distance_source_cmd);
install_element (BGP_NODE, &bgp_distance_source_access_list_cmd);
install_element (BGP_NODE, &no_bgp_distance_source_access_list_cmd);
install_element (BGP_IPV4_NODE, &bgp_distance_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_distance_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_distance2_cmd);
install_element (BGP_IPV4_NODE, &bgp_distance_source_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
install_element (BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
install_element (BGP_IPV4M_NODE, &bgp_distance_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_distance_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_distance2_cmd);
install_element (BGP_IPV4M_NODE, &bgp_distance_source_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
install_element (BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_access_list_cmd);
install_element (BGP_IPV6_NODE, &bgp_distance_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_distance_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_distance2_cmd);
install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_access_list_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
install_element (BGP_IPV6M_NODE, &bgp_distance_cmd);
install_element (BGP_IPV6M_NODE, &no_bgp_distance_cmd);
- install_element (BGP_IPV6M_NODE, &no_bgp_distance2_cmd);
install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_access_list_cmd);
install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
install_element (BGP_NODE, &bgp_damp_set_cmd);
- install_element (BGP_NODE, &bgp_damp_set2_cmd);
- install_element (BGP_NODE, &bgp_damp_set3_cmd);
install_element (BGP_NODE, &bgp_damp_unset_cmd);
- install_element (BGP_NODE, &bgp_damp_unset2_cmd);
- install_element (BGP_NODE, &bgp_damp_unset3_cmd);
install_element (BGP_IPV4_NODE, &bgp_damp_set_cmd);
- install_element (BGP_IPV4_NODE, &bgp_damp_set2_cmd);
- install_element (BGP_IPV4_NODE, &bgp_damp_set3_cmd);
install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
- install_element (BGP_IPV4_NODE, &bgp_damp_unset2_cmd);
- install_element (BGP_IPV4_NODE, &bgp_damp_unset3_cmd);
/* IPv4 Multicast Mode */
install_element (BGP_IPV4M_NODE, &bgp_damp_set_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_damp_set2_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_damp_set3_cmd);
install_element (BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_damp_unset2_cmd);
+
+ /* Large Communities */
+ install_element (VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_large_community_cmd);
}
void
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 3c7aa83a0e..2103338b7d 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -26,6 +26,31 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
struct bgp_nexthop_cache;
+enum bgp_show_type
+{
+ bgp_show_type_normal,
+ bgp_show_type_regexp,
+ bgp_show_type_prefix_list,
+ bgp_show_type_filter_list,
+ bgp_show_type_route_map,
+ bgp_show_type_neighbor,
+ bgp_show_type_cidr_only,
+ bgp_show_type_prefix_longer,
+ bgp_show_type_community_all,
+ bgp_show_type_community,
+ bgp_show_type_community_exact,
+ bgp_show_type_community_list,
+ bgp_show_type_community_list_exact,
+ bgp_show_type_lcommunity_all,
+ bgp_show_type_lcommunity,
+ bgp_show_type_lcommunity_list,
+ bgp_show_type_flap_statistics,
+ bgp_show_type_flap_neighbor,
+ bgp_show_type_dampend_paths,
+ bgp_show_type_damp_neighbor
+};
+
+
#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, "\
"h history, * valid, > best, = multipath,%s"\
" i internal, r RIB-failure, S Stale, R Removed%s"
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index d0cce4a955..c7bcfe25f9 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -22,6 +22,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "prefix.h"
#include "filter.h"
+#include "vty.h"
#include "routemap.h"
#include "command.h"
#include "linklist.h"
@@ -51,6 +52,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_filter.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_debug.h"
@@ -83,6 +85,8 @@ o Cisco route-map
as-path tag : Not yet
automatic-tag : (This will not be implemented by bgpd)
community : Done
+ large-community : Done
+ large-comm-list : Done
comm-list : Not yet
dampning : Not yet
default : (This will not be implemented by bgpd)
@@ -106,7 +110,7 @@ o Local extensions
set ipv6 next-hop local : Done
set as-path exclude : Done
-*/
+*/
/* generic value manipulation to be shared in multiple rules */
@@ -328,7 +332,7 @@ struct route_map_rule_cmd route_match_peer_cmd =
/* Match function should return 1 if match is success else return
zero. */
static route_map_result_t
-route_match_ip_address (void *rule, struct prefix *prefix,
+route_match_ip_address (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
@@ -339,7 +343,7 @@ route_match_ip_address (void *rule, struct prefix *prefix,
alist = access_list_lookup (AFI_IP, (char *) rule);
if (alist == NULL)
return RMAP_NOMATCH;
-
+
return (access_list_apply (alist, prefix) == FILTER_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
@@ -374,7 +378,7 @@ struct route_map_rule_cmd route_match_ip_address_cmd =
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
-route_match_ip_next_hop (void *rule, struct prefix *prefix,
+route_match_ip_next_hop (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
@@ -426,7 +430,7 @@ struct route_map_rule_cmd route_match_ip_next_hop_cmd =
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
-route_match_ip_route_source (void *rule, struct prefix *prefix,
+route_match_ip_route_source (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
@@ -483,7 +487,7 @@ struct route_map_rule_cmd route_match_ip_route_source_cmd =
/* `match ip address prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
+route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
@@ -493,7 +497,7 @@ route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
plist = prefix_list_lookup (AFI_IP, (char *) rule);
if (plist == NULL)
return RMAP_NOMATCH;
-
+
return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
@@ -690,7 +694,7 @@ struct route_map_rule_cmd route_match_local_pref_cmd =
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
-route_match_metric (void *rule, struct prefix *prefix,
+route_match_metric (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_value *rv;
@@ -718,10 +722,10 @@ struct route_map_rule_cmd route_match_metric_cmd =
/* Match function for as-path match. I assume given object is */
static route_map_result_t
-route_match_aspath (void *rule, struct prefix *prefix,
+route_match_aspath (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
-
+
struct as_list *as_list;
struct bgp_info *bgp_info;
@@ -754,7 +758,7 @@ route_match_aspath_free (void *rule)
}
/* Route map commands for aspath matching. */
-struct route_map_rule_cmd route_match_aspath_cmd =
+struct route_map_rule_cmd route_match_aspath_cmd =
{
"as-path",
route_match_aspath,
@@ -771,14 +775,14 @@ struct rmap_community
/* Match function for community match. */
static route_map_result_t
-route_match_community (void *rule, struct prefix *prefix,
+route_match_community (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct community_list *list;
struct bgp_info *bgp_info;
struct rmap_community *rcom;
- if (type == RMAP_BGP)
+ if (type == RMAP_BGP)
{
bgp_info = object;
rcom = rule;
@@ -833,12 +837,12 @@ route_match_community_free (void *rule)
{
struct rmap_community *rcom = rule;
- XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
}
/* Route map commands for community matching. */
-struct route_map_rule_cmd route_match_community_cmd =
+struct route_map_rule_cmd route_match_community_cmd =
{
"community",
route_match_community,
@@ -846,21 +850,93 @@ struct route_map_rule_cmd route_match_community_cmd =
route_match_community_free
};
+/* Match function for lcommunity match. */
+static route_map_result_t
+route_match_lcommunity (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct community_list *list;
+ struct bgp_info *bgp_info;
+ struct rmap_community *rcom;
+
+ if (type == RMAP_BGP)
+ {
+ bgp_info = object;
+ rcom = rule;
+
+ list = community_list_lookup (bgp_clist, rcom->name,
+ LARGE_COMMUNITY_LIST_MASTER);
+ if (! list)
+ return RMAP_NOMATCH;
+
+ if (bgp_info->attr->extra &&
+ lcommunity_list_match (bgp_info->attr->extra->lcommunity, list))
+ return RMAP_MATCH;
+
+ }
+ return RMAP_NOMATCH;
+}
+
+/* Compile function for community match. */
+static void *
+route_match_lcommunity_compile (const char *arg)
+{
+ struct rmap_community *rcom;
+ int len;
+ char *p;
+
+ rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
+
+ p = strchr (arg, ' ');
+ if (p)
+ {
+ len = p - arg;
+ rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
+ memcpy (rcom->name, arg, len);
+ }
+ else
+ {
+ rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+ rcom->exact = 0;
+ }
+ return rcom;
+}
+
+/* Compile function for community match. */
+static void
+route_match_lcommunity_free (void *rule)
+{
+ struct rmap_community *rcom = rule;
+
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
+}
+
+/* Route map commands for community matching. */
+struct route_map_rule_cmd route_match_lcommunity_cmd =
+{
+ "large-community",
+ route_match_lcommunity,
+ route_match_lcommunity_compile,
+ route_match_lcommunity_free
+};
+
+
/* Match function for extcommunity match. */
static route_map_result_t
-route_match_ecommunity (void *rule, struct prefix *prefix,
+route_match_ecommunity (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct community_list *list;
struct bgp_info *bgp_info;
- if (type == RMAP_BGP)
+ if (type == RMAP_BGP)
{
bgp_info = object;
-
+
if (!bgp_info->attr->extra)
return RMAP_NOMATCH;
-
+
list = community_list_lookup (bgp_clist, (char *) rule,
EXTCOMMUNITY_LIST_MASTER);
if (! list)
@@ -887,7 +963,7 @@ route_match_ecommunity_free (void *rule)
}
/* Route map commands for community matching. */
-struct route_map_rule_cmd route_match_ecommunity_cmd =
+struct route_map_rule_cmd route_match_ecommunity_cmd =
{
"extcommunity",
route_match_ecommunity,
@@ -900,7 +976,7 @@ struct route_map_rule_cmd route_match_ecommunity_cmd =
/* `match origin' */
static route_map_result_t
-route_match_origin (void *rule, struct prefix *prefix,
+route_match_origin (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
u_char *origin;
@@ -910,7 +986,7 @@ route_match_origin (void *rule, struct prefix *prefix,
{
origin = rule;
bgp_info = object;
-
+
if (bgp_info->attr->origin == *origin)
return RMAP_MATCH;
}
@@ -1124,7 +1200,7 @@ route_set_ip_nexthop (void *rule, struct prefix *prefix,
{
if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
- && peer->su_remote
+ && peer->su_remote
&& sockunion_family (peer->su_remote) == AF_INET)
{
bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
@@ -1198,7 +1274,7 @@ route_set_ip_nexthop_free (void *rule)
if (rins->address)
XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
-
+
XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
}
@@ -1227,8 +1303,8 @@ route_set_local_pref (void *rule, struct prefix *prefix,
/* Fetch routemap's rule information. */
rv = rule;
bgp_info = object;
-
- /* Set local preference value. */
+
+ /* Set local preference value. */
if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
locpref = bgp_info->attr->local_pref;
@@ -1240,7 +1316,7 @@ route_set_local_pref (void *rule, struct prefix *prefix,
}
/* Set local preference rule structure. */
-struct route_map_rule_cmd route_set_local_pref_cmd =
+struct route_map_rule_cmd route_set_local_pref_cmd =
{
"local-preference",
route_set_local_pref,
@@ -1264,8 +1340,8 @@ route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
/* Fetch routemap's rule information. */
rv = rule;
bgp_info = object;
-
- /* Set weight value. */
+
+ /* Set weight value. */
weight = route_value_adjust(rv, 0, bgp_info->peer);
if (weight)
(bgp_attr_extra_get (bgp_info->attr))->weight = weight;
@@ -1277,7 +1353,7 @@ route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
}
/* Set local preference rule structure. */
-struct route_map_rule_cmd route_set_weight_cmd =
+struct route_map_rule_cmd route_set_weight_cmd =
{
"weight",
route_set_weight,
@@ -1289,7 +1365,7 @@ struct route_map_rule_cmd route_set_weight_cmd =
/* Set metric to attribute. */
static route_map_result_t
-route_set_metric (void *rule, struct prefix *prefix,
+route_set_metric (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_value *rv;
@@ -1312,7 +1388,7 @@ route_set_metric (void *rule, struct prefix *prefix,
}
/* Set metric rule structure. */
-struct route_map_rule_cmd route_set_metric_cmd =
+struct route_map_rule_cmd route_set_metric_cmd =
{
"metric",
route_set_metric,
@@ -1333,7 +1409,7 @@ route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t
if (type == RMAP_BGP)
{
binfo = object;
-
+
if (binfo->attr->aspath->refcnt)
new = aspath_dup (binfo->attr->aspath);
else
@@ -1377,7 +1453,7 @@ route_set_aspath_prepend_free (void *rule)
/* Set as-path prepend rule structure. */
-struct route_map_rule_cmd route_set_aspath_prepend_cmd =
+struct route_map_rule_cmd route_set_aspath_prepend_cmd =
{
"as-path prepend",
route_set_aspath_prepend,
@@ -1411,7 +1487,7 @@ route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t t
}
/* Set ASn exlude rule structure. */
-struct route_map_rule_cmd route_set_aspath_exclude_cmd =
+struct route_map_rule_cmd route_set_aspath_exclude_cmd =
{
"as-path exclude",
route_set_aspath_exclude,
@@ -1438,7 +1514,7 @@ route_set_community (void *rule, struct prefix *prefix,
struct community *new = NULL;
struct community *old;
struct community *merge;
-
+
if (type == RMAP_BGP)
{
rcs = rule;
@@ -1461,8 +1537,8 @@ route_set_community (void *rule, struct prefix *prefix,
if (rcs->additive && old)
{
merge = community_merge (community_dup (old), rcs->com);
-
- /* HACK: if the old community is not intern'd,
+
+ /* HACK: if the old community is not intern'd,
* we should free it here, or all reference to it may be lost.
* Really need to cleanup attribute caching sometime.
*/
@@ -1473,7 +1549,7 @@ route_set_community (void *rule, struct prefix *prefix,
}
else
new = community_dup (rcs->com);
-
+
/* will be interned by caller if required */
attr->community = new;
@@ -1492,7 +1568,7 @@ route_set_community_compile (const char *arg)
char *sp;
int additive = 0;
int none = 0;
-
+
if (strcmp (arg, "none") == 0)
none = 1;
else
@@ -1514,12 +1590,12 @@ route_set_community_compile (const char *arg)
if (! com)
return NULL;
}
-
+
rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
rcs->com = com;
rcs->additive = additive;
rcs->none = none;
-
+
return rcs;
}
@@ -1535,7 +1611,7 @@ route_set_community_free (void *rule)
}
/* Set community rule structure. */
-struct route_map_rule_cmd route_set_community_cmd =
+struct route_map_rule_cmd route_set_community_cmd =
{
"community",
route_set_community,
@@ -1543,6 +1619,224 @@ struct route_map_rule_cmd route_set_community_cmd =
route_set_community_free,
};
+/* `set community COMMUNITY' */
+struct rmap_lcom_set
+{
+ struct lcommunity *lcom;
+ int additive;
+ int none;
+};
+
+
+/* For lcommunity set mechanism. */
+static route_map_result_t
+route_set_lcommunity (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct rmap_lcom_set *rcs;
+ struct bgp_info *binfo;
+ struct attr *attr;
+ struct lcommunity *new = NULL;
+ struct lcommunity *old;
+ struct lcommunity *merge;
+
+ if (type == RMAP_BGP)
+ {
+ rcs = rule;
+ binfo = object;
+ attr = binfo->attr;
+ old = (attr->extra) ? attr->extra->lcommunity : NULL;
+
+ /* "none" case. */
+ if (rcs->none)
+ {
+ attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
+ if (attr->extra)
+ attr->extra->lcommunity = NULL;
+
+ /* See the longer comment down below. */
+ if (old && old->refcnt == 0)
+ lcommunity_free(&old);
+ return RMAP_OKAY;
+ }
+
+ if (rcs->additive && old)
+ {
+ merge = lcommunity_merge (lcommunity_dup (old), rcs->lcom);
+
+ /* HACK: if the old large-community is not intern'd,
+ * we should free it here, or all reference to it may be lost.
+ * Really need to cleanup attribute caching sometime.
+ */
+ if (old->refcnt == 0)
+ lcommunity_free (&old);
+ new = lcommunity_uniq_sort (merge);
+ lcommunity_free (&merge);
+ }
+ else
+ new = lcommunity_dup (rcs->lcom);
+
+ /* will be intern()'d or attr_flush()'d by bgp_update_main() */
+ (bgp_attr_extra_get (attr))->lcommunity = new;
+
+ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
+ }
+
+ return RMAP_OKAY;
+}
+
+/* Compile function for set community. */
+static void *
+route_set_lcommunity_compile (const char *arg)
+{
+ struct rmap_lcom_set *rcs;
+ struct lcommunity *lcom = NULL;
+ char *sp;
+ int additive = 0;
+ int none = 0;
+
+ if (strcmp (arg, "none") == 0)
+ none = 1;
+ else
+ {
+ sp = strstr (arg, "additive");
+
+ if (sp && sp > arg)
+ {
+ /* "additive" keyworkd is included. */
+ additive = 1;
+ *(sp - 1) = '\0';
+ }
+
+ lcom = lcommunity_str2com (arg);
+
+ if (additive)
+ *(sp - 1) = ' ';
+
+ if (! lcom)
+ return NULL;
+ }
+
+ rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
+ rcs->lcom = lcom;
+ rcs->additive = additive;
+ rcs->none = none;
+
+ return rcs;
+}
+
+/* Free function for set lcommunity. */
+static void
+route_set_lcommunity_free (void *rule)
+{
+ struct rmap_lcom_set *rcs = rule;
+
+ if (rcs->lcom) {
+ lcommunity_free (&rcs->lcom);
+ }
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
+}
+
+/* Set community rule structure. */
+struct route_map_rule_cmd route_set_lcommunity_cmd =
+{
+ "large-community",
+ route_set_lcommunity,
+ route_set_lcommunity_compile,
+ route_set_lcommunity_free,
+};
+
+/* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
+
+/* For large community set mechanism. */
+static route_map_result_t
+route_set_lcommunity_delete (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct community_list *list;
+ struct lcommunity *merge;
+ struct lcommunity *new;
+ struct lcommunity *old;
+ struct bgp_info *binfo;
+
+ if (type == RMAP_BGP)
+ {
+ if (! rule)
+ return RMAP_OKAY;
+
+ binfo = object;
+ list = community_list_lookup (bgp_clist, rule,
+ LARGE_COMMUNITY_LIST_MASTER);
+ old = ((binfo->attr->extra) ? binfo->attr->extra->lcommunity : NULL);
+
+ if (list && old)
+ {
+ merge = lcommunity_list_match_delete (lcommunity_dup (old), list);
+ new = lcommunity_uniq_sort (merge);
+ lcommunity_free (&merge);
+
+ /* HACK: if the old community is not intern'd,
+ * we should free it here, or all reference to it may be lost.
+ * Really need to cleanup attribute caching sometime.
+ */
+ if (old->refcnt == 0)
+ lcommunity_free (&old);
+
+ if (new->size == 0)
+ {
+ binfo->attr->extra->lcommunity = NULL;
+ binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
+ lcommunity_free (&new);
+ }
+ else
+ {
+ binfo->attr->extra->lcommunity = new;
+ binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
+ }
+ }
+ }
+
+ return RMAP_OKAY;
+}
+
+/* Compile function for set lcommunity. */
+static void *
+route_set_lcommunity_delete_compile (const char *arg)
+{
+ char *p;
+ char *str;
+ int len;
+
+ p = strchr (arg, ' ');
+ if (p)
+ {
+ len = p - arg;
+ str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
+ memcpy (str, arg, len);
+ }
+ else
+ str = NULL;
+
+ return str;
+}
+
+/* Free function for set lcommunity. */
+static void
+route_set_lcommunity_delete_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Set lcommunity rule structure. */
+struct route_map_rule_cmd route_set_lcommunity_delete_cmd =
+{
+ "large-comm-list",
+ route_set_lcommunity_delete,
+ route_set_lcommunity_delete_compile,
+ route_set_lcommunity_delete_free,
+};
+
+
/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
/* For community set mechanism. */
@@ -1648,10 +1942,10 @@ route_set_ecommunity (void *rule, struct prefix *prefix,
{
ecom = rule;
bgp_info = object;
-
+
if (! ecom)
return RMAP_OKAY;
-
+
/* We assume additive for Extended Community. */
old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
@@ -1696,7 +1990,7 @@ route_set_ecommunity_free (void *rule)
}
/* Set community rule structure. */
-struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
+struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
{
"extcommunity rt",
route_set_ecommunity,
@@ -1715,12 +2009,12 @@ route_set_ecommunity_soo_compile (const char *arg)
ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
if (! ecom)
return NULL;
-
+
return ecommunity_intern (ecom);
}
/* Set community rule structure. */
-struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
+struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
{
"extcommunity soo",
route_set_ecommunity,
@@ -1741,7 +2035,7 @@ route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, vo
{
origin = rule;
bgp_info = object;
-
+
bgp_info->attr->origin = *origin;
}
@@ -1774,7 +2068,7 @@ route_set_origin_free (void *rule)
}
/* Set origin rule structure. */
-struct route_map_rule_cmd route_set_origin_cmd =
+struct route_map_rule_cmd route_set_origin_cmd =
{
"origin",
route_set_origin,
@@ -1815,7 +2109,7 @@ route_set_atomic_aggregate_free (void *rule)
}
/* Set atomic aggregate rule structure. */
-struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
+struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
{
"atomic-aggregate",
route_set_atomic_aggregate,
@@ -1831,7 +2125,7 @@ struct aggregator
};
static route_map_result_t
-route_set_aggregator_as (void *rule, struct prefix *prefix,
+route_set_aggregator_as (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct bgp_info *bgp_info;
@@ -1843,7 +2137,7 @@ route_set_aggregator_as (void *rule, struct prefix *prefix,
bgp_info = object;
aggregator = rule;
ae = bgp_attr_extra_get (bgp_info->attr);
-
+
ae->aggregator_as = aggregator->as;
ae->aggregator_addr = aggregator->address;
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
@@ -1874,7 +2168,7 @@ route_set_aggregator_as_free (void *rule)
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
-struct route_map_rule_cmd route_set_aggregator_as_cmd =
+struct route_map_rule_cmd route_set_aggregator_as_cmd =
{
"aggregator as",
route_set_aggregator_as,
@@ -1915,11 +2209,10 @@ static struct route_map_rule_cmd route_set_tag_cmd =
};
-#ifdef HAVE_IPV6
/* `match ipv6 address IP_ACCESS_LIST' */
static route_map_result_t
-route_match_ipv6_address (void *rule, struct prefix *prefix,
+route_match_ipv6_address (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
@@ -1929,7 +2222,7 @@ route_match_ipv6_address (void *rule, struct prefix *prefix,
alist = access_list_lookup (AFI_IP6, (char *) rule);
if (alist == NULL)
return RMAP_NOMATCH;
-
+
return (access_list_apply (alist, prefix) == FILTER_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
@@ -1960,7 +2253,7 @@ struct route_map_rule_cmd route_match_ipv6_address_cmd =
/* `match ipv6 next-hop IP_ADDRESS' */
static route_map_result_t
-route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
+route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in6_addr *addr = rule;
@@ -1969,10 +2262,10 @@ route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
if (type == RMAP_BGP)
{
bgp_info = object;
-
+
if (!bgp_info->attr->extra)
return RMAP_NOMATCH;
-
+
if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
return RMAP_MATCH;
@@ -2021,7 +2314,7 @@ struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
/* `match ipv6 address prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
+route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
@@ -2031,7 +2324,7 @@ route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
plist = prefix_list_lookup (AFI_IP6, (char *) rule);
if (plist == NULL)
return RMAP_NOMATCH;
-
+
return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
@@ -2062,7 +2355,7 @@ struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
/* Set nexthop to object. ojbect must be pointer to struct attr. */
static route_map_result_t
-route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
+route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in6_addr *address;
@@ -2073,8 +2366,8 @@ route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
/* Fetch routemap's rule information. */
address = rule;
bgp_info = object;
-
- /* Set next hop value. */
+
+ /* Set next hop value. */
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
/* Set nexthop length. */
@@ -2190,7 +2483,7 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd =
/* Set nexthop to object. ojbect must be pointer to struct attr. */
static route_map_result_t
-route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
+route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in6_addr *address;
@@ -2201,10 +2494,10 @@ route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
/* Fetch routemap's rule information. */
address = rule;
bgp_info = object;
-
- /* Set next hop value. */
+
+ /* Set next hop value. */
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
-
+
/* Set nexthop length. */
if (bgp_info->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
@@ -2340,7 +2633,112 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
route_set_ipv6_nexthop_peer_free
};
-#endif /* HAVE_IPV6 */
+/* `set ip vpn nexthop A.B.C.D' */
+
+static route_map_result_t
+route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct in_addr *address;
+ struct bgp_info *bgp_info;
+
+ if (type == RMAP_BGP)
+ {
+ /* Fetch routemap's rule information. */
+ address = rule;
+ bgp_info = object;
+
+ /* Set next hop value. */
+ (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
+ (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
+ }
+
+ return RMAP_OKAY;
+}
+
+static void *
+route_set_vpnv4_nexthop_compile (const char *arg)
+{
+ int ret;
+ struct in_addr *address;
+
+ address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
+
+ ret = inet_aton (arg, address);
+
+ if (ret == 0)
+ {
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
+ return NULL;
+ }
+
+ return address;
+}
+
+/* `set ipv6 vpn nexthop A.B.C.D' */
+
+static route_map_result_t
+route_set_vpnv6_nexthop (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct in6_addr *address;
+ struct bgp_info *bgp_info;
+
+ if (type == RMAP_BGP)
+ {
+ /* Fetch routemap's rule information. */
+ address = rule;
+ bgp_info = object;
+
+ /* Set next hop value. */
+ memcpy (&(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global, address, sizeof(struct in6_addr));
+ (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = BGP_ATTR_NHLEN_VPNV6_GLOBAL;
+ }
+
+ return RMAP_OKAY;
+}
+
+static void *
+route_set_vpnv6_nexthop_compile (const char *arg)
+{
+ int ret;
+ struct in6_addr *address;
+
+ address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
+ ret = inet_pton (AF_INET6, arg, address);
+
+ if (ret == 0)
+ {
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
+ return NULL;
+ }
+
+ return address;
+}
+
+static void
+route_set_vpn_nexthop_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for ip nexthop set. */
+struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
+{
+ "ip vpn next-hop",
+ route_set_vpnv4_nexthop,
+ route_set_vpnv4_nexthop_compile,
+ route_set_vpn_nexthop_free
+};
+
+/* Route map commands for ip nexthop set. */
+struct route_map_rule_cmd route_set_vpnv6_nexthop_cmd =
+{
+ "ipv6 vpn next-hop",
+ route_set_vpnv6_nexthop,
+ route_set_vpnv6_nexthop_compile,
+ route_set_vpn_nexthop_free
+};
/* `set originator-id' */
@@ -2351,11 +2749,11 @@ route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t t
struct in_addr *address;
struct bgp_info *bgp_info;
- if (type == RMAP_BGP)
+ if (type == RMAP_BGP)
{
address = rule;
bgp_info = object;
-
+
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
(bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
}
@@ -2391,7 +2789,7 @@ route_set_originator_id_free (void *rule)
}
/* Set originator-id rule structure. */
-struct route_map_rule_cmd route_set_originator_id_cmd =
+struct route_map_rule_cmd route_set_originator_id_cmd =
{
"originator-id",
route_set_originator_id,
@@ -2401,10 +2799,11 @@ struct route_map_rule_cmd route_set_originator_id_cmd =
/* Add bgp route map rule. */
static int
-bgp_route_match_add (struct vty *vty, struct route_map_index *index,
+bgp_route_match_add (struct vty *vty,
const char *command, const char *arg,
route_map_event_t type)
{
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
int ret;
ret = route_map_add_match (index, command, arg);
@@ -2431,10 +2830,11 @@ bgp_route_match_add (struct vty *vty, struct route_map_index *index,
/* Delete bgp route map rule. */
static int
-bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
+bgp_route_match_delete (struct vty *vty,
const char *command, const char *arg,
route_map_event_t type)
{
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
int ret;
char *dep_name = NULL;
const char *tmpstr;
@@ -2485,52 +2885,6 @@ bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
return CMD_SUCCESS;
}
-/* Add bgp route map rule. */
-static int
-bgp_route_set_add (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_add_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
-/* Delete bgp route map rule. */
-static int
-bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_delete_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
/*
* This is the workhorse routine for processing in/out routemap
* modifications.
@@ -2873,178 +3227,82 @@ bgp_route_map_event (route_map_event_t event, const char *rmap_name)
DEFUN (match_peer,
match_peer_cmd,
- "match peer (A.B.C.D|X:X::X:X)",
+ "match peer <A.B.C.D|X:X::X:X>",
MATCH_STR
"Match peer address\n"
"IP address of peer\n"
"IPv6 address of peer\n")
{
- return bgp_route_match_add (vty, vty->index, "peer", argv[0],
+ int idx_ip = 2;
+ return bgp_route_match_add (vty, "peer", argv[idx_ip]->arg,
RMAP_EVENT_MATCH_ADDED);
}
DEFUN (match_peer_local,
- match_peer_local_cmd,
+ match_peer_local_cmd,
"match peer local",
MATCH_STR
"Match peer address\n"
"Static or Redistributed routes\n")
{
- return bgp_route_match_add (vty, vty->index, "peer", "local",
+ return bgp_route_match_add (vty, "peer", "local",
RMAP_EVENT_MATCH_DELETED);
}
DEFUN (no_match_peer,
no_match_peer_cmd,
- "no match peer",
- NO_STR
- MATCH_STR
- "Match peer address\n")
-{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "peer", NULL,
- RMAP_EVENT_MATCH_DELETED);
-
- return bgp_route_match_delete (vty, vty->index, "peer", argv[0],
- RMAP_EVENT_MATCH_DELETED);
-}
-
-ALIAS (no_match_peer,
- no_match_peer_val_cmd,
- "no match peer (A.B.C.D|X:X::X:X)",
+ "no match peer [<local|A.B.C.D|X:X::X:X>]",
NO_STR
MATCH_STR
"Match peer address\n"
+ "Static or Redistributed routes\n"
"IP address of peer\n"
"IPv6 address of peer\n")
-
-ALIAS (no_match_peer,
- no_match_peer_local_cmd,
- "no match peer local",
- NO_STR
- MATCH_STR
- "Match peer address\n"
- "Static or Redistributed routes\n")
-
-DEFUN (match_ip_address,
- match_ip_address_cmd,
- "match ip address (<1-199>|<1300-2699>|WORD)",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip address", argv[0],
- RMAP_EVENT_FILTER_ADDED);
-}
+ int idx_peer = 3;
-DEFUN (no_match_ip_address,
- no_match_ip_address_cmd,
- "no match ip address",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n")
-{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "ip address", NULL,
- RMAP_EVENT_FILTER_DELETED);
-
- return bgp_route_match_delete (vty, vty->index, "ip address", argv[0],
- RMAP_EVENT_FILTER_DELETED);
-}
-
-ALIAS (no_match_ip_address,
- no_match_ip_address_val_cmd,
- "no match ip address (<1-199>|<1300-2699>|WORD)",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-
-DEFUN (match_ip_next_hop,
- match_ip_next_hop_cmd,
- "match ip next-hop (<1-199>|<1300-2699>|WORD)",
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-{
- return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0],
- RMAP_EVENT_FILTER_ADDED);
-}
-
-DEFUN (no_match_ip_next_hop,
- no_match_ip_next_hop_cmd,
- "no match ip next-hop",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n")
-{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL,
- RMAP_EVENT_FILTER_DELETED);
-
- return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0],
- RMAP_EVENT_FILTER_DELETED);
+ if (argc <= idx_peer)
+ return bgp_route_match_delete (vty, "peer", NULL,
+ RMAP_EVENT_MATCH_DELETED);
+ return bgp_route_match_delete (vty, "peer", argv[idx_peer]->arg,
+ RMAP_EVENT_MATCH_DELETED);
}
-ALIAS (no_match_ip_next_hop,
- no_match_ip_next_hop_val_cmd,
- "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-
-/* match probability { */
+/* match probability */
DEFUN (match_probability,
match_probability_cmd,
- "match probability <0-100>",
+ "match probability (0-100)",
MATCH_STR
"Match portion of routes defined by percentage value\n"
"Percentage of routes\n")
{
- return bgp_route_match_add (vty, vty->index, "probability", argv[0],
+ int idx_number = 2;
+ return bgp_route_match_add (vty, "probability", argv[idx_number]->arg,
RMAP_EVENT_MATCH_ADDED);
}
+
DEFUN (no_match_probability,
no_match_probability_cmd,
- "no match probability",
+ "no match probability [(1-99)]",
NO_STR
MATCH_STR
- "Match portion of routes defined by percentage value\n")
+ "Match portion of routes defined by percentage value\n"
+ "Percentage of routes\n")
{
- return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL,
+ int idx_number = 3;
+ if (argc <= idx_number)
+ return bgp_route_match_delete (vty, "probability", NULL,
+ RMAP_EVENT_MATCH_DELETED);
+ return bgp_route_match_delete (vty, "probability", argv[idx_number]->arg,
RMAP_EVENT_MATCH_DELETED);
}
-ALIAS (no_match_probability,
- no_match_probability_val_cmd,
- "no match probability <1-99>",
- NO_STR
- MATCH_STR
- "Match portion of routes defined by percentage value\n"
- "Percentage of routes\n")
-
-/* } */
-DEFUN (match_ip_route_source,
+DEFUN (match_ip_route_source,
match_ip_route_source_cmd,
- "match ip route-source (<1-199>|<1300-2699>|WORD)",
+ "match ip route-source <(1-199)|(1300-2699)|WORD>",
MATCH_STR
IP_STR
"Match advertising source address of route\n"
@@ -3052,29 +3310,15 @@ DEFUN (match_ip_route_source,
"IP access-list number (expanded range)\n"
"IP standard access-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0],
+ int idx_acl = 3;
+ return bgp_route_match_add (vty, "ip route-source", argv[idx_acl]->arg,
RMAP_EVENT_FILTER_ADDED);
}
+
DEFUN (no_match_ip_route_source,
no_match_ip_route_source_cmd,
- "no match ip route-source",
- NO_STR
- MATCH_STR
- IP_STR
- "Match advertising source address of route\n")
-{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL,
- RMAP_EVENT_FILTER_DELETED);
-
- return bgp_route_match_delete (vty, vty->index, "ip route-source",
- argv[0], RMAP_EVENT_FILTER_DELETED);
-}
-
-ALIAS (no_match_ip_route_source,
- no_match_ip_route_source_val_cmd,
- "no match ip route-source (<1-199>|<1300-2699>|WORD)",
+ "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
NO_STR
MATCH_STR
IP_STR
@@ -3082,82 +3326,17 @@ ALIAS (no_match_ip_route_source,
"IP access-list number\n"
"IP access-list number (expanded range)\n"
"IP standard access-list name\n")
-
-DEFUN (match_ip_address_prefix_list,
- match_ip_address_prefix_list_cmd,
- "match ip address prefix-list WORD",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip address prefix-list",
- argv[0], RMAP_EVENT_PLIST_ADDED);
+ int idx_number = 4;
+ if (argc <= idx_number)
+ return bgp_route_match_delete (vty, "ip route-source",
+ NULL, RMAP_EVENT_FILTER_DELETED);
+ return bgp_route_match_delete (vty, "ip route-source",
+ argv[idx_number]->arg, RMAP_EVENT_FILTER_DELETED);
}
-DEFUN (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_cmd,
- "no match ip address prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n")
-{
- return bgp_route_match_delete (vty, vty->index, "ip address prefix-list",
- argc == 0 ? NULL : argv[0],
- RMAP_EVENT_PLIST_DELETED);
-}
-ALIAS (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_val_cmd,
- "no match ip address prefix-list WORD",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-
-DEFUN (match_ip_next_hop_prefix_list,
- match_ip_next_hop_prefix_list_cmd,
- "match ip next-hop prefix-list WORD",
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list",
- argv[0], RMAP_EVENT_PLIST_ADDED);
-}
-
-DEFUN (no_match_ip_next_hop_prefix_list,
- no_match_ip_next_hop_prefix_list_cmd,
- "no match ip next-hop prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n")
-{
- return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
- argc == 0 ? NULL : argv[0],
- RMAP_EVENT_PLIST_DELETED);
-}
-
-ALIAS (no_match_ip_next_hop_prefix_list,
- no_match_ip_next_hop_prefix_list_val_cmd,
- "no match ip next-hop prefix-list WORD",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-
-DEFUN (match_ip_route_source_prefix_list,
+DEFUN (match_ip_route_source_prefix_list,
match_ip_route_source_prefix_list_cmd,
"match ip route-source prefix-list WORD",
MATCH_STR
@@ -3166,115 +3345,65 @@ DEFUN (match_ip_route_source_prefix_list,
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list",
- argv[0], RMAP_EVENT_PLIST_ADDED);
+ int idx_word = 4;
+ return bgp_route_match_add (vty, "ip route-source prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
}
+
DEFUN (no_match_ip_route_source_prefix_list,
no_match_ip_route_source_prefix_list_cmd,
- "no match ip route-source prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match advertising source address of route\n"
- "Match entries of prefix-lists\n")
-{
- return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list",
- argc == 0 ? NULL : argv[0],
- RMAP_EVENT_PLIST_DELETED);
-}
-
-ALIAS (no_match_ip_route_source_prefix_list,
- no_match_ip_route_source_prefix_list_val_cmd,
- "no match ip route-source prefix-list WORD",
+ "no match ip route-source prefix-list [WORD]",
NO_STR
MATCH_STR
IP_STR
"Match advertising source address of route\n"
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
-
-DEFUN (match_metric,
- match_metric_cmd,
- "match metric <0-4294967295>",
- MATCH_STR
- "Match metric of route\n"
- "Metric value\n")
{
- return bgp_route_match_add (vty, vty->index, "metric", argv[0],
- RMAP_EVENT_MATCH_ADDED);
+ int idx_word = 5;
+ if (argc <= idx_word)
+ return bgp_route_match_delete (vty, "ip route-source prefix-list",
+ NULL, RMAP_EVENT_PLIST_DELETED);
+ return bgp_route_match_delete (vty, "ip route-source prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
}
-DEFUN (no_match_metric,
- no_match_metric_cmd,
- "no match metric",
- NO_STR
- MATCH_STR
- "Match metric of route\n")
-{
- return bgp_route_match_delete (vty, vty->index, "metric",
- argc == 0 ? NULL : argv[0],
- RMAP_EVENT_MATCH_DELETED);
-}
-
-ALIAS (no_match_metric,
- no_match_metric_val_cmd,
- "no match metric <0-4294967295>",
- NO_STR
- MATCH_STR
- "Match metric of route\n"
- "Metric value\n")
DEFUN (match_local_pref,
match_local_pref_cmd,
- "match local-preference <0-4294967295>",
+ "match local-preference (0-4294967295)",
MATCH_STR
"Match local-preference of route\n"
"Metric value\n")
{
- return bgp_route_match_add (vty, vty->index, "local-preference", argv[0],
+ int idx_number = 2;
+ return bgp_route_match_add (vty, "local-preference", argv[idx_number]->arg,
RMAP_EVENT_MATCH_ADDED);
}
+
DEFUN (no_match_local_pref,
no_match_local_pref_cmd,
- "no match local-preference",
+ "no match local-preference [(0-4294967295)]",
NO_STR
MATCH_STR
- "Match local preference of route\n")
+ "Match local preference of route\n"
+ "Local preference value\n")
{
- return bgp_route_match_delete (vty, vty->index, "local-preference",
- argc == 0 ? NULL : argv[0],
- RMAP_EVENT_MATCH_DELETED);
-
- return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0],
+ int idx_localpref = 3;
+ if (argc <= idx_localpref)
+ return bgp_route_match_delete (vty, "local-preference",
+ NULL, RMAP_EVENT_MATCH_DELETED);
+ return bgp_route_match_delete (vty, "local-preference",
+ argv[idx_localpref]->arg,
RMAP_EVENT_MATCH_DELETED);
}
-ALIAS (no_match_local_pref,
- no_match_local_pref_val_cmd,
- "no match local-preference <0-4294967295>",
- NO_STR
- MATCH_STR
- "Match local preference of route\n"
- "Local preference value\n")
-DEFUN (match_community,
+DEFUN (match_community,
match_community_cmd,
- "match community (<1-99>|<100-500>|WORD)",
- MATCH_STR
- "Match BGP community list\n"
- "Community-list number (standard)\n"
- "Community-list number (expanded)\n"
- "Community-list name\n")
-{
- return bgp_route_match_add (vty, vty->index, "community", argv[0],
- RMAP_EVENT_CLIST_ADDED);
-}
-
-DEFUN (match_community_exact,
- match_community_exact_cmd,
- "match community (<1-99>|<100-500>|WORD) exact-match",
+ "match community <(1-99)|(100-500)|WORD> [exact-match]",
MATCH_STR
"Match BGP community list\n"
"Community-list number (standard)\n"
@@ -3282,87 +3411,101 @@ DEFUN (match_community_exact,
"Community-list name\n"
"Do exact matching of communities\n")
{
+ int idx_comm_list = 2;
int ret;
char *argstr;
- argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
- strlen (argv[0]) + strlen ("exact-match") + 2);
+ if (argc == 4)
+ {
+ argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
+ strlen (argv[idx_comm_list]->arg) +
+ strlen ("exact-match") + 2);
- sprintf (argstr, "%s exact-match", argv[0]);
+ sprintf (argstr, "%s exact-match", argv[idx_comm_list]->arg);
+ }
+ else
+ argstr = argv[idx_comm_list]->arg;
- ret = bgp_route_match_add (vty, vty->index, "community", argstr,
+ ret = bgp_route_match_add (vty, "community", argstr,
RMAP_EVENT_CLIST_ADDED);
- XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
+ if (argstr != argv[idx_comm_list]->arg)
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
return ret;
}
DEFUN (no_match_community,
no_match_community_cmd,
- "no match community",
+ "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
NO_STR
MATCH_STR
- "Match BGP community list\n")
+ "Match BGP community list\n"
+ "Community-list number (standard)\n"
+ "Community-list number (expanded)\n"
+ "Community-list name\n"
+ "Do exact matching of communities\n")
{
- return bgp_route_match_delete (vty, vty->index, "community", NULL,
+ return bgp_route_match_delete (vty, "community", NULL,
RMAP_EVENT_CLIST_DELETED);
}
-ALIAS (no_match_community,
- no_match_community_val_cmd,
- "no match community (<1-99>|<100-500>|WORD)",
- NO_STR
+DEFUN (match_lcommunity,
+ match_lcommunity_cmd,
+ "match large-community <(1-99)|(100-500)|WORD>",
MATCH_STR
- "Match BGP community list\n"
- "Community-list number (standard)\n"
- "Community-list number (expanded)\n"
- "Community-list name\n")
+ "Match BGP large community list\n"
+ "Large Community-list number (standard)\n"
+ "Large Community-list number (expanded)\n"
+ "Large Community-list name\n")
+{
+ return bgp_route_match_add (vty, "large-community", argv[2]->arg,
+ RMAP_EVENT_LLIST_ADDED);
+}
-ALIAS (no_match_community,
- no_match_community_exact_cmd,
- "no match community (<1-99>|<100-500>|WORD) exact-match",
+DEFUN (no_match_lcommunity,
+ no_match_lcommunity_cmd,
+ "no match large-community [<(1-99)|(100-500)|WORD>]",
NO_STR
MATCH_STR
- "Match BGP community list\n"
- "Community-list number (standard)\n"
- "Community-list number (expanded)\n"
- "Community-list name\n"
- "Do exact matching of communities\n")
+ "Match BGP large community list\n"
+ "Large Community-list number (standard)\n"
+ "Large Community-list number (expanded)\n"
+ "Large Community-list name\n")
+{
+ return bgp_route_match_delete (vty, "large-community", NULL,
+ RMAP_EVENT_LLIST_DELETED);
+}
-DEFUN (match_ecommunity,
+DEFUN (match_ecommunity,
match_ecommunity_cmd,
- "match extcommunity (<1-99>|<100-500>|WORD)",
+ "match extcommunity <(1-99)|(100-500)|WORD>",
MATCH_STR
"Match BGP/VPN extended community list\n"
"Extended community-list number (standard)\n"
"Extended community-list number (expanded)\n"
"Extended community-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0],
+ int idx_comm_list = 2;
+ return bgp_route_match_add (vty, "extcommunity", argv[idx_comm_list]->arg,
RMAP_EVENT_ECLIST_ADDED);
}
+
DEFUN (no_match_ecommunity,
no_match_ecommunity_cmd,
- "no match extcommunity",
- NO_STR
- MATCH_STR
- "Match BGP/VPN extended community list\n")
-{
- return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL,
- RMAP_EVENT_ECLIST_DELETED);
-}
-
-ALIAS (no_match_ecommunity,
- no_match_ecommunity_val_cmd,
- "no match extcommunity (<1-99>|<100-500>|WORD)",
+ "no match extcommunity [<(1-99)|(100-500)|WORD>]",
NO_STR
MATCH_STR
"Match BGP/VPN extended community list\n"
"Extended community-list number (standard)\n"
"Extended community-list number (expanded)\n"
"Extended community-list name\n")
+{
+ return bgp_route_match_delete (vty, "extcommunity", NULL,
+ RMAP_EVENT_ECLIST_DELETED);
+}
+
DEFUN (match_aspath,
match_aspath_cmd,
@@ -3371,169 +3514,63 @@ DEFUN (match_aspath,
"Match BGP AS path list\n"
"AS path access-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "as-path", argv[0],
+ int idx_word = 2;
+ return bgp_route_match_add (vty, "as-path", argv[idx_word]->arg,
RMAP_EVENT_ASLIST_ADDED);
}
+
DEFUN (no_match_aspath,
no_match_aspath_cmd,
- "no match as-path",
+ "no match as-path [WORD]",
NO_STR
MATCH_STR
- "Match BGP AS path list\n")
+ "Match BGP AS path list\n"
+ "AS path access-list name\n")
{
- return bgp_route_match_delete (vty, vty->index, "as-path", NULL,
+ return bgp_route_match_delete (vty, "as-path", NULL,
RMAP_EVENT_ASLIST_DELETED);
}
-ALIAS (no_match_aspath,
- no_match_aspath_val_cmd,
- "no match as-path WORD",
- NO_STR
- MATCH_STR
- "Match BGP AS path list\n"
- "AS path access-list name\n")
DEFUN (match_origin,
match_origin_cmd,
- "match origin (egp|igp|incomplete)",
+ "match origin <egp|igp|incomplete>",
MATCH_STR
"BGP origin code\n"
"remote EGP\n"
"local IGP\n"
"unknown heritage\n")
{
- if (strncmp (argv[0], "igp", 2) == 0)
- return bgp_route_match_add (vty, vty->index, "origin", "igp",
+ int idx_origin = 2;
+ if (strncmp (argv[idx_origin]->arg, "igp", 2) == 0)
+ return bgp_route_match_add (vty, "origin", "igp",
RMAP_EVENT_MATCH_ADDED);
- if (strncmp (argv[0], "egp", 1) == 0)
- return bgp_route_match_add (vty, vty->index, "origin", "egp",
+ if (strncmp (argv[idx_origin]->arg, "egp", 1) == 0)
+ return bgp_route_match_add (vty, "origin", "egp",
RMAP_EVENT_MATCH_ADDED);
- if (strncmp (argv[0], "incomplete", 2) == 0)
- return bgp_route_match_add (vty, vty->index, "origin", "incomplete",
+ if (strncmp (argv[idx_origin]->arg, "incomplete", 2) == 0)
+ return bgp_route_match_add (vty, "origin", "incomplete",
RMAP_EVENT_MATCH_ADDED);
return CMD_WARNING;
}
+
DEFUN (no_match_origin,
no_match_origin_cmd,
- "no match origin",
- NO_STR
- MATCH_STR
- "BGP origin code\n")
-{
- return bgp_route_match_delete (vty, vty->index, "origin", NULL,
- RMAP_EVENT_MATCH_DELETED);
-}
-
-ALIAS (no_match_origin,
- no_match_origin_val_cmd,
- "no match origin (egp|igp|incomplete)",
+ "no match origin [<egp|igp|incomplete>]",
NO_STR
MATCH_STR
"BGP origin code\n"
"remote EGP\n"
"local IGP\n"
"unknown heritage\n")
-
-DEFUN (match_interface,
- match_interface_cmd,
- "match interface WORD",
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-{
- return bgp_route_match_add (vty, vty->index, "interface", argv[0],
- RMAP_EVENT_MATCH_ADDED);
-}
-
-DEFUN (no_match_interface,
- no_match_interface_cmd,
- "no match interface",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n")
{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "interface", NULL,
- RMAP_EVENT_MATCH_DELETED);
-
- return bgp_route_match_delete (vty, vty->index, "interface", argv[0],
+ return bgp_route_match_delete (vty, "origin", NULL,
RMAP_EVENT_MATCH_DELETED);
}
-ALIAS (no_match_interface,
- no_match_interface_val_cmd,
- "no match interface WORD",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-
-DEFUN (match_tag,
- match_tag_cmd,
- "match tag <1-4294967295>",
- MATCH_STR
- "Match tag of route\n"
- "Tag value\n")
-{
- return bgp_route_match_add (vty, vty->index, "tag", argv[0],
- RMAP_EVENT_MATCH_ADDED);
-}
-
-DEFUN (no_match_tag,
- no_match_tag_cmd,
- "no match tag",
- NO_STR
- MATCH_STR
- "Match tag of route\n")
-{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "tag", NULL,
- RMAP_EVENT_MATCH_DELETED);
-
- return bgp_route_match_delete (vty, vty->index, "tag", argv[0],
- RMAP_EVENT_MATCH_DELETED);
-}
-
-ALIAS (no_match_tag,
- no_match_tag_val_cmd,
- "no match tag <1-4294967295>",
- NO_STR
- MATCH_STR
- "Match tag of route\n"
- "Tag value\n")
-
-
-DEFUN (set_ip_nexthop,
- set_ip_nexthop_cmd,
- "set ip next-hop A.B.C.D",
- SET_STR
- IP_STR
- "Next hop address\n"
- "IP address of next hop\n")
-{
- union sockunion su;
- int ret;
-
- ret = str2sockunion (argv[0], &su);
- if (ret < 0)
- {
- vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (su.sin.sin_addr.s_addr == 0 ||
- IPV4_CLASS_DE(su.sin.sin_addr.s_addr))
- {
- vty_out (vty, "%% nexthop address cannot be 0.0.0.0, multicast "
- "or reserved%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
-}
-
DEFUN (set_ip_nexthop_peer,
set_ip_nexthop_peer_cmd,
"set ip next-hop peer-address",
@@ -3542,7 +3579,8 @@ DEFUN (set_ip_nexthop_peer,
"Next hop address\n"
"Use peer address (for BGP only)\n")
{
- return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip next-hop", "peer-address");
}
DEFUN (set_ip_nexthop_unchanged,
@@ -3553,258 +3591,172 @@ DEFUN (set_ip_nexthop_unchanged,
"Next hop address\n"
"Don't modify existing Next hop address\n")
{
- return bgp_route_set_add (vty, vty->index, "ip next-hop", "unchanged");
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip next-hop", "unchanged");
}
-DEFUN (no_set_ip_nexthop,
- no_set_ip_nexthop_cmd,
- "no set ip next-hop",
- NO_STR
- SET_STR
- "Next hop address\n")
-{
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
-
- return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
-}
-
-ALIAS (no_set_ip_nexthop,
- no_set_ip_nexthop_val_cmd,
- "no set ip next-hop A.B.C.D",
- NO_STR
- SET_STR
- IP_STR
- "Next hop address\n"
- "IP address of next hop\n")
-
-ALIAS (no_set_ip_nexthop,
- no_set_ip_nexthop_peer_cmd,
- "no set ip next-hop peer-address",
- NO_STR
- SET_STR
- IP_STR
- "Next hop address\n"
- "Use peer address (for BGP only)\n")
-
-DEFUN (set_metric,
- set_metric_cmd,
- "set metric <0-4294967295>",
- SET_STR
- "Metric value for destination routing protocol\n"
- "Metric value\n")
-{
- return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
-}
-
-ALIAS (set_metric,
- set_metric_addsub_cmd,
- "set metric <+/-metric>",
- SET_STR
- "Metric value for destination routing protocol\n"
- "Add or subtract metric\n")
-
-ALIAS (set_metric,
- set_metric_rtt_cmd,
- "set metric (rtt|+rtt|-rtt)",
- SET_STR
- "Metric value for destination routing protocol\n"
- "Assign round trip time\n"
- "Add round trip time\n"
- "Subtract round trip time\n")
-
-DEFUN (no_set_metric,
- no_set_metric_cmd,
- "no set metric",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n")
-{
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "metric", NULL);
-
- return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
-}
-
-ALIAS (no_set_metric,
- no_set_metric_val_cmd,
- "no set metric <0-4294967295>",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n"
- "Metric value\n")
DEFUN (set_local_pref,
set_local_pref_cmd,
- "set local-preference <0-4294967295>",
+ "set local-preference (0-4294967295)",
SET_STR
"BGP local preference path attribute\n"
"Preference value\n")
{
- return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
+ int idx_number = 2;
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "local-preference", argv[idx_number]->arg);
}
+
DEFUN (no_set_local_pref,
no_set_local_pref_cmd,
- "no set local-preference",
+ "no set local-preference [(0-4294967295)]",
NO_STR
SET_STR
- "BGP local preference path attribute\n")
+ "BGP local preference path attribute\n"
+ "Preference value\n")
{
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
-
- return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
+ int idx_localpref = 3;
+ if (argc <= idx_localpref)
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "local-preference", NULL);
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "local-preference", argv[idx_localpref]->arg);
}
-ALIAS (no_set_local_pref,
- no_set_local_pref_val_cmd,
- "no set local-preference <0-4294967295>",
- NO_STR
- SET_STR
- "BGP local preference path attribute\n"
- "Preference value\n")
DEFUN (set_weight,
set_weight_cmd,
- "set weight <0-4294967295>",
+ "set weight (0-4294967295)",
SET_STR
"BGP weight for routing table\n"
"Weight value\n")
{
- return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
+ int idx_number = 2;
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "weight",
+ argv[idx_number]->arg);
}
+
DEFUN (no_set_weight,
no_set_weight_cmd,
- "no set weight",
+ "no set weight [(0-4294967295)]",
NO_STR
SET_STR
- "BGP weight for routing table\n")
+ "BGP weight for routing table\n"
+ "Weight value\n")
{
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "weight", NULL);
-
- return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
+ int idx_weight = 3;
+ if (argc <= idx_weight)
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "weight", NULL);
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), "weight",
+ argv[idx_weight]->arg);
}
-ALIAS (no_set_weight,
- no_set_weight_val_cmd,
- "no set weight <0-4294967295>",
- NO_STR
- SET_STR
- "BGP weight for routing table\n"
- "Weight value\n")
-DEFUN (set_aspath_prepend,
- set_aspath_prepend_cmd,
- "set as-path prepend ." CMD_AS_RANGE,
+DEFUN (set_aspath_prepend_asn,
+ set_aspath_prepend_asn_cmd,
+ "set as-path prepend (1-4294967295)...",
SET_STR
"Transform BGP AS_PATH attribute\n"
"Prepend to the as-path\n"
"AS number\n")
{
+ int idx_asn = 3;
int ret;
char *str;
- str = argv_concat (argv, argc, 0);
- ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
+ str = argv_concat (argv, argc, idx_asn);
+ ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "as-path prepend", str);
XFREE (MTYPE_TMP, str);
return ret;
}
-ALIAS (set_aspath_prepend,
+DEFUN (set_aspath_prepend_lastas,
set_aspath_prepend_lastas_cmd,
- "set as-path prepend (last-as) <1-10>",
+ "set as-path prepend last-as (1-9)",
SET_STR
"Transform BGP AS_PATH attribute\n"
"Prepend to the as-path\n"
"Use the peer's AS-number\n"
"Number of times to insert")
+{
+ return set_aspath_prepend_asn (self, vty, argc, argv);
+}
DEFUN (no_set_aspath_prepend,
no_set_aspath_prepend_cmd,
- "no set as-path prepend",
+ "no set as-path prepend [(1-4294967295)]",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
- "Prepend to the as-path\n")
+ "Prepend to the as-path\n"
+ "AS number\n")
{
+ int idx_asn = 4;
int ret;
char *str;
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
-
- str = argv_concat (argv, argc, 0);
- ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
+ str = argv_concat (argv, argc, idx_asn);
+ ret = generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "as-path prepend", str);
XFREE (MTYPE_TMP, str);
return ret;
}
-ALIAS (no_set_aspath_prepend,
- no_set_aspath_prepend_val_cmd,
- "no set as-path prepend ." CMD_AS_RANGE,
- NO_STR
- SET_STR
- "Transform BGP AS_PATH attribute\n"
- "Prepend to the as-path\n"
- "AS number\n")
DEFUN (set_aspath_exclude,
set_aspath_exclude_cmd,
- "set as-path exclude ." CMD_AS_RANGE,
+ "set as-path exclude (1-4294967295)...",
SET_STR
"Transform BGP AS-path attribute\n"
"Exclude from the as-path\n"
"AS number\n")
{
+ int idx_asn = 3;
int ret;
char *str;
- str = argv_concat (argv, argc, 0);
- ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
+ str = argv_concat (argv, argc, idx_asn);
+ ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "as-path exclude", str);
XFREE (MTYPE_TMP, str);
return ret;
}
DEFUN (no_set_aspath_exclude,
no_set_aspath_exclude_cmd,
- "no set as-path exclude",
+ "no set as-path exclude (1-4294967295)...",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
- "Exclude from the as-path\n")
+ "Exclude from the as-path\n"
+ "AS number\n")
{
+ int idx_asn = 4;
int ret;
char *str;
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
-
- str = argv_concat (argv, argc, 0);
- ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
+ str = argv_concat (argv, argc, idx_asn);
+ ret = generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "as-path exclude", str);
XFREE (MTYPE_TMP, str);
return ret;
}
-ALIAS (no_set_aspath_exclude,
- no_set_aspath_exclude_val_cmd,
- "no set as-path exclude ." CMD_AS_RANGE,
- NO_STR
- SET_STR
- "Transform BGP AS_PATH attribute\n"
- "Exclude from the as-path\n"
- "AS number\n")
DEFUN (set_community,
set_community_cmd,
- "set community .AA:NN",
+ "set community AA:NN...",
SET_STR
"BGP community attribute\n"
COMMUNITY_VAL_STR)
{
+ int idx_aa_nn = 2;
int i;
int first = 0;
int additive = 0;
@@ -3816,9 +3768,9 @@ DEFUN (set_community,
b = buffer_new (1024);
- for (i = 0; i < argc; i++)
+ for (i = idx_aa_nn; i < argc; i++)
{
- if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
+ if (strncmp (argv[i]->arg, "additive", strlen (argv[i]->arg)) == 0)
{
additive = 1;
continue;
@@ -3829,29 +3781,29 @@ DEFUN (set_community,
else
first = 1;
- if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
+ if (strncmp (argv[i]->arg, "internet", strlen (argv[i]->arg)) == 0)
{
buffer_putstr (b, "internet");
continue;
}
- if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
+ if (strncmp (argv[i]->arg, "local-AS", strlen (argv[i]->arg)) == 0)
{
buffer_putstr (b, "local-AS");
continue;
}
- if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
- && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
+ if (strncmp (argv[i]->arg, "no-a", strlen ("no-a")) == 0
+ && strncmp (argv[i]->arg, "no-advertise", strlen (argv[i]->arg)) == 0)
{
buffer_putstr (b, "no-advertise");
continue;
}
- if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
- && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
+ if (strncmp (argv[i]->arg, "no-e", strlen ("no-e"))== 0
+ && strncmp (argv[i]->arg, "no-export", strlen (argv[i]->arg)) == 0)
{
buffer_putstr (b, "no-export");
continue;
}
- buffer_putstr (b, argv[i]);
+ buffer_putstr (b, argv[i]->arg);
}
buffer_putc (b, '\0');
@@ -3880,11 +3832,13 @@ DEFUN (set_community,
argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
strcpy (argstr, str);
strcpy (argstr + strlen (str), " additive");
- ret = bgp_route_set_add (vty, vty->index, "community", argstr);
+ ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "community", argstr);
XFREE (MTYPE_TMP, argstr);
}
else
- ret = bgp_route_set_add (vty, vty->index, "community", str);
+ ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "community", str);
community_free (com);
@@ -3898,38 +3852,27 @@ DEFUN (set_community_none,
"BGP community attribute\n"
"No community attribute\n")
{
- return bgp_route_set_add (vty, vty->index, "community", "none");
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "community",
+ "none");
}
DEFUN (no_set_community,
no_set_community_cmd,
- "no set community",
+ "no set community AA:NN...",
NO_STR
SET_STR
- "BGP community attribute\n")
+ "BGP community attribute\n"
+ COMMUNITY_VAL_STR)
{
- return bgp_route_set_delete (vty, vty->index, "community", NULL);
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "community", NULL);
}
-ALIAS (no_set_community,
- no_set_community_val_cmd,
- "no set community .AA:NN",
- NO_STR
- SET_STR
- "BGP community attribute\n"
- COMMUNITY_VAL_STR)
-ALIAS (no_set_community,
- no_set_community_none_cmd,
- "no set community none",
- NO_STR
- SET_STR
- "BGP community attribute\n"
- "No community attribute\n")
DEFUN (set_community_delete,
set_community_delete_cmd,
- "set comm-list (<1-99>|<100-500>|WORD) delete",
+ "set comm-list <(1-99)|(100-500)|WORD> delete",
SET_STR
"set BGP community list (for deletion)\n"
"Community-list number (standard)\n"
@@ -3937,13 +3880,14 @@ DEFUN (set_community_delete,
"Community-list name\n"
"Delete matching communities\n")
{
+ int idx_comm_list = 2;
char *str;
- str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
- strcpy (str, argv[0]);
- strcpy (str + strlen (argv[0]), " delete");
+ str = XCALLOC (MTYPE_TMP, strlen (argv[idx_comm_list]->arg) + strlen (" delete") + 1);
+ strcpy (str, argv[idx_comm_list]->arg);
+ strcpy (str + strlen (argv[idx_comm_list]->arg), " delete");
- bgp_route_set_add (vty, vty->index, "comm-list", str);
+ generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "comm-list", str);
XFREE (MTYPE_TMP, str);
return CMD_SUCCESS;
@@ -3951,17 +3895,7 @@ DEFUN (set_community_delete,
DEFUN (no_set_community_delete,
no_set_community_delete_cmd,
- "no set comm-list",
- NO_STR
- SET_STR
- "set BGP community list (for deletion)\n")
-{
- return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
-}
-
-ALIAS (no_set_community_delete,
- no_set_community_delete_val_cmd,
- "no set comm-list (<1-99>|<100-500>|WORD) delete",
+ "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
NO_STR
SET_STR
"set BGP community list (for deletion)\n"
@@ -3969,20 +3903,116 @@ ALIAS (no_set_community_delete,
"Community-list number (expanded)\n"
"Community-list name\n"
"Delete matching communities\n")
+{
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "comm-list", NULL);
+}
+
+DEFUN (set_lcommunity,
+ set_lcommunity_cmd,
+ "set large-community AA:BB:CC...",
+ SET_STR
+ "BGP large community attribute\n"
+ "Large Community number in aa:bb:cc format or additive\n")
+{
+ int ret;
+ char *str;
+
+ str = argv_concat (argv, argc, 2);
+ ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "large-community", str);
+ XFREE (MTYPE_TMP, str);
+
+ return ret;
+}
+
+DEFUN (set_lcommunity_none,
+ set_lcommunity_none_cmd,
+ "set large-community none",
+ SET_STR
+ "BGP large community attribute\n"
+ "No large community attribute\n")
+{
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "large-community", "none");
+}
+
+DEFUN (no_set_lcommunity,
+ no_set_lcommunity_cmd,
+ "no set large-community none",
+ NO_STR
+ SET_STR
+ "BGP large community attribute\n"
+ "No community attribute\n")
+{
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "large-community", NULL);
+}
+
+DEFUN (no_set_lcommunity1,
+ no_set_lcommunity1_cmd,
+ "no set large-community AA:BB:CC...",
+ NO_STR
+ SET_STR
+ "BGP large community attribute\n"
+ "Large community in AA:BB:CC... format or additive\n")
+{
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "large-community", NULL);
+}
+
+DEFUN (set_lcommunity_delete,
+ set_lcommunity_delete_cmd,
+ "set large-comm-list <(1-99)|(100-500)|WORD> delete",
+ SET_STR
+ "set BGP large community list (for deletion)\n"
+ "Large Community-list number (standard)\n"
+ "Large Communitly-list number (expanded)\n"
+ "Large Community-list name\n"
+ "Delete matching large communities\n")
+{
+ char *str;
+
+ str = XCALLOC (MTYPE_TMP, strlen (argv[2]->arg) + strlen (" delete") + 1);
+ strcpy (str, argv[2]->arg);
+ strcpy (str + strlen (argv[2]->arg), " delete");
+
+ generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "large-comm-list", str);
+
+ XFREE (MTYPE_TMP, str);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_set_lcommunity_delete,
+ no_set_lcommunity_delete_cmd,
+ "no set large-comm-list <(1-99)|(100-500)|WORD> [delete]",
+ NO_STR
+ SET_STR
+ "set BGP large community list (for deletion)\n"
+ "Large Community-list number (standard)\n"
+ "Large Communitly-list number (expanded)\n"
+ "Large Community-list name\n"
+ "Delete matching large communities\n")
+{
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "large-comm-list", NULL);
+}
DEFUN (set_ecommunity_rt,
set_ecommunity_rt_cmd,
- "set extcommunity rt .ASN:nn_or_IP-address:nn",
+ "set extcommunity rt ASN:nn_or_IP-address:nn...",
SET_STR
"BGP extended community attribute\n"
"Route Target extended community\n"
"VPN extended community\n")
{
+ int idx_asn_nn = 3;
int ret;
char *str;
- str = argv_concat (argv, argc, 0);
- ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
+ str = argv_concat (argv, argc, idx_asn_nn);
+ ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "extcommunity rt", str);
XFREE (MTYPE_TMP, str);
return ret;
@@ -3990,99 +4020,90 @@ DEFUN (set_ecommunity_rt,
DEFUN (no_set_ecommunity_rt,
no_set_ecommunity_rt_cmd,
- "no set extcommunity rt",
+ "no set extcommunity rt ASN:nn_or_IP-address:nn...",
NO_STR
SET_STR
"BGP extended community attribute\n"
- "Route Target extended community\n")
+ "Route Target extended community\n"
+ "VPN extended community\n")
{
- return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "extcommunity rt", NULL);
}
-ALIAS (no_set_ecommunity_rt,
- no_set_ecommunity_rt_val_cmd,
- "no set extcommunity rt .ASN:nn_or_IP-address:nn",
- NO_STR
- SET_STR
- "BGP extended community attribute\n"
- "Route Target extended community\n"
- "VPN extended community\n")
DEFUN (set_ecommunity_soo,
set_ecommunity_soo_cmd,
- "set extcommunity soo .ASN:nn_or_IP-address:nn",
+ "set extcommunity soo ASN:nn_or_IP-address:nn...",
SET_STR
"BGP extended community attribute\n"
"Site-of-Origin extended community\n"
"VPN extended community\n")
{
+ int idx_asn_nn = 3;
int ret;
char *str;
- str = argv_concat (argv, argc, 0);
- ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
+ str = argv_concat (argv, argc, idx_asn_nn);
+ ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "extcommunity soo", str);
XFREE (MTYPE_TMP, str);
return ret;
}
+
DEFUN (no_set_ecommunity_soo,
no_set_ecommunity_soo_cmd,
- "no set extcommunity soo",
+ "no set extcommunity soo ASN:nn_or_IP-address:nn...",
NO_STR
SET_STR
"BGP extended community attribute\n"
- "Site-of-Origin extended community\n")
+ "Site-of-Origin extended community\n"
+ "VPN extended community\n")
{
- return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "extcommunity soo", NULL);
}
-ALIAS (no_set_ecommunity_soo,
- no_set_ecommunity_soo_val_cmd,
- "no set extcommunity soo .ASN:nn_or_IP-address:nn",
- NO_STR
- SET_STR
- "BGP extended community attribute\n"
- "Site-of-Origin extended community\n"
- "VPN extended community\n")
DEFUN (set_origin,
set_origin_cmd,
- "set origin (egp|igp|incomplete)",
+ "set origin <egp|igp|incomplete>",
SET_STR
"BGP origin code\n"
"remote EGP\n"
"local IGP\n"
"unknown heritage\n")
{
- if (strncmp (argv[0], "igp", 2) == 0)
- return bgp_route_set_add (vty, vty->index, "origin", "igp");
- if (strncmp (argv[0], "egp", 1) == 0)
- return bgp_route_set_add (vty, vty->index, "origin", "egp");
- if (strncmp (argv[0], "incomplete", 2) == 0)
- return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
+ int idx_origin = 2;
+ if (strncmp (argv[idx_origin]->arg, "igp", 2) == 0)
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "origin",
+ "igp");
+ if (strncmp (argv[idx_origin]->arg, "egp", 1) == 0)
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "origin",
+ "egp");
+ if (strncmp (argv[idx_origin]->arg, "incomplete", 2) == 0)
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), "origin",
+ "incomplete");
return CMD_WARNING;
}
+
DEFUN (no_set_origin,
no_set_origin_cmd,
- "no set origin",
- NO_STR
- SET_STR
- "BGP origin code\n")
-{
- return bgp_route_set_delete (vty, vty->index, "origin", NULL);
-}
-
-ALIAS (no_set_origin,
- no_set_origin_val_cmd,
- "no set origin (egp|igp|incomplete)",
+ "no set origin [<egp|igp|incomplete>]",
NO_STR
SET_STR
"BGP origin code\n"
"remote EGP\n"
"local IGP\n"
"unknown heritage\n")
+{
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), "origin",
+ NULL);
+}
+
DEFUN (set_atomic_aggregate,
set_atomic_aggregate_cmd,
@@ -4090,7 +4111,8 @@ DEFUN (set_atomic_aggregate,
SET_STR
"BGP atomic aggregate attribute\n" )
{
- return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "atomic-aggregate", NULL);
}
DEFUN (no_set_atomic_aggregate,
@@ -4100,23 +4122,26 @@ DEFUN (no_set_atomic_aggregate,
SET_STR
"BGP atomic aggregate attribute\n" )
{
- return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "atomic-aggregate", NULL);
}
DEFUN (set_aggregator_as,
set_aggregator_as_cmd,
- "set aggregator as " CMD_AS_RANGE " A.B.C.D",
+ "set aggregator as (1-4294967295) A.B.C.D",
SET_STR
"BGP aggregator attribute\n"
"AS number of aggregator\n"
"AS number\n"
"IP address of aggregator\n")
{
+ int idx_number = 3;
+ int idx_ipv4 = 4;
int ret;
struct in_addr address;
char *argstr;
-
- ret = inet_aton (argv[1], &address);
+
+ ret = inet_aton (argv[idx_ipv4]->arg, &address);
if (ret == 0)
{
vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
@@ -4124,33 +4149,40 @@ DEFUN (set_aggregator_as,
}
argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
- strlen (argv[0]) + strlen (argv[1]) + 2);
+ strlen (argv[idx_number]->arg) + strlen (argv[idx_ipv4]->arg) + 2);
- sprintf (argstr, "%s %s", argv[0], argv[1]);
+ sprintf (argstr, "%s %s", argv[idx_number]->arg, argv[idx_ipv4]->arg);
- ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
+ ret = generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "aggregator as", argstr);
XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
return ret;
}
+
DEFUN (no_set_aggregator_as,
no_set_aggregator_as_cmd,
- "no set aggregator as",
+ "no set aggregator as [(1-4294967295) A.B.C.D]",
NO_STR
SET_STR
"BGP aggregator attribute\n"
- "AS number of aggregator\n")
+ "AS number of aggregator\n"
+ "AS number\n"
+ "IP address of aggregator\n")
{
+ int idx_asn = 4;
+ int idx_ip = 5;
int ret;
struct in_addr address;
char *argstr;
- if (argv == 0)
- return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
-
- ret = inet_aton (argv[1], &address);
+ if (argc <= idx_asn)
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "aggregator as", NULL);
+
+ ret = inet_aton (argv[idx_ip]->arg, &address);
if (ret == 0)
{
vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
@@ -4158,86 +4190,19 @@ DEFUN (no_set_aggregator_as,
}
argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
- strlen (argv[0]) + strlen (argv[1]) + 2);
+ strlen (argv[idx_asn]->arg) + strlen (argv[idx_ip]->arg) + 2);
- sprintf (argstr, "%s %s", argv[0], argv[1]);
+ sprintf (argstr, "%s %s", argv[idx_asn]->arg, argv[idx_ip]->arg);
- ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
+ ret = generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "aggregator as", argstr);
XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
return ret;
}
-ALIAS (no_set_aggregator_as,
- no_set_aggregator_as_val_cmd,
- "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
- NO_STR
- SET_STR
- "BGP aggregator attribute\n"
- "AS number of aggregator\n"
- "AS number\n"
- "IP address of aggregator\n")
-
-DEFUN (set_tag,
- set_tag_cmd,
- "set tag <1-4294967295>",
- SET_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
-{
- return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
-}
-
-DEFUN (no_set_tag,
- no_set_tag_cmd,
- "no set tag",
- NO_STR
- SET_STR
- "Tag value for routing protocol\n")
-{
- if (argc == 0)
- bgp_route_set_delete(vty, vty->index, "tag", NULL);
-
- return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
-}
-
-ALIAS (no_set_tag,
- no_set_tag_val_cmd,
- "no set tag <1-4294967295>",
- NO_STR
- SET_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
-
-
-#ifdef HAVE_IPV6
-DEFUN (match_ipv6_address,
- match_ipv6_address_cmd,
- "match ipv6 address WORD",
- MATCH_STR
- IPV6_STR
- "Match IPv6 address of route\n"
- "IPv6 access-list name\n")
-{
- return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0],
- RMAP_EVENT_FILTER_ADDED);
-}
-
-DEFUN (no_match_ipv6_address,
- no_match_ipv6_address_cmd,
- "no match ipv6 address WORD",
- NO_STR
- MATCH_STR
- IPV6_STR
- "Match IPv6 address of route\n"
- "IPv6 access-list name\n")
-{
- return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0],
- RMAP_EVENT_FILTER_DELETED);
-}
-
-DEFUN (match_ipv6_next_hop,
+DEFUN (match_ipv6_next_hop,
match_ipv6_next_hop_cmd,
"match ipv6 next-hop X:X::X:X",
MATCH_STR
@@ -4245,7 +4210,8 @@ DEFUN (match_ipv6_next_hop,
"Match IPv6 next-hop address of route\n"
"IPv6 address of next hop\n")
{
- return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0],
+ int idx_ipv6 = 3;
+ return bgp_route_match_add (vty, "ipv6 next-hop", argv[idx_ipv6]->arg,
RMAP_EVENT_MATCH_ADDED);
}
@@ -4258,36 +4224,11 @@ DEFUN (no_match_ipv6_next_hop,
"Match IPv6 next-hop address of route\n"
"IPv6 address of next hop\n")
{
- return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0],
+ int idx_ipv6 = 4;
+ return bgp_route_match_delete (vty, "ipv6 next-hop", argv[idx_ipv6]->arg,
RMAP_EVENT_MATCH_DELETED);
}
-DEFUN (match_ipv6_address_prefix_list,
- match_ipv6_address_prefix_list_cmd,
- "match ipv6 address prefix-list WORD",
- MATCH_STR
- IPV6_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list",
- argv[0], RMAP_EVENT_PLIST_ADDED);
-}
-
-DEFUN (no_match_ipv6_address_prefix_list,
- no_match_ipv6_address_prefix_list_cmd,
- "no match ipv6 address prefix-list WORD",
- NO_STR
- MATCH_STR
- IPV6_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list",
- argv[0], RMAP_EVENT_PLIST_DELETED);
-}
DEFUN (set_ipv6_nexthop_peer,
set_ipv6_nexthop_peer_cmd,
@@ -4297,7 +4238,8 @@ DEFUN (set_ipv6_nexthop_peer,
"Next hop address\n"
"Use peer address (for BGP only)\n")
{
- return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 next-hop peer-address", NULL);
}
DEFUN (no_set_ipv6_nexthop_peer,
@@ -4309,7 +4251,8 @@ DEFUN (no_set_ipv6_nexthop_peer,
"IPv6 next-hop address\n"
"Use peer address (for BGP only)\n")
{
- return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop peer-address", NULL);
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 next-hop peer-address", NULL);
}
DEFUN (set_ipv6_nexthop_prefer_global,
@@ -4320,7 +4263,8 @@ DEFUN (set_ipv6_nexthop_prefer_global,
"IPv6 next-hop address\n"
"Prefer global over link-local if both exist\n")
{
- return bgp_route_set_add (vty, vty->index, "ipv6 next-hop prefer-global", NULL);;
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 next-hop prefer-global", NULL);;
}
DEFUN (no_set_ipv6_nexthop_prefer_global,
@@ -4332,7 +4276,8 @@ DEFUN (no_set_ipv6_nexthop_prefer_global,
"IPv6 next-hop address\n"
"Prefer global over link-local if both exist\n")
{
- return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop prefer-global", NULL);
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 next-hop prefer-global", NULL);
}
DEFUN (set_ipv6_nexthop_global,
@@ -4344,10 +4289,11 @@ DEFUN (set_ipv6_nexthop_global,
"IPv6 global address\n"
"IPv6 address of next hop\n")
{
+ int idx_ipv6 = 4;
struct in6_addr addr;
int ret;
- ret = inet_pton (AF_INET6, argv[0], &addr);
+ ret = inet_pton (AF_INET6, argv[idx_ipv6]->arg, &addr);
if (!ret)
{
vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
@@ -4362,26 +4308,13 @@ DEFUN (set_ipv6_nexthop_global,
return CMD_WARNING;
}
- return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 next-hop global", argv[idx_ipv6]->arg);
}
+
DEFUN (no_set_ipv6_nexthop_global,
no_set_ipv6_nexthop_global_cmd,
- "no set ipv6 next-hop global",
- NO_STR
- SET_STR
- IPV6_STR
- "IPv6 next-hop address\n"
- "IPv6 global address\n")
-{
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
-
- return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
-}
-
-ALIAS (no_set_ipv6_nexthop_global,
- no_set_ipv6_nexthop_global_val_cmd,
"no set ipv6 next-hop global X:X::X:X",
NO_STR
SET_STR
@@ -4389,59 +4322,133 @@ ALIAS (no_set_ipv6_nexthop_global,
"IPv6 next-hop address\n"
"IPv6 global address\n"
"IPv6 address of next hop\n")
+{
+ int idx_ipv6 = 5;
+ if (argc <= idx_ipv6)
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 next-hop global", NULL);
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 next-hop global", argv[idx_ipv6]->arg);
+}
-DEFUN (set_ipv6_nexthop_local,
- set_ipv6_nexthop_local_cmd,
- "set ipv6 next-hop local X:X::X:X",
+#ifdef KEEP_OLD_VPN_COMMANDS
+DEFUN (set_vpn_nexthop,
+ set_vpn_nexthop_cmd,
+ "set <vpnv4|vpnv6> next-hop [A.B.C.D|X:X::X:X]",
SET_STR
- IPV6_STR
- "IPv6 next-hop address\n"
- "IPv6 local address\n"
+ "VPNv4 information\n"
+ "VPNv6 information\n"
+ "VPN next-hop address\n"
+ "IP address of next hop\n"
"IPv6 address of next hop\n")
{
- struct in6_addr addr;
- int ret;
+ int idx_ip = 3;
+ afi_t afi;
+ int idx = 0;
- ret = inet_pton (AF_INET6, argv[0], &addr);
- if (!ret)
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
{
- vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
- return CMD_WARNING;
+ if (afi == AFI_IP)
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip vpn next-hop", argv[idx_ip]->arg);
+ else
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 vpn next-hop", argv[idx_ip]->arg);
}
- if (!IN6_IS_ADDR_LINKLOCAL(&addr))
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_set_vpn_nexthop,
+ no_set_vpn_nexthop_cmd,
+ "no set vpn next-hop [A.B.C.D|X:X::X:X]",
+ NO_STR
+ SET_STR
+ "VPN information\n"
+ "VPN next-hop address\n"
+ "IP address of next hop\n"
+ "IPv6 address of next hop\n")
+{
+ int idx_ip = 4;
+ char *arg;
+ afi_t afi;
+ int idx = 0;
+
+ if (argc <= idx_ip)
+ arg = NULL;
+ else
+ arg = argv[idx_ip]->arg;
+ if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
{
- vty_out (vty, "%% Invalid link-local nexthop address%s", VTY_NEWLINE);
- return CMD_WARNING;
+ if (afi == AFI_IP)
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip vpn next-hop", arg);
+ else
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 vpn next-hop", argv[idx_ip]->arg);
}
-
- return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
+ return CMD_SUCCESS;
}
+#endif /* KEEP_OLD_VPN_COMMANDS */
-DEFUN (no_set_ipv6_nexthop_local,
- no_set_ipv6_nexthop_local_cmd,
- "no set ipv6 next-hop local",
- NO_STR
+DEFUN (set_ipx_vpn_nexthop,
+ set_ipx_vpn_nexthop_cmd,
+ "set <ipv4|ipv6> vpn next-hop <A.B.C.D|X:X::X:X>",
SET_STR
- IPV6_STR
- "IPv6 next-hop address\n"
- "IPv6 local address\n")
+ "IPv4 information\n"
+ "IPv6 information\n"
+ "VPN information\n"
+ "VPN next-hop address\n"
+ "IP address of next hop\n"
+ "IPv6 address of next hop\n")
{
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
-
- return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
+ int idx_ip = 4;
+ afi_t afi;
+ int idx = 0;
+
+ if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
+ {
+ if (afi == AFI_IP)
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip vpn next-hop", argv[idx_ip]->arg);
+ else
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 vpn next-hop", argv[idx_ip]->arg);
+ }
+ return CMD_SUCCESS;
}
-ALIAS (no_set_ipv6_nexthop_local,
- no_set_ipv6_nexthop_local_val_cmd,
- "no set ipv6 next-hop local X:X::X:X",
+DEFUN (no_set_ipx_vpn_nexthop,
+ no_set_ipx_vpn_nexthop_cmd,
+ "no set <ipv4|ipv6> vpn next-hop [<A.B.C.D|X:X::X:X>]",
NO_STR
SET_STR
- IPV6_STR
- "IPv6 next-hop address\n"
- "IPv6 local address\n"
+ "IPv4 information\n"
+ "IPv6 information\n"
+ "VPN information\n"
+ "VPN next-hop address\n"
+ "IP address of next hop\n"
"IPv6 address of next hop\n")
-#endif /* HAVE_IPV6 */
+{
+ int idx_ip = 5;
+ char *arg;
+ afi_t afi;
+ int idx = 0;
+
+ if (argc <= idx_ip)
+ arg = NULL;
+ else
+ arg = argv[idx_ip]->arg;
+ if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
+ {
+ if (afi == AFI_IP)
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ip vpn next-hop", arg);
+ else
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "ipv6 vpn next-hop", argv[idx_ip]->arg);
+ }
+ return CMD_SUCCESS;
+}
DEFUN (set_originator_id,
set_originator_id_cmd,
@@ -4450,29 +4457,27 @@ DEFUN (set_originator_id,
"BGP originator ID attribute\n"
"IP address of originator\n")
{
- return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
+ int idx_ipv4 = 2;
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "originator-id", argv[idx_ipv4]->arg);
}
+
DEFUN (no_set_originator_id,
no_set_originator_id_cmd,
- "no set originator-id",
+ "no set originator-id [A.B.C.D]",
NO_STR
SET_STR
- "BGP originator ID attribute\n")
+ "BGP originator ID attribute\n"
+ "IP address of originator\n")
{
- if (argc == 0)
- return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
-
- return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
+ int idx = 0;
+ char *arg = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
+
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "originator-id", arg);
}
-ALIAS (no_set_originator_id,
- no_set_originator_id_val_cmd,
- "no set originator-id A.B.C.D",
- NO_STR
- SET_STR
- "BGP originator ID attribute\n"
- "IP address of originator\n")
/* Initialization of route map. */
void
@@ -4484,6 +4489,45 @@ bgp_route_map_init (void)
route_map_delete_hook (bgp_route_map_delete);
route_map_event_hook (bgp_route_map_event);
+ route_map_match_interface_hook (generic_match_add);
+ route_map_no_match_interface_hook (generic_match_delete);
+
+ route_map_match_ip_address_hook (generic_match_add);
+ route_map_no_match_ip_address_hook (generic_match_delete);
+
+ route_map_match_ip_address_prefix_list_hook (generic_match_add);
+ route_map_no_match_ip_address_prefix_list_hook (generic_match_delete);
+
+ route_map_match_ip_next_hop_hook (generic_match_add);
+ route_map_no_match_ip_next_hop_hook (generic_match_delete);
+
+ route_map_match_ip_next_hop_prefix_list_hook (generic_match_add);
+ route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete);
+
+ route_map_match_ipv6_address_hook (generic_match_add);
+ route_map_no_match_ipv6_address_hook (generic_match_delete);
+
+ route_map_match_ipv6_address_prefix_list_hook (generic_match_add);
+ route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete);
+
+ route_map_match_metric_hook (generic_match_add);
+ route_map_no_match_metric_hook (generic_match_delete);
+
+ route_map_match_tag_hook (generic_match_add);
+ route_map_no_match_tag_hook (generic_match_delete);
+
+ route_map_set_ip_nexthop_hook (generic_set_add);
+ route_map_no_set_ip_nexthop_hook (generic_set_delete);
+
+ route_map_set_ipv6_nexthop_local_hook (generic_set_add);
+ route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete);
+
+ route_map_set_metric_hook (generic_set_add);
+ route_map_no_set_metric_hook (generic_set_delete);
+
+ route_map_set_tag_hook (generic_set_add);
+ route_map_no_set_tag_hook (generic_set_delete);
+
route_map_install_match (&route_match_peer_cmd);
route_map_install_match (&route_match_local_pref_cmd);
route_map_install_match (&route_match_ip_address_cmd);
@@ -4494,6 +4538,7 @@ bgp_route_map_init (void)
route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
route_map_install_match (&route_match_aspath_cmd);
route_map_install_match (&route_match_community_cmd);
+ route_map_install_match (&route_match_lcommunity_cmd);
route_map_install_match (&route_match_ecommunity_cmd);
route_map_install_match (&route_match_local_pref_cmd);
route_map_install_match (&route_match_metric_cmd);
@@ -4513,6 +4558,10 @@ bgp_route_map_init (void)
route_map_install_set (&route_set_aggregator_as_cmd);
route_map_install_set (&route_set_community_cmd);
route_map_install_set (&route_set_community_delete_cmd);
+ route_map_install_set (&route_set_lcommunity_cmd);
+ route_map_install_set (&route_set_lcommunity_delete_cmd);
+ route_map_install_set (&route_set_vpnv4_nexthop_cmd);
+ route_map_install_set (&route_set_vpnv6_nexthop_cmd);
route_map_install_set (&route_set_originator_id_cmd);
route_map_install_set (&route_set_ecommunity_rt_cmd);
route_map_install_set (&route_set_ecommunity_soo_cmd);
@@ -4521,111 +4570,67 @@ bgp_route_map_init (void)
install_element (RMAP_NODE, &match_peer_cmd);
install_element (RMAP_NODE, &match_peer_local_cmd);
install_element (RMAP_NODE, &no_match_peer_cmd);
- install_element (RMAP_NODE, &no_match_peer_val_cmd);
- install_element (RMAP_NODE, &no_match_peer_local_cmd);
- install_element (RMAP_NODE, &match_ip_address_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
- install_element (RMAP_NODE, &match_ip_next_hop_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
install_element (RMAP_NODE, &match_ip_route_source_cmd);
install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
- install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
- install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
- install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
install_element (RMAP_NODE, &match_aspath_cmd);
install_element (RMAP_NODE, &no_match_aspath_cmd);
- install_element (RMAP_NODE, &no_match_aspath_val_cmd);
- install_element (RMAP_NODE, &match_metric_cmd);
- install_element (RMAP_NODE, &no_match_metric_cmd);
- install_element (RMAP_NODE, &no_match_metric_val_cmd);
install_element (RMAP_NODE, &match_local_pref_cmd);
install_element (RMAP_NODE, &no_match_local_pref_cmd);
- install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
install_element (RMAP_NODE, &match_community_cmd);
- install_element (RMAP_NODE, &match_community_exact_cmd);
install_element (RMAP_NODE, &no_match_community_cmd);
- install_element (RMAP_NODE, &no_match_community_val_cmd);
- install_element (RMAP_NODE, &no_match_community_exact_cmd);
+ install_element (RMAP_NODE, &match_lcommunity_cmd);
+ install_element (RMAP_NODE, &no_match_lcommunity_cmd);
install_element (RMAP_NODE, &match_ecommunity_cmd);
install_element (RMAP_NODE, &no_match_ecommunity_cmd);
- install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
install_element (RMAP_NODE, &match_origin_cmd);
install_element (RMAP_NODE, &no_match_origin_cmd);
- install_element (RMAP_NODE, &no_match_origin_val_cmd);
install_element (RMAP_NODE, &match_probability_cmd);
install_element (RMAP_NODE, &no_match_probability_cmd);
- install_element (RMAP_NODE, &no_match_probability_val_cmd);
- install_element (RMAP_NODE, &match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_val_cmd);
- install_element (RMAP_NODE, &match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_val_cmd);
-
- install_element (RMAP_NODE, &set_ip_nexthop_cmd);
+
install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
install_element (RMAP_NODE, &set_ip_nexthop_unchanged_cmd);
- install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
- install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
- install_element (RMAP_NODE, &no_set_ip_nexthop_peer_cmd);
install_element (RMAP_NODE, &set_local_pref_cmd);
install_element (RMAP_NODE, &no_set_local_pref_cmd);
- install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
install_element (RMAP_NODE, &set_weight_cmd);
install_element (RMAP_NODE, &no_set_weight_cmd);
- install_element (RMAP_NODE, &no_set_weight_val_cmd);
- install_element (RMAP_NODE, &set_metric_cmd);
- install_element (RMAP_NODE, &set_metric_addsub_cmd);
- install_element (RMAP_NODE, &set_metric_rtt_cmd);
- install_element (RMAP_NODE, &no_set_metric_cmd);
- install_element (RMAP_NODE, &no_set_metric_val_cmd);
- install_element (RMAP_NODE, &set_aspath_prepend_cmd);
+ install_element (RMAP_NODE, &set_aspath_prepend_asn_cmd);
install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
install_element (RMAP_NODE, &set_aspath_exclude_cmd);
install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
- install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
- install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
install_element (RMAP_NODE, &set_origin_cmd);
install_element (RMAP_NODE, &no_set_origin_cmd);
- install_element (RMAP_NODE, &no_set_origin_val_cmd);
install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
install_element (RMAP_NODE, &set_aggregator_as_cmd);
install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
- install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
install_element (RMAP_NODE, &set_community_cmd);
install_element (RMAP_NODE, &set_community_none_cmd);
install_element (RMAP_NODE, &no_set_community_cmd);
- install_element (RMAP_NODE, &no_set_community_val_cmd);
- install_element (RMAP_NODE, &no_set_community_none_cmd);
install_element (RMAP_NODE, &set_community_delete_cmd);
install_element (RMAP_NODE, &no_set_community_delete_cmd);
- install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
+ install_element (RMAP_NODE, &set_lcommunity_cmd);
+ install_element (RMAP_NODE, &set_lcommunity_none_cmd);
+ install_element (RMAP_NODE, &no_set_lcommunity_cmd);
+ install_element (RMAP_NODE, &no_set_lcommunity1_cmd);
+ install_element (RMAP_NODE, &set_lcommunity_delete_cmd);
+ install_element (RMAP_NODE, &no_set_lcommunity_delete_cmd);
install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
- install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
- install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
+ install_element (RMAP_NODE, &set_vpn_nexthop_cmd);
+ install_element (RMAP_NODE, &no_set_vpn_nexthop_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
+ install_element (RMAP_NODE, &set_ipx_vpn_nexthop_cmd);
+ install_element (RMAP_NODE, &no_set_ipx_vpn_nexthop_cmd);
install_element (RMAP_NODE, &set_originator_id_cmd);
install_element (RMAP_NODE, &no_set_originator_id_cmd);
- install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
- install_element (RMAP_NODE, &set_tag_cmd);
- install_element (RMAP_NODE, &no_set_tag_cmd);
- install_element (RMAP_NODE, &no_set_tag_val_cmd);
-#ifdef HAVE_IPV6
route_map_install_match (&route_match_ipv6_address_cmd);
route_map_install_match (&route_match_ipv6_next_hop_cmd);
route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
@@ -4634,23 +4639,14 @@ bgp_route_map_init (void)
route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
- install_element (RMAP_NODE, &match_ipv6_address_cmd);
- install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
- install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
- install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
install_element (RMAP_NODE, &set_ipv6_nexthop_prefer_global_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_prefer_global_cmd);
- install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
- install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
- install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
-#endif /* HAVE_IPV6 */
}
void
diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c
index 114c6ef013..884523919e 100644
--- a/bgpd/bgp_table.c
+++ b/bgpd/bgp_table.c
@@ -26,6 +26,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "vty.h"
#include "queue.h"
#include "filter.h"
+#include "command.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h
index 2f839c4af7..3c96dac617 100644
--- a/bgpd/bgp_table.h
+++ b/bgpd/bgp_table.h
@@ -222,8 +222,6 @@ bgp_node_match_ipv4 (const struct bgp_table *table, struct in_addr *addr)
addr));
}
-#ifdef HAVE_IPV6
-
/*
* bgp_node_match_ipv6
*/
@@ -234,8 +232,6 @@ bgp_node_match_ipv6 (const struct bgp_table *table, struct in6_addr *addr)
addr));
}
-#endif /* HAVE_IPV6 */
-
static inline unsigned long
bgp_table_count (const struct bgp_table *const table)
{
diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c
index 8a3f4567ca..48f56a29b2 100644
--- a/bgpd/bgp_updgrp_adv.c
+++ b/bgpd/bgp_updgrp_adv.c
@@ -167,7 +167,7 @@ group_announce_route_walkcb (struct update_group *updgrp, void *arg)
subgroup_process_announce_selected (subgrp, ri, ctx->rn, ri->addpath_tx_id);
}
- /* Process the bestpath last so the "show ip bgp neighbor x.x.x.x advertised"
+ /* Process the bestpath last so the "show [ip] bgp neighbor x.x.x.x advertised"
* output shows the attributes from the bestpath */
if (ctx->ri)
subgroup_process_announce_selected (subgrp, ctx->ri, ctx->rn, ctx->ri->addpath_tx_id);
@@ -711,7 +711,6 @@ subgroup_default_originate (struct update_subgroup *subgrp, int withdraw)
if (afi == AFI_IP)
str2prefix ("0.0.0.0/0", &p);
-#ifdef HAVE_IPV6
else if (afi == AFI_IP6)
{
struct attr_extra *ae = attr.extra;
@@ -727,7 +726,6 @@ subgroup_default_originate (struct update_subgroup *subgrp, int withdraw)
&& !IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))
ae->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
}
-#endif /* HAVE_IPV6 */
if (peer->default_rmap[afi][safi].name)
{
@@ -785,10 +783,8 @@ subgroup_default_originate (struct update_subgroup *subgrp, int withdraw)
*/
if (afi == AFI_IP)
str2prefix ("0.0.0.0/0", &p);
-#ifdef HAVE_IPV6
else
str2prefix ("::/0", &p);
-#endif /* HAVE_IPV6 */
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, &p, NULL);
bgp_adj_out_unset_subgroup (rn, subgrp, 0, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c
index ce2e0dbca0..79c11358fe 100644
--- a/bgpd/bgp_updgrp_packet.c
+++ b/bgpd/bgp_updgrp_packet.c
@@ -1003,10 +1003,8 @@ subgroup_default_update_packet (struct update_subgroup *subgrp,
if (afi == AFI_IP)
str2prefix ("0.0.0.0/0", &p);
-#ifdef HAVE_IPV6
else
str2prefix ("::/0", &p);
-#endif /* HAVE_IPV6 */
/* Logging the attribute. */
if (bgp_debug_update(NULL, &p, subgrp->update_group, 0))
@@ -1081,10 +1079,8 @@ subgroup_default_withdraw_packet (struct update_subgroup *subgrp)
if (afi == AFI_IP)
str2prefix ("0.0.0.0/0", &p);
-#ifdef HAVE_IPV6
else
str2prefix ("::/0", &p);
-#endif /* HAVE_IPV6 */
if (bgp_debug_update(NULL, &p, subgrp->update_group, 0))
{
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 39933a1953..01d1768691 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -20,8 +20,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include <zebra.h>
-#include "lib/json.h"
#include "command.h"
+#include "lib/json.h"
#include "prefix.h"
#include "plist.h"
#include "buffer.h"
@@ -41,14 +41,15 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_damp.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_fsm.h"
-#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_open.h"
#include "bgpd/bgp_regex.h"
#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_vty.h"
@@ -107,7 +108,7 @@ bgp_node_safi (struct vty *vty)
return safi;
}
-/* supports (ipv4|ipv6) */
+/* supports <ipv4|ipv6> */
afi_t
bgp_vty_afi_from_arg(const char *afi_str)
{
@@ -131,10 +132,28 @@ bgp_parse_afi(const char *str, afi_t *afi)
return -1;
}
+int
+argv_find_and_parse_afi(struct cmd_token **argv, int argc, int *index, afi_t *afi)
+{
+ int ret = 0;
+ if (argv_find (argv, argc, "ipv4", index))
+ {
+ ret = 1;
+ if (afi)
+ *afi = AFI_IP;
+ }
+ else if (argv_find (argv, argc, "ipv6", index))
+ {
+ ret = 1;
+ if (afi)
+ *afi = AFI_IP6;
+ }
+ return ret;
+}
-/* supports (unicast|multicast|vpn|encap) */
+/* supports <unicast|multicast|vpn|encap> */
safi_t
-bgp_vty_safi_from_arg(const char *safi_str)
+bgp_vty_safi_from_arg(const char *safi_str)
{
safi_t safi = SAFI_MAX; /* unknown */
if (strncmp (safi_str, "m", 1) == 0)
@@ -149,13 +168,108 @@ bgp_vty_safi_from_arg(const char *safi_str)
}
int
-bgp_parse_safi(const char *str, safi_t *safi)
+argv_find_and_parse_safi (struct cmd_token **argv, int argc, int *index, safi_t *safi)
{
- *safi = bgp_vty_safi_from_arg(str);
- if (*safi != SAFI_MAX)
- return 0;
- else
- return -1;
+ int ret = 0;
+ if (argv_find (argv, argc, "unicast", index))
+ {
+ ret = 1;
+ if (safi)
+ *safi = SAFI_UNICAST;
+ }
+ else if (argv_find (argv, argc, "multicast", index))
+ {
+ ret = 1;
+ if (safi)
+ *safi = SAFI_MULTICAST;
+ }
+ else if (argv_find (argv, argc, "vpn", index))
+ {
+ ret = 1;
+ if (safi)
+ *safi = SAFI_MPLS_VPN;
+ }
+ else if (argv_find (argv, argc, "encap", index))
+ {
+ ret = 1;
+ if (safi)
+ *safi = SAFI_ENCAP;
+ }
+ return ret;
+}
+
+/*
+ * bgp_vty_find_and_parse_afi_safi_vrf
+ *
+ * For a given 'show ...' command, correctly parse the afi/safi/vrf out from it
+ * This function *assumes* that the calling function pre-sets the afi/safi/vrf
+ * to appropriate values for the calling function. This is to allow the
+ * calling function to make decisions appropriate for the show command
+ * that is being parsed.
+ *
+ * The show commands are generally of the form:
+ * "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] ..."
+ *
+ * Since we use argv_find if the show command in particular doesn't have:
+ * [ip]
+ * [<view|vrf> WORD]
+ * [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]]
+ * The command parsing should still be ok.
+ *
+ * vty -> The vty for the command so we can output some useful data in
+ * the event of a parse error in the vrf.
+ * argv -> The command tokens
+ * argc -> How many command tokens we have
+ * idx -> The current place in the command, generally should be 0 for this function
+ * afi -> The parsed afi if it was included in the show command, returned here
+ * safi -> The parsed safi if it was included in the show command, returned here
+ * vrf -> The parsed vrf id if it was included in the show command, returned here
+ *
+ * The function returns the correct location in the parse tree for the
+ * last token found.
+ *
+ * Returns 0 for failure to parse correctly, else the idx position of where
+ * it found the last token.
+ */
+int
+bgp_vty_find_and_parse_afi_safi_vrf (struct vty *vty, struct cmd_token **argv, int argc, int *idx,
+ afi_t *afi, safi_t *safi, vrf_id_t *vrf)
+{
+ char *vrf_name = NULL;
+
+ assert (afi);
+ assert (safi);
+ assert (vrf && *vrf != VRF_UNKNOWN);
+
+ if (argv_find (argv, argc, "ip", idx))
+ *afi = AFI_IP;
+
+ if (argv_find (argv, argc, "view", idx) || argv_find (argv, argc, "vrf", idx))
+ {
+ vrf_name = argv[*idx + 1]->arg;
+ *idx += 2;
+ }
+
+ if (argv_find_and_parse_afi (argv, argc, idx, afi))
+ argv_find_and_parse_safi (argv, argc, idx, safi);
+
+ if (vrf_name)
+ {
+ if (strmatch(vrf_name, "all"))
+ *vrf = VRF_ALL;
+ else
+ *vrf = vrf_name_to_id (vrf_name);
+ }
+
+ if (*vrf == VRF_UNKNOWN)
+ {
+ vty_out (vty, "View/Vrf specified is unknown: %s", vrf_name);
+ *idx = 0;
+ return 0;
+ }
+
+ *idx += 1;
+ return *idx;
}
static int
@@ -182,12 +296,14 @@ peer_address_self_check (struct bgp *bgp, union sockunion *su)
static struct peer *
peer_lookup_vty (struct vty *vty, const char *ip_str)
{
+ struct bgp *bgp = VTY_GET_CONTEXT(bgp);
int ret;
- struct bgp *bgp;
union sockunion su;
struct peer *peer;
- bgp = vty->index;
+ if (!bgp) {
+ return NULL;
+ }
ret = str2sockunion (ip_str, &su);
if (ret < 0)
@@ -229,13 +345,15 @@ peer_lookup_vty (struct vty *vty, const char *ip_str)
struct peer *
peer_and_group_lookup_vty (struct vty *vty, const char *peer_str)
{
+ struct bgp *bgp = VTY_GET_CONTEXT(bgp);
int ret;
- struct bgp *bgp;
union sockunion su;
struct peer *peer = NULL;
struct peer_group *group = NULL;
- bgp = vty->index;
+ if (!bgp) {
+ return NULL;
+ }
ret = str2sockunion (peer_str, &su);
if (ret == 0)
@@ -568,7 +686,7 @@ bgp_clear_vty (struct vty *vty, const char *name, afi_t afi, safi_t safi,
static void
bgp_clear_star_soft_in (struct vty *vty, const char *name)
{
- bgp_clear_vty (vty,name, AFI_IP, SAFI_UNICAST, clear_all,
+ bgp_clear_vty (vty, name, AFI_IP, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_IN, NULL);
bgp_clear_vty (vty, name, AFI_IP6, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_IN, NULL);
@@ -617,13 +735,14 @@ DEFUN (no_bgp_multiple_instance,
DEFUN (bgp_config_type,
bgp_config_type_cmd,
- "bgp config-type (cisco|zebra)",
+ "bgp config-type <cisco|zebra>",
BGP_STR
"Configuration type\n"
"cisco\n"
"zebra\n")
{
- if (strncmp (argv[0], "c", 1) == 0)
+ int idx_vendor = 2;
+ if (strncmp (argv[idx_vendor]->arg, "c", 1) == 0)
bgp_option_set (BGP_OPT_CONFIG_CISCO);
else
bgp_option_unset (BGP_OPT_CONFIG_CISCO);
@@ -633,23 +752,17 @@ DEFUN (bgp_config_type,
DEFUN (no_bgp_config_type,
no_bgp_config_type_cmd,
- "no bgp config-type",
+ "no bgp config-type [<cisco|zebra>]",
NO_STR
BGP_STR
- "Display configuration type\n")
+ "Display configuration type\n"
+ "cisco\n"
+ "zebra\n")
{
bgp_option_unset (BGP_OPT_CONFIG_CISCO);
return CMD_SUCCESS;
}
-ALIAS (no_bgp_config_type,
- no_bgp_config_type_val_cmd,
- "no bgp config-type (cisco|zebra)",
- NO_STR
- BGP_STR
- "Configuration type\n"
- "cisco\n"
- "zebra\n")
DEFUN (no_synchronization,
no_synchronization_cmd,
@@ -670,13 +783,17 @@ DEFUN (no_auto_summary,
}
/* "router bgp" commands. */
-DEFUN (router_bgp,
- router_bgp_cmd,
- "router bgp " CMD_AS_RANGE,
+DEFUN (router_bgp,
+ router_bgp_cmd,
+ "router bgp [(1-4294967295) [<view|vrf> WORD]]",
ROUTER_STR
BGP_STR
- AS_STR)
+ AS_STR
+ BGP_INSTANCE_HELP_STR)
{
+ int idx_asn = 2;
+ int idx_view_vrf = 3;
+ int idx_vrf = 4;
int ret;
as_t as;
struct bgp *bgp;
@@ -684,7 +801,7 @@ DEFUN (router_bgp,
enum bgp_instance_type inst_type;
// "router bgp" without an ASN
- if (argc < 1)
+ if (argc == 2)
{
//Pending: Make VRF option available for ASN less config
bgp = bgp_get_default();
@@ -705,15 +822,16 @@ DEFUN (router_bgp,
// "router bgp X"
else
{
- VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
+ VTY_GET_INTEGER_RANGE ("AS", as, argv[idx_asn]->arg, 1, BGP_AS4_MAX);
inst_type = BGP_INSTANCE_TYPE_DEFAULT;
- if (argc == 3)
+ if (argc > 3)
{
- name = argv[2];
- if (!strcmp(argv[1], "vrf"))
+ name = argv[idx_vrf]->arg;
+
+ if (!strcmp(argv[idx_view_vrf]->text, "vrf"))
inst_type = BGP_INSTANCE_TYPE_VRF;
- else if (!strcmp(argv[1], "view"))
+ else if (!strcmp(argv[idx_view_vrf]->text, "view"))
inst_type = BGP_INSTANCE_TYPE_VIEW;
}
@@ -737,43 +855,29 @@ DEFUN (router_bgp,
/* Pending: handle when user tries to change a view to vrf n vv. */
}
- vty->node = BGP_NODE;
- vty->index = bgp;
+ VTY_PUSH_CONTEXT(BGP_NODE, bgp);
return CMD_SUCCESS;
}
-ALIAS (router_bgp,
- router_bgp_instance_cmd,
- "router bgp " CMD_AS_RANGE " (view|vrf) WORD",
- ROUTER_STR
- BGP_STR
- AS_STR
- "BGP view\nBGP VRF\n"
- "View/VRF name\n")
-
-ALIAS (router_bgp,
- router_bgp_noasn_cmd,
- "router bgp",
- ROUTER_STR
- BGP_STR)
-
/* "no router bgp" commands. */
DEFUN (no_router_bgp,
no_router_bgp_cmd,
- "no router bgp " CMD_AS_RANGE,
+ "no router bgp [(1-4294967295) [<view|vrf> WORD]]",
NO_STR
ROUTER_STR
BGP_STR
- AS_STR)
+ AS_STR
+ BGP_INSTANCE_HELP_STR)
{
+ int idx_asn = 3;
+ int idx_vrf = 5;
as_t as;
struct bgp *bgp;
const char *name = NULL;
-
// "no router bgp" without an ASN
- if (argc < 1)
+ if (argc == 3)
{
//Pending: Make VRF option available for ASN less config
bgp = bgp_get_default();
@@ -792,10 +896,10 @@ DEFUN (no_router_bgp,
}
else
{
- VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
+ VTY_GET_INTEGER_RANGE ("AS", as, argv[idx_asn]->arg, 1, BGP_AS4_MAX);
- if (argc == 3)
- name = argv[2];
+ if (argc > 4)
+ name = argv[idx_vrf]->arg;
/* Lookup bgp structure. */
bgp = bgp_lookup (as, name);
@@ -811,22 +915,7 @@ DEFUN (no_router_bgp,
return CMD_SUCCESS;
}
-ALIAS (no_router_bgp,
- no_router_bgp_instance_cmd,
- "no router bgp " CMD_AS_RANGE " (view|vrf) WORD",
- NO_STR
- ROUTER_STR
- BGP_STR
- AS_STR
- "BGP view\nBGP VRF\n"
- "View/VRF name\n")
-ALIAS (no_router_bgp,
- no_router_bgp_noasn_cmd,
- "no router bgp",
- NO_STR
- ROUTER_STR
- BGP_STR)
/* BGP router-id. */
@@ -837,13 +926,12 @@ DEFUN (bgp_router_id,
"Override configured router identifier\n"
"Manually configured router identifier\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_ipv4 = 2;
int ret;
struct in_addr id;
- struct bgp *bgp;
- bgp = vty->index;
-
- ret = inet_aton (argv[0], &id);
+ ret = inet_aton (argv[idx_ipv4]->arg, &id);
if (! ret)
{
vty_out (vty, "%% Malformed bgp router identifier%s", VTY_NEWLINE);
@@ -857,20 +945,20 @@ DEFUN (bgp_router_id,
DEFUN (no_bgp_router_id,
no_bgp_router_id_cmd,
- "no bgp router-id",
+ "no bgp router-id [A.B.C.D]",
NO_STR
BGP_STR
- "Override configured router identifier\n")
+ "Override configured router identifier\n"
+ "Manually configured router identifier\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_router_id = 3;
int ret;
struct in_addr id;
- struct bgp *bgp;
- bgp = vty->index;
-
- if (argc == 1)
+ if (argc > idx_router_id)
{
- ret = inet_aton (argv[0], &id);
+ ret = inet_aton (argv[idx_router_id]->arg, &id);
if (! ret)
{
vty_out (vty, "%% Malformed BGP router identifier%s", VTY_NEWLINE);
@@ -890,30 +978,22 @@ DEFUN (no_bgp_router_id,
return CMD_SUCCESS;
}
-ALIAS (no_bgp_router_id,
- no_bgp_router_id_val_cmd,
- "no bgp router-id A.B.C.D",
- NO_STR
- BGP_STR
- "Override configured router identifier\n"
- "Manually configured router identifier\n")
/* BGP Cluster ID. */
-
DEFUN (bgp_cluster_id,
bgp_cluster_id_cmd,
- "bgp cluster-id A.B.C.D",
+ "bgp cluster-id <A.B.C.D|(1-4294967295)>",
BGP_STR
"Configure Route-Reflector Cluster-id\n"
- "Route-Reflector Cluster-id in IP address format\n")
+ "Route-Reflector Cluster-id in IP address format\n"
+ "Route-Reflector Cluster-id as 32 bit quantity\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_ipv4 = 2;
int ret;
- struct bgp *bgp;
struct in_addr cluster;
- bgp = vty->index;
-
- ret = inet_aton (argv[0], &cluster);
+ ret = inet_aton (argv[idx_ipv4]->arg, &cluster);
if (! ret)
{
vty_out (vty, "%% Malformed bgp cluster identifier%s", VTY_NEWLINE);
@@ -926,72 +1006,35 @@ DEFUN (bgp_cluster_id,
return CMD_SUCCESS;
}
-ALIAS (bgp_cluster_id,
- bgp_cluster_id32_cmd,
- "bgp cluster-id <1-4294967295>",
- BGP_STR
- "Configure Route-Reflector Cluster-id\n"
- "Route-Reflector Cluster-id as 32 bit quantity\n")
-
DEFUN (no_bgp_cluster_id,
no_bgp_cluster_id_cmd,
- "no bgp cluster-id",
+ "no bgp cluster-id [<A.B.C.D|(1-4294967295)>]",
NO_STR
BGP_STR
- "Configure Route-Reflector Cluster-id\n")
+ "Configure Route-Reflector Cluster-id\n"
+ "Route-Reflector Cluster-id in IP address format\n"
+ "Route-Reflector Cluster-id as 32 bit quantity\n")
{
- int ret;
- struct bgp *bgp;
- struct in_addr cluster;
-
- bgp = vty->index;
-
- if (argc == 1)
- {
- ret = inet_aton (argv[0], &cluster);
- if (! ret)
- {
- vty_out (vty, "%% Malformed bgp cluster identifier%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_cluster_id_unset (bgp);
bgp_clear_star_soft_out (vty, bgp->name);
return CMD_SUCCESS;
}
-ALIAS (no_bgp_cluster_id,
- no_bgp_cluster_id_ip_cmd,
- "no bgp cluster-id A.B.C.D",
- NO_STR
- BGP_STR
- "Configure Route-Reflector Cluster-id\n"
- "Route-Reflector Cluster-id in IP address format\n")
-
-ALIAS (no_bgp_cluster_id,
- no_bgp_cluster_id_decimal_cmd,
- "no bgp cluster-id <1-4294967295>",
- NO_STR
- BGP_STR
- "Configure Route-Reflector Cluster-id\n"
- "Route-Reflector Cluster-id as 32 bit quantity\n")
-
DEFUN (bgp_confederation_identifier,
bgp_confederation_identifier_cmd,
- "bgp confederation identifier " CMD_AS_RANGE,
+ "bgp confederation identifier (1-4294967295)",
"BGP specific commands\n"
"AS confederation parameters\n"
"AS number\n"
"Set routing domain confederation AS\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
as_t as;
- bgp = vty->index;
-
- VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
+ VTY_GET_INTEGER_RANGE ("AS", as, argv[idx_number]->arg, 1, BGP_AS4_MAX);
bgp_confederation_id_set (bgp, as);
@@ -1000,47 +1043,35 @@ DEFUN (bgp_confederation_identifier,
DEFUN (no_bgp_confederation_identifier,
no_bgp_confederation_identifier_cmd,
- "no bgp confederation identifier",
+ "no bgp confederation identifier [(1-4294967295)]",
NO_STR
"BGP specific commands\n"
"AS confederation parameters\n"
- "AS number\n")
+ "AS number\n"
+ "Set routing domain confederation AS\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
-
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_confederation_id_unset (bgp);
return CMD_SUCCESS;
}
-ALIAS (no_bgp_confederation_identifier,
- no_bgp_confederation_identifier_arg_cmd,
- "no bgp confederation identifier " CMD_AS_RANGE,
- NO_STR
- "BGP specific commands\n"
- "AS confederation parameters\n"
- "AS number\n"
- "Set routing domain confederation AS\n")
-
DEFUN (bgp_confederation_peers,
bgp_confederation_peers_cmd,
- "bgp confederation peers ." CMD_AS_RANGE,
+ "bgp confederation peers (1-4294967295)...",
"BGP specific commands\n"
"AS confederation parameters\n"
"Peer ASs in BGP confederation\n"
AS_STR)
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_asn = 3;
as_t as;
int i;
- bgp = vty->index;
-
- for (i = 0; i < argc; i++)
+ for (i = idx_asn; i < argc; i++)
{
- VTY_GET_INTEGER_RANGE ("AS", as, argv[i], 1, BGP_AS4_MAX);
+ VTY_GET_INTEGER_RANGE ("AS", as, argv[i]->arg, 1, BGP_AS4_MAX);
if (bgp->as == as)
{
@@ -1056,22 +1087,21 @@ DEFUN (bgp_confederation_peers,
DEFUN (no_bgp_confederation_peers,
no_bgp_confederation_peers_cmd,
- "no bgp confederation peers ." CMD_AS_RANGE,
+ "no bgp confederation peers (1-4294967295)...",
NO_STR
"BGP specific commands\n"
"AS confederation parameters\n"
"Peer ASs in BGP confederation\n"
AS_STR)
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_asn = 4;
as_t as;
int i;
- bgp = vty->index;
-
- for (i = 0; i < argc; i++)
+ for (i = idx_asn; i < argc; i++)
{
- VTY_GET_INTEGER_RANGE ("AS", as, argv[i], 1, BGP_AS4_MAX);
+ VTY_GET_INTEGER_RANGE ("AS", as, argv[i]->arg, 1, BGP_AS4_MAX);
bgp_confederation_peers_remove (bgp, as);
}
@@ -1087,23 +1117,20 @@ static int
bgp_maxpaths_config_vty (struct vty *vty, int peer_type, const char *mpaths,
u_int16_t options, int set)
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
u_int16_t maxpaths = 0;
int ret;
afi_t afi;
safi_t safi;
- bgp = vty->index;
afi = bgp_node_afi (vty);
safi = bgp_node_safi (vty);
if (set)
- {
- VTY_GET_INTEGER_RANGE ("maximum-paths", maxpaths, mpaths, 1,
- MULTIPATH_NUM);
- ret = bgp_maximum_paths_set (bgp, afi, safi, peer_type, maxpaths,
- options);
- }
+ {
+ maxpaths = strtol(mpaths, NULL, 10);
+ ret = bgp_maximum_paths_set (bgp, afi, safi, peer_type, maxpaths, options);
+ }
else
ret = bgp_maximum_paths_unset (bgp, afi, safi, peer_type);
@@ -1129,9 +1156,7 @@ DEFUN (bgp_maxmed_admin,
"Advertise routes with max-med\n"
"Administratively applied, for an indefinite period\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp->v_maxmed_admin = 1;
bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT;
@@ -1143,18 +1168,17 @@ DEFUN (bgp_maxmed_admin,
DEFUN (bgp_maxmed_admin_medv,
bgp_maxmed_admin_medv_cmd,
- "bgp max-med administrative <0-4294967294>",
+ "bgp max-med administrative (0-4294967294)",
BGP_STR
"Advertise routes with max-med\n"
"Administratively applied, for an indefinite period\n"
"Max MED value to be used\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
bgp->v_maxmed_admin = 1;
- VTY_GET_INTEGER ("max-med admin med-value", bgp->maxmed_admin_value, argv[0]);
+ VTY_GET_INTEGER ("max-med admin med-value", bgp->maxmed_admin_value, argv[idx_number]->arg);
bgp_maxmed_update(bgp);
@@ -1163,55 +1187,33 @@ DEFUN (bgp_maxmed_admin_medv,
DEFUN (no_bgp_maxmed_admin,
no_bgp_maxmed_admin_cmd,
- "no bgp max-med administrative",
+ "no bgp max-med administrative [(0-4294967294)]",
NO_STR
BGP_STR
"Advertise routes with max-med\n"
- "Administratively applied, for an indefinite period\n")
+ "Administratively applied, for an indefinite period\n"
+ "Max MED value to be used\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
-
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp->v_maxmed_admin = BGP_MAXMED_ADMIN_UNCONFIGURED;
bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT;
-
bgp_maxmed_update(bgp);
return CMD_SUCCESS;
}
-ALIAS (no_bgp_maxmed_admin,
- no_bgp_maxmed_admin_medv_cmd,
- "no bgp max-med administrative <0-4294967294>",
- NO_STR
- BGP_STR
- "Advertise routes with max-med\n"
- "Administratively applied, for an indefinite period\n"
- "Max MED value to be used\n")
-
-
DEFUN (bgp_maxmed_onstartup,
bgp_maxmed_onstartup_cmd,
- "bgp max-med on-startup <5-86400>",
+ "bgp max-med on-startup (5-86400)",
BGP_STR
"Advertise routes with max-med\n"
"Effective on a startup\n"
"Time (seconds) period for max-med\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
-
- if (argc != 1)
- {
- vty_out (vty, "%% Must supply max-med on-startup period");
- return CMD_WARNING;
- }
-
- VTY_GET_INTEGER ("max-med on-startup period", bgp->v_maxmed_onstartup, argv[0]);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
+ VTY_GET_INTEGER ("max-med on-startup period", bgp->v_maxmed_onstartup, argv[idx_number]->arg);
bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT;
-
bgp_maxmed_update(bgp);
return CMD_SUCCESS;
@@ -1219,26 +1221,18 @@ DEFUN (bgp_maxmed_onstartup,
DEFUN (bgp_maxmed_onstartup_medv,
bgp_maxmed_onstartup_medv_cmd,
- "bgp max-med on-startup <5-86400> <0-4294967294>",
+ "bgp max-med on-startup (5-86400) (0-4294967294)",
BGP_STR
"Advertise routes with max-med\n"
"Effective on a startup\n"
"Time (seconds) period for max-med\n"
"Max MED value to be used\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
-
- if (argc != 2)
- {
- vty_out (vty, "%% Must supply max-med on-startup period and med value");
- return CMD_WARNING;
- }
-
- VTY_GET_INTEGER ("max-med on-startup period", bgp->v_maxmed_onstartup, argv[0]);
- VTY_GET_INTEGER ("max-med on-startup med-value", bgp->maxmed_onstartup_value, argv[1]);
-
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ VTY_GET_INTEGER ("max-med on-startup period", bgp->v_maxmed_onstartup, argv[idx_number]->arg);
+ VTY_GET_INTEGER ("max-med on-startup med-value", bgp->maxmed_onstartup_value, argv[idx_number_2]->arg);
bgp_maxmed_update(bgp);
return CMD_SUCCESS;
@@ -1246,15 +1240,15 @@ DEFUN (bgp_maxmed_onstartup_medv,
DEFUN (no_bgp_maxmed_onstartup,
no_bgp_maxmed_onstartup_cmd,
- "no bgp max-med on-startup",
+ "no bgp max-med on-startup [(5-86400) [(0-4294967294)]]",
NO_STR
BGP_STR
"Advertise routes with max-med\n"
- "Effective on a startup\n")
+ "Effective on a startup\n"
+ "Time (seconds) period for max-med\n"
+ "Max MED value to be used\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
/* Cancel max-med onstartup if its on */
if (bgp->t_maxmed_onstartup)
@@ -1271,36 +1265,14 @@ DEFUN (no_bgp_maxmed_onstartup,
return CMD_SUCCESS;
}
-ALIAS (no_bgp_maxmed_onstartup,
- no_bgp_maxmed_onstartup_period_cmd,
- "no bgp max-med on-startup <5-86400>",
- NO_STR
- BGP_STR
- "Advertise routes with max-med\n"
- "Effective on a startup\n"
- "Time (seconds) period for max-med\n")
-
-ALIAS (no_bgp_maxmed_onstartup,
- no_bgp_maxmed_onstartup_period_medv_cmd,
- "no bgp max-med on-startup <5-86400> <0-4294967294>",
- NO_STR
- BGP_STR
- "Advertise routes with max-med\n"
- "Effective on a startup\n"
- "Time (seconds) period for max-med\n"
- "Max MED value to be used\n")
-
static int
bgp_update_delay_config_vty (struct vty *vty, const char *delay,
const char *wait)
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
u_int16_t update_delay;
u_int16_t establish_wait;
-
- bgp = vty->index;
-
VTY_GET_INTEGER_RANGE ("update-delay", update_delay, delay,
BGP_UPDATE_DELAY_MIN, BGP_UPDATE_DELAY_MAX);
@@ -1329,9 +1301,7 @@ bgp_update_delay_config_vty (struct vty *vty, const char *delay,
static int
bgp_update_delay_deconfig_vty (struct vty *vty)
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp->v_update_delay = BGP_UPDATE_DELAY_DEF;
bgp->v_establish_wait = bgp->v_update_delay;
@@ -1357,48 +1327,44 @@ bgp_config_write_update_delay (struct vty *vty, struct bgp *bgp)
/* Update-delay configuration */
DEFUN (bgp_update_delay,
bgp_update_delay_cmd,
- "update-delay <0-3600>",
+ "update-delay (0-3600)",
"Force initial delay for best-path and updates\n"
"Seconds\n")
{
- return bgp_update_delay_config_vty(vty, argv[0], NULL);
+ int idx_number = 1;
+ return bgp_update_delay_config_vty(vty, argv[idx_number]->arg, NULL);
}
DEFUN (bgp_update_delay_establish_wait,
bgp_update_delay_establish_wait_cmd,
- "update-delay <0-3600> <1-3600>",
+ "update-delay (0-3600) (1-3600)",
"Force initial delay for best-path and updates\n"
"Seconds\n"
"Wait for peers to be established\n"
"Seconds\n")
{
- return bgp_update_delay_config_vty(vty, argv[0], argv[1]);
+ int idx_number = 1;
+ int idx_number_2 = 2;
+ return bgp_update_delay_config_vty(vty, argv[idx_number]->arg, argv[idx_number_2]->arg);
}
/* Update-delay deconfiguration */
DEFUN (no_bgp_update_delay,
no_bgp_update_delay_cmd,
- "no update-delay <0-3600>",
+ "no update-delay [(0-3600) [(1-3600)]]",
+ NO_STR
"Force initial delay for best-path and updates\n"
- "Seconds\n")
+ "Seconds\n"
+ "Wait for peers to be established\n")
{
return bgp_update_delay_deconfig_vty(vty);
}
-ALIAS (no_bgp_update_delay,
- no_bgp_update_delay_establish_wait_cmd,
- "no update-delay <0-3600> <1-3600>",
- "Force initial delay for best-path and updates\n"
- "Seconds\n"
- "Wait for peers to be established\n"
- "Seconds\n")
static int
bgp_wpkt_quanta_config_vty (struct vty *vty, const char *num, char set)
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (set)
VTY_GET_INTEGER_RANGE ("write-quanta", bgp->wpkt_quanta, num,
@@ -1423,29 +1389,30 @@ bgp_config_write_wpkt_quanta (struct vty *vty, struct bgp *bgp)
/* Update-delay configuration */
DEFUN (bgp_wpkt_quanta,
bgp_wpkt_quanta_cmd,
- "write-quanta <1-10000>",
+ "write-quanta (1-10000)",
"How many packets to write to peer socket per run\n"
"Number of packets\n")
{
- return bgp_wpkt_quanta_config_vty(vty, argv[0], 1);
+ int idx_number = 1;
+ return bgp_wpkt_quanta_config_vty(vty, argv[idx_number]->arg, 1);
}
/* Update-delay deconfiguration */
DEFUN (no_bgp_wpkt_quanta,
no_bgp_wpkt_quanta_cmd,
- "no write-quanta <1-10000>",
+ "no write-quanta (1-10000)",
+ NO_STR
"How many packets to write to peer socket per run\n"
"Number of packets\n")
{
- return bgp_wpkt_quanta_config_vty(vty, argv[0], 0);
+ int idx_number = 2;
+ return bgp_wpkt_quanta_config_vty(vty, argv[idx_number]->arg, 0);
}
static int
bgp_coalesce_config_vty (struct vty *vty, const char *num, char set)
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (set)
VTY_GET_INTEGER_RANGE ("coalesce-time", bgp->coalesce_time, num,
@@ -1469,57 +1436,63 @@ bgp_config_write_coalesce_time (struct vty *vty, struct bgp *bgp)
DEFUN (bgp_coalesce_time,
bgp_coalesce_time_cmd,
- "coalesce-time <0-4294967295>",
+ "coalesce-time (0-4294967295)",
"Subgroup coalesce timer\n"
"Subgroup coalesce timer value (in ms)\n")
{
- return bgp_coalesce_config_vty(vty, argv[0], 1);
+ int idx_number = 1;
+ return bgp_coalesce_config_vty(vty, argv[idx_number]->arg, 1);
}
DEFUN (no_bgp_coalesce_time,
no_bgp_coalesce_time_cmd,
- "no coalesce-time <0-4294967295>",
+ "no coalesce-time (0-4294967295)",
+ NO_STR
"Subgroup coalesce timer\n"
"Subgroup coalesce timer value (in ms)\n")
{
- return bgp_coalesce_config_vty(vty, argv[0], 0);
+ int idx_number = 2;
+ return bgp_coalesce_config_vty(vty, argv[idx_number]->arg, 0);
}
/* Maximum-paths configuration */
DEFUN (bgp_maxpaths,
bgp_maxpaths_cmd,
- "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM),
+ "maximum-paths (1-255)",
"Forward packets over multiple paths\n"
"Number of paths\n")
{
- return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, argv[0], 0, 1);
+ int idx_number = 1;
+ return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, argv[idx_number]->arg, 0, 1);
}
DEFUN (bgp_maxpaths_ibgp,
bgp_maxpaths_ibgp_cmd,
- "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM),
+ "maximum-paths ibgp (1-255)",
"Forward packets over multiple paths\n"
"iBGP-multipath\n"
"Number of paths\n")
{
- return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, argv[0], 0, 1);
+ int idx_number = 2;
+ return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, argv[idx_number]->arg, 0, 1);
}
DEFUN (bgp_maxpaths_ibgp_cluster,
bgp_maxpaths_ibgp_cluster_cmd,
- "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM) " equal-cluster-length",
+ "maximum-paths ibgp (1-255) equal-cluster-length",
"Forward packets over multiple paths\n"
"iBGP-multipath\n"
"Number of paths\n"
"Match the cluster length\n")
{
- return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, argv[0],
+ int idx_number = 2;
+ return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, argv[idx_number]->arg,
BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN, 1);
}
DEFUN (no_bgp_maxpaths,
no_bgp_maxpaths_cmd,
- "no maximum-paths",
+ "no maximum-paths [(1-255)]",
NO_STR
"Forward packets over multiple paths\n"
"Number of paths\n")
@@ -1527,41 +1500,18 @@ DEFUN (no_bgp_maxpaths,
return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, NULL, 0, 0);
}
-ALIAS (no_bgp_maxpaths,
- no_bgp_maxpaths_arg_cmd,
- "no maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM),
- NO_STR
- "Forward packets over multiple paths\n"
- "Number of paths\n")
-
DEFUN (no_bgp_maxpaths_ibgp,
no_bgp_maxpaths_ibgp_cmd,
- "no maximum-paths ibgp",
+ "no maximum-paths ibgp [(1-255) [equal-cluster-length]]",
NO_STR
"Forward packets over multiple paths\n"
"iBGP-multipath\n"
- "Number of paths\n")
+ "Number of paths\n"
+ "Match the cluster length\n")
{
return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, NULL, 0, 0);
}
-ALIAS (no_bgp_maxpaths_ibgp,
- no_bgp_maxpaths_ibgp_arg_cmd,
- "no maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM),
- NO_STR
- "Forward packets over multiple paths\n"
- "iBGP-multipath\n"
- "Number of paths\n")
-
-ALIAS (no_bgp_maxpaths_ibgp,
- no_bgp_maxpaths_ibgp_cluster_cmd,
- "no maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM) " equal-cluster-length",
- NO_STR
- "Forward packets over multiple paths\n"
- "iBGP-multipath\n"
- "Number of paths\n"
- "Match the cluster length\n")
-
int
bgp_config_write_maxpaths (struct vty *vty, struct bgp *bgp, afi_t afi,
safi_t safi, int *write)
@@ -1591,20 +1541,20 @@ bgp_config_write_maxpaths (struct vty *vty, struct bgp *bgp, afi_t afi,
DEFUN (bgp_timers,
bgp_timers_cmd,
- "timers bgp <0-65535> <0-65535>",
+ "timers bgp (0-65535) (0-65535)",
"Adjust routing timers\n"
"BGP timers\n"
"Keepalive interval\n"
"Holdtime\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 2;
+ int idx_number_2 = 3;
unsigned long keepalive = 0;
unsigned long holdtime = 0;
- bgp = vty->index;
-
- VTY_GET_INTEGER ("keepalive", keepalive, argv[0]);
- VTY_GET_INTEGER ("holdtime", holdtime, argv[1]);
+ VTY_GET_INTEGER ("keepalive", keepalive, argv[idx_number]->arg);
+ VTY_GET_INTEGER ("holdtime", holdtime, argv[idx_number_2]->arg);
/* Holdtime value check. */
if (holdtime < 3 && holdtime != 0)
@@ -1621,27 +1571,19 @@ DEFUN (bgp_timers,
DEFUN (no_bgp_timers,
no_bgp_timers_cmd,
- "no timers bgp",
+ "no timers bgp [(0-65535) (0-65535)]",
NO_STR
"Adjust routing timers\n"
- "BGP timers\n")
+ "BGP timers\n"
+ "Keepalive interval\n"
+ "Holdtime\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_timers_unset (bgp);
return CMD_SUCCESS;
}
-ALIAS (no_bgp_timers,
- no_bgp_timers_arg_cmd,
- "no timers bgp <0-65535> <0-65535>",
- NO_STR
- "Adjust routing timers\n"
- "BGP timers\n"
- "Keepalive interval\n"
- "Holdtime\n")
DEFUN (bgp_client_to_client_reflection,
bgp_client_to_client_reflection_cmd,
@@ -1650,9 +1592,7 @@ DEFUN (bgp_client_to_client_reflection,
"Configure client to client route reflection\n"
"reflection of routes allowed\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT);
bgp_clear_star_soft_out (vty, bgp->name);
@@ -1667,9 +1607,7 @@ DEFUN (no_bgp_client_to_client_reflection,
"Configure client to client route reflection\n"
"reflection of routes allowed\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT);
bgp_clear_star_soft_out (vty, bgp->name);
@@ -1683,9 +1621,7 @@ DEFUN (bgp_always_compare_med,
"BGP specific commands\n"
"Allow comparing MED from different neighbors\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_ALWAYS_COMPARE_MED);
bgp_recalculate_all_bestpaths (bgp);
@@ -1699,9 +1635,7 @@ DEFUN (no_bgp_always_compare_med,
"BGP specific commands\n"
"Allow comparing MED from different neighbors\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_ALWAYS_COMPARE_MED);
bgp_recalculate_all_bestpaths (bgp);
@@ -1715,9 +1649,7 @@ DEFUN (bgp_deterministic_med,
"BGP specific commands\n"
"Pick the best-MED path among paths advertised from the neighboring AS\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED))
{
@@ -1735,15 +1667,13 @@ DEFUN (no_bgp_deterministic_med,
"BGP specific commands\n"
"Pick the best-MED path among paths advertised from the neighboring AS\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int bestpath_per_as_used;
afi_t afi;
safi_t safi;
struct peer *peer;
struct listnode *node, *nnode;
- bgp = vty->index;
-
if (bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED))
{
bestpath_per_as_used = 0;
@@ -1785,9 +1715,7 @@ DEFUN (bgp_graceful_restart,
"BGP specific commands\n"
"Graceful restart capability parameters\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_GRACEFUL_RESTART);
return CMD_SUCCESS;
}
@@ -1799,66 +1727,55 @@ DEFUN (no_bgp_graceful_restart,
"BGP specific commands\n"
"Graceful restart capability parameters\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_GRACEFUL_RESTART);
return CMD_SUCCESS;
}
DEFUN (bgp_graceful_restart_stalepath_time,
bgp_graceful_restart_stalepath_time_cmd,
- "bgp graceful-restart stalepath-time <1-3600>",
+ "bgp graceful-restart stalepath-time (1-3600)",
"BGP specific commands\n"
"Graceful restart capability parameters\n"
"Set the max time to hold onto restarting peer's stale paths\n"
"Delay value (seconds)\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
u_int32_t stalepath;
- bgp = vty->index;
- if (! bgp)
- return CMD_WARNING;
-
- VTY_GET_INTEGER_RANGE ("stalepath-time", stalepath, argv[0], 1, 3600);
+ VTY_GET_INTEGER_RANGE ("stalepath-time", stalepath, argv[idx_number]->arg, 1, 3600);
bgp->stalepath_time = stalepath;
return CMD_SUCCESS;
}
DEFUN (bgp_graceful_restart_restart_time,
bgp_graceful_restart_restart_time_cmd,
- "bgp graceful-restart restart-time <1-3600>",
+ "bgp graceful-restart restart-time (1-3600)",
"BGP specific commands\n"
"Graceful restart capability parameters\n"
"Set the time to wait to delete stale routes before a BGP open message is received\n"
"Delay value (seconds)\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
u_int32_t restart;
- bgp = vty->index;
- if (! bgp)
- return CMD_WARNING;
-
- VTY_GET_INTEGER_RANGE ("restart-time", restart, argv[0], 1, 3600);
+ VTY_GET_INTEGER_RANGE ("restart-time", restart, argv[idx_number]->arg, 1, 3600);
bgp->restart_time = restart;
return CMD_SUCCESS;
}
DEFUN (no_bgp_graceful_restart_stalepath_time,
no_bgp_graceful_restart_stalepath_time_cmd,
- "no bgp graceful-restart stalepath-time",
+ "no bgp graceful-restart stalepath-time [(1-3600)]",
NO_STR
"BGP specific commands\n"
"Graceful restart capability parameters\n"
- "Set the max time to hold onto restarting peer's stale paths\n")
+ "Set the max time to hold onto restarting peer's stale paths\n"
+ "Delay value (seconds)\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
- if (! bgp)
- return CMD_WARNING;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
return CMD_SUCCESS;
@@ -1866,39 +1783,43 @@ DEFUN (no_bgp_graceful_restart_stalepath_time,
DEFUN (no_bgp_graceful_restart_restart_time,
no_bgp_graceful_restart_restart_time_cmd,
- "no bgp graceful-restart restart-time",
+ "no bgp graceful-restart restart-time [(1-3600)]",
NO_STR
"BGP specific commands\n"
"Graceful restart capability parameters\n"
- "Set the time to wait to delete stale routes before a BGP open message is received\n")
+ "Set the time to wait to delete stale routes before a BGP open message is received\n"
+ "Delay value (seconds)\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
- if (! bgp)
- return CMD_WARNING;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
return CMD_SUCCESS;
}
-ALIAS (no_bgp_graceful_restart_stalepath_time,
- no_bgp_graceful_restart_stalepath_time_val_cmd,
- "no bgp graceful-restart stalepath-time <1-3600>",
- NO_STR
+DEFUN (bgp_graceful_restart_preserve_fw,
+ bgp_graceful_restart_preserve_fw_cmd,
+ "bgp graceful-restart preserve-fw-state",
"BGP specific commands\n"
"Graceful restart capability parameters\n"
- "Set the max time to hold onto restarting peer's stale paths\n"
- "Delay value (seconds)\n")
+ "Sets F-bit indication that fib is preserved while doing Graceful Restart\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_set(bgp, BGP_FLAG_GR_PRESERVE_FWD);
+ return CMD_SUCCESS;
+}
-ALIAS (no_bgp_graceful_restart_restart_time,
- no_bgp_graceful_restart_restart_time_val_cmd,
- "no bgp graceful-restart restart-time <1-3600>",
+DEFUN (no_bgp_graceful_restart_preserve_fw,
+ no_bgp_graceful_restart_preserve_fw_cmd,
+ "no bgp graceful-restart preserve-fw-state",
NO_STR
"BGP specific commands\n"
"Graceful restart capability parameters\n"
- "Set the time to wait to delete stale routes before a BGP open message is received\n"
- "Delay value (seconds)\n")
+ "Unsets F-bit indication that fib is preserved while doing Graceful Restart\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_unset(bgp, BGP_FLAG_GR_PRESERVE_FWD);
+ return CMD_SUCCESS;
+}
/* "bgp fast-external-failover" configuration. */
DEFUN (bgp_fast_external_failover,
@@ -1907,9 +1828,7 @@ DEFUN (bgp_fast_external_failover,
BGP_STR
"Immediately reset session if a link to a directly connected external peer goes down\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
return CMD_SUCCESS;
}
@@ -1921,9 +1840,7 @@ DEFUN (no_bgp_fast_external_failover,
BGP_STR
"Immediately reset session if a link to a directly connected external peer goes down\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
return CMD_SUCCESS;
}
@@ -1935,9 +1852,7 @@ DEFUN (bgp_enforce_first_as,
BGP_STR
"Enforce the first AS for EBGP routes\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_ENFORCE_FIRST_AS);
bgp_clear_star_soft_in (vty, bgp->name);
@@ -1951,9 +1866,7 @@ DEFUN (no_bgp_enforce_first_as,
BGP_STR
"Enforce the first AS for EBGP routes\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_ENFORCE_FIRST_AS);
bgp_clear_star_soft_in (vty, bgp->name);
@@ -1968,9 +1881,7 @@ DEFUN (bgp_bestpath_compare_router_id,
"Change the default bestpath selection\n"
"Compare router-id for identical EBGP paths\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_COMPARE_ROUTER_ID);
bgp_recalculate_all_bestpaths (bgp);
@@ -1985,9 +1896,7 @@ DEFUN (no_bgp_bestpath_compare_router_id,
"Change the default bestpath selection\n"
"Compare router-id for identical EBGP paths\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_COMPARE_ROUTER_ID);
bgp_recalculate_all_bestpaths (bgp);
@@ -2003,9 +1912,7 @@ DEFUN (bgp_bestpath_aspath_ignore,
"AS-path attribute\n"
"Ignore as-path length in selecting a route\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_ASPATH_IGNORE);
bgp_recalculate_all_bestpaths (bgp);
@@ -2021,9 +1928,7 @@ DEFUN (no_bgp_bestpath_aspath_ignore,
"AS-path attribute\n"
"Ignore as-path length in selecting a route\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_ASPATH_IGNORE);
bgp_recalculate_all_bestpaths (bgp);
@@ -2039,9 +1944,7 @@ DEFUN (bgp_bestpath_aspath_confed,
"AS-path attribute\n"
"Compare path lengths including confederation sets & sequences in selecting a route\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_ASPATH_CONFED);
bgp_recalculate_all_bestpaths (bgp);
@@ -2057,9 +1960,7 @@ DEFUN (no_bgp_bestpath_aspath_confed,
"AS-path attribute\n"
"Compare path lengths including confederation sets & sequences in selecting a route\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_ASPATH_CONFED);
bgp_recalculate_all_bestpaths (bgp);
@@ -2069,7 +1970,7 @@ DEFUN (no_bgp_bestpath_aspath_confed,
/* "bgp bestpath as-path multipath-relax" configuration. */
DEFUN (bgp_bestpath_aspath_multipath_relax,
bgp_bestpath_aspath_multipath_relax_cmd,
- "bgp bestpath as-path multipath-relax {as-set|no-as-set}",
+ "bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
"BGP specific commands\n"
"Change the default bestpath selection\n"
"AS-path attribute\n"
@@ -2077,14 +1978,13 @@ DEFUN (bgp_bestpath_aspath_multipath_relax,
"Generate an AS_SET\n"
"Do not generate an AS_SET\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx = 0;
bgp_flag_set (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
/* no-as-set is now the default behavior so we can silently
* ignore it */
- if (argv[0] != NULL && strncmp (argv[0], "a", 1) == 0)
+ if (argv_find (argv, argc, "as-set", &idx))
bgp_flag_set (bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
else
bgp_flag_unset (bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET) ;
@@ -2096,7 +1996,7 @@ DEFUN (bgp_bestpath_aspath_multipath_relax,
DEFUN (no_bgp_bestpath_aspath_multipath_relax,
no_bgp_bestpath_aspath_multipath_relax_cmd,
- "no bgp bestpath as-path multipath-relax {as-set|no-as-set}",
+ "no bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
NO_STR
"BGP specific commands\n"
"Change the default bestpath selection\n"
@@ -2105,9 +2005,7 @@ DEFUN (no_bgp_bestpath_aspath_multipath_relax,
"Generate an AS_SET\n"
"Do not generate an AS_SET\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
bgp_flag_unset (bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
bgp_recalculate_all_bestpaths (bgp);
@@ -2122,9 +2020,7 @@ DEFUN (bgp_log_neighbor_changes,
"BGP specific commands\n"
"Log neighbor up/down and reset reason\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
return CMD_SUCCESS;
}
@@ -2136,9 +2032,7 @@ DEFUN (no_bgp_log_neighbor_changes,
"BGP specific commands\n"
"Log neighbor up/down and reset reason\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
return CMD_SUCCESS;
}
@@ -2146,20 +2040,22 @@ DEFUN (no_bgp_log_neighbor_changes,
/* "bgp bestpath med" configuration. */
DEFUN (bgp_bestpath_med,
bgp_bestpath_med_cmd,
- "bgp bestpath med (confed|missing-as-worst)",
+ "bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
"BGP specific commands\n"
"Change the default bestpath selection\n"
"MED attribute\n"
"Compare MED among confederation paths\n"
- "Treat missing MED as the least preferred one\n")
+ "Treat missing MED as the least preferred one\n"
+ "Treat missing MED as the least preferred one\n"
+ "Compare MED among confederation paths\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
- if (strncmp (argv[0], "confed", 1) == 0)
+ int idx = 0;
+ if (argv_find (argv, argc, "confed", &idx))
bgp_flag_set (bgp, BGP_FLAG_MED_CONFED);
- else
+ idx = 0;
+ if (argv_find (argv, argc, "missing-as-worst", &idx))
bgp_flag_set (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
bgp_recalculate_all_bestpaths (bgp);
@@ -2167,51 +2063,25 @@ DEFUN (bgp_bestpath_med,
return CMD_SUCCESS;
}
-DEFUN (bgp_bestpath_med2,
- bgp_bestpath_med2_cmd,
- "bgp bestpath med confed missing-as-worst",
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "MED attribute\n"
- "Compare MED among confederation paths\n"
- "Treat missing MED as the least preferred one\n")
-{
- struct bgp *bgp;
-
- bgp = vty->index;
- bgp_flag_set (bgp, BGP_FLAG_MED_CONFED);
- bgp_flag_set (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
- bgp_recalculate_all_bestpaths (bgp);
-
- return CMD_SUCCESS;
-}
-
-ALIAS (bgp_bestpath_med2,
- bgp_bestpath_med3_cmd,
- "bgp bestpath med missing-as-worst confed",
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "MED attribute\n"
- "Treat missing MED as the least preferred one\n"
- "Compare MED among confederation paths\n")
-
DEFUN (no_bgp_bestpath_med,
no_bgp_bestpath_med_cmd,
- "no bgp bestpath med (confed|missing-as-worst)",
+ "no bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
NO_STR
"BGP specific commands\n"
"Change the default bestpath selection\n"
"MED attribute\n"
"Compare MED among confederation paths\n"
- "Treat missing MED as the least preferred one\n")
+ "Treat missing MED as the least preferred one\n"
+ "Treat missing MED as the least preferred one\n"
+ "Compare MED among confederation paths\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp = vty->index;
-
- if (strncmp (argv[0], "confed", 1) == 0)
+ int idx = 0;
+ if (argv_find (argv, argc, "confed", &idx))
bgp_flag_unset (bgp, BGP_FLAG_MED_CONFED);
- else
+ idx = 0;
+ if (argv_find (argv, argc, "missing-as-worst", &idx))
bgp_flag_unset (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
bgp_recalculate_all_bestpaths (bgp);
@@ -2219,36 +2089,6 @@ DEFUN (no_bgp_bestpath_med,
return CMD_SUCCESS;
}
-DEFUN (no_bgp_bestpath_med2,
- no_bgp_bestpath_med2_cmd,
- "no bgp bestpath med confed missing-as-worst",
- NO_STR
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "MED attribute\n"
- "Compare MED among confederation paths\n"
- "Treat missing MED as the least preferred one\n")
-{
- struct bgp *bgp;
-
- bgp = vty->index;
- bgp_flag_unset (bgp, BGP_FLAG_MED_CONFED);
- bgp_flag_unset (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
- bgp_recalculate_all_bestpaths (bgp);
-
- return CMD_SUCCESS;
-}
-
-ALIAS (no_bgp_bestpath_med2,
- no_bgp_bestpath_med3_cmd,
- "no bgp bestpath med missing-as-worst confed",
- NO_STR
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "MED attribute\n"
- "Treat missing MED as the least preferred one\n"
- "Compare MED among confederation paths\n")
-
/* "no bgp default ipv4-unicast". */
DEFUN (no_bgp_default_ipv4_unicast,
no_bgp_default_ipv4_unicast_cmd,
@@ -2258,9 +2098,7 @@ DEFUN (no_bgp_default_ipv4_unicast,
"Configure BGP defaults\n"
"Activate ipv4-unicast for a peer by default\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_NO_DEFAULT_IPV4);
return CMD_SUCCESS;
}
@@ -2272,9 +2110,7 @@ DEFUN (bgp_default_ipv4_unicast,
"Configure BGP defaults\n"
"Activate ipv4-unicast for a peer by default\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_NO_DEFAULT_IPV4);
return CMD_SUCCESS;
}
@@ -2287,9 +2123,7 @@ DEFUN (bgp_default_show_hostname,
"Configure BGP defaults\n"
"Show hostname in certain command ouputs\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_SHOW_HOSTNAME);
return CMD_SUCCESS;
}
@@ -2302,9 +2136,7 @@ DEFUN (no_bgp_default_show_hostname,
"Configure BGP defaults\n"
"Show hostname in certain command ouputs\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_SHOW_HOSTNAME);
return CMD_SUCCESS;
}
@@ -2317,9 +2149,7 @@ DEFUN (bgp_network_import_check,
"BGP network command\n"
"Check BGP network route exists in IGP\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK))
{
bgp_flag_set (bgp, BGP_FLAG_IMPORT_CHECK);
@@ -2345,9 +2175,7 @@ DEFUN (no_bgp_network_import_check,
"BGP network command\n"
"Check BGP network route exists in IGP\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK))
{
bgp_flag_unset (bgp, BGP_FLAG_IMPORT_CHECK);
@@ -2359,18 +2187,17 @@ DEFUN (no_bgp_network_import_check,
DEFUN (bgp_default_local_preference,
bgp_default_local_preference_cmd,
- "bgp default local-preference <0-4294967295>",
+ "bgp default local-preference (0-4294967295)",
"BGP specific commands\n"
"Configure BGP defaults\n"
"local preference (higher=more preferred)\n"
"Configure default local preference value\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
u_int32_t local_pref;
- bgp = vty->index;
-
- VTY_GET_INTEGER ("local preference", local_pref, argv[0]);
+ VTY_GET_INTEGER ("local preference", local_pref, argv[idx_number]->arg);
bgp_default_local_preference_set (bgp, local_pref);
bgp_clear_star_soft_in (vty, bgp->name);
@@ -2380,44 +2207,34 @@ DEFUN (bgp_default_local_preference,
DEFUN (no_bgp_default_local_preference,
no_bgp_default_local_preference_cmd,
- "no bgp default local-preference",
+ "no bgp default local-preference [(0-4294967295)]",
NO_STR
"BGP specific commands\n"
"Configure BGP defaults\n"
- "local preference (higher=more preferred)\n")
+ "local preference (higher=more preferred)\n"
+ "Configure default local preference value\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_default_local_preference_unset (bgp);
bgp_clear_star_soft_in (vty, bgp->name);
return CMD_SUCCESS;
}
-ALIAS (no_bgp_default_local_preference,
- no_bgp_default_local_preference_val_cmd,
- "no bgp default local-preference <0-4294967295>",
- NO_STR
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "local preference (higher=more preferred)\n"
- "Configure default local preference value\n")
DEFUN (bgp_default_subgroup_pkt_queue_max,
bgp_default_subgroup_pkt_queue_max_cmd,
- "bgp default subgroup-pkt-queue-max <20-100>",
+ "bgp default subgroup-pkt-queue-max (20-100)",
"BGP specific commands\n"
"Configure BGP defaults\n"
"subgroup-pkt-queue-max\n"
"Configure subgroup packet queue max\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
u_int32_t max_size;
- bgp = vty->index;
-
- VTY_GET_INTEGER ("subgroup packet queue max", max_size, argv[0]);
+ VTY_GET_INTEGER ("subgroup packet queue max", max_size, argv[idx_number]->arg);
bgp_default_subgroup_pkt_queue_max_set (bgp, max_size);
@@ -2426,27 +2243,18 @@ DEFUN (bgp_default_subgroup_pkt_queue_max,
DEFUN (no_bgp_default_subgroup_pkt_queue_max,
no_bgp_default_subgroup_pkt_queue_max_cmd,
- "no bgp default subgroup-pkt-queue-max",
+ "no bgp default subgroup-pkt-queue-max [(20-100)]",
NO_STR
"BGP specific commands\n"
"Configure BGP defaults\n"
- "subgroup-pkt-queue-max\n")
+ "subgroup-pkt-queue-max\n"
+ "Configure subgroup packet queue max\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_default_subgroup_pkt_queue_max_unset (bgp);
return CMD_SUCCESS;
}
-ALIAS (no_bgp_default_subgroup_pkt_queue_max,
- no_bgp_default_subgroup_pkt_queue_max_val_cmd,
- "no bgp default subgroup-pkt-queue-max <20-100>",
- NO_STR
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "subgroup-pkt-queue-max\n"
- "Configure subgroup packet queue max\n")
DEFUN (bgp_rr_allow_outbound_policy,
bgp_rr_allow_outbound_policy_cmd,
@@ -2455,9 +2263,7 @@ DEFUN (bgp_rr_allow_outbound_policy,
"Allow modifications made by out route-map\n"
"on ibgp neighbors\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY))
{
@@ -2477,9 +2283,7 @@ DEFUN (no_bgp_rr_allow_outbound_policy,
"Allow modifications made by out route-map\n"
"on ibgp neighbors\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY))
{
@@ -2493,18 +2297,17 @@ DEFUN (no_bgp_rr_allow_outbound_policy,
DEFUN (bgp_listen_limit,
bgp_listen_limit_cmd,
- "bgp listen limit " DYNAMIC_NEIGHBOR_LIMIT_RANGE,
+ "bgp listen limit (1-5000)",
"BGP specific commands\n"
"Configure BGP defaults\n"
"maximum number of BGP Dynamic Neighbors that can be created\n"
"Configure Dynamic Neighbors listen limit value\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
int listen_limit;
- bgp = vty->index;
-
- VTY_GET_INTEGER_RANGE ("listen limit", listen_limit, argv[0],
+ VTY_GET_INTEGER_RANGE ("listen limit", listen_limit, argv[idx_number]->arg,
BGP_DYNAMIC_NEIGHBORS_LIMIT_MIN,
BGP_DYNAMIC_NEIGHBORS_LIMIT_MAX);
@@ -2515,27 +2318,18 @@ DEFUN (bgp_listen_limit,
DEFUN (no_bgp_listen_limit,
no_bgp_listen_limit_cmd,
- "no bgp listen limit",
+ "no bgp listen limit [(1-5000)]",
"BGP specific commands\n"
"Configure BGP defaults\n"
"unset maximum number of BGP Dynamic Neighbors that can be created\n"
- "Configure Dynamic Neighbors listen limit value to default\n")
+ "Configure Dynamic Neighbors listen limit value to default\n"
+ "Configure Dynamic Neighbors listen limit value\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_listen_limit_unset (bgp);
return CMD_SUCCESS;
}
-ALIAS (no_bgp_listen_limit,
- no_bgp_listen_limit_val_cmd,
- "no bgp listen limit " DYNAMIC_NEIGHBOR_LIMIT_RANGE,
- NO_STR
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "maximum number of BGP Dynamic Neighbors that can be created\n"
- "Configure Dynamic Neighbors listen limit value\n")
/*
* Check if this listen range is already configured. Check for exact
@@ -2571,24 +2365,29 @@ listen_range_exists (struct bgp *bgp, struct prefix *range, int exact)
DEFUN (bgp_listen_range,
bgp_listen_range_cmd,
- LISTEN_RANGE_CMD "peer-group WORD" ,
+ "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group WORD",
"BGP specific commands\n"
- "Configure BGP Dynamic Neighbors\n"
- "add a listening range for Dynamic Neighbors\n"
- LISTEN_RANGE_ADDR_STR)
+ "Configure BGP dynamic neighbors listen range\n"
+ "Configure BGP dynamic neighbors listen range\n"
+ NEIGHBOR_ADDR_STR
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct prefix range;
struct peer_group *group, *existing_group;
afi_t afi;
int ret;
+ int idx = 0;
- bgp = vty->index;
-
- //VTY_GET_IPV4_PREFIX ("listen range", range, argv[0]);
+ argv_find (argv, argc, "A.B.C.D/M", &idx);
+ argv_find (argv, argc, "X:X::X:X/M", &idx);
+ char *prefix = argv[idx]->arg;
+ argv_find (argv, argc, "WORD", &idx);
+ char *peergroup = argv[idx]->arg;
/* Convert IP prefix string to struct prefix. */
- ret = str2prefix (argv[0], &range);
+ ret = str2prefix (prefix, &range);
if (! ret)
{
vty_out (vty, "%% Malformed listen range%s", VTY_NEWLINE);
@@ -2610,7 +2409,7 @@ DEFUN (bgp_listen_range,
existing_group = listen_range_exists (bgp, &range, 1);
if (existing_group)
{
- if (strcmp (existing_group->name, argv[1]) == 0)
+ if (strcmp (existing_group->name, peergroup) == 0)
return CMD_SUCCESS;
else
{
@@ -2628,7 +2427,7 @@ DEFUN (bgp_listen_range,
return CMD_WARNING;
}
- group = peer_group_lookup (bgp, argv[1]);
+ group = peer_group_lookup (bgp, peergroup);
if (! group)
{
vty_out (vty, "%% Configure the peer-group first%s", VTY_NEWLINE);
@@ -2641,24 +2440,32 @@ DEFUN (bgp_listen_range,
DEFUN (no_bgp_listen_range,
no_bgp_listen_range_cmd,
- "no bgp listen range A.B.C.D/M peer-group WORD" ,
+ "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group WORD",
+ NO_STR
"BGP specific commands\n"
- "Configure BGP defaults\n"
- "delete a listening range for Dynamic Neighbors\n"
- "Remove Dynamic Neighbors listening range\n")
+ "Unconfigure BGP dynamic neighbors listen range\n"
+ "Unconfigure BGP dynamic neighbors listen range\n"
+ NEIGHBOR_ADDR_STR
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct prefix range;
struct peer_group *group;
afi_t afi;
int ret;
+ int idx = 0;
- bgp = vty->index;
+ argv_find (argv, argc, "A.B.C.D/M", &idx);
+ argv_find (argv, argc, "X:X::X:X/M", &idx);
+ char *prefix = argv[idx]->arg;
+ argv_find (argv, argc, "WORD", &idx);
+ char *peergroup = argv[idx]->arg;
- // VTY_GET_IPV4_PREFIX ("listen range", range, argv[0]);
+ // VTY_GET_IPV4_PREFIX ("listen range", range, argv[idx_ipv4_prefixlen]->arg);
/* Convert IP prefix string to struct prefix. */
- ret = str2prefix (argv[0], &range);
+ ret = str2prefix (prefix, &range);
if (! ret)
{
vty_out (vty, "%% Malformed listen range%s", VTY_NEWLINE);
@@ -2676,8 +2483,7 @@ DEFUN (no_bgp_listen_range,
apply_mask (&range);
-
- group = peer_group_lookup (bgp, argv[1]);
+ group = peer_group_lookup (bgp, peergroup);
if (! group)
{
vty_out (vty, "%% Peer-group does not exist%s", VTY_NEWLINE);
@@ -2724,9 +2530,7 @@ DEFUN (bgp_disable_connected_route_check,
"BGP specific commands\n"
"Disable checking if nexthop is connected on ebgp sessions\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set (bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
bgp_clear_star_soft_in (vty, bgp->name);
@@ -2740,9 +2544,7 @@ DEFUN (no_bgp_disable_connected_route_check,
"BGP specific commands\n"
"Disable checking if nexthop is connected on ebgp sessions\n")
{
- struct bgp *bgp;
-
- bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset (bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
bgp_clear_star_soft_in (vty, bgp->name);
@@ -2751,23 +2553,21 @@ DEFUN (no_bgp_disable_connected_route_check,
static int
-peer_remote_as_vty (struct vty *vty, const char *peer_str,
+peer_remote_as_vty (struct vty *vty, const char *peer_str,
const char *as_str, afi_t afi, safi_t safi)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
- struct bgp *bgp;
as_t as;
int as_type = AS_SPECIFIED;
union sockunion su;
- bgp = vty->index;
-
- if (strncmp(as_str, "internal", strlen("internal")) == 0)
+ if (as_str[0] == 'i')
{
as = 0;
as_type = AS_INTERNAL;
}
- else if (strncmp(as_str, "external", strlen("external")) == 0)
+ else if (as_str[0] == 'e')
{
as = 0;
as_type = AS_EXTERNAL;
@@ -2822,13 +2622,17 @@ peer_remote_as_vty (struct vty *vty, const char *peer_str,
DEFUN (neighbor_remote_as,
neighbor_remote_as_cmd,
- NEIGHBOR_CMD2 "remote-as (" CMD_AS_RANGE "|external|internal)",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> remote-as <(1-4294967295)|internal|external>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a BGP neighbor\n"
- AS_STR)
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
- return peer_remote_as_vty (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST);
+ int idx_peer = 1;
+ int idx_remote_as = 3;
+ return peer_remote_as_vty (vty, argv[idx_peer]->arg, argv[idx_remote_as]->arg, AFI_IP, SAFI_UNICAST);
}
static int
@@ -2836,15 +2640,14 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
safi_t safi, int v6only, const char *peer_group_name,
const char *as_str)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
as_t as = 0;
int as_type = AS_UNSPECIFIED;
- struct bgp *bgp;
struct peer *peer;
struct peer_group *group;
int ret = 0;
union sockunion su;
- bgp = vty->index;
group = peer_group_lookup (bgp, conf_if);
if (group)
@@ -2855,11 +2658,11 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
if (as_str)
{
- if (strncmp(as_str, "internal", strlen("internal")) == 0)
+ if (as_str[0] == 'i')
{
as_type = AS_INTERNAL;
}
- else if (strncmp(as_str, "external", strlen("external")) == 0)
+ else if (as_str[0] == 'e')
{
as_type = AS_EXTERNAL;
}
@@ -2935,76 +2738,79 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
DEFUN (neighbor_interface_config,
neighbor_interface_config_cmd,
- "neighbor WORD interface",
+ "neighbor WORD interface [peer-group WORD]",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
- "Enable BGP on interface\n")
+ "Enable BGP on interface\n"
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
- if (argc == 2)
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0,
- argv[1], NULL);
+ int idx_word = 1;
+ int idx_peer_group_word = 4;
+
+ if (argc > idx_peer_group_word)
+ return peer_conf_interface_get (vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 0,
+ argv[idx_peer_group_word]->arg, NULL);
else
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0,
+ return peer_conf_interface_get (vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 0,
NULL, NULL);
}
-ALIAS (neighbor_interface_config,
- neighbor_interface_config_peergroup_cmd,
- "neighbor WORD interface peer-group WORD",
- NEIGHBOR_STR
- "Interface name or neighbor tag\n"
- "Enable BGP on interface\n"
- "Member of the peer-group\n"
- "peer-group name\n")
-
DEFUN (neighbor_interface_config_v6only,
neighbor_interface_config_v6only_cmd,
- "neighbor WORD interface v6only",
+ "neighbor WORD interface v6only [peer-group WORD]",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Enable BGP on interface\n"
- "Enable BGP with v6 link-local only\n")
+ "Enable BGP with v6 link-local only\n"
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
- if (argc == 2)
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1,
- argv[1], NULL);
- else
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1,
- NULL, NULL);
+ int idx_word = 1;
+ int idx_peer_group_word = 5;
+
+ if (argc > idx_peer_group_word)
+ return peer_conf_interface_get (vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 1,
+ argv[idx_peer_group_word]->arg, NULL);
+
+ return peer_conf_interface_get (vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 1,
+ NULL, NULL);
}
-ALIAS (neighbor_interface_config_v6only,
- neighbor_interface_config_v6only_peergroup_cmd,
- "neighbor WORD interface v6only peer-group WORD",
- NEIGHBOR_STR
- "Interface name or neighbor tag\n"
- "Enable BGP on interface\n"
- "Enable BGP with v6 link-local only\n"
- "Member of the peer-group\n"
- "peer-group name\n")
DEFUN (neighbor_interface_config_remote_as,
neighbor_interface_config_remote_as_cmd,
- "neighbor WORD interface remote-as (" CMD_AS_RANGE "|external|internal)",
+ "neighbor WORD interface remote-as <(1-4294967295)|internal|external>",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Enable BGP on interface\n"
- AS_STR)
+ "Specify a BGP neighbor\n"
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0,
- NULL, argv[1]);
+ int idx_word = 1;
+ int idx_remote_as = 4;
+ return peer_conf_interface_get (vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 0,
+ NULL, argv[idx_remote_as]->arg);
}
DEFUN (neighbor_interface_v6only_config_remote_as,
neighbor_interface_v6only_config_remote_as_cmd,
- "neighbor WORD interface v6only remote-as (" CMD_AS_RANGE "|external|internal)",
+ "neighbor WORD interface v6only remote-as <(1-4294967295)|internal|external>",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
+ "Enable BGP with v6 link-local only\n"
"Enable BGP on interface\n"
- AS_STR)
+ "Specify a BGP neighbor\n"
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1,
- NULL, argv[1]);
+ int idx_word = 1;
+ int idx_remote_as = 5;
+ return peer_conf_interface_get (vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 1,
+ NULL, argv[idx_remote_as]->arg);
}
DEFUN (neighbor_peer_group,
@@ -3014,19 +2820,19 @@ DEFUN (neighbor_peer_group,
"Interface name or neighbor tag\n"
"Configure peer-group\n")
{
- struct bgp *bgp;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_word = 1;
struct peer *peer;
struct peer_group *group;
- bgp = vty->index;
- peer = peer_lookup_by_conf_if (bgp, argv[0]);
+ peer = peer_lookup_by_conf_if (bgp, argv[idx_word]->arg);
if (peer)
{
vty_out (vty, "%% Name conflict with interface: %s", VTY_NEWLINE);
return CMD_WARNING;
}
- group = peer_group_get (bgp, argv[0]);
+ group = peer_group_get (bgp, argv[idx_word]->arg);
if (! group)
return CMD_WARNING;
@@ -3035,22 +2841,28 @@ DEFUN (neighbor_peer_group,
DEFUN (no_neighbor,
no_neighbor_cmd,
- NO_NEIGHBOR_CMD2,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> [remote-as <(1-4294967295)|internal|external>]",
NO_STR
NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2)
+ NEIGHBOR_ADDR_STR2
+ "Specify a BGP neighbor\n"
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_peer = 2;
int ret;
union sockunion su;
struct peer_group *group;
struct peer *peer;
struct peer *other;
- ret = str2sockunion (argv[0], &su);
+ ret = str2sockunion (argv[idx_peer]->arg, &su);
if (ret < 0)
{
/* look up for neighbor by interface name config. */
- peer = peer_lookup_by_conf_if (vty->index, argv[0]);
+ peer = peer_lookup_by_conf_if (bgp, argv[idx_peer]->arg);
if (peer)
{
/* Request zebra to terminate IPv6 RAs on this interface. */
@@ -3060,7 +2872,7 @@ DEFUN (no_neighbor,
return CMD_SUCCESS;
}
- group = peer_group_lookup (vty->index, argv[0]);
+ group = peer_group_lookup (bgp, argv[idx_peer]->arg);
if (group)
peer_group_delete (group);
else
@@ -3071,7 +2883,7 @@ DEFUN (no_neighbor,
}
else
{
- peer = peer_lookup (vty->index, &su);
+ peer = peer_lookup (bgp, &su);
if (peer)
{
if (peer_dynamic_neighbor (peer))
@@ -3091,27 +2903,27 @@ DEFUN (no_neighbor,
return CMD_SUCCESS;
}
-ALIAS (no_neighbor,
- no_neighbor_remote_as_cmd,
- NO_NEIGHBOR_CMD "remote-as (" CMD_AS_RANGE "|internal|external)",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR
- "Specify a BGP neighbor\n"
- AS_STR)
-
DEFUN (no_neighbor_interface_config,
no_neighbor_interface_config_cmd,
- "no neighbor WORD interface",
+ "no neighbor WORD interface [v6only] [peer-group WORD] [remote-as <(1-4294967295)|internal|external>]",
NO_STR
NEIGHBOR_STR
"Interface name\n"
- "Configure BGP on interface\n")
+ "Configure BGP on interface\n"
+ "Enable BGP with v6 link-local only\n"
+ "Member of the peer-group\n"
+ "Peer-group name\n"
+ "Specify a BGP neighbor\n"
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_word = 2;
struct peer *peer;
/* look up for neighbor by interface name config. */
- peer = peer_lookup_by_conf_if (vty->index, argv[0]);
+ peer = peer_lookup_by_conf_if (bgp, argv[idx_word]->arg);
if (peer)
{
/* Request zebra to terminate IPv6 RAs on this interface. */
@@ -3127,55 +2939,6 @@ DEFUN (no_neighbor_interface_config,
return CMD_SUCCESS;
}
-ALIAS (no_neighbor_interface_config,
- no_neighbor_interface_config_peergroup_cmd,
- "no neighbor WORD interface peer-group WORD",
- NO_STR
- NEIGHBOR_STR
- "Interface name\n"
- "Configure BGP on interface\n"
- "Member of the peer-group\n"
- "peer-group name\n")
-
-ALIAS (no_neighbor_interface_config,
- no_neighbor_interface_config_v6only_cmd,
- "no neighbor WORD interface v6only",
- NO_STR
- NEIGHBOR_STR
- "Interface name\n"
- "Configure BGP on interface\n"
- "Enable BGP with v6 link-local only\n")
-
-ALIAS (no_neighbor_interface_config,
- no_neighbor_interface_config_v6only_peergroup_cmd,
- "no neighbor WORD interface v6only peer-group WORD",
- NO_STR
- NEIGHBOR_STR
- "Interface name\n"
- "Configure BGP on interface\n"
- "Enable BGP with v6 link-local only\n"
- "Member of the peer-group\n"
- "peer-group name\n")
-
-ALIAS (no_neighbor_interface_config,
- no_neighbor_interface_config_remote_as_cmd,
- "no neighbor WORD interface remote-as (" CMD_AS_RANGE "|internal|external)",
- NO_STR
- NEIGHBOR_STR
- "Interface name\n"
- "Configure BGP on interface\n"
- AS_STR)
-
-ALIAS (no_neighbor_interface_config,
- no_neighbor_interface_config_v6only_remote_as_cmd,
- "no neighbor WORD interface v6only remote-as (" CMD_AS_RANGE "|internal|external)",
- NO_STR
- NEIGHBOR_STR
- "Interface name\n"
- "Configure BGP on interface\n"
- "Enable BGP with v6 link-local only\n"
- AS_STR)
-
DEFUN (no_neighbor_peer_group,
no_neighbor_peer_group_cmd,
"no neighbor WORD peer-group",
@@ -3184,9 +2947,11 @@ DEFUN (no_neighbor_peer_group,
"Neighbor tag\n"
"Configure peer-group\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_word = 2;
struct peer_group *group;
- group = peer_group_lookup (vty->index, argv[0]);
+ group = peer_group_lookup (bgp, argv[idx_word]->arg);
if (group)
peer_group_delete (group);
else
@@ -3199,25 +2964,29 @@ DEFUN (no_neighbor_peer_group,
DEFUN (no_neighbor_interface_peer_group_remote_as,
no_neighbor_interface_peer_group_remote_as_cmd,
- "no neighbor WORD remote-as (" CMD_AS_RANGE "|internal|external)",
+ "no neighbor WORD remote-as <(1-4294967295)|internal|external>",
NO_STR
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Specify a BGP neighbor\n"
- AS_STR)
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_word = 2;
struct peer_group *group;
struct peer *peer;
/* look up for neighbor by interface name config. */
- peer = peer_lookup_by_conf_if (vty->index, argv[0]);
+ peer = peer_lookup_by_conf_if (bgp, argv[idx_word]->arg);
if (peer)
{
peer_as_change (peer, 0, AS_SPECIFIED);
return CMD_SUCCESS;
}
- group = peer_group_lookup (vty->index, argv[0]);
+ group = peer_group_lookup (bgp, argv[idx_word]->arg);
if (group)
peer_group_remote_as_delete (group);
else
@@ -3230,49 +2999,54 @@ DEFUN (no_neighbor_interface_peer_group_remote_as,
DEFUN (neighbor_local_as,
neighbor_local_as_cmd,
- NEIGHBOR_CMD2 "local-as " CMD_AS_RANGE,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a local-as number\n"
"AS number used as local AS\n")
{
+ int idx_peer = 1;
+ int idx_number = 3;
struct peer *peer;
int ret;
as_t as;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- VTY_GET_INTEGER_RANGE ("Local AS", as, argv[1], 1, BGP_AS4_MAX);
+ VTY_GET_INTEGER_RANGE ("Local AS", as, argv[idx_number]->arg, 1, BGP_AS4_MAX);
ret = peer_local_as_set (peer, as, 0, 0);
return bgp_vty_return (vty, ret);
}
DEFUN (neighbor_local_as_no_prepend,
neighbor_local_as_no_prepend_cmd,
- NEIGHBOR_CMD2 "local-as " CMD_AS_RANGE " no-prepend",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a local-as number\n"
"AS number used as local AS\n"
"Do not prepend local-as to updates from ebgp peers\n")
{
+ int idx_peer = 1;
+ int idx_number = 3;
struct peer *peer;
int ret;
as_t as;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- VTY_GET_INTEGER_RANGE ("Local AS", as, argv[1], 1, BGP_AS4_MAX);
+ VTY_GET_INTEGER_RANGE ("Local AS", as, argv[idx_number]->arg, 1, BGP_AS4_MAX);
ret = peer_local_as_set (peer, as, 1, 0);
return bgp_vty_return (vty, ret);
}
DEFUN (neighbor_local_as_no_prepend_replace_as,
neighbor_local_as_no_prepend_replace_as_cmd,
- NEIGHBOR_CMD2 "local-as " CMD_AS_RANGE " no-prepend replace-as",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend replace-as",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a local-as number\n"
@@ -3280,32 +3054,37 @@ DEFUN (neighbor_local_as_no_prepend_replace_as,
"Do not prepend local-as to updates from ebgp peers\n"
"Do not prepend local-as to updates from ibgp peers\n")
{
+ int idx_peer = 1;
+ int idx_number = 3;
struct peer *peer;
int ret;
as_t as;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- VTY_GET_INTEGER_RANGE ("Local AS", as, argv[1], 1, BGP_AS4_MAX);
+ VTY_GET_INTEGER_RANGE ("Local AS", as, argv[idx_number]->arg, 1, BGP_AS4_MAX);
ret = peer_local_as_set (peer, as, 1, 1);
return bgp_vty_return (vty, ret);
}
-
DEFUN (no_neighbor_local_as,
no_neighbor_local_as_cmd,
- NO_NEIGHBOR_CMD2 "local-as",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> local-as [(1-4294967295) [no-prepend [replace-as]]]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Specify a local-as number\n")
+ "Specify a local-as number\n"
+ "AS number used as local AS\n"
+ "Do not prepend local-as to updates from ebgp peers\n"
+ "Do not prepend local-as to updates from ibgp peers\n")
{
+ int idx_peer = 2;
struct peer *peer;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -3313,47 +3092,21 @@ DEFUN (no_neighbor_local_as,
return bgp_vty_return (vty, ret);
}
-ALIAS (no_neighbor_local_as,
- no_neighbor_local_as_val_cmd,
- NO_NEIGHBOR_CMD2 "local-as " CMD_AS_RANGE,
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a local-as number\n"
- "AS number used as local AS\n")
-ALIAS (no_neighbor_local_as,
- no_neighbor_local_as_val2_cmd,
- NO_NEIGHBOR_CMD2 "local-as " CMD_AS_RANGE " no-prepend",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a local-as number\n"
- "AS number used as local AS\n"
- "Do not prepend local-as to updates from ebgp peers\n")
-ALIAS (no_neighbor_local_as,
- no_neighbor_local_as_val3_cmd,
- NO_NEIGHBOR_CMD2 "local-as " CMD_AS_RANGE " no-prepend replace-as",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a local-as number\n"
- "AS number used as local AS\n"
- "Do not prepend local-as to updates from ebgp peers\n"
- "Do not prepend local-as to updates from ibgp peers\n")
DEFUN (neighbor_solo,
neighbor_solo_cmd,
- NEIGHBOR_CMD2 "solo",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> solo",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Solo peer - part of its own update group\n")
{
+ int idx_peer = 1;
struct peer *peer;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -3363,16 +3116,17 @@ DEFUN (neighbor_solo,
DEFUN (no_neighbor_solo,
no_neighbor_solo_cmd,
- NO_NEIGHBOR_CMD2 "solo",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> solo",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Solo peer - part of its own update group\n")
{
+ int idx_peer = 2;
struct peer *peer;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -3382,35 +3136,39 @@ DEFUN (no_neighbor_solo,
DEFUN (neighbor_password,
neighbor_password_cmd,
- NEIGHBOR_CMD2 "password LINE",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> password LINE",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Set a password\n"
"The password\n")
{
+ int idx_peer = 1;
+ int idx_line = 3;
struct peer *peer;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- ret = peer_password_set (peer, argv[1]);
+ ret = peer_password_set (peer, argv[idx_line]->arg);
return bgp_vty_return (vty, ret);
}
DEFUN (no_neighbor_password,
no_neighbor_password_cmd,
- NO_NEIGHBOR_CMD2 "password",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> password [LINE]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Set a password\n")
+ "Set a password\n"
+ "The password\n")
{
+ int idx_peer = 2;
struct peer *peer;
int ret;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -3418,26 +3176,19 @@ DEFUN (no_neighbor_password,
return bgp_vty_return (vty, ret);
}
-ALIAS (no_neighbor_password,
- no_neighbor_password_val_cmd,
- NO_NEIGHBOR_CMD2 "password LINE",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Set a password\n"
- "The password\n")
DEFUN (neighbor_activate,
neighbor_activate_cmd,
- NEIGHBOR_CMD2 "activate",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Enable the Address Family for this Neighbor\n")
{
+ int idx_peer = 1;
int ret;
struct peer *peer;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -3450,17 +3201,18 @@ DEFUN (neighbor_activate,
DEFUN (no_neighbor_activate,
no_neighbor_activate_cmd,
- NO_NEIGHBOR_CMD2 "activate",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Enable the Address Family for this Neighbor\n")
{
+ int idx_peer = 2;
int ret;
struct peer *peer;
/* Lookup peer. */
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -3473,29 +3225,30 @@ DEFUN (no_neighbor_activate,
DEFUN (neighbor_set_peer_group,
neighbor_set_peer_group_cmd,
- NEIGHBOR_CMD2 "peer-group WORD",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Member of the peer-group\n"
- "peer-group name\n")
+ "Peer-group name\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_peer = 1;
+ int idx_word = 3;
int ret;
as_t as;
union sockunion su;
- struct bgp *bgp;
struct peer *peer;
struct peer_group *group;
- bgp = vty->index;
peer = NULL;
- ret = str2sockunion (argv[0], &su);
+ ret = str2sockunion (argv[idx_peer]->arg, &su);
if (ret < 0)
{
- peer = peer_lookup_by_conf_if (bgp, argv[0]);
+ peer = peer_lookup_by_conf_if (bgp, argv[idx_peer]->arg);
if (!peer)
{
- vty_out (vty, "%% Malformed address or name: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Malformed address or name: %s%s", argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
}
@@ -3518,7 +3271,7 @@ DEFUN (neighbor_set_peer_group,
}
}
- group = peer_group_lookup (bgp, argv[1]);
+ group = peer_group_lookup (bgp, argv[idx_word]->arg);
if (! group)
{
vty_out (vty, "%% Configure the peer-group first%s", VTY_NEWLINE);
@@ -3538,25 +3291,25 @@ DEFUN (neighbor_set_peer_group,
DEFUN (no_neighbor_set_peer_group,
no_neighbor_set_peer_group_cmd,
- NO_NEIGHBOR_CMD2 "peer-group WORD",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Member of the peer-group\n"
- "peer-group name\n")
+ "Peer-group name\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_peer = 2;
+ int idx_word = 4;
int ret;
- struct bgp *bgp;
struct peer *peer;
struct peer_group *group;
- bgp = vty->index;
-
- peer = peer_lookup_vty (vty, argv[0]);
+ peer = peer_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- group = peer_group_lookup (bgp, argv[1]);
+ group = peer_group_lookup (bgp, argv[idx_word]->arg);
if (! group)
{
vty_out (vty, "%% Configure the peer-group first%s", VTY_NEWLINE);
@@ -3569,7 +3322,7 @@ DEFUN (no_neighbor_set_peer_group,
}
static int
-peer_flag_modify_vty (struct vty *vty, const char *ip_str,
+peer_flag_modify_vty (struct vty *vty, const char *ip_str,
u_int16_t flag, int set)
{
int ret;
@@ -3612,115 +3365,125 @@ peer_flag_unset_vty (struct vty *vty, const char *ip_str, u_int16_t flag)
/* neighbor passive. */
DEFUN (neighbor_passive,
neighbor_passive_cmd,
- NEIGHBOR_CMD2 "passive",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> passive",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Don't send open messages to this neighbor\n")
{
- return peer_flag_set_vty (vty, argv[0], PEER_FLAG_PASSIVE);
+ int idx_peer = 1;
+ return peer_flag_set_vty (vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
}
DEFUN (no_neighbor_passive,
no_neighbor_passive_cmd,
- NO_NEIGHBOR_CMD2 "passive",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> passive",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Don't send open messages to this neighbor\n")
{
- return peer_flag_unset_vty (vty, argv[0], PEER_FLAG_PASSIVE);
+ int idx_peer = 2;
+ return peer_flag_unset_vty (vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
}
/* neighbor shutdown. */
DEFUN (neighbor_shutdown,
neighbor_shutdown_cmd,
- NEIGHBOR_CMD2 "shutdown",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n")
{
- return peer_flag_set_vty (vty, argv[0], PEER_FLAG_SHUTDOWN);
+ int idx_peer = 1;
+ return peer_flag_set_vty (vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
}
DEFUN (no_neighbor_shutdown,
no_neighbor_shutdown_cmd,
- NO_NEIGHBOR_CMD2 "shutdown",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n")
{
- return peer_flag_unset_vty (vty, argv[0], PEER_FLAG_SHUTDOWN);
+ int idx_peer = 2;
+ return peer_flag_unset_vty (vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
}
/* neighbor capability dynamic. */
DEFUN (neighbor_capability_dynamic,
neighbor_capability_dynamic_cmd,
- NEIGHBOR_CMD2 "capability dynamic",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Advertise capability to the peer\n"
"Advertise dynamic capability to this neighbor\n")
{
- return peer_flag_set_vty (vty, argv[0], PEER_FLAG_DYNAMIC_CAPABILITY);
+ int idx_peer = 1;
+ return peer_flag_set_vty (vty, argv[idx_peer]->arg, PEER_FLAG_DYNAMIC_CAPABILITY);
}
DEFUN (no_neighbor_capability_dynamic,
no_neighbor_capability_dynamic_cmd,
- NO_NEIGHBOR_CMD2 "capability dynamic",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Advertise capability to the peer\n"
"Advertise dynamic capability to this neighbor\n")
{
- return peer_flag_unset_vty (vty, argv[0], PEER_FLAG_DYNAMIC_CAPABILITY);
+ int idx_peer = 2;
+ return peer_flag_unset_vty (vty, argv[idx_peer]->arg, PEER_FLAG_DYNAMIC_CAPABILITY);
}
/* neighbor dont-capability-negotiate */
DEFUN (neighbor_dont_capability_negotiate,
neighbor_dont_capability_negotiate_cmd,
- NEIGHBOR_CMD2 "dont-capability-negotiate",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Do not perform capability negotiation\n")
{
- return peer_flag_set_vty (vty, argv[0], PEER_FLAG_DONT_CAPABILITY);
+ int idx_peer = 1;
+ return peer_flag_set_vty (vty, argv[idx_peer]->arg, PEER_FLAG_DONT_CAPABILITY);
}
DEFUN (no_neighbor_dont_capability_negotiate,
no_neighbor_dont_capability_negotiate_cmd,
- NO_NEIGHBOR_CMD2 "dont-capability-negotiate",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Do not perform capability negotiation\n")
{
- return peer_flag_unset_vty (vty, argv[0], PEER_FLAG_DONT_CAPABILITY);
+ int idx_peer = 2;
+ return peer_flag_unset_vty (vty, argv[idx_peer]->arg, PEER_FLAG_DONT_CAPABILITY);
}
/* neighbor capability extended next hop encoding */
DEFUN (neighbor_capability_enhe,
neighbor_capability_enhe_cmd,
- NEIGHBOR_CMD2 "capability extended-nexthop",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Advertise capability to the peer\n"
"Advertise extended next-hop capability to the peer\n")
{
- return peer_flag_set_vty (vty, argv[0], PEER_FLAG_CAPABILITY_ENHE);
+ int idx_peer = 1;
+ return peer_flag_set_vty (vty, argv[idx_peer]->arg, PEER_FLAG_CAPABILITY_ENHE);
}
DEFUN (no_neighbor_capability_enhe,
no_neighbor_capability_enhe_cmd,
- NO_NEIGHBOR_CMD2 "capability extended-nexthop",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Advertise capability to the peer\n"
"Advertise extended next-hop capability to the peer\n")
{
- return peer_flag_unset_vty (vty, argv[0], PEER_FLAG_CAPABILITY_ENHE);
+ int idx_peer = 2;
+ return peer_flag_unset_vty (vty, argv[idx_peer]->arg, PEER_FLAG_CAPABILITY_ENHE);
}
static int
@@ -3759,7 +3522,7 @@ peer_af_flag_unset_vty (struct vty *vty, const char *peer_str, afi_t afi,
/* neighbor capability orf prefix-list. */
DEFUN (neighbor_capability_orf_prefix,
neighbor_capability_orf_prefix_cmd,
- NEIGHBOR_CMD2 "capability orf prefix-list (both|send|receive)",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> capability orf prefix-list <both|send|receive>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Advertise capability to the peer\n"
@@ -3769,24 +3532,26 @@ DEFUN (neighbor_capability_orf_prefix,
"Capability to RECEIVE the ORF from this neighbor\n"
"Capability to SEND the ORF to this neighbor\n")
{
+ int idx_peer = 1;
+ int idx_send_recv = 5;
u_int16_t flag = 0;
- if (strncmp (argv[1], "s", 1) == 0)
+ if (strncmp (argv[idx_send_recv]->arg, "s", 1) == 0)
flag = PEER_FLAG_ORF_PREFIX_SM;
- else if (strncmp (argv[1], "r", 1) == 0)
+ else if (strncmp (argv[idx_send_recv]->arg, "r", 1) == 0)
flag = PEER_FLAG_ORF_PREFIX_RM;
- else if (strncmp (argv[1], "b", 1) == 0)
+ else if (strncmp (argv[idx_send_recv]->arg, "b", 1) == 0)
flag = PEER_FLAG_ORF_PREFIX_SM|PEER_FLAG_ORF_PREFIX_RM;
else
return CMD_WARNING;
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty), flag);
}
DEFUN (no_neighbor_capability_orf_prefix,
no_neighbor_capability_orf_prefix_cmd,
- NO_NEIGHBOR_CMD2 "capability orf prefix-list (both|send|receive)",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> capability orf prefix-list <both|send|receive>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
@@ -3797,70 +3562,76 @@ DEFUN (no_neighbor_capability_orf_prefix,
"Capability to RECEIVE the ORF from this neighbor\n"
"Capability to SEND the ORF to this neighbor\n")
{
+ int idx_peer = 2;
+ int idx_send_recv = 6;
u_int16_t flag = 0;
- if (strncmp (argv[1], "s", 1) == 0)
+ if (strncmp (argv[idx_send_recv]->arg, "s", 1) == 0)
flag = PEER_FLAG_ORF_PREFIX_SM;
- else if (strncmp (argv[1], "r", 1) == 0)
+ else if (strncmp (argv[idx_send_recv]->arg, "r", 1) == 0)
flag = PEER_FLAG_ORF_PREFIX_RM;
- else if (strncmp (argv[1], "b", 1) == 0)
+ else if (strncmp (argv[idx_send_recv]->arg, "b", 1) == 0)
flag = PEER_FLAG_ORF_PREFIX_SM|PEER_FLAG_ORF_PREFIX_RM;
else
return CMD_WARNING;
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty), flag);
}
/* neighbor next-hop-self. */
DEFUN (neighbor_nexthop_self,
neighbor_nexthop_self_cmd,
- NEIGHBOR_CMD2 "next-hop-self",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Disable the next hop calculation for this neighbor\n")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty), PEER_FLAG_NEXTHOP_SELF);
}
/* neighbor next-hop-self. */
DEFUN (neighbor_nexthop_self_force,
neighbor_nexthop_self_force_cmd,
- NEIGHBOR_CMD2 "next-hop-self force",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self force",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Disable the next hop calculation for this neighbor\n"
"Set the next hop to self for reflected routes\n")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_FORCE_NEXTHOP_SELF);
}
DEFUN (no_neighbor_nexthop_self,
no_neighbor_nexthop_self_cmd,
- NO_NEIGHBOR_CMD2 "next-hop-self",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Disable the next hop calculation for this neighbor\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_NEXTHOP_SELF);
}
DEFUN (no_neighbor_nexthop_self_force,
no_neighbor_nexthop_self_force_cmd,
- NO_NEIGHBOR_CMD2 "next-hop-self force",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self force",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Disable the next hop calculation for this neighbor\n"
"Set the next hop to self for reflected routes\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_FORCE_NEXTHOP_SELF);
}
@@ -3868,25 +3639,27 @@ DEFUN (no_neighbor_nexthop_self_force,
/* neighbor as-override */
DEFUN (neighbor_as_override,
neighbor_as_override_cmd,
- NEIGHBOR_CMD2 "as-override",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> as-override",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Override ASNs in outbound updates if aspath equals remote-as\n")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_AS_OVERRIDE);
}
DEFUN (no_neighbor_as_override,
no_neighbor_as_override_cmd,
- NO_NEIGHBOR_CMD2 "as-override",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> as-override",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Override ASNs in outbound updates if aspath equals remote-as\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_AS_OVERRIDE);
}
@@ -3894,108 +3667,116 @@ DEFUN (no_neighbor_as_override,
/* neighbor remove-private-AS. */
DEFUN (neighbor_remove_private_as,
neighbor_remove_private_as_cmd,
- NEIGHBOR_CMD2 "remove-private-AS",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Remove private ASNs in outbound updates\n")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REMOVE_PRIVATE_AS);
}
DEFUN (neighbor_remove_private_as_all,
neighbor_remove_private_as_all_cmd,
- NEIGHBOR_CMD2 "remove-private-AS all",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS all",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Remove private ASNs in outbound updates\n"
"Apply to all AS numbers")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
}
DEFUN (neighbor_remove_private_as_replace_as,
neighbor_remove_private_as_replace_as_cmd,
- NEIGHBOR_CMD2 "remove-private-AS replace-AS",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS replace-AS",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Remove private ASNs in outbound updates\n"
"Replace private ASNs with our ASN in outbound updates\n")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
}
DEFUN (neighbor_remove_private_as_all_replace_as,
neighbor_remove_private_as_all_replace_as_cmd,
- NEIGHBOR_CMD2 "remove-private-AS all replace-AS",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS all replace-AS",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Remove private ASNs in outbound updates\n"
- "Apply to all AS numbers"
+ "Apply to all AS numbers\n"
"Replace private ASNs with our ASN in outbound updates\n")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE);
}
DEFUN (no_neighbor_remove_private_as,
no_neighbor_remove_private_as_cmd,
- NO_NEIGHBOR_CMD2 "remove-private-AS",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Remove private ASNs in outbound updates\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REMOVE_PRIVATE_AS);
}
DEFUN (no_neighbor_remove_private_as_all,
no_neighbor_remove_private_as_all_cmd,
- NO_NEIGHBOR_CMD2 "remove-private-AS all",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS all",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Remove private ASNs in outbound updates\n"
- "Apply to all AS numbers")
+ "Apply to all AS numbers\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
}
DEFUN (no_neighbor_remove_private_as_replace_as,
no_neighbor_remove_private_as_replace_as_cmd,
- NO_NEIGHBOR_CMD2 "remove-private-AS replace-AS",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS replace-AS",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Remove private ASNs in outbound updates\n"
"Replace private ASNs with our ASN in outbound updates\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
}
DEFUN (no_neighbor_remove_private_as_all_replace_as,
no_neighbor_remove_private_as_all_replace_as_cmd,
- NO_NEIGHBOR_CMD2 "remove-private-AS all replace-AS",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS all replace-AS",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Remove private ASNs in outbound updates\n"
- "Apply to all AS numbers"
+ "Apply to all AS numbers\n"
"Replace private ASNs with our ASN in outbound updates\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE);
}
@@ -4004,25 +3785,27 @@ DEFUN (no_neighbor_remove_private_as_all_replace_as,
/* neighbor send-community. */
DEFUN (neighbor_send_community,
neighbor_send_community_cmd,
- NEIGHBOR_CMD2 "send-community",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> send-community",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Send Community attribute to this neighbor\n")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_SEND_COMMUNITY);
}
DEFUN (no_neighbor_send_community,
no_neighbor_send_community_cmd,
- NO_NEIGHBOR_CMD2 "send-community",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> send-community",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Send Community attribute to this neighbor\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_SEND_COMMUNITY);
}
@@ -4030,111 +3813,142 @@ DEFUN (no_neighbor_send_community,
/* neighbor send-community extended. */
DEFUN (neighbor_send_community_type,
neighbor_send_community_type_cmd,
- NEIGHBOR_CMD2 "send-community (both|extended|standard)",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> send-community <both|all|extended|standard|large>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Send Community attribute to this neighbor\n"
"Send Standard and Extended Community attributes\n"
+ "Send Standard, Large and Extended Community attributes\n"
"Send Extended Community attributes\n"
- "Send Standard Community attributes\n")
+ "Send Standard Community attributes\n"
+ "Send Large Community attributes\n")
{
- if (strncmp (argv[1], "s", 1) == 0)
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty),
- PEER_FLAG_SEND_COMMUNITY);
- if (strncmp (argv[1], "e", 1) == 0)
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty),
- PEER_FLAG_SEND_EXT_COMMUNITY);
+ int idx = 0;
+ u_int32_t flag = 0;
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty),
- (PEER_FLAG_SEND_COMMUNITY|
- PEER_FLAG_SEND_EXT_COMMUNITY));
+ char *peer = argv[1]->arg;
+
+ if (argv_find (argv, argc, "standard", &idx))
+ SET_FLAG (flag, PEER_FLAG_SEND_COMMUNITY);
+ else if (argv_find (argv, argc, "extended", &idx))
+ SET_FLAG (flag, PEER_FLAG_SEND_EXT_COMMUNITY);
+ else if (argv_find (argv, argc, "large", &idx))
+ SET_FLAG (flag, PEER_FLAG_SEND_LARGE_COMMUNITY);
+ else if (argv_find (argv, argc, "both", &idx))
+ {
+ SET_FLAG (flag, PEER_FLAG_SEND_COMMUNITY);
+ SET_FLAG (flag, PEER_FLAG_SEND_EXT_COMMUNITY);
+ }
+ else
+ {
+ SET_FLAG (flag, PEER_FLAG_SEND_COMMUNITY);
+ SET_FLAG (flag, PEER_FLAG_SEND_EXT_COMMUNITY);
+ SET_FLAG (flag, PEER_FLAG_SEND_LARGE_COMMUNITY);
+ }
+
+ return peer_af_flag_set_vty (vty, peer, bgp_node_afi (vty), bgp_node_safi (vty), flag);
}
DEFUN (no_neighbor_send_community_type,
no_neighbor_send_community_type_cmd,
- NO_NEIGHBOR_CMD2 "send-community (both|extended|standard)",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> send-community <both|all|extended|standard|large>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Send Community attribute to this neighbor\n"
"Send Standard and Extended Community attributes\n"
+ "Send Standard, Large and Extended Community attributes\n"
"Send Extended Community attributes\n"
- "Send Standard Community attributes\n")
+ "Send Standard Community attributes\n"
+ "Send Large Community attributes\n")
{
- if (strncmp (argv[1], "s", 1) == 0)
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ int idx_type = 4;
+ if (strncmp (argv[idx_type]->arg, "s", 1) == 0)
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_SEND_COMMUNITY);
- if (strncmp (argv[1], "e", 1) == 0)
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ if (strncmp (argv[idx_type]->arg, "e", 1) == 0)
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_SEND_EXT_COMMUNITY);
+ if (strncmp (argv[idx_type]->arg, "l", 1) == 0)
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_SEND_LARGE_COMMUNITY);
+ if (strncmp (argv[idx_type]->arg, "b", 1) == 0)
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_SEND_COMMUNITY |
+ PEER_FLAG_SEND_EXT_COMMUNITY);
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
(PEER_FLAG_SEND_COMMUNITY |
- PEER_FLAG_SEND_EXT_COMMUNITY));
+ PEER_FLAG_SEND_EXT_COMMUNITY|
+ PEER_FLAG_SEND_LARGE_COMMUNITY));
}
/* neighbor soft-reconfig. */
DEFUN (neighbor_soft_reconfiguration,
neighbor_soft_reconfiguration_cmd,
- NEIGHBOR_CMD2 "soft-reconfiguration inbound",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> soft-reconfiguration inbound",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Per neighbor soft reconfiguration\n"
"Allow inbound soft reconfiguration for this neighbor\n")
{
- return peer_af_flag_set_vty (vty, argv[0],
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg,
bgp_node_afi (vty), bgp_node_safi (vty),
PEER_FLAG_SOFT_RECONFIG);
}
DEFUN (no_neighbor_soft_reconfiguration,
no_neighbor_soft_reconfiguration_cmd,
- NO_NEIGHBOR_CMD2 "soft-reconfiguration inbound",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> soft-reconfiguration inbound",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Per neighbor soft reconfiguration\n"
"Allow inbound soft reconfiguration for this neighbor\n")
{
- return peer_af_flag_unset_vty (vty, argv[0],
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg,
bgp_node_afi (vty), bgp_node_safi (vty),
PEER_FLAG_SOFT_RECONFIG);
}
DEFUN (neighbor_route_reflector_client,
neighbor_route_reflector_client_cmd,
- NEIGHBOR_CMD2 "route-reflector-client",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> route-reflector-client",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Configure a neighbor as Route Reflector client\n")
{
+ int idx_peer = 1;
struct peer *peer;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REFLECTOR_CLIENT);
}
DEFUN (no_neighbor_route_reflector_client,
no_neighbor_route_reflector_client_cmd,
- NO_NEIGHBOR_CMD2 "route-reflector-client",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> route-reflector-client",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Configure a neighbor as Route Reflector client\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REFLECTOR_CLIENT);
}
@@ -4142,396 +3956,170 @@ DEFUN (no_neighbor_route_reflector_client,
/* neighbor route-server-client. */
DEFUN (neighbor_route_server_client,
neighbor_route_server_client_cmd,
- NEIGHBOR_CMD2 "route-server-client",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> route-server-client",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Configure a neighbor as Route Server client\n")
{
+ int idx_peer = 1;
struct peer *peer;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_RSERVER_CLIENT);
}
DEFUN (no_neighbor_route_server_client,
no_neighbor_route_server_client_cmd,
- NO_NEIGHBOR_CMD2 "route-server-client",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> route-server-client",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Configure a neighbor as Route Server client\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_RSERVER_CLIENT);
}
DEFUN (neighbor_nexthop_local_unchanged,
neighbor_nexthop_local_unchanged_cmd,
- NEIGHBOR_CMD2 "nexthop-local unchanged",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> nexthop-local unchanged",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Configure treatment of outgoing link-local nexthop attribute\n"
"Leave link-local nexthop unchanged for this peer\n")
{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED );
}
DEFUN (no_neighbor_nexthop_local_unchanged,
no_neighbor_nexthop_local_unchanged_cmd,
- NO_NEIGHBOR_CMD2 "nexthop-local unchanged",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> nexthop-local unchanged",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Configure treatment of outgoing link-local-nexthop attribute\n"
"Leave link-local nexthop unchanged for this peer\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED );
}
DEFUN (neighbor_attr_unchanged,
neighbor_attr_unchanged_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n")
-{
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty),
- (PEER_FLAG_AS_PATH_UNCHANGED |
- PEER_FLAG_NEXTHOP_UNCHANGED |
- PEER_FLAG_MED_UNCHANGED));
-}
-
-DEFUN (neighbor_attr_unchanged1,
- neighbor_attr_unchanged1_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged (as-path|next-hop|med)",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> attribute-unchanged\
+ [<\
+ as-path [<next-hop [med]|med [next-hop]>]|\
+ next-hop [<as-path [med]|med [as-path]>]|\
+ med [<as-path [next-hop]|next-hop [as-path]>]\
+ >]",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"BGP attribute is propagated unchanged to this neighbor\n"
"As-path attribute\n"
"Nexthop attribute\n"
- "Med attribute\n")
-{
- u_int16_t flags = 0;
-
- if (strncmp (argv[1], "as-path", 1) == 0)
- SET_FLAG (flags, PEER_FLAG_AS_PATH_UNCHANGED);
- else if (strncmp (argv[1], "next-hop", 1) == 0)
- SET_FLAG (flags, PEER_FLAG_NEXTHOP_UNCHANGED);
- else if (strncmp (argv[1], "med", 1) == 0)
- SET_FLAG (flags, PEER_FLAG_MED_UNCHANGED);
-
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), flags);
-}
-
-DEFUN (neighbor_attr_unchanged2,
- neighbor_attr_unchanged2_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged as-path (next-hop|med)",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "As-path attribute\n"
+ "Med attribute\n"
+ "Med attribute\n"
"Nexthop attribute\n"
- "Med attribute\n")
-{
- u_int16_t flags = PEER_FLAG_AS_PATH_UNCHANGED;
-
- if (strncmp (argv[1], "next-hop", 1) == 0)
- SET_FLAG (flags, PEER_FLAG_NEXTHOP_UNCHANGED);
- else if (strncmp (argv[1], "med", 1) == 0)
- SET_FLAG (flags, PEER_FLAG_MED_UNCHANGED);
-
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), flags);
-
-}
-
-DEFUN (neighbor_attr_unchanged3,
- neighbor_attr_unchanged3_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged next-hop (as-path|med)",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
"Nexthop attribute\n"
"As-path attribute\n"
- "Med attribute\n")
+ "Med attribute\n"
+ "Med attribute\n"
+ "As-path attribute\n"
+ "Med attribute\n"
+ "As-path attribute\n"
+ "Nexthop attribute\n"
+ "Nexthop attribute\n"
+ "As-path attribute\n")
{
- u_int16_t flags = PEER_FLAG_NEXTHOP_UNCHANGED;
+ int idx = 0;
+ char *peer = argv[1]->arg;
+ u_int16_t flags = 0;
- if (strncmp (argv[1], "as-path", 1) == 0)
+ if (argv_find (argv, argc, "as-path", &idx))
SET_FLAG (flags, PEER_FLAG_AS_PATH_UNCHANGED);
- else if (strncmp (argv[1], "med", 1) == 0)
+ idx = 0;
+ if (argv_find (argv, argc, "next-hop", &idx))
+ SET_FLAG (flags, PEER_FLAG_NEXTHOP_UNCHANGED);
+ idx = 0;
+ if (argv_find (argv, argc, "med", &idx))
SET_FLAG (flags, PEER_FLAG_MED_UNCHANGED);
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), flags);
-}
-
-DEFUN (neighbor_attr_unchanged4,
- neighbor_attr_unchanged4_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged med (as-path|next-hop)",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "Med attribute\n"
- "As-path attribute\n"
- "Nexthop attribute\n")
-{
- u_int16_t flags = PEER_FLAG_MED_UNCHANGED;
-
- if (strncmp (argv[1], "as-path", 1) == 0)
+ if (!flags) // no flags means all of them!
+ {
SET_FLAG (flags, PEER_FLAG_AS_PATH_UNCHANGED);
- else if (strncmp (argv[1], "next-hop", 1) == 0)
SET_FLAG (flags, PEER_FLAG_NEXTHOP_UNCHANGED);
+ SET_FLAG (flags, PEER_FLAG_MED_UNCHANGED);
+ }
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), flags);
+ return peer_af_flag_set_vty (vty, peer, bgp_node_afi (vty), bgp_node_safi (vty), flags);
}
-ALIAS (neighbor_attr_unchanged,
- neighbor_attr_unchanged5_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged as-path next-hop med",
+DEFUN (no_neighbor_attr_unchanged,
+ no_neighbor_attr_unchanged_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> attribute-unchanged\
+ [<\
+ as-path [<next-hop [med]|med [next-hop]>]|\
+ next-hop [<as-path [med]|med [as-path]>]|\
+ med [<as-path [next-hop]|next-hop [as-path]>]\
+ >]",
+ NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"BGP attribute is propagated unchanged to this neighbor\n"
"As-path attribute\n"
"Nexthop attribute\n"
- "Med attribute\n")
-
-ALIAS (neighbor_attr_unchanged,
- neighbor_attr_unchanged6_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged as-path med next-hop",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "As-path attribute\n"
"Med attribute\n"
- "Nexthop attribute\n")
-
-ALIAS (neighbor_attr_unchanged,
- neighbor_attr_unchanged7_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged next-hop med as-path",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "Nexthop attribute\n"
"Med attribute\n"
- "As-path attribute\n")
-
-ALIAS (neighbor_attr_unchanged,
- neighbor_attr_unchanged8_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged next-hop as-path med",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
+ "Nexthop attribute\n"
"Nexthop attribute\n"
"As-path attribute\n"
- "Med attribute\n")
-
-ALIAS (neighbor_attr_unchanged,
- neighbor_attr_unchanged9_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged med next-hop as-path",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
"Med attribute\n"
- "Nexthop attribute\n"
- "As-path attribute\n")
-
-ALIAS (neighbor_attr_unchanged,
- neighbor_attr_unchanged10_cmd,
- NEIGHBOR_CMD2 "attribute-unchanged med as-path next-hop",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
"Med attribute\n"
"As-path attribute\n"
- "Nexthop attribute\n")
-
-DEFUN (no_neighbor_attr_unchanged,
- no_neighbor_attr_unchanged_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n")
-{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty),
- (PEER_FLAG_AS_PATH_UNCHANGED |
- PEER_FLAG_NEXTHOP_UNCHANGED |
- PEER_FLAG_MED_UNCHANGED));
-}
-
-DEFUN (no_neighbor_attr_unchanged1,
- no_neighbor_attr_unchanged1_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged (as-path|next-hop|med)",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
+ "Med attribute\n"
"As-path attribute\n"
"Nexthop attribute\n"
- "Med attribute\n")
+ "Nexthop attribute\n"
+ "As-path attribute\n")
{
+ int idx = 0;
+ char *peer = argv[2]->arg;
u_int16_t flags = 0;
- if (strncmp (argv[1], "as-path", 1) == 0)
+ if (argv_find (argv, argc, "as-path", &idx))
SET_FLAG (flags, PEER_FLAG_AS_PATH_UNCHANGED);
- else if (strncmp (argv[1], "next-hop", 1) == 0)
- SET_FLAG (flags, PEER_FLAG_NEXTHOP_UNCHANGED);
- else if (strncmp (argv[1], "med", 1) == 0)
- SET_FLAG (flags, PEER_FLAG_MED_UNCHANGED);
-
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), flags);
-}
-
-DEFUN (no_neighbor_attr_unchanged2,
- no_neighbor_attr_unchanged2_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged as-path (next-hop|med)",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "As-path attribute\n"
- "Nexthop attribute\n"
- "Med attribute\n")
-{
- u_int16_t flags = PEER_FLAG_AS_PATH_UNCHANGED;
-
- if (strncmp (argv[1], "next-hop", 1) == 0)
+ idx = 0;
+ if (argv_find (argv, argc, "next-hop", &idx))
SET_FLAG (flags, PEER_FLAG_NEXTHOP_UNCHANGED);
- else if (strncmp (argv[1], "med", 1) == 0)
+ idx = 0;
+ if (argv_find (argv, argc, "med", &idx))
SET_FLAG (flags, PEER_FLAG_MED_UNCHANGED);
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), flags);
-}
-
-DEFUN (no_neighbor_attr_unchanged3,
- no_neighbor_attr_unchanged3_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged next-hop (as-path|med)",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "Nexthop attribute\n"
- "As-path attribute\n"
- "Med attribute\n")
-{
- u_int16_t flags = PEER_FLAG_NEXTHOP_UNCHANGED;
-
- if (strncmp (argv[1], "as-path", 1) == 0)
- SET_FLAG (flags, PEER_FLAG_AS_PATH_UNCHANGED);
- else if (strncmp (argv[1], "med", 1) == 0)
- SET_FLAG (flags, PEER_FLAG_MED_UNCHANGED);
-
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), flags);
-}
-
-DEFUN (no_neighbor_attr_unchanged4,
- no_neighbor_attr_unchanged4_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged med (as-path|next-hop)",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "Med attribute\n"
- "As-path attribute\n"
- "Nexthop attribute\n")
-{
- u_int16_t flags = PEER_FLAG_MED_UNCHANGED;
-
- if (strncmp (argv[1], "as-path", 1) == 0)
+ if (!flags) // no flags means all of them!
+ {
SET_FLAG (flags, PEER_FLAG_AS_PATH_UNCHANGED);
- else if (strncmp (argv[1], "next-hop", 1) == 0)
SET_FLAG (flags, PEER_FLAG_NEXTHOP_UNCHANGED);
+ SET_FLAG (flags, PEER_FLAG_MED_UNCHANGED);
+ }
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), flags);
+ return peer_af_flag_unset_vty (vty, peer, bgp_node_afi (vty), bgp_node_safi (vty), flags);
}
-ALIAS (no_neighbor_attr_unchanged,
- no_neighbor_attr_unchanged5_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged as-path next-hop med",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "As-path attribute\n"
- "Nexthop attribute\n"
- "Med attribute\n")
-
-ALIAS (no_neighbor_attr_unchanged,
- no_neighbor_attr_unchanged6_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged as-path med next-hop",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "As-path attribute\n"
- "Med attribute\n"
- "Nexthop attribute\n")
-
-ALIAS (no_neighbor_attr_unchanged,
- no_neighbor_attr_unchanged7_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged next-hop med as-path",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "Nexthop attribute\n"
- "Med attribute\n"
- "As-path attribute\n")
-
-ALIAS (no_neighbor_attr_unchanged,
- no_neighbor_attr_unchanged8_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged next-hop as-path med",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "Nexthop attribute\n"
- "As-path attribute\n"
- "Med attribute\n")
-
-ALIAS (no_neighbor_attr_unchanged,
- no_neighbor_attr_unchanged9_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged med next-hop as-path",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "Med attribute\n"
- "Nexthop attribute\n"
- "As-path attribute\n")
-
-ALIAS (no_neighbor_attr_unchanged,
- no_neighbor_attr_unchanged10_cmd,
- NO_NEIGHBOR_CMD2 "attribute-unchanged med as-path next-hop",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP attribute is propagated unchanged to this neighbor\n"
- "Med attribute\n"
- "As-path attribute\n"
- "Nexthop attribute\n")
/* EBGP multihop configuration. */
static int
-peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str,
+peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str,
const char *ttl_str)
{
struct peer *peer;
@@ -4553,7 +4141,7 @@ peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str,
}
static int
-peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str)
+peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str)
{
struct peer *peer;
@@ -4567,103 +4155,86 @@ peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str)
/* neighbor ebgp-multihop. */
DEFUN (neighbor_ebgp_multihop,
neighbor_ebgp_multihop_cmd,
- NEIGHBOR_CMD2 "ebgp-multihop",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> ebgp-multihop",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Allow EBGP neighbors not on directly connected networks\n")
{
- return peer_ebgp_multihop_set_vty (vty, argv[0], NULL);
+ int idx_peer = 1;
+ return peer_ebgp_multihop_set_vty (vty, argv[idx_peer]->arg, NULL);
}
DEFUN (neighbor_ebgp_multihop_ttl,
neighbor_ebgp_multihop_ttl_cmd,
- NEIGHBOR_CMD2 "ebgp-multihop " CMD_RANGE_STR(1, MAXTTL),
+ "neighbor <A.B.C.D|X:X::X:X|WORD> ebgp-multihop (1-255)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Allow EBGP neighbors not on directly connected networks\n"
"maximum hop count\n")
{
- return peer_ebgp_multihop_set_vty (vty, argv[0], argv[1]);
+ int idx_peer = 1;
+ int idx_number = 3;
+ return peer_ebgp_multihop_set_vty (vty, argv[idx_peer]->arg, argv[idx_number]->arg);
}
DEFUN (no_neighbor_ebgp_multihop,
no_neighbor_ebgp_multihop_cmd,
- NO_NEIGHBOR_CMD2 "ebgp-multihop",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> ebgp-multihop [(1-255)]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Allow EBGP neighbors not on directly connected networks\n")
+ "Allow EBGP neighbors not on directly connected networks\n"
+ "maximum hop count\n")
{
- return peer_ebgp_multihop_unset_vty (vty, argv[0]);
+ int idx_peer = 2;
+ return peer_ebgp_multihop_unset_vty (vty, argv[idx_peer]->arg);
}
-ALIAS (no_neighbor_ebgp_multihop,
- no_neighbor_ebgp_multihop_ttl_cmd,
- NO_NEIGHBOR_CMD2 "ebgp-multihop " CMD_RANGE_STR(1, MAXTTL),
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Allow EBGP neighbors not on directly connected networks\n"
- "maximum hop count\n")
/* disable-connected-check */
DEFUN (neighbor_disable_connected_check,
neighbor_disable_connected_check_cmd,
- NEIGHBOR_CMD2 "disable-connected-check",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> <disable-connected-check|enforce-multihop>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "one-hop away EBGP peer using loopback address\n")
+ "one-hop away EBGP peer using loopback address\n"
+ "Enforce EBGP neighbors perform multihop\n")
{
- return peer_flag_set_vty (vty, argv[0], PEER_FLAG_DISABLE_CONNECTED_CHECK);
+ int idx_peer = 1;
+ return peer_flag_set_vty (vty, argv[idx_peer]->arg, PEER_FLAG_DISABLE_CONNECTED_CHECK);
}
DEFUN (no_neighbor_disable_connected_check,
no_neighbor_disable_connected_check_cmd,
- NO_NEIGHBOR_CMD2 "disable-connected-check",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> <disable-connected-check|enforce-multihop>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "one-hop away EBGP peer using loopback address\n")
+ "one-hop away EBGP peer using loopback address\n"
+ "Enforce EBGP neighbors perform multihop\n")
{
- return peer_flag_unset_vty (vty, argv[0], PEER_FLAG_DISABLE_CONNECTED_CHECK);
+ int idx_peer = 2;
+ return peer_flag_unset_vty (vty, argv[idx_peer]->arg, PEER_FLAG_DISABLE_CONNECTED_CHECK);
}
-/* Enforce multihop. */
-ALIAS (neighbor_disable_connected_check,
- neighbor_enforce_multihop_cmd,
- NEIGHBOR_CMD2 "enforce-multihop",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Enforce EBGP neighbors perform multihop\n")
-
-/* Enforce multihop. */
-ALIAS (no_neighbor_disable_connected_check,
- no_neighbor_enforce_multihop_cmd,
- NO_NEIGHBOR_CMD2 "enforce-multihop",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Enforce EBGP neighbors perform multihop\n")
-
DEFUN (neighbor_description,
neighbor_description_cmd,
- NEIGHBOR_CMD2 "description .LINE",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> description LINE...",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Neighbor specific description\n"
"Up to 80 characters describing this neighbor\n")
{
+ int idx_peer = 1;
+ int idx_line = 3;
struct peer *peer;
char *str;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- if (argc == 1)
- return CMD_SUCCESS;
-
- str = argv_concat(argv, argc, 1);
+ str = argv_concat(argv, argc, idx_line);
peer_description_set (peer, str);
@@ -4674,15 +4245,17 @@ DEFUN (neighbor_description,
DEFUN (no_neighbor_description,
no_neighbor_description_cmd,
- NO_NEIGHBOR_CMD2 "description",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> description [LINE]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Neighbor specific description\n")
+ "Neighbor specific description\n"
+ "Up to 80 characters describing this neighbor\n")
{
+ int idx_peer = 2;
struct peer *peer;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -4691,18 +4264,10 @@ DEFUN (no_neighbor_description,
return CMD_SUCCESS;
}
-ALIAS (no_neighbor_description,
- no_neighbor_description_val_cmd,
- NO_NEIGHBOR_CMD2 "description .LINE",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Neighbor specific description\n"
- "Up to 80 characters describing this neighbor\n")
/* Neighbor update-source. */
static int
-peer_update_source_vty (struct vty *vty, const char *peer_str,
+peer_update_source_vty (struct vty *vty, const char *peer_str,
const char *source_str)
{
struct peer *peer;
@@ -4740,9 +4305,6 @@ peer_update_source_vty (struct vty *vty, const char *peer_str,
return CMD_SUCCESS;
}
-#define BGP_UPDATE_SOURCE_STR "A.B.C.D|X:X::X:X|WORD"
-#define BGP_UPDATE_SOURCE_REQ_STR "(" BGP_UPDATE_SOURCE_STR ")"
-#define BGP_UPDATE_SOURCE_OPT_STR "{" BGP_UPDATE_SOURCE_STR "}"
#define BGP_UPDATE_SOURCE_HELP_STR \
"IPv4 address\n" \
"IPv6 address\n" \
@@ -4750,30 +4312,33 @@ peer_update_source_vty (struct vty *vty, const char *peer_str,
DEFUN (neighbor_update_source,
neighbor_update_source_cmd,
- NEIGHBOR_CMD2 "update-source " BGP_UPDATE_SOURCE_REQ_STR,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> update-source <A.B.C.D|X:X::X:X|WORD>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Source of routing updates\n"
BGP_UPDATE_SOURCE_HELP_STR)
{
- return peer_update_source_vty (vty, argv[0], argv[1]);
+ int idx_peer = 1;
+ int idx_peer_2 = 3;
+ return peer_update_source_vty (vty, argv[idx_peer]->arg, argv[idx_peer_2]->arg);
}
DEFUN (no_neighbor_update_source,
no_neighbor_update_source_cmd,
- NO_NEIGHBOR_CMD2 "update-source " BGP_UPDATE_SOURCE_OPT_STR,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> update-source [<A.B.C.D|X:X::X:X|WORD>]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Source of routing updates\n"
BGP_UPDATE_SOURCE_HELP_STR)
{
- return peer_update_source_vty (vty, argv[0], NULL);
+ int idx_peer = 2;
+ return peer_update_source_vty (vty, argv[idx_peer]->arg, NULL);
}
static int
-peer_default_originate_set_vty (struct vty *vty, const char *peer_str,
- afi_t afi, safi_t safi,
+peer_default_originate_set_vty (struct vty *vty, const char *peer_str,
+ afi_t afi, safi_t safi,
const char *rmap, int set)
{
int ret;
@@ -4794,53 +4359,50 @@ peer_default_originate_set_vty (struct vty *vty, const char *peer_str,
/* neighbor default-originate. */
DEFUN (neighbor_default_originate,
neighbor_default_originate_cmd,
- NEIGHBOR_CMD2 "default-originate",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> default-originate",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Originate default route to this neighbor\n")
{
- return peer_default_originate_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 1;
+ return peer_default_originate_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty), NULL, 1);
}
DEFUN (neighbor_default_originate_rmap,
neighbor_default_originate_rmap_cmd,
- NEIGHBOR_CMD2 "default-originate route-map WORD",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> default-originate route-map WORD",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Originate default route to this neighbor\n"
"Route-map to specify criteria to originate default\n"
"route-map name\n")
{
- return peer_default_originate_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], 1);
+ int idx_peer = 1;
+ int idx_word = 4;
+ return peer_default_originate_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_word]->arg, 1);
}
DEFUN (no_neighbor_default_originate,
no_neighbor_default_originate_cmd,
- NO_NEIGHBOR_CMD2 "default-originate",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> default-originate [route-map WORD]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Originate default route to this neighbor\n")
+ "Originate default route to this neighbor\n"
+ "Route-map to specify criteria to originate default\n"
+ "route-map name\n")
{
- return peer_default_originate_set_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_default_originate_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty), NULL, 0);
}
-ALIAS (no_neighbor_default_originate,
- no_neighbor_default_originate_rmap_cmd,
- NO_NEIGHBOR_CMD2 "default-originate route-map WORD",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Originate default route to this neighbor\n"
- "Route-map to specify criteria to originate default\n"
- "route-map name\n")
/* Set neighbor's BGP port. */
static int
-peer_port_vty (struct vty *vty, const char *ip_str, int afi,
+peer_port_vty (struct vty *vty, const char *ip_str, int afi,
const char *port_str)
{
struct peer *peer;
@@ -4852,7 +4414,7 @@ peer_port_vty (struct vty *vty, const char *ip_str, int afi,
return CMD_WARNING;
if (! port_str)
- {
+ {
sp = getservbyname ("bgp", "tcp");
port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port);
}
@@ -4869,38 +4431,34 @@ peer_port_vty (struct vty *vty, const char *ip_str, int afi,
/* Set specified peer's BGP port. */
DEFUN (neighbor_port,
neighbor_port_cmd,
- NEIGHBOR_CMD "port <0-65535>",
+ "neighbor <A.B.C.D|X:X::X:X> port (0-65535)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR
"Neighbor's BGP port\n"
"TCP port number\n")
{
- return peer_port_vty (vty, argv[0], AFI_IP, argv[1]);
+ int idx_ip = 1;
+ int idx_number = 3;
+ return peer_port_vty (vty, argv[idx_ip]->arg, AFI_IP, argv[idx_number]->arg);
}
DEFUN (no_neighbor_port,
no_neighbor_port_cmd,
- NO_NEIGHBOR_CMD "port",
+ "no neighbor <A.B.C.D|X:X::X:X> port [(0-65535)]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR
- "Neighbor's BGP port\n")
+ "Neighbor's BGP port\n"
+ "TCP port number\n")
{
- return peer_port_vty (vty, argv[0], AFI_IP, NULL);
+ int idx_ip = 2;
+ return peer_port_vty (vty, argv[idx_ip]->arg, AFI_IP, NULL);
}
-ALIAS (no_neighbor_port,
- no_neighbor_port_val_cmd,
- NO_NEIGHBOR_CMD "port <0-65535>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR
- "Neighbor's BGP port\n"
- "TCP port number\n")
/* neighbor weight. */
static int
-peer_weight_set_vty (struct vty *vty, const char *ip_str,
+peer_weight_set_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *weight_str)
{
@@ -4935,80 +4493,84 @@ peer_weight_unset_vty (struct vty *vty, const char *ip_str,
DEFUN (neighbor_weight,
neighbor_weight_cmd,
- NEIGHBOR_CMD2 "weight <0-65535>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> weight (0-65535)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Set default weight for routes from this neighbor\n"
"default weight\n")
{
- return peer_weight_set_vty (vty, argv[0], bgp_node_afi (vty), bgp_node_safi (vty), argv[1]);
+ int idx_peer = 1;
+ int idx_number = 3;
+ return peer_weight_set_vty (vty,
+ argv[idx_peer]->arg,
+ bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ argv[idx_number]->arg);
}
DEFUN (no_neighbor_weight,
no_neighbor_weight_cmd,
- NO_NEIGHBOR_CMD2 "weight",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> weight [(0-65535)]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Set default weight for routes from this neighbor\n")
+ "Set default weight for routes from this neighbor\n"
+ "default weight\n")
{
- return peer_weight_unset_vty (vty, argv[0], bgp_node_afi (vty), bgp_node_safi (vty));
+ int idx_peer = 2;
+ return peer_weight_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty), bgp_node_safi (vty));
}
-ALIAS (no_neighbor_weight,
- no_neighbor_weight_val_cmd,
- NO_NEIGHBOR_CMD2 "weight <0-65535>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Set default weight for routes from this neighbor\n"
- "default weight\n")
/* Override capability negotiation. */
DEFUN (neighbor_override_capability,
neighbor_override_capability_cmd,
- NEIGHBOR_CMD2 "override-capability",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> override-capability",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Override capability negotiation result\n")
{
- return peer_flag_set_vty (vty, argv[0], PEER_FLAG_OVERRIDE_CAPABILITY);
+ int idx_peer = 1;
+ return peer_flag_set_vty (vty, argv[idx_peer]->arg, PEER_FLAG_OVERRIDE_CAPABILITY);
}
DEFUN (no_neighbor_override_capability,
no_neighbor_override_capability_cmd,
- NO_NEIGHBOR_CMD2 "override-capability",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> override-capability",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Override capability negotiation result\n")
{
- return peer_flag_unset_vty (vty, argv[0], PEER_FLAG_OVERRIDE_CAPABILITY);
+ int idx_peer = 2;
+ return peer_flag_unset_vty (vty, argv[idx_peer]->arg, PEER_FLAG_OVERRIDE_CAPABILITY);
}
DEFUN (neighbor_strict_capability,
neighbor_strict_capability_cmd,
- NEIGHBOR_CMD "strict-capability-match",
+ "neighbor <A.B.C.D|X:X::X:X> strict-capability-match",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR
"Strict capability negotiation match\n")
{
- return peer_flag_set_vty (vty, argv[0], PEER_FLAG_STRICT_CAP_MATCH);
+ int idx_ip = 1;
+ return peer_flag_set_vty (vty, argv[idx_ip]->arg, PEER_FLAG_STRICT_CAP_MATCH);
}
DEFUN (no_neighbor_strict_capability,
no_neighbor_strict_capability_cmd,
- NO_NEIGHBOR_CMD "strict-capability-match",
+ "no neighbor <A.B.C.D|X:X::X:X> strict-capability-match",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR
"Strict capability negotiation match\n")
{
- return peer_flag_unset_vty (vty, argv[0], PEER_FLAG_STRICT_CAP_MATCH);
+ int idx_ip = 2;
+ return peer_flag_unset_vty (vty, argv[idx_ip]->arg, PEER_FLAG_STRICT_CAP_MATCH);
}
static int
-peer_timers_set_vty (struct vty *vty, const char *ip_str,
+peer_timers_set_vty (struct vty *vty, const char *ip_str,
const char *keep_str, const char *hold_str)
{
int ret;
@@ -5045,39 +4607,36 @@ peer_timers_unset_vty (struct vty *vty, const char *ip_str)
DEFUN (neighbor_timers,
neighbor_timers_cmd,
- NEIGHBOR_CMD2 "timers <0-65535> <0-65535>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> timers (0-65535) (0-65535)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"BGP per neighbor timers\n"
"Keepalive interval\n"
"Holdtime\n")
{
- return peer_timers_set_vty (vty, argv[0], argv[1], argv[2]);
+ int idx_peer = 1;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ return peer_timers_set_vty (vty, argv[idx_peer]->arg, argv[idx_number]->arg, argv[idx_number_2]->arg);
}
DEFUN (no_neighbor_timers,
no_neighbor_timers_cmd,
- NO_NEIGHBOR_CMD2 "timers",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP per neighbor timers\n")
-{
- return peer_timers_unset_vty (vty, argv[0]);
-}
-
-ALIAS (no_neighbor_timers,
- no_neighbor_timers_val_cmd,
- NO_NEIGHBOR_CMD2 "timers <0-65535> <0-65535>",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> timers [(0-65535) (0-65535)]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"BGP per neighbor timers\n"
"Keepalive interval\n"
"Holdtime\n")
+{
+ int idx_peer = 2;
+ return peer_timers_unset_vty (vty, argv[idx_peer]->arg);
+}
+
static int
-peer_timers_connect_set_vty (struct vty *vty, const char *ip_str,
+peer_timers_connect_set_vty (struct vty *vty, const char *ip_str,
const char *time_str)
{
int ret;
@@ -5112,41 +4671,36 @@ peer_timers_connect_unset_vty (struct vty *vty, const char *ip_str)
DEFUN (neighbor_timers_connect,
neighbor_timers_connect_cmd,
- NEIGHBOR_CMD2 "timers connect <1-65535>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> timers connect (1-65535)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"BGP per neighbor timers\n"
"BGP connect timer\n"
"Connect timer\n")
{
- return peer_timers_connect_set_vty (vty, argv[0], argv[1]);
+ int idx_peer = 1;
+ int idx_number = 4;
+ return peer_timers_connect_set_vty (vty, argv[idx_peer]->arg, argv[idx_number]->arg);
}
DEFUN (no_neighbor_timers_connect,
no_neighbor_timers_connect_cmd,
- NO_NEIGHBOR_CMD2 "timers connect",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> timers connect [(1-65535)]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"BGP per neighbor timers\n"
- "BGP connect timer\n")
+ "BGP connect timer\n"
+ "Connect timer\n")
{
- return peer_timers_connect_unset_vty (vty, argv[0]);
+ int idx_peer = 2;
+ return peer_timers_connect_unset_vty (vty, argv[idx_peer]->arg);
}
-ALIAS (no_neighbor_timers_connect,
- no_neighbor_timers_connect_val_cmd,
- NO_NEIGHBOR_CMD2 "timers connect <1-65535>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "BGP per neighbor timers\n"
- "BGP connect timer\n"
- "Connect timer\n")
static int
-peer_advertise_interval_vty (struct vty *vty, const char *ip_str,
- const char *time_str, int set)
+peer_advertise_interval_vty (struct vty *vty, const char *ip_str,
+ const char *time_str, int set)
{
int ret;
struct peer *peer;
@@ -5169,49 +4723,46 @@ peer_advertise_interval_vty (struct vty *vty, const char *ip_str,
DEFUN (neighbor_advertise_interval,
neighbor_advertise_interval_cmd,
- NEIGHBOR_CMD2 "advertisement-interval <0-600>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> advertisement-interval (0-600)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Minimum interval between sending BGP routing updates\n"
"time in seconds\n")
{
- return peer_advertise_interval_vty (vty, argv[0], argv[1], 1);
+ int idx_peer = 1;
+ int idx_number = 3;
+ return peer_advertise_interval_vty (vty, argv[idx_peer]->arg, argv[idx_number]->arg, 1);
}
DEFUN (no_neighbor_advertise_interval,
no_neighbor_advertise_interval_cmd,
- NO_NEIGHBOR_CMD2 "advertisement-interval",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> advertisement-interval [(0-600)]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Minimum interval between sending BGP routing updates\n")
+ "Minimum interval between sending BGP routing updates\n"
+ "time in seconds\n")
{
- return peer_advertise_interval_vty (vty, argv[0], NULL, 0);
+ int idx_peer = 2;
+ return peer_advertise_interval_vty (vty, argv[idx_peer]->arg, NULL, 0);
}
-ALIAS (no_neighbor_advertise_interval,
- no_neighbor_advertise_interval_val_cmd,
- NO_NEIGHBOR_CMD2 "advertisement-interval <0-600>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Minimum interval between sending BGP routing updates\n"
- "time in seconds\n")
/* Time to wait before processing route-map updates */
DEFUN (bgp_set_route_map_delay_timer,
bgp_set_route_map_delay_timer_cmd,
- "bgp route-map delay-timer <0-600>",
+ "bgp route-map delay-timer (0-600)",
SET_STR
"BGP route-map delay timer\n"
"Time in secs to wait before processing route-map changes\n"
"0 disables the timer, no route updates happen when route-maps change\n")
{
+ int idx_number = 3;
u_int32_t rmap_delay_timer;
- if (argv[0])
+ if (argv[idx_number]->arg)
{
- VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer, argv[0], 0, 600);
+ VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer, argv[idx_number]->arg, 0, 600);
bm->rmap_update_timer = rmap_delay_timer;
/* if the dynamic update handling is being disabled, and a timer is
@@ -5230,10 +4781,12 @@ DEFUN (bgp_set_route_map_delay_timer,
DEFUN (no_bgp_set_route_map_delay_timer,
no_bgp_set_route_map_delay_timer_cmd,
- "no bgp route-map delay-timer",
+ "no bgp route-map delay-timer [(0-600)]",
NO_STR
+ BGP_STR
"Default BGP route-map delay timer\n"
- "Reset to default time to wait for processing route-map changes\n")
+ "Reset to default time to wait for processing route-map changes\n"
+ "0 disables the timer, no route updates happen when route-maps change\n")
{
bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
@@ -5241,13 +4794,6 @@ DEFUN (no_bgp_set_route_map_delay_timer,
return CMD_SUCCESS;
}
-ALIAS (no_bgp_set_route_map_delay_timer,
- no_bgp_set_route_map_delay_timer_val_cmd,
- "no bgp route-map delay-timer <0-600>",
- NO_STR
- "Default BGP route-map delay timer\n"
- "Reset to default time to wait for processing route-map changes\n"
- "0 disables the timer, no route updates happen when route-maps change\n")
/* neighbor interface */
static int
@@ -5269,33 +4815,33 @@ peer_interface_vty (struct vty *vty, const char *ip_str, const char *str)
DEFUN (neighbor_interface,
neighbor_interface_cmd,
- NEIGHBOR_CMD "interface WORD",
+ "neighbor <A.B.C.D|X:X::X:X> interface WORD",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR
"Interface\n"
"Interface name\n")
{
- if (argc == 3)
- return peer_interface_vty (vty, argv[0], argv[1]);
- else
- return peer_interface_vty (vty, argv[0], argv[1]);
+ int idx_ip = 1;
+ int idx_word = 3;
+ return peer_interface_vty (vty, argv[idx_ip]->arg, argv[idx_word]->arg);
}
DEFUN (no_neighbor_interface,
no_neighbor_interface_cmd,
- NO_NEIGHBOR_CMD2 "interface WORD",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> interface WORD",
NO_STR
NEIGHBOR_STR
- NEIGHBOR_ADDR_STR
+ NEIGHBOR_ADDR_STR2
"Interface\n"
"Interface name\n")
{
- return peer_interface_vty (vty, argv[0], NULL);
+ int idx_peer = 2;
+ return peer_interface_vty (vty, argv[idx_peer]->arg, NULL);
}
/* Set distribute list to the peer. */
static int
-peer_distribute_set_vty (struct vty *vty, const char *ip_str,
+peer_distribute_set_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *name_str, const char *direct_str)
{
@@ -5343,7 +4889,7 @@ peer_distribute_unset_vty (struct vty *vty, const char *ip_str, afi_t afi,
DEFUN (neighbor_distribute_list,
neighbor_distribute_list_cmd,
- NEIGHBOR_CMD2 "distribute-list (<1-199>|<1300-2699>|WORD) (in|out)",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list <(1-199)|(1300-2699)|WORD> <in|out>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Filter updates to/from this neighbor\n"
@@ -5353,13 +4899,16 @@ DEFUN (neighbor_distribute_list,
"Filter incoming updates\n"
"Filter outgoing updates\n")
{
- return peer_distribute_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], argv[2]);
+ int idx_peer = 1;
+ int idx_acl = 3;
+ int idx_in_out = 4;
+ return peer_distribute_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_acl]->arg, argv[idx_in_out]->arg);
}
DEFUN (no_neighbor_distribute_list,
no_neighbor_distribute_list_cmd,
- NO_NEIGHBOR_CMD2 "distribute-list (<1-199>|<1300-2699>|WORD) (in|out)",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list <(1-199)|(1300-2699)|WORD> <in|out>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
@@ -5370,14 +4919,16 @@ DEFUN (no_neighbor_distribute_list,
"Filter incoming updates\n"
"Filter outgoing updates\n")
{
- return peer_distribute_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[2]);
+ int idx_peer = 2;
+ int idx_in_out = 5;
+ return peer_distribute_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_in_out]->arg);
}
/* Set prefix list to the peer. */
static int
peer_prefix_list_set_vty (struct vty *vty, const char *ip_str, afi_t afi,
- safi_t safi, const char *name_str,
+ safi_t safi, const char *name_str,
const char *direct_str)
{
int ret;
@@ -5410,7 +4961,7 @@ peer_prefix_list_unset_vty (struct vty *vty, const char *ip_str, afi_t afi,
peer = peer_and_group_lookup_vty (vty, ip_str);
if (! peer)
return CMD_WARNING;
-
+
/* Check filter direction. */
if (strncmp (direct_str, "i", 1) == 0)
direct = FILTER_IN;
@@ -5424,7 +4975,7 @@ peer_prefix_list_unset_vty (struct vty *vty, const char *ip_str, afi_t afi,
DEFUN (neighbor_prefix_list,
neighbor_prefix_list_cmd,
- NEIGHBOR_CMD2 "prefix-list WORD (in|out)",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Filter updates to/from this neighbor\n"
@@ -5432,13 +4983,16 @@ DEFUN (neighbor_prefix_list,
"Filter incoming updates\n"
"Filter outgoing updates\n")
{
- return peer_prefix_list_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], argv[2]);
+ int idx_peer = 1;
+ int idx_word = 3;
+ int idx_in_out = 4;
+ return peer_prefix_list_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_word]->arg, argv[idx_in_out]->arg);
}
DEFUN (no_neighbor_prefix_list,
no_neighbor_prefix_list_cmd,
- NO_NEIGHBOR_CMD2 "prefix-list WORD (in|out)",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
@@ -5447,12 +5001,14 @@ DEFUN (no_neighbor_prefix_list,
"Filter incoming updates\n"
"Filter outgoing updates\n")
{
- return peer_prefix_list_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[2]);
+ int idx_peer = 2;
+ int idx_in_out = 5;
+ return peer_prefix_list_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_in_out]->arg);
}
static int
-peer_aslist_set_vty (struct vty *vty, const char *ip_str,
+peer_aslist_set_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *name_str, const char *direct_str)
{
@@ -5476,7 +5032,7 @@ peer_aslist_set_vty (struct vty *vty, const char *ip_str,
}
static int
-peer_aslist_unset_vty (struct vty *vty, const char *ip_str,
+peer_aslist_unset_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *direct_str)
{
@@ -5501,7 +5057,7 @@ peer_aslist_unset_vty (struct vty *vty, const char *ip_str,
DEFUN (neighbor_filter_list,
neighbor_filter_list_cmd,
- NEIGHBOR_CMD2 "filter-list WORD (in|out)",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> filter-list WORD <in|out>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Establish BGP filters\n"
@@ -5509,13 +5065,16 @@ DEFUN (neighbor_filter_list,
"Filter incoming routes\n"
"Filter outgoing routes\n")
{
- return peer_aslist_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], argv[2]);
+ int idx_peer = 1;
+ int idx_word = 3;
+ int idx_in_out = 4;
+ return peer_aslist_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_word]->arg, argv[idx_in_out]->arg);
}
DEFUN (no_neighbor_filter_list,
no_neighbor_filter_list_cmd,
- NO_NEIGHBOR_CMD2 "filter-list WORD (in|out)",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> filter-list WORD <in|out>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
@@ -5524,13 +5083,15 @@ DEFUN (no_neighbor_filter_list,
"Filter incoming routes\n"
"Filter outgoing routes\n")
{
- return peer_aslist_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[2]);
+ int idx_peer = 2;
+ int idx_in_out = 5;
+ return peer_aslist_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_in_out]->arg);
}
/* Set route-map to the peer. */
static int
-peer_route_map_set_vty (struct vty *vty, const char *ip_str,
+peer_route_map_set_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *name_str, const char *direct_str)
{
@@ -5578,7 +5139,7 @@ peer_route_map_unset_vty (struct vty *vty, const char *ip_str, afi_t afi,
DEFUN (neighbor_route_map,
neighbor_route_map_cmd,
- NEIGHBOR_CMD2 "route-map WORD (in|out)",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Apply route map to neighbor\n"
@@ -5586,13 +5147,16 @@ DEFUN (neighbor_route_map,
"Apply map to incoming routes\n"
"Apply map to outbound routes\n")
{
- return peer_route_map_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], argv[2]);
+ int idx_peer = 1;
+ int idx_word = 3;
+ int idx_in_out = 4;
+ return peer_route_map_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_word]->arg, argv[idx_in_out]->arg);
}
DEFUN (no_neighbor_route_map,
no_neighbor_route_map_cmd,
- NO_NEIGHBOR_CMD2 "route-map WORD (in|out)",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
@@ -5601,8 +5165,10 @@ DEFUN (no_neighbor_route_map,
"Apply map to incoming routes\n"
"Apply map to outbound routes\n")
{
- return peer_route_map_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[2]);
+ int idx_peer = 2;
+ int idx_in_out = 5;
+ return peer_route_map_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_in_out]->arg);
}
/* Set unsuppress-map to the peer. */
@@ -5641,32 +5207,35 @@ peer_unsuppress_map_unset_vty (struct vty *vty, const char *ip_str, afi_t afi,
DEFUN (neighbor_unsuppress_map,
neighbor_unsuppress_map_cmd,
- NEIGHBOR_CMD2 "unsuppress-map WORD",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> unsuppress-map WORD",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Route-map to selectively unsuppress suppressed routes\n"
"Name of route map\n")
{
- return peer_unsuppress_map_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1]);
+ int idx_peer = 1;
+ int idx_word = 3;
+ return peer_unsuppress_map_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_word]->arg);
}
DEFUN (no_neighbor_unsuppress_map,
no_neighbor_unsuppress_map_cmd,
- NO_NEIGHBOR_CMD2 "unsuppress-map WORD",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> unsuppress-map WORD",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Route-map to selectively unsuppress suppressed routes\n"
"Name of route map\n")
{
- return peer_unsuppress_map_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_unsuppress_map_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty));
}
static int
peer_maximum_prefix_set_vty (struct vty *vty, const char *ip_str, afi_t afi,
- safi_t safi, const char *num_str,
+ safi_t safi, const char *num_str,
const char *threshold_str, int warning,
const char *restart_str)
{
@@ -5717,48 +5286,55 @@ peer_maximum_prefix_unset_vty (struct vty *vty, const char *ip_str, afi_t afi,
each peer configuration. */
DEFUN (neighbor_maximum_prefix,
neighbor_maximum_prefix_cmd,
- NEIGHBOR_CMD2 "maximum-prefix <1-4294967295>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Maximum number of prefix accept from this peer\n"
"maximum no. of prefix limit\n")
{
- return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], NULL, 0,
+ int idx_peer = 1;
+ int idx_number = 3;
+ return peer_maximum_prefix_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_number]->arg, NULL, 0,
NULL);
}
DEFUN (neighbor_maximum_prefix_threshold,
neighbor_maximum_prefix_threshold_cmd,
- NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Maximum number of prefix accept from this peer\n"
"maximum no. of prefix limit\n"
"Threshold value (%) at which to generate a warning msg\n")
{
- return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], argv[2], 0,
+ int idx_peer = 1;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ return peer_maximum_prefix_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_number]->arg, argv[idx_number_2]->arg, 0,
NULL);
}
DEFUN (neighbor_maximum_prefix_warning,
neighbor_maximum_prefix_warning_cmd,
- NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> warning-only",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) warning-only",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Maximum number of prefix accept from this peer\n"
"maximum no. of prefix limit\n"
"Only give warning message when limit is exceeded\n")
{
- return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], NULL, 1,
+ int idx_peer = 1;
+ int idx_number = 3;
+ return peer_maximum_prefix_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_number]->arg, NULL, 1,
NULL);
}
DEFUN (neighbor_maximum_prefix_threshold_warning,
neighbor_maximum_prefix_threshold_warning_cmd,
- NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> warning-only",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) warning-only",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Maximum number of prefix accept from this peer\n"
@@ -5766,13 +5342,16 @@ DEFUN (neighbor_maximum_prefix_threshold_warning,
"Threshold value (%) at which to generate a warning msg\n"
"Only give warning message when limit is exceeded\n")
{
- return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], argv[2], 1, NULL);
+ int idx_peer = 1;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ return peer_maximum_prefix_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_number]->arg, argv[idx_number_2]->arg, 1, NULL);
}
DEFUN (neighbor_maximum_prefix_restart,
neighbor_maximum_prefix_restart_cmd,
- NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> restart <1-65535>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) restart (1-65535)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Maximum number of prefix accept from this peer\n"
@@ -5780,125 +5359,80 @@ DEFUN (neighbor_maximum_prefix_restart,
"Restart bgp connection after limit is exceeded\n"
"Restart interval in minutes")
{
- return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], NULL, 0, argv[2]);
+ int idx_peer = 1;
+ int idx_number = 3;
+ int idx_number_2 = 5;
+ return peer_maximum_prefix_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_number]->arg, NULL, 0, argv[idx_number_2]->arg);
}
DEFUN (neighbor_maximum_prefix_threshold_restart,
neighbor_maximum_prefix_threshold_restart_cmd,
- NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> restart <1-65535>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) restart (1-65535)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
+ "Maximum number of prefixes to accept from this peer\n"
"maximum no. of prefix limit\n"
"Threshold value (%) at which to generate a warning msg\n"
"Restart bgp connection after limit is exceeded\n"
- "Restart interval in minutes")
+ "Restart interval in minutes\n")
{
- return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], argv[2], 0, argv[3]);
+ int idx_peer = 1;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 6;
+ return peer_maximum_prefix_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[idx_number]->arg, argv[idx_number_2]->arg, 0, argv[idx_number_3]->arg);
}
DEFUN (no_neighbor_maximum_prefix,
no_neighbor_maximum_prefix_cmd,
- NO_NEIGHBOR_CMD2 "maximum-prefix",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n")
-{
- return peer_maximum_prefix_unset_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty));
-}
-
-ALIAS (no_neighbor_maximum_prefix,
- no_neighbor_maximum_prefix_val_cmd,
- NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n")
-
-ALIAS (no_neighbor_maximum_prefix,
- no_neighbor_maximum_prefix_threshold_cmd,
- NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100>",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix [(1-4294967295) [(1-100)] [restart (1-65535)] [warning-only]]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Threshold value (%) at which to generate a warning msg\n")
-
-ALIAS (no_neighbor_maximum_prefix,
- no_neighbor_maximum_prefix_warning_cmd,
- NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> warning-only",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Only give warning message when limit is exceeded\n")
-
-ALIAS (no_neighbor_maximum_prefix,
- no_neighbor_maximum_prefix_threshold_warning_cmd,
- NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> warning-only",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
+ "Maximum number of prefixes to accept from this peer\n"
"maximum no. of prefix limit\n"
"Threshold value (%) at which to generate a warning msg\n"
+ "Restart bgp connection after limit is exceeded\n"
+ "Restart interval in minutes\n"
"Only give warning message when limit is exceeded\n")
+{
+ int idx_peer = 2;
+ return peer_maximum_prefix_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
+ bgp_node_safi (vty));
+}
-ALIAS (no_neighbor_maximum_prefix,
- no_neighbor_maximum_prefix_restart_cmd,
- NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> restart <1-65535>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Restart bgp connection after limit is exceeded\n"
- "Restart interval in minutes")
-
-ALIAS (no_neighbor_maximum_prefix,
- no_neighbor_maximum_prefix_threshold_restart_cmd,
- NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> restart <1-65535>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n"
- "Threshold value (%) at which to generate a warning msg\n"
- "Restart bgp connection after limit is exceeded\n"
- "Restart interval in minutes")
/* "neighbor allowas-in" */
DEFUN (neighbor_allowas_in,
neighbor_allowas_in_cmd,
- NEIGHBOR_CMD2 "allowas-in",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> allowas-in [<(1-10)|origin>]",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Accept as-path with my AS present in it\n")
+ "Accept as-path with my AS present in it\n"
+ "Number of occurances of AS number\n"
+ "Only accept my AS in the as-path if the route was originated in my AS\n")
{
+ int idx_peer = 1;
+ int idx_number_origin = 3;
int ret;
int origin = 0;
struct peer *peer;
int allow_num = 0;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- if (argc == 1)
+ if (argc <= idx_number_origin)
allow_num = 3;
else
{
- if (strncmp (argv[1], "o", 1) == 0)
+ if (argv[idx_number_origin]->type == WORD_TKN)
origin = 1;
else
- VTY_GET_INTEGER_RANGE ("AS number", allow_num, argv[1], 1, 10);
+ allow_num = atoi (argv[idx_number_origin]->arg);
}
ret = peer_allowas_in_set (peer, bgp_node_afi (vty), bgp_node_safi (vty),
@@ -5907,27 +5441,21 @@ DEFUN (neighbor_allowas_in,
return bgp_vty_return (vty, ret);
}
-ALIAS (neighbor_allowas_in,
- neighbor_allowas_in_arg_cmd,
- NEIGHBOR_CMD2 "allowas-in (<1-10>|origin)",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Accept as-path with my AS present in it\n"
- "Number of occurances of AS number\n"
- "Only accept my AS in the as-path if the route was originated in my AS\n")
-
DEFUN (no_neighbor_allowas_in,
no_neighbor_allowas_in_cmd,
- NO_NEIGHBOR_CMD2 "allowas-in",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> allowas-in [<(1-10)|origin>]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "allow local ASN appears in aspath attribute\n")
+ "allow local ASN appears in aspath attribute\n"
+ "Number of occurances of AS number\n"
+ "Only accept my AS in the as-path if the route was originated in my AS\n")
{
+ int idx_peer = 2;
int ret;
struct peer *peer;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -5936,31 +5464,25 @@ DEFUN (no_neighbor_allowas_in,
return bgp_vty_return (vty, ret);
}
-ALIAS (no_neighbor_allowas_in,
- no_neighbor_allowas_in_val_cmd,
- NO_NEIGHBOR_CMD2 "allowas-in (<1-10>|origin)",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "allow local ASN appears in aspath attribute\n"
- "Number of occurances of AS number\n"
- "Only accept my AS in the as-path if the route was originated in my AS\n")
-
DEFUN (neighbor_ttl_security,
neighbor_ttl_security_cmd,
- NEIGHBOR_CMD2 "ttl-security hops <1-254>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> ttl-security hops (1-254)",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Specify the maximum number of hops to the BGP peer\n")
+ "BGP ttl-security parameters\n"
+ "Specify the maximum number of hops to the BGP peer\n"
+ "Number of hops to BGP peer\n")
{
+ int idx_peer = 1;
+ int idx_number = 4;
struct peer *peer;
int gtsm_hops;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
-
- VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[1], 1, 254);
+
+ VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[idx_number]->arg, 1, 254);
/*
* If 'neighbor swpX', then this is for directly connected peers,
@@ -5968,7 +5490,7 @@ DEFUN (neighbor_ttl_security,
*/
if (peer->conf_if && (gtsm_hops > 1)) {
vty_out (vty, "%s is directly connected peer, hops cannot exceed 1%s",
- argv[0], VTY_NEWLINE);
+ argv[idx_peer]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -5977,15 +5499,18 @@ DEFUN (neighbor_ttl_security,
DEFUN (no_neighbor_ttl_security,
no_neighbor_ttl_security_cmd,
- NO_NEIGHBOR_CMD2 "ttl-security hops <1-254>",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> ttl-security hops (1-254)",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Specify the maximum number of hops to the BGP peer\n")
+ "BGP ttl-security parameters\n"
+ "Specify the maximum number of hops to the BGP peer\n"
+ "Number of hops to BGP peer\n")
{
+ int idx_peer = 2;
struct peer *peer;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
@@ -5994,148 +5519,143 @@ DEFUN (no_neighbor_ttl_security,
DEFUN (neighbor_addpath_tx_all_paths,
neighbor_addpath_tx_all_paths_cmd,
- NEIGHBOR_CMD2 "addpath-tx-all-paths",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-all-paths",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Use addpath to advertise all paths to a neighbor\n")
{
+ int idx_peer = 1;
struct peer *peer;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_ADDPATH_TX_ALL_PATHS);
}
DEFUN (no_neighbor_addpath_tx_all_paths,
no_neighbor_addpath_tx_all_paths_cmd,
- NO_NEIGHBOR_CMD2 "addpath-tx-all-paths",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-all-paths",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Use addpath to advertise all paths to a neighbor\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_ADDPATH_TX_ALL_PATHS);
}
DEFUN (neighbor_addpath_tx_bestpath_per_as,
neighbor_addpath_tx_bestpath_per_as_cmd,
- NEIGHBOR_CMD2 "addpath-tx-bestpath-per-AS",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-bestpath-per-AS",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Use addpath to advertise the bestpath per each neighboring AS\n")
{
+ int idx_peer = 1;
struct peer *peer;
- peer = peer_and_group_lookup_vty (vty, argv[0]);
+ peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
- return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ return peer_af_flag_set_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS);
}
DEFUN (no_neighbor_addpath_tx_bestpath_per_as,
no_neighbor_addpath_tx_bestpath_per_as_cmd,
- NO_NEIGHBOR_CMD2 "addpath-tx-bestpath-per-AS",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-bestpath-per-AS",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Use addpath to advertise the bestpath per each neighboring AS\n")
{
- return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ int idx_peer = 2;
+ return peer_af_flag_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS);
}
-
-/* Address family configuration. */
-DEFUN (address_family_ipv4,
- address_family_ipv4_cmd,
- "address-family ipv4",
- "Enter Address Family command mode\n"
- "Address family\n")
-{
- vty->node = BGP_IPV4_NODE;
- return CMD_SUCCESS;
-}
-
DEFUN (address_family_ipv4_safi,
address_family_ipv4_safi_cmd,
- "address-family ipv4 (unicast|multicast|vpn|encap)",
+ "address-family ipv4 [<unicast|multicast|vpn|encap>]",
"Enter Address Family command mode\n"
"Address Family\n"
BGP_SAFI_HELP_STR)
{
- switch (bgp_vty_safi_from_arg(argv[0]))
+ int idx_safi = 2;
+ if (argc == (idx_safi + 1))
{
- case SAFI_MULTICAST:
- vty->node = BGP_IPV4M_NODE;
- break;
- case SAFI_ENCAP:
- vty->node = BGP_ENCAP_NODE;
- break;
- case SAFI_MPLS_VPN:
- vty->node = BGP_VPNV4_NODE;
- break;
- case SAFI_UNICAST:
- default:
- vty->node = BGP_IPV4_NODE;
- break;
+ switch (bgp_vty_safi_from_arg(argv[idx_safi]->arg))
+ {
+ case SAFI_MULTICAST:
+ vty->node = BGP_IPV4M_NODE;
+ break;
+ case SAFI_ENCAP:
+ vty->node = BGP_ENCAP_NODE;
+ break;
+ case SAFI_MPLS_VPN:
+ vty->node = BGP_VPNV4_NODE;
+ break;
+ case SAFI_UNICAST:
+ default:
+ vty->node = BGP_IPV4_NODE;
+ break;
+ }
}
+ else
+ vty->node = BGP_IPV4_NODE;
return CMD_SUCCESS;
}
-DEFUN (address_family_ipv6,
- address_family_ipv6_cmd,
- "address-family ipv6",
- "Enter Address Family command mode\n"
- "Address family\n")
-{
- vty->node = BGP_IPV6_NODE;
- return CMD_SUCCESS;
-}
-
DEFUN (address_family_ipv6_safi,
address_family_ipv6_safi_cmd,
- "address-family ipv6 (unicast|multicast|vpn|encap)",
+ "address-family ipv6 [<unicast|multicast|vpn|encap>]",
"Enter Address Family command mode\n"
"Address Family\n"
BGP_SAFI_HELP_STR)
{
- int idx_safi = 0;
- switch (bgp_vty_safi_from_arg(argv[idx_safi]))
+ int idx_safi = 2;
+ if (argc == (idx_safi + 1))
{
- case SAFI_MULTICAST:
- vty->node = BGP_IPV6M_NODE;
- break;
- case SAFI_ENCAP:
- vty->node = BGP_ENCAPV6_NODE;
- break;
- case SAFI_MPLS_VPN:
- vty->node = BGP_VPNV6_NODE;
- break;
- case SAFI_UNICAST:
- default:
- vty->node = BGP_IPV6_NODE;
- break;
+ switch (bgp_vty_safi_from_arg(argv[idx_safi]->arg))
+ {
+ case SAFI_MULTICAST:
+ vty->node = BGP_IPV6M_NODE;
+ break;
+ case SAFI_ENCAP:
+ vty->node = BGP_ENCAPV6_NODE;
+ break;
+ case SAFI_MPLS_VPN:
+ vty->node = BGP_VPNV6_NODE;
+ break;
+ case SAFI_UNICAST:
+ default:
+ vty->node = BGP_IPV6_NODE;
+ break;
+ }
}
+ else
+ vty->node = BGP_IPV6_NODE;
return CMD_SUCCESS;
}
+#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (address_family_vpnv4,
address_family_vpnv4_cmd,
- "address-family vpnv4",
+ "address-family vpnv4 [unicast]",
"Enter Address Family command mode\n"
- "Address family\n")
+ "Address Family\n"
+ "Address Family modifier\n")
{
vty->node = BGP_VPNV4_NODE;
return CMD_SUCCESS;
@@ -6143,35 +5663,33 @@ DEFUN (address_family_vpnv4,
DEFUN (address_family_vpnv6,
address_family_vpnv6_cmd,
- "address-family vpnv6",
+ "address-family vpnv6 [unicast]",
"Enter Address Family command mode\n"
- "Address family\n")
+ "Address Family\n"
+ "Address Family modifier\n")
{
vty->node = BGP_VPNV6_NODE;
return CMD_SUCCESS;
}
+#endif
DEFUN (address_family_encap,
address_family_encap_cmd,
- "address-family encap",
+ "address-family <encap|encapv4>",
"Enter Address Family command mode\n"
- "Address family\n")
+ "Address Family\n"
+ "Address Family\n")
{
vty->node = BGP_ENCAP_NODE;
return CMD_SUCCESS;
}
-ALIAS (address_family_encap,
- address_family_encapv4_cmd,
- "address-family encapv4",
- "Enter Address Family command mode\n"
- "Address family\n")
DEFUN (address_family_encapv6,
address_family_encapv6_cmd,
"address-family encapv6",
"Enter Address Family command mode\n"
- "Address family\n")
+ "Address Family\n")
{
vty->node = BGP_ENCAPV6_NODE;
return CMD_SUCCESS;
@@ -6275,3224 +5793,192 @@ bgp_clear_prefix (struct vty *vty, const char *view_name, const char *ip_str,
return CMD_SUCCESS;
}
+/* one clear bgp command to rule them all */
DEFUN (clear_ip_bgp_all,
clear_ip_bgp_all_cmd,
- "clear ip bgp *",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n")
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL);
-
- return bgp_clear_vty (vty, NULL, 0, 0, clear_all, BGP_CLEAR_SOFT_NONE, NULL);
-}
-
-ALIAS (clear_ip_bgp_all,
- clear_ip_bgp_instance_all_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " *",
+ "clear [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<soft [<in|out>]|in [prefix-filter]|out>]",
CLEAR_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "Clear all peers\n")
-
-ALIAS (clear_ip_bgp_all,
- clear_bgp_all_cmd,
- "clear bgp *",
- CLEAR_STR
- BGP_STR
- "Clear all peers\n")
-
-ALIAS (clear_ip_bgp_all,
- clear_bgp_instance_all_cmd,
- "clear bgp " BGP_INSTANCE_CMD " *",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n")
-
-ALIAS (clear_ip_bgp_all,
- clear_bgp_ipv6_all_cmd,
- "clear bgp ipv6 *",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all peers\n")
-
-ALIAS (clear_ip_bgp_all,
- clear_bgp_instance_ipv6_all_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 *",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all peers\n")
-
-DEFUN (clear_ip_bgp_peer,
- clear_ip_bgp_peer_cmd,
- "clear ip bgp (A.B.C.D|X:X::X:X|WORD)",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor IP address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n")
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], 0, 0, clear_peer, BGP_CLEAR_SOFT_NONE, argv[2]);
-
- return bgp_clear_vty (vty, NULL, 0, 0, clear_peer, BGP_CLEAR_SOFT_NONE, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_peer,
- clear_ip_bgp_instance_peer_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|X:X::X:X|WORD)",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor IP address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n")
-
-ALIAS (clear_ip_bgp_peer,
- clear_bgp_peer_cmd,
- "clear bgp (A.B.C.D|X:X::X:X|WORD)",
- CLEAR_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n")
-
-ALIAS (clear_ip_bgp_peer,
- clear_bgp_instance_peer_cmd,
- "clear bgp " BGP_INSTANCE_CMD " (A.B.C.D|X:X::X:X|WORD)",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor IP address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n")
-
-ALIAS (clear_ip_bgp_peer,
- clear_bgp_ipv6_peer_cmd,
- "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD)",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n")
-
-ALIAS (clear_ip_bgp_peer,
- clear_bgp_instance_ipv6_peer_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 (A.B.C.D|X:X::X:X|WORD)",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "BGP neighbor IP address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n")
-
-DEFUN (clear_ip_bgp_peer_group,
- clear_ip_bgp_peer_group_cmd,
- "clear ip bgp peer-group WORD",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n")
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], 0, 0, clear_group, BGP_CLEAR_SOFT_NONE, argv[2]);
-
- return bgp_clear_vty (vty, NULL, 0, 0, clear_group, BGP_CLEAR_SOFT_NONE, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_peer_group,
- clear_ip_bgp_instance_peer_group_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n")
-
-ALIAS (clear_ip_bgp_peer_group,
- clear_bgp_peer_group_cmd,
- "clear bgp peer-group WORD",
- CLEAR_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n")
-
-ALIAS (clear_ip_bgp_peer_group,
- clear_bgp_instance_peer_group_cmd,
- "clear bgp " BGP_INSTANCE_CMD " peer-group WORD",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n")
-
-ALIAS (clear_ip_bgp_peer_group,
- clear_bgp_ipv6_peer_group_cmd,
- "clear bgp ipv6 peer-group WORD",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n")
-
-ALIAS (clear_ip_bgp_peer_group,
- clear_bgp_instance_ipv6_peer_group_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 peer-group WORD",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n")
-
-DEFUN (clear_ip_bgp_external,
- clear_ip_bgp_external_cmd,
- "clear ip bgp external",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n")
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], 0, 0, clear_external, BGP_CLEAR_SOFT_NONE, NULL);
-
- return bgp_clear_vty (vty, NULL, 0, 0, clear_external, BGP_CLEAR_SOFT_NONE, NULL);
-}
-
-ALIAS (clear_ip_bgp_external,
- clear_ip_bgp_instance_external_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n")
-
-ALIAS (clear_ip_bgp_external,
- clear_bgp_external_cmd,
- "clear bgp external",
- CLEAR_STR
- BGP_STR
- "Clear all external peers\n")
-
-ALIAS (clear_ip_bgp_external,
- clear_bgp_instance_external_cmd,
- "clear bgp " BGP_INSTANCE_CMD " external",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n")
-
-ALIAS (clear_ip_bgp_external,
- clear_bgp_ipv6_external_cmd,
- "clear bgp ipv6 external",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all external peers\n")
-
-ALIAS (clear_ip_bgp_external,
- clear_bgp_instance_ipv6_external_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 external",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all external peers\n")
-
-DEFUN (clear_ip_bgp_prefix,
- clear_ip_bgp_prefix_cmd,
- "clear ip bgp prefix A.B.C.D/M",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear bestpath and re-advertise\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
-{
- if (argc == 3)
- return bgp_clear_prefix (vty, argv[1], argv[2], AFI_IP, SAFI_UNICAST, NULL);
-
- return bgp_clear_prefix (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL);
-}
-
-ALIAS (clear_ip_bgp_prefix,
- clear_ip_bgp_instance_prefix_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " prefix A.B.C.D/M",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear bestpath and re-advertise\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
-
-ALIAS (clear_ip_bgp_prefix,
- clear_bgp_prefix_cmd,
- "clear bgp prefix A.B.C.D/M",
- CLEAR_STR
- BGP_STR
- "Clear bestpath and re-advertise\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
-
-ALIAS (clear_ip_bgp_prefix,
- clear_bgp_instance_prefix_cmd,
- "clear bgp " BGP_INSTANCE_CMD " prefix A.B.C.D/M",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear bestpath and re-advertise\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
-
-DEFUN (clear_ip_bgp_as,
- clear_ip_bgp_as_cmd,
- "clear ip bgp " CMD_AS_RANGE,
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n")
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], 0, 0, clear_as, BGP_CLEAR_SOFT_NONE, argv[2]);
-
- return bgp_clear_vty (vty, NULL, 0, 0, clear_as, BGP_CLEAR_SOFT_NONE, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_as,
- clear_ip_bgp_instance_as_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE,
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n")
-
-ALIAS (clear_ip_bgp_as,
- clear_bgp_as_cmd,
- "clear bgp " CMD_AS_RANGE,
- CLEAR_STR
- BGP_STR
- "Clear peers with the AS number\n")
-
-ALIAS (clear_ip_bgp_as,
- clear_bgp_instance_as_cmd,
- "clear bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE,
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n")
-
-ALIAS (clear_ip_bgp_as,
- clear_bgp_ipv6_as_cmd,
- "clear bgp ipv6 " CMD_AS_RANGE,
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear peers with the AS number\n")
-
-ALIAS (clear_ip_bgp_as,
- clear_bgp_instance_ipv6_as_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 " CMD_AS_RANGE,
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear peers with the AS number\n")
-
-/* Outbound soft-reconfiguration */
-DEFUN (clear_ip_bgp_all_soft_out,
- clear_ip_bgp_all_soft_out_cmd,
- "clear ip bgp * soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_OUT, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_OUT, NULL);
-}
-
-ALIAS (clear_ip_bgp_all_soft_out,
- clear_ip_bgp_instance_all_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_all_soft_out,
- clear_ip_bgp_all_out_cmd,
- "clear ip bgp * out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_all_soft_out,
- clear_ip_bgp_instance_all_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_ip_bgp_all_ipv4_soft_out,
- clear_ip_bgp_all_ipv4_soft_out_cmd,
- "clear ip bgp * ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_all,
- BGP_CLEAR_SOFT_OUT, NULL);
-}
-
-DEFUN (clear_ip_bgp_instance_all_ipv4_soft_out,
- clear_ip_bgp_instance_all_ipv4_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[2]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_all,
- BGP_CLEAR_SOFT_OUT, NULL);
-}
-
-ALIAS (clear_ip_bgp_all_ipv4_soft_out,
- clear_ip_bgp_all_ipv4_out_cmd,
- "clear ip bgp * ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_instance_all_ipv4_soft_out,
- clear_ip_bgp_instance_all_ipv4_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_bgp_all_soft_out,
- clear_bgp_all_soft_out_cmd,
- "clear bgp * soft out",
- CLEAR_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_OUT, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_OUT, NULL);
-}
-
-ALIAS (clear_bgp_all_soft_out,
- clear_bgp_instance_all_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " * soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_all_soft_out,
- clear_bgp_all_out_cmd,
- "clear bgp * out",
- CLEAR_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_all_soft_out,
- clear_bgp_instance_all_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " * out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_all_soft_out,
- clear_bgp_ipv6_all_soft_out_cmd,
- "clear bgp ipv6 * soft out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_all_soft_out,
- clear_bgp_instance_ipv6_all_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 * soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_all_soft_out,
- clear_bgp_ipv6_all_out_cmd,
- "clear bgp ipv6 * out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_all_soft_out,
- clear_bgp_instance_ipv6_all_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 * out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
"Clear all peers\n"
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_bgp_ipv6_safi_prefix,
- clear_bgp_ipv6_safi_prefix_cmd,
- "clear bgp ipv6 "BGP_SAFI_CMD_STR" prefix X:X::X:X/M",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Address Family Modifier\n"
- "Clear bestpath and re-advertise\n"
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_clear_prefix (vty, NULL, argv[1], AFI_IP6, safi, NULL);
-}
-
-DEFUN (clear_bgp_instance_ipv6_safi_prefix,
- clear_bgp_instance_ipv6_safi_prefix_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 "BGP_SAFI_CMD_STR" prefix X:X::X:X/M",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Address Family Modifier\n"
- "Clear bestpath and re-advertise\n"
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[2]);
- return bgp_clear_prefix (vty, argv[1], argv[3], AFI_IP6, safi, NULL);
-}
-
-DEFUN (clear_ip_bgp_peer_soft_out,
- clear_ip_bgp_peer_soft_out_cmd,
- "clear ip bgp (A.B.C.D|WORD) soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_OUT, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_OUT, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_peer_soft_out,
- clear_ip_bgp_instance_peer_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_peer_soft_out,
- clear_ip_bgp_peer_out_cmd,
- "clear ip bgp (A.B.C.D|WORD) out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_peer_soft_out,
- clear_ip_bgp_instance_peer_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_ip_bgp_peer_ipv4_soft_out,
- clear_ip_bgp_peer_ipv4_soft_out_cmd,
- "clear ip bgp (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_peer,
- BGP_CLEAR_SOFT_OUT, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_instance_peer_ipv4_soft_out,
- clear_ip_bgp_instance_peer_ipv4_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_peer,
- BGP_CLEAR_SOFT_OUT, argv[2]);
-}
-
-ALIAS (clear_ip_bgp_peer_ipv4_soft_out,
- clear_ip_bgp_peer_ipv4_out_cmd,
- "clear ip bgp (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_instance_peer_ipv4_soft_out,
- clear_ip_bgp_instance_peer_ipv4_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_bgp_peer_soft_out,
- clear_bgp_peer_soft_out_cmd,
- "clear bgp (A.B.C.D|X:X::X:X|WORD) soft out",
- CLEAR_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_OUT, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_OUT, argv[0]);
-}
-
-ALIAS (clear_bgp_peer_soft_out,
- clear_bgp_instance_peer_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " (A.B.C.D|X:X::X:X|WORD) soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_soft_out,
- clear_bgp_ipv6_peer_soft_out_cmd,
- "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) soft out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
"BGP neighbor address to clear\n"
"BGP IPv6 neighbor to clear\n"
"BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_soft_out,
- clear_bgp_instance_ipv6_peer_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 (A.B.C.D|X:X::X:X|WORD) soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_soft_out,
- clear_bgp_peer_out_cmd,
- "clear bgp (A.B.C.D|X:X::X:X|WORD) out",
- CLEAR_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_soft_out,
- clear_bgp_instance_peer_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " (A.B.C.D|X:X::X:X|WORD) out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_soft_out,
- clear_bgp_ipv6_peer_out_cmd,
- "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_soft_out,
- clear_bgp_instance_ipv6_peer_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 (A.B.C.D|X:X::X:X|WORD) out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_ip_bgp_peer_group_soft_out,
- clear_ip_bgp_peer_group_soft_out_cmd,
- "clear ip bgp peer-group WORD soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_OUT, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_OUT, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_peer_group_soft_out,
- clear_ip_bgp_instance_peer_group_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_peer_group_soft_out,
- clear_ip_bgp_peer_group_out_cmd,
- "clear ip bgp peer-group WORD out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_peer_group_soft_out,
- clear_ip_bgp_instance_peer_group_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_ip_bgp_peer_group_ipv4_soft_out,
- clear_ip_bgp_peer_group_ipv4_soft_out_cmd,
- "clear ip bgp peer-group WORD ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_group,
- BGP_CLEAR_SOFT_OUT, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_instance_peer_group_ipv4_soft_out,
- clear_ip_bgp_instance_peer_group_ipv4_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_group,
- BGP_CLEAR_SOFT_OUT, argv[2]);
-}
-
-ALIAS (clear_ip_bgp_peer_group_ipv4_soft_out,
- clear_ip_bgp_peer_group_ipv4_out_cmd,
- "clear ip bgp peer-group WORD ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_instance_peer_group_ipv4_soft_out,
- clear_ip_bgp_instance_peer_group_ipv4_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_bgp_peer_group_soft_out,
- clear_bgp_peer_group_soft_out_cmd,
- "clear bgp peer-group WORD soft out",
- CLEAR_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_OUT, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_OUT, argv[0]);
-}
-
-ALIAS (clear_bgp_peer_group_soft_out,
- clear_bgp_instance_peer_group_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " peer-group WORD soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_group_soft_out,
- clear_bgp_ipv6_peer_group_soft_out_cmd,
- "clear bgp ipv6 peer-group WORD soft out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_group_soft_out,
- clear_bgp_instance_ipv6_peer_group_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 peer-group WORD soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_group_soft_out,
- clear_bgp_peer_group_out_cmd,
- "clear bgp peer-group WORD out",
- CLEAR_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_group_soft_out,
- clear_bgp_instance_peer_group_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " peer-group WORD out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_group_soft_out,
- clear_bgp_ipv6_peer_group_out_cmd,
- "clear bgp ipv6 peer-group WORD out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_peer_group_soft_out,
- clear_bgp_instance_ipv6_peer_group_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 peer-group WORD out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_ip_bgp_external_soft_out,
- clear_ip_bgp_external_soft_out_cmd,
- "clear ip bgp external soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_OUT, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_OUT, NULL);
-}
-
-ALIAS (clear_ip_bgp_external_soft_out,
- clear_ip_bgp_instance_external_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_external_soft_out,
- clear_ip_bgp_external_out_cmd,
- "clear ip bgp external out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_external_soft_out,
- clear_ip_bgp_instance_external_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_ip_bgp_external_ipv4_soft_out,
- clear_ip_bgp_external_ipv4_soft_out_cmd,
- "clear ip bgp external ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_external,
- BGP_CLEAR_SOFT_OUT, NULL);
-}
-
-DEFUN (clear_ip_bgp_instance_external_ipv4_soft_out,
- clear_ip_bgp_instance_external_ipv4_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[2]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_external,
- BGP_CLEAR_SOFT_OUT, NULL);
-}
-
-ALIAS (clear_ip_bgp_external_ipv4_soft_out,
- clear_ip_bgp_external_ipv4_out_cmd,
- "clear ip bgp external ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_instance_external_ipv4_soft_out,
- clear_ip_bgp_instance_external_ipv4_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_bgp_external_soft_out,
- clear_bgp_external_soft_out_cmd,
- "clear bgp external soft out",
- CLEAR_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_OUT, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_OUT, NULL);
-}
-
-ALIAS (clear_bgp_external_soft_out,
- clear_bgp_instance_external_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " external soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_external_soft_out,
- clear_bgp_ipv6_external_soft_out_cmd,
- "clear bgp ipv6 external soft out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_external_soft_out,
- clear_bgp_instance_ipv6_external_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 external soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_external_soft_out,
- clear_bgp_external_out_cmd,
- "clear bgp external out",
- CLEAR_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_external_soft_out,
- clear_bgp_instance_external_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " external out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_external_soft_out,
- clear_bgp_ipv6_external_out_cmd,
- "clear bgp ipv6 external WORD out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_external_soft_out,
- clear_bgp_instance_ipv6_external_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 external WORD out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_ip_bgp_as_soft_out,
- clear_ip_bgp_as_soft_out_cmd,
- "clear ip bgp " CMD_AS_RANGE " soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_OUT, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_OUT, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_as_soft_out,
- clear_ip_bgp_instance_as_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_as_soft_out,
- clear_ip_bgp_as_out_cmd,
- "clear ip bgp " CMD_AS_RANGE " out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_as_soft_out,
- clear_ip_bgp_instance_as_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_ip_bgp_as_ipv4_soft_out,
- clear_ip_bgp_as_ipv4_soft_out_cmd,
- "clear ip bgp " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_as,
- BGP_CLEAR_SOFT_OUT, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_instance_as_ipv4_soft_out,
- clear_ip_bgp_instance_as_ipv4_soft_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" soft out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_as,
- BGP_CLEAR_SOFT_OUT, argv[2]);
-}
-
-ALIAS (clear_ip_bgp_as_ipv4_soft_out,
- clear_ip_bgp_as_ipv4_out_cmd,
- "clear ip bgp " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_ip_bgp_instance_as_ipv4_soft_out,
- clear_ip_bgp_instance_as_ipv4_out_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" out",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_OUT_STR)
-
-DEFUN (clear_bgp_as_soft_out,
- clear_bgp_as_soft_out_cmd,
- "clear bgp " CMD_AS_RANGE " soft out",
- CLEAR_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_OUT, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_OUT, argv[0]);
-}
-
-ALIAS (clear_bgp_as_soft_out,
- clear_bgp_instance_as_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_as_soft_out,
- clear_bgp_ipv6_as_soft_out_cmd,
- "clear bgp ipv6 " CMD_AS_RANGE " soft out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_as_soft_out,
- clear_bgp_instance_ipv6_as_soft_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 " CMD_AS_RANGE " soft out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_as_soft_out,
- clear_bgp_as_out_cmd,
- "clear bgp " CMD_AS_RANGE " out",
- CLEAR_STR
- BGP_STR
"Clear peers with the AS number\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_as_soft_out,
- clear_bgp_instance_as_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_as_soft_out,
- clear_bgp_ipv6_as_out_cmd,
- "clear bgp ipv6 " CMD_AS_RANGE " out",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_OUT_STR)
-
-ALIAS (clear_bgp_as_soft_out,
- clear_bgp_instance_ipv6_as_out_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 " CMD_AS_RANGE " out",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_OUT_STR)
-
-/* Inbound soft-reconfiguration */
-DEFUN (clear_ip_bgp_all_soft_in,
- clear_ip_bgp_all_soft_in_cmd,
- "clear ip bgp * soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_IN, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_IN, NULL);
-}
-
-ALIAS (clear_ip_bgp_all_soft_in,
- clear_ip_bgp_instance_all_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_all_soft_in,
- clear_ip_bgp_all_in_cmd,
- "clear ip bgp * in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_all_soft_in,
- clear_ip_bgp_instance_all_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_all_in_prefix_filter,
- clear_ip_bgp_all_in_prefix_filter_cmd,
- "clear ip bgp * in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- if (argc== 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
-}
-
-DEFUN (clear_ip_bgp_all_ipv4_soft_in,
- clear_ip_bgp_all_ipv4_soft_in_cmd,
- "clear ip bgp * ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_all,
- BGP_CLEAR_SOFT_IN, NULL);
-}
-
-DEFUN (clear_ip_bgp_instance_all_ipv4_soft_in,
- clear_ip_bgp_instance_all_ipv4_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[2]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_all,
- BGP_CLEAR_SOFT_IN, NULL);
-}
-
-ALIAS (clear_ip_bgp_all_ipv4_soft_in,
- clear_ip_bgp_all_ipv4_in_cmd,
- "clear ip bgp * ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_instance_all_ipv4_soft_in,
- clear_ip_bgp_instance_all_ipv4_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_all_ipv4_in_prefix_filter,
- clear_ip_bgp_all_ipv4_in_prefix_filter_cmd,
- "clear ip bgp * ipv4 "BGP_SAFI_CMD_STR" in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_all,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
-}
-
-DEFUN (clear_bgp_all_soft_in,
- clear_bgp_all_soft_in_cmd,
- "clear bgp * soft in",
- CLEAR_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_IN, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_IN, NULL);
-}
-
-ALIAS (clear_bgp_all_soft_in,
- clear_bgp_instance_all_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " * soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_all_soft_in,
- clear_bgp_ipv6_all_soft_in_cmd,
- "clear bgp ipv6 * soft in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_all_soft_in,
- clear_bgp_instance_ipv6_all_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 * soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_all_soft_in,
- clear_bgp_all_in_cmd,
- "clear bgp * in",
- CLEAR_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_all_soft_in,
- clear_bgp_instance_all_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " * in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_all_soft_in,
- clear_bgp_ipv6_all_in_cmd,
- "clear bgp ipv6 * in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_all_soft_in,
- clear_bgp_instance_ipv6_all_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 * in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_bgp_all_in_prefix_filter,
- clear_bgp_all_in_prefix_filter_cmd,
- "clear bgp * in prefix-filter",
- CLEAR_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
-}
-
-ALIAS (clear_bgp_all_in_prefix_filter,
- clear_bgp_ipv6_all_in_prefix_filter_cmd,
- "clear bgp ipv6 * in prefix-filter",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-
-DEFUN (clear_ip_bgp_peer_soft_in,
- clear_ip_bgp_peer_soft_in_cmd,
- "clear ip bgp (A.B.C.D|WORD) soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_IN, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_IN, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_peer_soft_in,
- clear_ip_bgp_instance_peer_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_peer_soft_in,
- clear_ip_bgp_peer_in_cmd,
- "clear ip bgp (A.B.C.D|WORD) in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_peer_soft_in,
- clear_ip_bgp_instance_peer_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_peer_in_prefix_filter,
- clear_ip_bgp_peer_in_prefix_filter_cmd,
- "clear ip bgp (A.B.C.D|WORD) in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_IN_STR
- "Push out the existing ORF prefix-list\n")
-{
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_peer_ipv4_soft_in,
- clear_ip_bgp_peer_ipv4_soft_in_cmd,
- "clear ip bgp (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_peer,
- BGP_CLEAR_SOFT_IN, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_instance_peer_ipv4_soft_in,
- clear_ip_bgp_instance_peer_ipv4_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_peer,
- BGP_CLEAR_SOFT_IN, argv[2]);
-}
-
-ALIAS (clear_ip_bgp_peer_ipv4_soft_in,
- clear_ip_bgp_peer_ipv4_in_cmd,
- "clear ip bgp (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_instance_peer_ipv4_soft_in,
- clear_ip_bgp_instance_peer_ipv4_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_peer_ipv4_in_prefix_filter,
- clear_ip_bgp_peer_ipv4_in_prefix_filter_cmd,
- "clear ip bgp (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR
- "Push out the existing ORF prefix-list\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_peer,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
-}
-
-DEFUN (clear_bgp_peer_soft_in,
- clear_bgp_peer_soft_in_cmd,
- "clear bgp (A.B.C.D|X:X::X:X|WORD) soft in",
- CLEAR_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_IN, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_IN, argv[0]);
-}
-
-ALIAS (clear_bgp_peer_soft_in,
- clear_bgp_instance_peer_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " (A.B.C.D|X:X::X:X|WORD) soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_soft_in,
- clear_bgp_ipv6_peer_soft_in_cmd,
- "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) soft in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_soft_in,
- clear_bgp_instance_ipv6_peer_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 (A.B.C.D|X:X::X:X|WORD) soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_soft_in,
- clear_bgp_peer_in_cmd,
- "clear bgp (A.B.C.D|X:X::X:X|WORD) in",
- CLEAR_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_soft_in,
- clear_bgp_instance_peer_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " (A.B.C.D|X:X::X:X|WORD) in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_soft_in,
- clear_bgp_ipv6_peer_in_cmd,
- "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_soft_in,
- clear_bgp_instance_ipv6_peer_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 (A.B.C.D|X:X::X:X|WORD) in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_bgp_peer_in_prefix_filter,
- clear_bgp_peer_in_prefix_filter_cmd,
- "clear bgp (A.B.C.D|X:X::X:X|WORD) in prefix-filter",
- CLEAR_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_IN_STR
- "Push out the existing ORF prefix-list\n")
-{
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
-}
-
-ALIAS (clear_bgp_peer_in_prefix_filter,
- clear_bgp_ipv6_peer_in_prefix_filter_cmd,
- "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) in prefix-filter",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_IN_STR
- "Push out the existing ORF prefix-list\n")
-
-DEFUN (clear_ip_bgp_peer_group_soft_in,
- clear_ip_bgp_peer_group_soft_in_cmd,
- "clear ip bgp peer-group WORD soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_IN, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_IN, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_peer_group_soft_in,
- clear_ip_bgp_instance_peer_group_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_peer_group_soft_in,
- clear_ip_bgp_peer_group_in_cmd,
- "clear ip bgp peer-group WORD in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_peer_group_soft_in,
- clear_ip_bgp_instance_peer_group_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_peer_group_in_prefix_filter,
- clear_ip_bgp_peer_group_in_prefix_filter_cmd,
- "clear ip bgp peer-group WORD in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_peer_group_ipv4_soft_in,
- clear_ip_bgp_peer_group_ipv4_soft_in_cmd,
- "clear ip bgp peer-group WORD ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_group,
- BGP_CLEAR_SOFT_IN, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_instance_peer_group_ipv4_soft_in,
- clear_ip_bgp_instance_peer_group_ipv4_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_group,
- BGP_CLEAR_SOFT_IN, argv[2]);
-}
-
-ALIAS (clear_ip_bgp_peer_group_ipv4_soft_in,
- clear_ip_bgp_peer_group_ipv4_in_cmd,
- "clear ip bgp peer-group WORD ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_instance_peer_group_ipv4_soft_in,
- clear_ip_bgp_instance_peer_group_ipv4_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_peer_group_ipv4_in_prefix_filter,
- clear_ip_bgp_peer_group_ipv4_in_prefix_filter_cmd,
- "clear ip bgp peer-group WORD ipv4 "BGP_SAFI_CMD_STR" in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
+ "Clear all external peers\n"
"Clear all members of peer-group\n"
"BGP peer-group name\n"
- "Address family\n"
+ BGP_AFI_HELP_STR
BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_group,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
-}
-
-DEFUN (clear_bgp_peer_group_soft_in,
- clear_bgp_peer_group_soft_in_cmd,
- "clear bgp peer-group WORD soft in",
- CLEAR_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_IN, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_IN, argv[0]);
-}
-
-ALIAS (clear_bgp_peer_group_soft_in,
- clear_bgp_instance_peer_group_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " peer-group WORD soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_group_soft_in,
- clear_bgp_ipv6_peer_group_soft_in_cmd,
- "clear bgp ipv6 peer-group WORD soft in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_group_soft_in,
- clear_bgp_instance_ipv6_peer_group_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 peer-group WORD soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_group_soft_in,
- clear_bgp_peer_group_in_cmd,
- "clear bgp peer-group WORD in",
- CLEAR_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_group_soft_in,
- clear_bgp_instance_peer_group_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " peer-group WORD in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_group_soft_in,
- clear_bgp_ipv6_peer_group_in_cmd,
- "clear bgp ipv6 peer-group WORD in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_peer_group_soft_in,
- clear_bgp_instance_ipv6_peer_group_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 peer-group WORD in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_bgp_peer_group_in_prefix_filter,
- clear_bgp_peer_group_in_prefix_filter_cmd,
- "clear bgp peer-group WORD in prefix-filter",
- CLEAR_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
-}
-
-ALIAS (clear_bgp_peer_group_in_prefix_filter,
- clear_bgp_ipv6_peer_group_in_prefix_filter_cmd,
- "clear bgp ipv6 peer-group WORD in prefix-filter",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-
-DEFUN (clear_ip_bgp_external_soft_in,
- clear_ip_bgp_external_soft_in_cmd,
- "clear ip bgp external soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_IN, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_IN, NULL);
-}
-
-ALIAS (clear_ip_bgp_external_soft_in,
- clear_ip_bgp_instance_external_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_external_soft_in,
- clear_ip_bgp_external_in_cmd,
- "clear ip bgp external in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_external_soft_in,
- clear_ip_bgp_instance_external_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_external_in_prefix_filter,
- clear_ip_bgp_external_in_prefix_filter_cmd,
- "clear ip bgp external in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
-}
-
-DEFUN (clear_ip_bgp_external_ipv4_soft_in,
- clear_ip_bgp_external_ipv4_soft_in_cmd,
- "clear ip bgp external ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_external,
- BGP_CLEAR_SOFT_IN, NULL);
-}
-
-DEFUN (clear_ip_bgp_instance_external_ipv4_soft_in,
- clear_ip_bgp_instance_external_ipv4_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[2]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_external,
- BGP_CLEAR_SOFT_IN, NULL);
-}
-
-ALIAS (clear_ip_bgp_external_ipv4_soft_in,
- clear_ip_bgp_external_ipv4_in_cmd,
- "clear ip bgp external ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_instance_external_ipv4_soft_in,
- clear_ip_bgp_instance_external_ipv4_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_external_ipv4_in_prefix_filter,
- clear_ip_bgp_external_ipv4_in_prefix_filter_cmd,
- "clear ip bgp external ipv4 "BGP_SAFI_CMD_STR" in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_external,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
-}
-
-DEFUN (clear_bgp_external_soft_in,
- clear_bgp_external_soft_in_cmd,
- "clear bgp external soft in",
- CLEAR_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_IN, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_IN, NULL);
-}
-
-ALIAS (clear_bgp_external_soft_in,
- clear_bgp_instance_external_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " external soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_external_soft_in,
- clear_bgp_ipv6_external_soft_in_cmd,
- "clear bgp ipv6 external soft in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_external_soft_in,
- clear_bgp_instance_ipv6_external_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 external soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_external_soft_in,
- clear_bgp_external_in_cmd,
- "clear bgp external in",
- CLEAR_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_external_soft_in,
- clear_bgp_instance_external_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " external in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_external_soft_in,
- clear_bgp_ipv6_external_in_cmd,
- "clear bgp ipv6 external WORD in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_external_soft_in,
- clear_bgp_instance_ipv6_external_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 external WORD in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_bgp_external_in_prefix_filter,
- clear_bgp_external_in_prefix_filter_cmd,
- "clear bgp external in prefix-filter",
- CLEAR_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, NULL);
-}
-
-ALIAS (clear_bgp_external_in_prefix_filter,
- clear_bgp_ipv6_external_in_prefix_filter_cmd,
- "clear bgp ipv6 external in prefix-filter",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-
-DEFUN (clear_ip_bgp_as_soft_in,
- clear_ip_bgp_as_soft_in_cmd,
- "clear ip bgp " CMD_AS_RANGE " soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_IN, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_IN, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_as_soft_in,
- clear_ip_bgp_instance_as_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_as_soft_in,
- clear_ip_bgp_as_in_cmd,
- "clear ip bgp " CMD_AS_RANGE " in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_as_soft_in,
- clear_ip_bgp_instance_as_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_as_in_prefix_filter,
- clear_ip_bgp_as_in_prefix_filter_cmd,
- "clear ip bgp " CMD_AS_RANGE " in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_as_ipv4_soft_in,
- clear_ip_bgp_as_ipv4_soft_in_cmd,
- "clear ip bgp " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_as,
- BGP_CLEAR_SOFT_IN, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_instance_as_ipv4_soft_in,
- clear_ip_bgp_instance_as_ipv4_soft_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" soft in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_as,
- BGP_CLEAR_SOFT_IN, argv[2]);
-}
-
-ALIAS (clear_ip_bgp_as_ipv4_soft_in,
- clear_ip_bgp_as_ipv4_in_cmd,
- "clear ip bgp " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_ip_bgp_instance_as_ipv4_soft_in,
- clear_ip_bgp_instance_as_ipv4_in_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" in",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_ip_bgp_as_ipv4_in_prefix_filter,
- clear_ip_bgp_as_ipv4_in_prefix_filter_cmd,
- "clear ip bgp " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" in prefix-filter",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_as,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
-}
-
-DEFUN (clear_bgp_as_soft_in,
- clear_bgp_as_soft_in_cmd,
- "clear bgp " CMD_AS_RANGE " soft in",
- CLEAR_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_IN, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_IN, argv[0]);
-}
-
-ALIAS (clear_bgp_as_soft_in,
- clear_bgp_instance_as_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_as_soft_in,
- clear_bgp_ipv6_as_soft_in_cmd,
- "clear bgp ipv6 " CMD_AS_RANGE " soft in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_as_soft_in,
- clear_bgp_instance_ipv6_as_soft_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 " CMD_AS_RANGE " soft in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_STR
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_as_soft_in,
- clear_bgp_as_in_cmd,
- "clear bgp " CMD_AS_RANGE " in",
- CLEAR_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_as_soft_in,
- clear_bgp_instance_as_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_as_soft_in,
- clear_bgp_ipv6_as_in_cmd,
- "clear bgp ipv6 " CMD_AS_RANGE " in",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_IN_STR)
-
-ALIAS (clear_bgp_as_soft_in,
- clear_bgp_instance_ipv6_as_in_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 " CMD_AS_RANGE " in",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_IN_STR)
-
-DEFUN (clear_bgp_as_in_prefix_filter,
- clear_bgp_as_in_prefix_filter_cmd,
- "clear bgp " CMD_AS_RANGE " in prefix-filter",
- CLEAR_STR
- BGP_STR
- "Clear peers with the AS number\n"
BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-{
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX, argv[0]);
-}
-
-ALIAS (clear_bgp_as_in_prefix_filter,
- clear_bgp_ipv6_as_in_prefix_filter_cmd,
- "clear bgp ipv6 " CMD_AS_RANGE " in prefix-filter",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
+ BGP_SOFT_OUT_STR
BGP_SOFT_IN_STR
- "Push out prefix-list ORF and do inbound soft reconfig\n")
-
-/* Both soft-reconfiguration */
-DEFUN (clear_ip_bgp_all_soft,
- clear_ip_bgp_all_soft_cmd,
- "clear ip bgp * soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_BOTH, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_BOTH, NULL);
-}
-
-ALIAS (clear_ip_bgp_all_soft,
- clear_ip_bgp_instance_all_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_STR)
-
-
-DEFUN (clear_ip_bgp_all_ipv4_soft,
- clear_ip_bgp_all_ipv4_soft_cmd,
- "clear ip bgp * ipv4 "BGP_SAFI_CMD_STR" soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all peers\n"
- "Address family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- BGP_SOFT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_all,
- BGP_CLEAR_SOFT_BOTH, NULL);
-}
-
-DEFUN (clear_ip_bgp_instance_all_ipv4_soft,
- clear_ip_bgp_instance_all_ipv4_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " * ipv4 "BGP_SAFI_CMD_STR" soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- "Address family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- BGP_SOFT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[2]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_all,
- BGP_CLEAR_SOFT_BOTH, NULL);
-}
-
-DEFUN (clear_bgp_all_soft,
- clear_bgp_all_soft_cmd,
- "clear bgp * soft",
- CLEAR_STR
- BGP_STR
- "Clear all peers\n"
- BGP_SOFT_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_BOTH, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
- BGP_CLEAR_SOFT_BOTH, NULL);
-}
-
-ALIAS (clear_bgp_all_soft,
- clear_bgp_instance_all_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " * soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all peers\n"
- BGP_SOFT_STR)
-
-ALIAS (clear_bgp_all_soft,
- clear_bgp_ipv6_all_soft_cmd,
- "clear bgp ipv6 * soft",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_STR)
-
-ALIAS (clear_bgp_all_soft,
- clear_bgp_instance_ipv6_all_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 * soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all peers\n"
- BGP_SOFT_STR)
-
-DEFUN (clear_ip_bgp_peer_soft,
- clear_ip_bgp_peer_soft_cmd,
- "clear ip bgp (A.B.C.D|WORD) soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_BOTH, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_BOTH, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_peer_soft,
- clear_ip_bgp_instance_peer_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR)
-
-DEFUN (clear_ip_bgp_peer_ipv4_soft,
- clear_ip_bgp_peer_ipv4_soft_cmd,
- "clear ip bgp (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- BGP_SOFT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_peer,
- BGP_CLEAR_SOFT_BOTH, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_instance_peer_ipv4_soft,
- clear_ip_bgp_instance_peer_ipv4_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " (A.B.C.D|WORD) ipv4 "BGP_SAFI_CMD_STR" soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP neighbor on interface to clear\n"
- "Address family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- BGP_SOFT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_peer,
- BGP_CLEAR_SOFT_BOTH, argv[2]);
-}
-
-DEFUN (clear_bgp_peer_soft,
- clear_bgp_peer_soft_cmd,
- "clear bgp (A.B.C.D|X:X::X:X|WORD) soft",
- CLEAR_STR
- BGP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR)
+ "Push out prefix-list ORF and do inbound soft reconfig\n"
+ BGP_SOFT_OUT_STR)
{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_BOTH, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer,
- BGP_CLEAR_SOFT_BOTH, argv[0]);
-}
-
-ALIAS (clear_bgp_peer_soft,
- clear_bgp_instance_peer_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " (A.B.C.D|X:X::X:X|WORD) soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR)
-
-ALIAS (clear_bgp_peer_soft,
- clear_bgp_ipv6_peer_soft_cmd,
- "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) soft",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR)
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ char *vrf = NULL;
-ALIAS (clear_bgp_peer_soft,
- clear_bgp_instance_ipv6_peer_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 (A.B.C.D|X:X::X:X|WORD) soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "BGP neighbor address to clear\n"
- "BGP IPv6 neighbor to clear\n"
- "BGP neighbor on interface to clear\n"
- BGP_SOFT_STR)
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ enum clear_sort clr_sort = clear_peer;
+ enum bgp_clear_type clr_type;
+ char *clr_arg = NULL;
-DEFUN (clear_ip_bgp_peer_group_soft,
- clear_ip_bgp_peer_group_soft_cmd,
- "clear ip bgp peer-group WORD soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_BOTH, argv[2]);
+ int idx = 0;
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_BOTH, argv[0]);
-}
+ /* clear [ip] bgp */
+ if (argv_find (argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ /* [<view|vrf> WORD] */
+ if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
+ {
+ vrf = argv[idx + 1]->arg;
+ idx += 2;
+ }
+ /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> */
+ if (argv_find (argv, argc, "*", &idx))
+ {
+ clr_sort = clear_all;
+ }
+ else if (argv_find (argv, argc, "A.B.C.D", &idx))
+ {
+ clr_sort = clear_peer;
+ clr_arg = argv[idx]->arg;
+ }
+ else if (argv_find (argv, argc, "X:X::X:X", &idx))
+ {
+ clr_sort = clear_peer;
+ clr_arg = argv[idx]->arg;
+ }
+ else if (argv_find (argv, argc, "peer-group", &idx))
+ {
+ clr_sort = clear_group;
+ idx++;
+ clr_arg = argv[idx]->arg;
-ALIAS (clear_ip_bgp_peer_group_soft,
- clear_ip_bgp_instance_peer_group_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR)
+ if (! peer_group_lookup (bgp, clr_arg))
+ {
+ vty_out (vty, "%% No such peer-group%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else if (argv_find (argv, argc, "WORD", &idx))
+ {
+ if (peer_lookup_by_conf_if (bgp, argv[idx]->arg))
+ {
+ clr_sort = clear_peer;
+ clr_arg = argv[idx]->arg;
+ }
+ else
+ {
+ vty_out (vty, "%% No such neighbor%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ else if (argv_find (argv, argc, "(1-4294967295)", &idx))
+ {
+ clr_sort = clear_as;
+ clr_arg = argv[idx]->arg;
+ }
+ else if (argv_find (argv, argc, "external", &idx))
+ {
+ clr_sort = clear_external;
+ }
+ /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
+ if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
+ {
+ argv_find_and_parse_safi (argv, argc, &idx, &safi);
+ }
+ /* [<soft [<in|out>]|in [prefix-filter]|out>] */
+ if (argv_find (argv, argc, "soft", &idx))
+ {
+ if (argv_find (argv, argc, "in", &idx) || argv_find (argv, argc, "out", &idx))
+ clr_type = strmatch (argv[idx]->text, "in") ? BGP_CLEAR_SOFT_IN : BGP_CLEAR_SOFT_OUT;
+ else
+ clr_type = BGP_CLEAR_SOFT_BOTH;
+ }
+ else if (argv_find (argv, argc, "in", &idx))
+ {
+ clr_type = argv_find (argv, argc, "prefix-filter", &idx) ? BGP_CLEAR_SOFT_IN_ORF_PREFIX : BGP_CLEAR_SOFT_IN;
+ }
+ else if (argv_find (argv, argc, "out", &idx))
+ {
+ clr_type = BGP_CLEAR_SOFT_OUT;
+ }
+ else
+ clr_type = BGP_CLEAR_SOFT_NONE;
-DEFUN (clear_ip_bgp_peer_group_ipv4_soft,
- clear_ip_bgp_peer_group_ipv4_soft_cmd,
- "clear ip bgp peer-group WORD ipv4 "BGP_SAFI_CMD_STR" soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_group,
- BGP_CLEAR_SOFT_BOTH, argv[0]);
+ return bgp_clear_vty (vty, vrf, afi, safi, clr_sort, clr_type, clr_arg);
}
-DEFUN (clear_ip_bgp_instance_peer_group_ipv4_soft,
- clear_ip_bgp_instance_peer_group_ipv4_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " peer-group WORD ipv4 "BGP_SAFI_CMD_STR" soft",
+DEFUN (clear_ip_bgp_prefix,
+ clear_ip_bgp_prefix_cmd,
+ "clear [ip] bgp [<view|vrf> WORD] prefix A.B.C.D/M",
CLEAR_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- BGP_SOFT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_group,
- BGP_CLEAR_SOFT_BOTH, argv[2]);
-}
-
-DEFUN (clear_bgp_peer_group_soft,
- clear_bgp_peer_group_soft_cmd,
- "clear bgp peer-group WORD soft",
- CLEAR_STR
- BGP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR)
+ "Clear bestpath and re-advertise\n"
+ "IPv4 prefix\n")
{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_BOTH, argv[2]);
+ char *vrf = NULL;
+ char *prefix = NULL;
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_group,
- BGP_CLEAR_SOFT_BOTH, argv[0]);
-}
-
-ALIAS (clear_bgp_peer_group_soft,
- clear_bgp_instance_peer_group_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " peer-group WORD soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR)
-
-ALIAS (clear_bgp_peer_group_soft,
- clear_bgp_ipv6_peer_group_soft_cmd,
- "clear bgp ipv6 peer-group WORD soft",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR)
+ int idx = 0;
-ALIAS (clear_bgp_peer_group_soft,
- clear_bgp_instance_ipv6_peer_group_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 peer-group WORD soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all members of peer-group\n"
- "BGP peer-group name\n"
- BGP_SOFT_STR)
+ /* [<view|vrf> WORD] */
+ if (argv_find (argv, argc, "WORD", &idx))
+ vrf = argv[idx]->arg;
-DEFUN (clear_ip_bgp_external_soft,
- clear_ip_bgp_external_soft_cmd,
- "clear ip bgp external soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_BOTH, NULL);
+ prefix = argv[argc-1]->arg;
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_BOTH, NULL);
+ return bgp_clear_prefix (vty, vrf, prefix, AFI_IP, SAFI_UNICAST, NULL);
}
-ALIAS (clear_ip_bgp_external_soft,
- clear_ip_bgp_instance_external_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR)
-
-DEFUN (clear_ip_bgp_external_ipv4_soft,
- clear_ip_bgp_external_ipv4_soft_cmd,
- "clear ip bgp external ipv4 "BGP_SAFI_CMD_STR" soft",
+DEFUN (clear_bgp_ipv6_safi_prefix,
+ clear_bgp_ipv6_safi_prefix_cmd,
+ "clear [ip] bgp ipv6 "BGP_SAFI_CMD_STR" prefix X:X::X:X/M",
CLEAR_STR
IP_STR
BGP_STR
- "Clear all external peers\n"
- "Address family\n"
+ "Address Family\n"
BGP_SAFI_HELP_STR
- BGP_SOFT_STR)
+ "Clear bestpath and re-advertise\n"
+ "IPv6 prefix\n")
{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[0]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_external,
- BGP_CLEAR_SOFT_BOTH, NULL);
+ int idx_safi = 3;
+ int idx_ipv6_prefixlen = 5;
+ return bgp_clear_prefix (vty, NULL, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
+ bgp_vty_safi_from_arg(argv[idx_safi]->arg), NULL);
}
-DEFUN (clear_ip_bgp_instance_external_ipv4_soft,
- clear_ip_bgp_instance_external_ipv4_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " external ipv4 "BGP_SAFI_CMD_STR" soft",
+DEFUN (clear_bgp_instance_ipv6_safi_prefix,
+ clear_bgp_instance_ipv6_safi_prefix_cmd,
+ "clear [ip] bgp <view|vrf> WORD ipv6 "BGP_SAFI_CMD_STR" prefix X:X::X:X/M",
CLEAR_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- "Address family\n"
+ "Address Family\n"
BGP_SAFI_HELP_STR
- BGP_SOFT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[2]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_external,
- BGP_CLEAR_SOFT_BOTH, NULL);
-}
-
-DEFUN (clear_bgp_external_soft,
- clear_bgp_external_soft_cmd,
- "clear bgp external soft",
- CLEAR_STR
- BGP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR)
-{
- if (argc == 2)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_BOTH, NULL);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_external,
- BGP_CLEAR_SOFT_BOTH, NULL);
-}
-
-ALIAS (clear_bgp_external_soft,
- clear_bgp_instance_external_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " external soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear all external peers\n"
- BGP_SOFT_STR)
-
-ALIAS (clear_bgp_external_soft,
- clear_bgp_ipv6_external_soft_cmd,
- "clear bgp ipv6 external soft",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_STR)
-
-ALIAS (clear_bgp_external_soft,
- clear_bgp_instance_ipv6_external_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 external soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear all external peers\n"
- BGP_SOFT_STR)
-
-DEFUN (clear_ip_bgp_as_soft,
- clear_ip_bgp_as_soft_cmd,
- "clear ip bgp " CMD_AS_RANGE " soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR)
-{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_BOTH, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_BOTH, argv[0]);
-}
-
-ALIAS (clear_ip_bgp_as_soft,
- clear_ip_bgp_instance_as_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR)
-
-DEFUN (clear_ip_bgp_as_ipv4_soft,
- clear_ip_bgp_as_ipv4_soft_cmd,
- "clear ip bgp " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- BGP_SOFT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_clear_vty (vty, NULL, AFI_IP, safi, clear_as,
- BGP_CLEAR_SOFT_BOTH, argv[0]);
-}
-
-DEFUN (clear_ip_bgp_instance_as_ipv4_soft,
- clear_ip_bgp_instance_as_ipv4_soft_cmd,
- "clear ip bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " ipv4 "BGP_SAFI_CMD_STR" soft",
- CLEAR_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- "Address family\n"
- "Address Family Modifier\n"
- "Address Family Modifier\n"
- BGP_SOFT_STR)
-{
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[3]);
- return bgp_clear_vty (vty, argv[1], AFI_IP, safi, clear_as,
- BGP_CLEAR_SOFT_BOTH, argv[2]);
-}
-
-DEFUN (clear_bgp_as_soft,
- clear_bgp_as_soft_cmd,
- "clear bgp " CMD_AS_RANGE " soft",
- CLEAR_STR
- BGP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR)
+ "Clear bestpath and re-advertise\n"
+ "IPv6 prefix\n")
{
- if (argc == 3)
- return bgp_clear_vty (vty, argv[1], AFI_IP6, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_BOTH, argv[2]);
-
- return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_as,
- BGP_CLEAR_SOFT_BOTH, argv[0]);
+ int idx_word = 3;
+ int idx_safi = 5;
+ int idx_ipv6_prefixlen = 7;
+ return bgp_clear_prefix (vty, argv[idx_word]->arg, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
+ bgp_vty_safi_from_arg(argv[idx_safi]->arg), NULL);
}
-ALIAS (clear_bgp_as_soft,
- clear_bgp_instance_as_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " " CMD_AS_RANGE " soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Clear peers with the AS number\n"
- BGP_SOFT_STR)
-
-ALIAS (clear_bgp_as_soft,
- clear_bgp_ipv6_as_soft_cmd,
- "clear bgp ipv6 " CMD_AS_RANGE " soft",
- CLEAR_STR
- BGP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_STR)
-
-ALIAS (clear_bgp_as_soft,
- clear_bgp_instance_ipv6_as_soft_cmd,
- "clear bgp " BGP_INSTANCE_CMD " ipv6 " CMD_AS_RANGE " soft",
- CLEAR_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Clear peers with the AS number\n"
- BGP_SOFT_STR)
-
DEFUN (show_bgp_views,
show_bgp_views_cmd,
- "show bgp views",
+ "show [ip] bgp views",
SHOW_STR
+ IP_STR
BGP_STR
"Show the defined BGP views\n")
{
@@ -9505,7 +5991,7 @@ DEFUN (show_bgp_views,
vty_out (vty, "BGP Multiple Instance is not enabled%s", VTY_NEWLINE);
return CMD_WARNING;
}
-
+
vty_out (vty, "Defined BGP views:%s", VTY_NEWLINE);
for (ALL_LIST_ELEMENTS_RO(inst, node, bgp))
{
@@ -9516,17 +6002,18 @@ DEFUN (show_bgp_views,
bgp->name ? bgp->name : "(null)",
bgp->as, VTY_NEWLINE);
}
-
+
return CMD_SUCCESS;
}
DEFUN (show_bgp_vrfs,
show_bgp_vrfs_cmd,
- "show bgp vrfs {json}",
+ "show [ip] bgp vrfs [json]",
SHOW_STR
+ IP_STR
BGP_STR
"Show BGP VRFs\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct list *inst = bm->bgp;
struct listnode *node;
@@ -9628,23 +6115,24 @@ DEFUN (show_bgp_vrfs,
return CMD_SUCCESS;
}
-DEFUN (show_bgp_memory,
+DEFUN (show_bgp_memory,
show_bgp_memory_cmd,
- "show bgp memory",
+ "show [ip] bgp memory",
SHOW_STR
+ IP_STR
BGP_STR
"Global BGP memory statistics\n")
{
char memstrbuf[MTYPE_MEMSTR_LEN];
unsigned long count;
-
+
/* RIB related usage stats */
count = mtype_stats_alloc (MTYPE_BGP_NODE);
vty_out (vty, "%ld RIB nodes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct bgp_node)),
VTY_NEWLINE);
-
+
count = mtype_stats_alloc (MTYPE_BGP_ROUTE);
vty_out (vty, "%ld BGP routes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
@@ -9655,7 +6143,7 @@ DEFUN (show_bgp_memory,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct bgp_info_extra)),
VTY_NEWLINE);
-
+
if ((count = mtype_stats_alloc (MTYPE_BGP_STATIC)))
vty_out (vty, "%ld Static routes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
@@ -9667,7 +6155,7 @@ DEFUN (show_bgp_memory,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct bpacket)),
VTY_NEWLINE);
-
+
/* Adj-In/Out */
if ((count = mtype_stats_alloc (MTYPE_BGP_ADJ_IN)))
vty_out (vty, "%ld Adj-In entries, using %s of memory%s", count,
@@ -9679,7 +6167,7 @@ DEFUN (show_bgp_memory,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct bgp_adj_out)),
VTY_NEWLINE);
-
+
if ((count = mtype_stats_alloc (MTYPE_BGP_NEXTHOP_CACHE)))
vty_out (vty, "%ld Nexthop cache entries, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
@@ -9694,32 +6182,32 @@ DEFUN (show_bgp_memory,
/* Attributes */
count = attr_count();
- vty_out (vty, "%ld BGP attributes, using %s of memory%s", count,
- mtype_memstr (memstrbuf, sizeof (memstrbuf),
- count * sizeof(struct attr)),
+ vty_out (vty, "%ld BGP attributes, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof(struct attr)),
VTY_NEWLINE);
if ((count = mtype_stats_alloc (MTYPE_ATTR_EXTRA)))
- vty_out (vty, "%ld BGP extra attributes, using %s of memory%s", count,
- mtype_memstr (memstrbuf, sizeof (memstrbuf),
- count * sizeof(struct attr_extra)),
+ vty_out (vty, "%ld BGP extra attributes, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof(struct attr_extra)),
VTY_NEWLINE);
-
+
if ((count = attr_unknown_count()))
vty_out (vty, "%ld unknown attributes%s", count, VTY_NEWLINE);
-
+
/* AS_PATH attributes */
count = aspath_count ();
vty_out (vty, "%ld BGP AS-PATH entries, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct aspath)),
VTY_NEWLINE);
-
+
count = mtype_stats_alloc (MTYPE_AS_SEG);
vty_out (vty, "%ld BGP AS-PATH segments, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct assegment)),
VTY_NEWLINE);
-
+
/* Other attributes */
if ((count = community_count ()))
vty_out (vty, "%ld BGP community entries, using %s of memory%s", count,
@@ -9731,26 +6219,32 @@ DEFUN (show_bgp_memory,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct ecommunity)),
VTY_NEWLINE);
-
+ if ((count = mtype_stats_alloc (MTYPE_LCOMMUNITY)))
+ vty_out (vty, "%ld BGP large-community entries, using %s of memory%s",
+ count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct lcommunity)),
+ VTY_NEWLINE);
+
if ((count = mtype_stats_alloc (MTYPE_CLUSTER)))
vty_out (vty, "%ld Cluster lists, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct cluster_list)),
VTY_NEWLINE);
-
+
/* Peer related usage */
count = mtype_stats_alloc (MTYPE_BGP_PEER);
vty_out (vty, "%ld peers, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct peer)),
VTY_NEWLINE);
-
+
if ((count = mtype_stats_alloc (MTYPE_PEER_GROUP)))
vty_out (vty, "%ld peer groups, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct peer_group)),
VTY_NEWLINE);
-
+
/* Other */
if ((count = mtype_stats_alloc (MTYPE_HASH)))
vty_out (vty, "%ld hash tables, using %s of memory%s", count,
@@ -9987,7 +6481,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
vty_out (vty, "V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd%s", VTY_NEWLINE);
}
}
-
+
count++;
if (use_json)
@@ -10046,10 +6540,10 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
}
if (peer->hostname && bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME))
- len = vty_out (vty, "%s%s(%s) ", dn_flag, peer->hostname,
+ len = vty_out (vty, "%s%s(%s)", dn_flag, peer->hostname,
peer->host);
else
- len = vty_out (vty, "%s%s ", dn_flag, peer->host);
+ len = vty_out (vty, "%s%s", dn_flag, peer->host);
/* pad the neighbor column with spaces */
if (len < max_neighbor_width)
@@ -10159,11 +6653,9 @@ bgp_show_summary_afi_safi (struct vty *vty, struct bgp *bgp, int afi, int safi,
}
}
bgp_show_summary (vty, bgp, afi, safi, use_json, json);
- if (safi == SAFI_MPLS_VPN) /* handle special cases to match zebra.h */
- safi = SAFI_ENCAP;
- else
- safi++;
- if (safi == SAFI_RESERVED_3) /* handle special cases to match zebra.h */
+ safi++;
+ if (safi == SAFI_RESERVED_4 ||
+ safi == SAFI_RESERVED_5) /* handle special cases to match zebra.h */
safi++;
if (! safi_wildcard)
safi = SAFI_MAX;
@@ -10179,34 +6671,6 @@ bgp_show_summary_afi_safi (struct vty *vty, struct bgp *bgp, int afi, int safi,
}
-static int
-bgp_show_summary_vty (struct vty *vty, const char *name,
- afi_t afi, safi_t safi, u_char use_json)
-{
- struct bgp *bgp;
-
- if (name)
- {
- bgp = bgp_lookup_by_name (name);
-
- if (! bgp)
- {
- vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- bgp_show_summary_afi_safi (vty, bgp, afi, safi, use_json, NULL);
- return CMD_SUCCESS;
- }
-
- bgp = bgp_get_default ();
-
- if (bgp)
- bgp_show_summary_afi_safi (vty, bgp, afi, safi, use_json, NULL);
-
- return CMD_SUCCESS;
-}
-
static void
bgp_show_all_instances_summary_vty (struct vty *vty, afi_t afi, safi_t safi,
u_char use_json)
@@ -10223,14 +6687,7 @@ bgp_show_all_instances_summary_vty (struct vty *vty, afi_t afi, safi_t safi,
{
if (use_json)
{
- if (!(json = json_object_new_object()))
- {
- zlog_err("Unable to allocate memory for JSON object");
- vty_out (vty,
- "{\"error\": {\"message:\": \"Unable to allocate memory for JSON object\"}}}%s",
- VTY_NEWLINE);
- return;
- }
+ json = json_object_new_object();
if (! is_first)
vty_out (vty, ",%s", VTY_NEWLINE);
@@ -10255,276 +6712,79 @@ bgp_show_all_instances_summary_vty (struct vty *vty, afi_t afi, safi_t safi,
}
-/* `show ip bgp summary' commands. */
-DEFUN (show_ip_bgp_summary,
- show_ip_bgp_summary_cmd,
- "show ip bgp summary {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- return bgp_show_summary_vty (vty, NULL, AFI_IP, SAFI_UNICAST, uj);
-}
-
-DEFUN (show_ip_bgp_instance_summary,
- show_ip_bgp_instance_summary_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " summary {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- return bgp_show_summary_vty (vty, argv[1], AFI_IP, SAFI_UNICAST, uj);
-}
-
-DEFUN (show_ip_bgp_instance_all_summary,
- show_ip_bgp_instance_all_summary_cmd,
- "show ip bgp " BGP_INSTANCE_ALL_CMD " summary {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_ALL_HELP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
-
- bgp_show_all_instances_summary_vty (vty, AFI_IP, SAFI_UNICAST, uj);
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_bgp_ipv4_summary,
- show_ip_bgp_ipv4_summary_cmd,
- "show ip bgp ipv4 "BGP_SAFI_CMD_STR" summary {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- BGP_SAFI_HELP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
+static int
+bgp_show_summary_vty (struct vty *vty, const char *name,
+ afi_t afi, safi_t safi, u_char use_json)
{
- u_char uj = use_json(argc, argv);
-
- return bgp_show_summary_vty (vty, NULL, AFI_IP, bgp_vty_safi_from_arg(argv[0]), uj);
-}
-
-ALIAS (show_ip_bgp_ipv4_summary,
- show_bgp_ipv4_safi_summary_cmd,
- "show bgp ipv4 "BGP_SAFI_CMD_STR" summary {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- BGP_SAFI_HELP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
+ struct bgp *bgp;
-DEFUN (show_ip_bgp_instance_ipv4_summary,
- show_ip_bgp_instance_ipv4_summary_cmd,
- "show ip bgp view WORD ipv4 "BGP_SAFI_CMD_STR" summary {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Address family\n"
- BGP_SAFI_HELP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[1]);
- return bgp_show_summary_vty (vty, argv[0], AFI_IP, safi, uj);
-}
+ if (name)
+ {
+ if (strmatch(name, "all"))
+ {
+ bgp_show_all_instances_summary_vty (vty, afi, safi, use_json);
+ return CMD_SUCCESS;
+ }
+ else
+ {
+ bgp = bgp_lookup_by_name (name);
-ALIAS (show_ip_bgp_instance_ipv4_summary,
- show_bgp_instance_ipv4_safi_summary_cmd,
- "show bgp view WORD ipv4 "BGP_SAFI_CMD_STR" summary {json}",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- BGP_AFI_SAFI_HELP_STR
- "Summary of BGP neighbor status\n")
+ if (! bgp)
+ {
+ if (use_json)
+ vty_out (vty, "{}%s", VTY_NEWLINE);
+ else
+ vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
-DEFUN (show_bgp_summary,
- show_bgp_summary_cmd,
- "show bgp summary {json}",
- SHOW_STR
- BGP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_summary_vty (vty, NULL, AFI_MAX, SAFI_MAX, use_json(argc, argv));
-}
+ bgp_show_summary_afi_safi (vty, bgp, afi, safi, use_json, NULL);
+ return CMD_SUCCESS;
+ }
+ }
-DEFUN (show_bgp_instance_summary,
- show_bgp_instance_summary_cmd,
- "show bgp " BGP_INSTANCE_CMD " summary {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_summary_vty (vty, argv[1], AFI_MAX, SAFI_MAX, use_json(argc, argv));
-}
+ bgp = bgp_get_default ();
-DEFUN (show_bgp_instance_all_summary,
- show_bgp_instance_all_summary_cmd,
- "show bgp " BGP_INSTANCE_ALL_CMD " summary {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_ALL_HELP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
+ if (bgp)
+ bgp_show_summary_afi_safi (vty, bgp, afi, safi, use_json, NULL);
- bgp_show_all_instances_summary_vty (vty, AFI_MAX, SAFI_MAX, uj);
return CMD_SUCCESS;
}
-DEFUN (show_bgp_ipv4_summary,
- show_bgp_ipv4_summary_cmd,
- "show bgp ipv4 summary {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_summary_vty (vty, NULL, AFI_IP, SAFI_MAX, use_json(argc, argv));
-}
-
-DEFUN (show_bgp_instance_ipv4_summary,
- show_bgp_instance_ipv4_summary_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv4 summary {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_summary_vty (vty, argv[1], AFI_IP, SAFI_MAX, use_json(argc, argv));
-}
-
-DEFUN (show_bgp_instance_ipv4_all_summary,
- show_bgp_instance_ipv4_all_summary_cmd,
- "show bgp " BGP_INSTANCE_ALL_CMD " ipv4 summary {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_ALL_HELP_STR
- "Address family\n"
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_summary_vty (vty, argv[1], AFI_IP, SAFI_MAX, use_json(argc, argv));
-}
-
-DEFUN (show_bgp_ipv6_summary,
- show_bgp_ipv6_summary_cmd,
- "show bgp ipv6 summary {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_summary_vty (vty, NULL, AFI_IP6, SAFI_MAX, use_json(argc, argv));
-}
-
-DEFUN (show_bgp_instance_ipv6_summary,
- show_bgp_instance_ipv6_summary_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 summary {json}",
+/* `show [ip] bgp summary' commands. */
+DEFUN (show_ip_bgp_summary,
+ show_ip_bgp_summary_cmd,
+ "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] summary [json]",
SHOW_STR
+ IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_summary_vty (vty, argv[1], AFI_IP6, SAFI_MAX, use_json(argc, argv));
-}
-
-DEFUN (show_bgp_instance_ipv6_all_summary,
- show_bgp_instance_ipv6_all_summary_cmd,
- "show bgp " BGP_INSTANCE_ALL_CMD " ipv6 summary {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_ALL_HELP_STR
- "Address family\n"
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- return bgp_show_summary_vty (vty, argv[1], AFI_IP6, SAFI_MAX, use_json(argc, argv));
-}
-
-DEFUN (show_bgp_ipv6_safi_summary,
- show_bgp_ipv6_safi_summary_cmd,
- "show bgp ipv6 "BGP_SAFI_CMD_STR" summary {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
+ BGP_AFI_HELP_STR
BGP_SAFI_HELP_STR
"Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
- u_char uj = use_json(argc, argv);
+ char *vrf = NULL;
+ afi_t afi = AFI_MAX;
+ safi_t safi = SAFI_MAX;
- return bgp_show_summary_vty (vty, NULL, AFI_IP6, bgp_vty_safi_from_arg(argv[0]), uj);
-}
+ int idx = 0;
-DEFUN (show_bgp_instance_ipv6_safi_summary,
- show_bgp_instance_ipv6_safi_summary_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 "BGP_SAFI_CMD_STR" summary {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- BGP_AFI_SAFI_HELP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- safi_t safi;
- safi = bgp_vty_safi_from_arg(argv[2]);
- return bgp_show_summary_vty (vty, argv[1], AFI_IP6, safi, uj);
-}
+ /* show [ip] bgp */
+ if (argv_find (argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ /* [<view|vrf> WORD] */
+ if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
+ vrf = argv[++idx]->arg;
+ /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
+ if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
+ {
+ argv_find_and_parse_safi (argv, argc, &idx, &safi);
+ }
-/* old command */
-DEFUN (show_ipv6_bgp_summary,
- show_ipv6_bgp_summary_cmd,
- "show ipv6 bgp summary {json}",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- return bgp_show_summary_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, uj);
-}
+ int uj = use_json (argc, argv);
-/* old command */
-DEFUN (show_ipv6_mbgp_summary,
- show_ipv6_mbgp_summary_cmd,
- "show ipv6 mbgp summary {json}",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Summary of BGP neighbor status\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
- return bgp_show_summary_vty (vty, NULL, AFI_IP6, SAFI_MULTICAST, uj);
+ return bgp_show_summary_vty (vty, vrf, afi, safi, uj);
}
const char *
@@ -10942,12 +7202,16 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi,
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
vty_out (vty, " MED is propagated unchanged to this neighbor%s", VTY_NEWLINE);
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
- || CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY))
+ || CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)
+ || CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY))
{
vty_out (vty, " Community attribute sent to this neighbor");
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
- && CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY))
- vty_out (vty, "(both)%s", VTY_NEWLINE);
+ && CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)
+ && CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY))
+ vty_out (vty, "(all)%s", VTY_NEWLINE);
+ else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY))
+ vty_out (vty, "(large)%s", VTY_NEWLINE);
else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY))
vty_out (vty, "(extended)%s", VTY_NEWLINE);
else
@@ -11073,6 +7337,10 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
if (use_json)
json_neigh = json_object_new_object();
+ memset (dn_flag, '\0', sizeof (dn_flag));
+ if (!p->conf_if && peer_dynamic_neighbor (p))
+ dn_flag[0] = '*';
+
if (!use_json)
{
if (p->conf_if) /* Configured interface name. */
@@ -11080,13 +7348,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
BGP_PEER_SU_UNSPEC(p) ? "None" :
sockunion2str (&p->su, buf, SU_ADDRSTRLEN));
else /* Configured IP address. */
- {
- memset(dn_flag, '\0', sizeof(dn_flag));
- if (peer_dynamic_neighbor(p))
- dn_flag[0] = '*';
-
- vty_out (vty, "BGP neighbor is %s%s, ", dn_flag, p->host);
- }
+ vty_out (vty, "BGP neighbor is %s%s, ", dn_flag, p->host);
}
if (use_json)
@@ -11240,7 +7502,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
/* BGP Version. */
json_object_int_add(json_neigh, "bgpVersion", 4);
- json_object_string_add(json_neigh, "remoteRouterId", inet_ntop (AF_INET, &p->remote_id, buf1, BUFSIZ));
+ json_object_string_add(json_neigh, "remoteRouterId",
+ inet_ntop (AF_INET, &p->remote_id, buf1, sizeof(buf1)));
/* Confederation */
if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION) && bgp_confederation_peers_check (bgp, p->as))
@@ -11307,14 +7570,15 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
/* BGP Version. */
vty_out (vty, " BGP version 4");
- vty_out (vty, ", remote router ID %s%s", inet_ntop (AF_INET, &p->remote_id, buf1, BUFSIZ),
+ vty_out (vty, ", remote router ID %s%s",
+ inet_ntop (AF_INET, &p->remote_id, buf1, sizeof(buf1)),
VTY_NEWLINE);
/* Confederation */
if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION)
&& bgp_confederation_peers_check (bgp, p->as))
vty_out (vty, " Neighbor under common administration%s", VTY_NEWLINE);
-
+
/* Status. */
vty_out (vty, " BGP state = %s", LOOKUP (bgp_status_msg, p->status));
@@ -11346,7 +7610,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
}
}
/* Capability. */
- if (p->status == Established)
+ if (p->status == Established)
{
if (p->cap
|| p->afc_adv[AFI_IP][SAFI_UNICAST]
@@ -11563,7 +7827,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
}
if (! restart_af_count)
{
- json_object_string_add(json_cap, "addressFamiliesByPeer", "none");
+ json_object_string_add(json_cap, "addressFamiliesByPeer", "none");
json_object_free(json_restart);
}
else
@@ -11687,7 +7951,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
if (p->afc_adv[afi][safi] || p->afc_recv[afi][safi])
{
- vty_out (vty, " Address family %s:", afi_safi_print (afi, safi));
+ vty_out (vty, " Address Family %s:", afi_safi_print (afi, safi));
if (p->afc_adv[afi][safi])
vty_out (vty, " advertised");
if (p->afc_recv[afi][safi])
@@ -11839,7 +8103,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
if (p->t_gr_restart)
vty_out (vty, " The remaining time of restart timer is %ld%s",
thread_timer_remain_second (p->t_gr_restart), VTY_NEWLINE);
-
+
if (p->t_gr_stale)
vty_out (vty, " The remaining time of stalepath timer is %ld%s",
thread_timer_remain_second (p->t_gr_stale), VTY_NEWLINE);
@@ -12096,7 +8360,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
ntohs (p->su_local->sin.sin_port),
VTY_NEWLINE);
}
-
+
/* Remote address. */
if (p->su_remote)
{
@@ -12117,9 +8381,12 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
{
if (use_json)
{
- json_object_string_add(json_neigh, "nexthop", inet_ntop (AF_INET, &p->nexthop.v4, buf1, BUFSIZ));
- json_object_string_add(json_neigh, "nexthopGlobal", inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, BUFSIZ));
- json_object_string_add(json_neigh, "nexthopLocal", inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, BUFSIZ));
+ json_object_string_add(json_neigh, "nexthop",
+ inet_ntop (AF_INET, &p->nexthop.v4, buf1, sizeof(buf1)));
+ json_object_string_add(json_neigh, "nexthopGlobal",
+ inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, sizeof(buf1)));
+ json_object_string_add(json_neigh, "nexthopLocal",
+ inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, sizeof(buf1)));
if (p->shared_network)
json_object_string_add(json_neigh, "bgpConnection", "sharedNetwork");
else
@@ -12128,17 +8395,17 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
else
{
vty_out (vty, "Nexthop: %s%s",
- inet_ntop (AF_INET, &p->nexthop.v4, buf1, BUFSIZ),
- VTY_NEWLINE);
+ inet_ntop (AF_INET, &p->nexthop.v4, buf1, sizeof(buf1)),
+ VTY_NEWLINE);
vty_out (vty, "Nexthop global: %s%s",
- inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, BUFSIZ),
- VTY_NEWLINE);
+ inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, sizeof(buf1)),
+ VTY_NEWLINE);
vty_out (vty, "Nexthop local: %s%s",
- inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, BUFSIZ),
- VTY_NEWLINE);
+ inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, sizeof(buf1)),
+ VTY_NEWLINE);
vty_out (vty, "BGP connection: %s%s",
- p->shared_network ? "shared network" : "non shared network",
- VTY_NEWLINE);
+ p->shared_network ? "shared network" : "non shared network",
+ VTY_NEWLINE);
}
}
@@ -12271,59 +8538,6 @@ bgp_show_neighbor (struct vty *vty, struct bgp *bgp, enum show_type type,
return CMD_SUCCESS;
}
-static int
-bgp_show_neighbor_vty (struct vty *vty, const char *name,
- enum show_type type, const char *ip_str, u_char use_json,
- json_object *json)
-{
- int ret;
- struct bgp *bgp;
- union sockunion su;
-
- if (use_json && (json == NULL))
- json = json_object_new_object();
-
- if (name)
- {
- bgp = bgp_lookup_by_name (name);
- if (! bgp)
- {
- if (use_json)
- {
- json_object_boolean_true_add(json, "bgpNoSuchInstance");
- vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
- json_object_free(json);
- }
- else
- vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
-
- return CMD_WARNING;
- }
- }
- else
- {
- bgp = bgp_get_default ();
- }
-
- if (bgp)
- {
- if (ip_str)
- {
- ret = str2sockunion (ip_str, &su);
- if (ret < 0)
- bgp_show_neighbor (vty, bgp, type, NULL, ip_str, use_json, json);
- else
- bgp_show_neighbor (vty, bgp, type, &su, NULL, use_json, json);
- }
- else
- {
- bgp_show_neighbor (vty, bgp, type, NULL, NULL, use_json, json);
- }
- }
-
- return CMD_SUCCESS;
-}
-
static void
bgp_show_all_instances_neighbors_vty (struct vty *vty, u_char use_json)
{
@@ -12378,225 +8592,125 @@ bgp_show_all_instances_neighbors_vty (struct vty *vty, u_char use_json)
vty_out (vty, "}%s", VTY_NEWLINE);
}
-/* "show ip bgp neighbors" commands. */
-DEFUN (show_ip_bgp_neighbors,
- show_ip_bgp_neighbors_cmd,
- "show ip bgp neighbors {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "JavaScript Object Notation\n")
+static int
+bgp_show_neighbor_vty (struct vty *vty, const char *name,
+ enum show_type type, const char *ip_str, u_char use_json)
{
- u_char uj = use_json(argc, argv);
-
- return bgp_show_neighbor_vty (vty, NULL, show_all, NULL, uj, NULL);
-}
+ int ret;
+ struct bgp *bgp;
+ union sockunion su;
+ json_object *json = NULL;
-ALIAS (show_ip_bgp_neighbors,
- show_ip_bgp_ipv4_neighbors_cmd,
- "show ip bgp ipv4 "BGP_SAFI_CMD_STR" neighbors {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- BGP_SAFI_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "JavaScript Object Notation\n")
+ if (use_json)
+ json = json_object_new_object();
-ALIAS (show_ip_bgp_neighbors,
- show_bgp_neighbors_cmd,
- "show bgp neighbors {json}",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "JavaScript Object Notation\n")
+ if (name)
+ {
+ if (strmatch(name, "all"))
+ {
+ bgp_show_all_instances_neighbors_vty (vty, use_json);
+ return CMD_SUCCESS;
+ }
+ else
+ {
+ bgp = bgp_lookup_by_name (name);
+ if (! bgp)
+ {
+ if (use_json)
+ {
+ json_object_boolean_true_add(json, "bgpNoSuchInstance");
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
+ else
+ vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
-ALIAS (show_ip_bgp_neighbors,
- show_bgp_ipv6_neighbors_cmd,
- "show bgp ipv6 neighbors {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "JavaScript Object Notation\n")
+ return CMD_WARNING;
+ }
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ }
-DEFUN (show_ip_bgp_neighbors_peer,
- show_ip_bgp_neighbors_peer_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
+ if (bgp)
+ {
+ if (ip_str)
+ {
+ ret = str2sockunion (ip_str, &su);
+ if (ret < 0)
+ bgp_show_neighbor (vty, bgp, type, NULL, ip_str, use_json, json);
+ else
+ bgp_show_neighbor (vty, bgp, type, &su, NULL, use_json, json);
+ }
+ else
+ {
+ bgp_show_neighbor (vty, bgp, type, NULL, NULL, use_json, json);
+ }
+ }
- return bgp_show_neighbor_vty (vty, NULL, show_peer, argv[argc - 2], uj, NULL);
+ return CMD_SUCCESS;
}
-ALIAS (show_ip_bgp_neighbors_peer,
- show_ip_bgp_ipv4_neighbors_peer_cmd,
- "show ip bgp ipv4 "BGP_SAFI_CMD_STR" neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
+/* "show [ip] bgp neighbors" commands. */
+DEFUN (show_ip_bgp_neighbors,
+ show_ip_bgp_neighbors_cmd,
+ "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6|vpnv4 <all|rd ASN:nn_or_IP-address:nn>>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]",
SHOW_STR
IP_STR
BGP_STR
- "Address family\n"
- BGP_SAFI_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "JavaScript Object Notation\n")
-
-ALIAS (show_ip_bgp_neighbors_peer,
- show_bgp_neighbors_peer_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "JavaScript Object Notation\n")
-
-ALIAS (show_ip_bgp_neighbors_peer,
- show_bgp_ipv6_neighbors_peer_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
- SHOW_STR
- BGP_STR
- "Address family\n"
+ BGP_INSTANCE_HELP_STR
+ "Address Family\n"
+ "Address Family\n"
+ "Address Family\n"
+ "Display information about all VPNv4 NLRIs\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "JavaScript Object Notation\n")
-
-DEFUN (show_ip_bgp_instance_neighbors,
- show_ip_bgp_instance_neighbors_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " neighbors {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "JavaScript Object Notation\n")
+ "Neighbor on BGP configured interface\n"
+ JSON_STR)
{
- u_char uj = use_json(argc, argv);
-
- return bgp_show_neighbor_vty (vty, argv[1], show_all, NULL, uj, NULL);
-}
+ char *vrf = NULL;
+ char *sh_arg = NULL;
+ enum show_type sh_type;
-DEFUN (show_ip_bgp_instance_all_neighbors,
- show_ip_bgp_instance_all_neighbors_cmd,
- "show ip bgp " BGP_INSTANCE_ALL_CMD " neighbors {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_ALL_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "JavaScript Object Notation\n")
-{
u_char uj = use_json(argc, argv);
- bgp_show_all_instances_neighbors_vty (vty, uj);
- return CMD_SUCCESS;
-}
-
-ALIAS (show_ip_bgp_instance_neighbors,
- show_bgp_instance_neighbors_cmd,
- "show bgp " BGP_INSTANCE_CMD " neighbors {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "JavaScript Object Notation\n")
+ int idx = 0;
-ALIAS (show_ip_bgp_instance_neighbors,
- show_bgp_instance_ipv6_neighbors_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 neighbors {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "JavaScript Object Notation\n")
+ if (argv_find (argv, argc, "WORD", &idx))
+ vrf = argv[idx]->arg;
-DEFUN (show_ip_bgp_instance_neighbors_peer,
- show_ip_bgp_instance_neighbors_peer_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "JavaScript Object Notation\n")
-{
- u_char uj = use_json(argc, argv);
+ if (argv_find (argv, argc, "A.B.C.D", &idx) ||
+ argv_find (argv, argc, "X:X::X:X", &idx) ||
+ argv_find (argv, argc, "WORD", &idx))
+ {
+ sh_type = show_peer;
+ sh_arg = argv[idx]->arg;
+ }
+ else
+ sh_type = show_all;
- return bgp_show_neighbor_vty (vty, argv[1], show_peer, argv[2], uj, NULL);
+ return bgp_show_neighbor_vty (vty, vrf, sh_type, sh_arg, uj);
}
-ALIAS (show_ip_bgp_instance_neighbors_peer,
- show_bgp_instance_neighbors_peer_cmd,
- "show bgp " BGP_INSTANCE_CMD " neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "JavaScript Object Notation\n")
-
-ALIAS (show_ip_bgp_instance_neighbors_peer,
- show_bgp_instance_ipv6_neighbors_peer_cmd,
- "show bgp " BGP_INSTANCE_CMD " ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Neighbor on bgp configured interface\n"
- "JavaScript Object Notation\n")
-
-/* Show BGP's AS paths internal data. There are both `show ip bgp
+/* Show BGP's AS paths internal data. There are both `show [ip] bgp
paths' and `show ip mbgp paths'. Those functions results are the
same.*/
-DEFUN (show_ip_bgp_paths,
+DEFUN (show_ip_bgp_paths,
show_ip_bgp_paths_cmd,
- "show ip bgp paths",
+ "show [ip] bgp ["BGP_SAFI_CMD_STR"] paths",
SHOW_STR
IP_STR
BGP_STR
- "Path information\n")
-{
- vty_out (vty, "Address Refcnt Path%s", VTY_NEWLINE);
- aspath_print_all_vty (vty);
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_bgp_ipv4_paths,
- show_ip_bgp_ipv4_paths_cmd,
- "show ip bgp ipv4 "BGP_SAFI_CMD_STR" paths",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
BGP_SAFI_HELP_STR
"Path information\n")
{
- vty_out (vty, "Address Refcnt Path\r\n");
+ vty_out (vty, "Address Refcnt Path%s", VTY_NEWLINE);
aspath_print_all_vty (vty);
-
return CMD_SUCCESS;
}
@@ -12613,9 +8727,9 @@ community_show_all_iterator (struct hash_backet *backet, struct vty *vty)
}
/* Show BGP's community internal data. */
-DEFUN (show_ip_bgp_community_info,
+DEFUN (show_ip_bgp_community_info,
show_ip_bgp_community_info_cmd,
- "show ip bgp community-info",
+ "show [ip] bgp community-info",
SHOW_STR
IP_STR
BGP_STR
@@ -12623,7 +8737,7 @@ DEFUN (show_ip_bgp_community_info,
{
vty_out (vty, "Address Refcnt Community%s", VTY_NEWLINE);
- hash_iterate (community_hash (),
+ hash_iterate (community_hash (),
(void (*) (struct hash_backet *, void *))
community_show_all_iterator,
vty);
@@ -12631,31 +8745,45 @@ DEFUN (show_ip_bgp_community_info,
return CMD_SUCCESS;
}
-DEFUN (show_ip_bgp_attr_info,
- show_ip_bgp_attr_info_cmd,
- "show ip bgp attribute-info",
+static void
+lcommunity_show_all_iterator (struct hash_backet *backet, struct vty *vty)
+{
+ struct lcommunity *lcom;
+
+ lcom = (struct lcommunity *) backet->data;
+ vty_out (vty, "[%p] (%ld) %s%s", (void *)backet, lcom->refcnt,
+ lcommunity_str (lcom), VTY_NEWLINE);
+}
+
+/* Show BGP's community internal data. */
+DEFUN (show_ip_bgp_lcommunity_info,
+ show_ip_bgp_lcommunity_info_cmd,
+ "show ip bgp large-community-info",
SHOW_STR
IP_STR
BGP_STR
- "List all bgp attribute information\n")
+ "List all bgp large-community information\n")
{
- attr_show_all (vty);
+ vty_out (vty, "Address Refcnt Large-community%s", VTY_NEWLINE);
+
+ hash_iterate (lcommunity_hash (),
+ (void (*) (struct hash_backet *, void *))
+ lcommunity_show_all_iterator,
+ vty);
+
return CMD_SUCCESS;
}
-static int bgp_show_update_groups(struct vty *vty, const char *name,
- int afi, int safi,
- uint64_t subgrp_id)
-{
- struct bgp *bgp;
- if (name)
- bgp = bgp_lookup_by_name (name);
- else
- bgp = bgp_get_default ();
-
- if (bgp)
- update_group_show(bgp, afi, safi, vty, subgrp_id);
+DEFUN (show_ip_bgp_attr_info,
+ show_ip_bgp_attr_info_cmd,
+ "show [ip] bgp attribute-info",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "List all bgp attribute information\n")
+{
+ attr_show_all (vty);
return CMD_SUCCESS;
}
@@ -12675,177 +8803,94 @@ bgp_show_all_instances_updgrps_vty (struct vty *vty, afi_t afi, safi_t safi)
}
}
-DEFUN (show_ip_bgp_updgrps,
- show_ip_bgp_updgrps_cmd,
- "show ip bgp update-groups",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed info about dynamic update groups\n")
-{
- return (bgp_show_update_groups(vty, NULL, AFI_IP, SAFI_UNICAST, 0));
-}
-
-DEFUN (show_ip_bgp_instance_updgrps,
- show_ip_bgp_instance_updgrps_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " update-groups",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed info about dynamic update groups\n")
-{
- return (bgp_show_update_groups(vty, argv[1], AFI_IP, SAFI_UNICAST, 0));
-}
-
-DEFUN (show_ip_bgp_instance_all_updgrps,
- show_ip_bgp_instance_all_updgrps_cmd,
- "show ip bgp " BGP_INSTANCE_ALL_CMD " update-groups",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_ALL_HELP_STR
- "Detailed info about dynamic update groups\n")
-{
- bgp_show_all_instances_updgrps_vty (vty, AFI_IP, SAFI_UNICAST);
- return CMD_SUCCESS;
-}
-
-DEFUN (show_bgp_ipv6_updgrps,
- show_bgp_ipv6_updgrps_cmd,
- "show bgp update-groups",
- SHOW_STR
- BGP_STR
- "Detailed info about v6 dynamic update groups\n")
+static int
+bgp_show_update_groups(struct vty *vty, const char *name,
+ int afi, int safi,
+ uint64_t subgrp_id)
{
- return (bgp_show_update_groups(vty, NULL, AFI_IP6, SAFI_UNICAST, 0));
-}
+ struct bgp *bgp;
-DEFUN (show_bgp_instance_ipv6_updgrps,
- show_bgp_instance_ipv6_updgrps_cmd,
- "show bgp " BGP_INSTANCE_CMD " update-groups",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Detailed info about v6 dynamic update groups\n")
-{
- return (bgp_show_update_groups(vty, argv[1], AFI_IP6, SAFI_UNICAST, 0));
-}
+ if (name)
+ {
+ if (strmatch (name, "all"))
+ {
+ bgp_show_all_instances_updgrps_vty (vty, afi, safi);
+ return CMD_SUCCESS;
+ }
+ else
+ {
+ bgp = bgp_lookup_by_name (name);
+ }
+ }
+ else
+ {
+ bgp = bgp_get_default ();
+ }
-DEFUN (show_bgp_instance_all_ipv6_updgrps,
- show_bgp_instance_all_ipv6_updgrps_cmd,
- "show bgp " BGP_INSTANCE_ALL_CMD " update-groups",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_ALL_HELP_STR
- "Detailed info about v6 dynamic update groups\n")
-{
- bgp_show_all_instances_updgrps_vty (vty, AFI_IP6, SAFI_UNICAST);
+ if (bgp)
+ update_group_show(bgp, afi, safi, vty, subgrp_id);
return CMD_SUCCESS;
}
-DEFUN (show_bgp_updgrps,
- show_bgp_updgrps_cmd,
- "show bgp "BGP_AFI_SAFI_CMD_STR" update-groups",
- SHOW_STR
- BGP_STR
- "Address family\n"
- BGP_SAFI_HELP_STR
- "Detailed info about dynamic update groups\n")
-{
- afi_t afi;
- safi_t safi;
-
- afi = bgp_vty_safi_from_arg(argv[0]);
- safi = bgp_vty_safi_from_arg(argv[1]);
- return (bgp_show_update_groups(vty, NULL, afi, safi, 0));
-}
-
-DEFUN (show_ip_bgp_updgrps_s,
- show_ip_bgp_updgrps_s_cmd,
- "show ip bgp update-groups SUBGROUP-ID",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed info about dynamic update groups\n"
- "Specific subgroup to display detailed info for\n")
-{
- uint64_t subgrp_id;
-
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[0]);
- return (bgp_show_update_groups(vty, NULL, AFI_IP, SAFI_UNICAST, subgrp_id));
-}
-
-DEFUN (show_ip_bgp_instance_updgrps_s,
- show_ip_bgp_instance_updgrps_s_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " update-groups SUBGROUP-ID",
+DEFUN (show_ip_bgp_updgrps,
+ show_ip_bgp_updgrps_cmd,
+ "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] update-groups [SUBGROUP-ID]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
+ BGP_AFI_HELP_STR
+ BGP_SAFI_HELP_STR
"Detailed info about dynamic update groups\n"
"Specific subgroup to display detailed info for\n")
{
- uint64_t subgrp_id;
+ char *vrf = NULL;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ uint64_t subgrp_id = 0;
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
- return (bgp_show_update_groups(vty, argv[1], AFI_IP, SAFI_UNICAST, subgrp_id));
-}
+ int idx = 0;
-DEFUN (show_bgp_ipv6_updgrps_s,
- show_bgp_ipv6_updgrps_s_cmd,
- "show bgp update-groups SUBGROUP-ID",
- SHOW_STR
- BGP_STR
- "Detailed info about v6 dynamic update groups\n"
- "Specific subgroup to display detailed info for\n")
-{
- uint64_t subgrp_id;
-
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[0]);
- return(bgp_show_update_groups(vty, NULL, AFI_IP6, SAFI_UNICAST, subgrp_id));
-}
+ /* show [ip] bgp */
+ if (argv_find (argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ /* [<view|vrf> WORD] */
+ if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
+ vrf = argv[++idx]->arg;
+ /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
+ if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
+ {
+ argv_find_and_parse_safi (argv, argc, &idx, &safi);
+ }
-DEFUN (show_bgp_instance_ipv6_updgrps_s,
- show_bgp_instance_ipv6_updgrps_s_cmd,
- "show bgp " BGP_INSTANCE_CMD " update-groups SUBGROUP-ID",
- SHOW_STR
- BGP_STR
- "Detailed info about v6 dynamic update groups\n"
- "Specific subgroup to display detailed info for\n")
-{
- uint64_t subgrp_id;
+ /* get subgroup id, if provided */
+ idx = argc - 1;
+ if (argv[idx]->type == VARIABLE_TKN)
+ VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx]->arg);
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
- return(bgp_show_update_groups(vty, argv[1], AFI_IP6, SAFI_UNICAST, subgrp_id));
+ return (bgp_show_update_groups(vty, vrf, afi, safi, subgrp_id));
}
-DEFUN (show_bgp_updgrps_s,
- show_bgp_updgrps_s_cmd,
- "show bgp "BGP_AFI_SAFI_CMD_STR" update-groups SUBGROUP-ID",
+DEFUN (show_bgp_instance_all_ipv6_updgrps,
+ show_bgp_instance_all_ipv6_updgrps_cmd,
+ "show [ip] bgp <view|vrf> all update-groups",
SHOW_STR
+ IP_STR
BGP_STR
- "Address family\n"
- BGP_AFI_SAFI_HELP_STR
- "Detailed info about v6 dynamic update groups\n"
- "Specific subgroup to display detailed info for")
+ BGP_INSTANCE_ALL_HELP_STR
+ "Detailed info about dynamic update groups\n")
{
- afi_t afi;
- safi_t safi;
- uint64_t subgrp_id;
-
- afi = bgp_vty_safi_from_arg(argv[0]);
- safi = bgp_vty_safi_from_arg(argv[1]);
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
- return(bgp_show_update_groups(vty, NULL, afi, safi, subgrp_id));
+ bgp_show_all_instances_updgrps_vty (vty, AFI_IP6, SAFI_UNICAST);
+ return CMD_SUCCESS;
}
DEFUN (show_bgp_updgrps_stats,
show_bgp_updgrps_stats_cmd,
- "show bgp update-groups statistics",
+ "show [ip] bgp update-groups statistics",
SHOW_STR
+ IP_STR
BGP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Statistics\n")
{
struct bgp *bgp;
@@ -12859,16 +8904,18 @@ DEFUN (show_bgp_updgrps_stats,
DEFUN (show_bgp_instance_updgrps_stats,
show_bgp_instance_updgrps_stats_cmd,
- "show bgp " BGP_INSTANCE_CMD " update-groups statistics",
+ "show [ip] bgp <view|vrf> WORD update-groups statistics",
SHOW_STR
+ IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Statistics\n")
{
+ int idx_word = 3;
struct bgp *bgp;
- bgp = bgp_lookup_by_name (argv[1]);
+ bgp = bgp_lookup_by_name (argv[idx_word]->arg);
if (bgp)
update_group_show_stats(bgp, vty);
@@ -12900,193 +8947,217 @@ show_bgp_updgrps_adj_info_aux (struct vty *vty, const char *name,
DEFUN (show_ip_bgp_updgrps_adj,
show_ip_bgp_updgrps_adj_cmd,
- "show ip bgp update-groups (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp update-groups <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
- show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP, SAFI_UNICAST, argv[0], 0);
+ int idx_type = 4;
+ show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP, SAFI_UNICAST, argv[idx_type]->arg, 0);
return CMD_SUCCESS;
}
DEFUN (show_ip_bgp_instance_updgrps_adj,
show_ip_bgp_instance_updgrps_adj_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " update-groups (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp <view|vrf> WORD update-groups <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
- show_bgp_updgrps_adj_info_aux(vty, argv[1], AFI_IP, SAFI_UNICAST, argv[2], 0);
+ int idx_word = 4;
+ int idx_type = 6;
+ show_bgp_updgrps_adj_info_aux(vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, argv[idx_type]->arg, 0);
return CMD_SUCCESS;
}
DEFUN (show_bgp_updgrps_afi_adj,
show_bgp_updgrps_afi_adj_cmd,
- "show bgp "BGP_AFI_SAFI_CMD_STR" update-groups (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp "BGP_AFI_SAFI_CMD_STR" update-groups <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
+ IP_STR
BGP_STR
- "Address family\n"
- BGP_SAFI_HELP_STR
- "BGP update groups\n"
+ BGP_AFI_SAFI_HELP_STR
+ "Detailed info about dynamic update groups\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n"
"Specific subgroup info wanted for\n")
{
- afi_t afi;
- safi_t safi;
-
- afi = bgp_vty_safi_from_arg(argv[0]);
- safi = bgp_vty_safi_from_arg(argv[1]);
- show_bgp_updgrps_adj_info_aux(vty, NULL, afi, safi, argv[2], 0);
+ int idx_afi = 2;
+ int idx_safi = 3;
+ int idx_type = 5;
+ show_bgp_updgrps_adj_info_aux(vty, NULL,
+ bgp_vty_afi_from_arg(argv[idx_afi]->arg),
+ bgp_vty_safi_from_arg(argv[idx_safi]->arg),
+ argv[idx_type]->arg, 0);
return CMD_SUCCESS;
}
DEFUN (show_bgp_updgrps_adj,
show_bgp_updgrps_adj_cmd,
- "show bgp update-groups (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp update-groups <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
+ IP_STR
BGP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
- show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP6, SAFI_UNICAST, argv[0], 0);
+ int idx_type = 3;
+ show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP6, SAFI_UNICAST, argv[idx_type]->arg, 0);
return CMD_SUCCESS;
}
DEFUN (show_bgp_instance_updgrps_adj,
show_bgp_instance_updgrps_adj_cmd,
- "show bgp " BGP_INSTANCE_CMD " update-groups (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp <view|vrf> WORD update-groups <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
+ IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
- show_bgp_updgrps_adj_info_aux(vty, argv[1], AFI_IP6, SAFI_UNICAST, argv[2], 0);
+ int idx_word = 3;
+ int idx_type = 5;
+ show_bgp_updgrps_adj_info_aux(vty, argv[idx_word]->arg, AFI_IP6, SAFI_UNICAST, argv[idx_type]->arg, 0);
return CMD_SUCCESS;
}
DEFUN (show_ip_bgp_updgrps_adj_s,
show_ip_bgp_updgrps_adj_s_cmd,
- "show ip bgp update-groups SUBGROUP-ID (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
+ int idx_subgroup_id = 4;
+ int idx_type = 5;
uint64_t subgrp_id;
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[0]);
+ VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx_subgroup_id]->arg);
- show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP, SAFI_UNICAST, argv[1], subgrp_id);
+ show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP, SAFI_UNICAST, argv[idx_type]->arg, subgrp_id);
return CMD_SUCCESS;
}
DEFUN (show_ip_bgp_instance_updgrps_adj_s,
show_ip_bgp_instance_updgrps_adj_s_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " update-groups SUBGROUP-ID (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp <view|vrf> WORD update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
+ int idx_vrf = 4;
+ int idx_subgroup_id = 6;
+ int idx_type = 7;
uint64_t subgrp_id;
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
+ VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx_subgroup_id]->arg);
- show_bgp_updgrps_adj_info_aux(vty, argv[1], AFI_IP, SAFI_UNICAST, argv[3], subgrp_id);
+ show_bgp_updgrps_adj_info_aux(vty, argv[idx_vrf]->arg, AFI_IP, SAFI_UNICAST, argv[idx_type]->arg, subgrp_id);
return CMD_SUCCESS;
}
DEFUN (show_bgp_updgrps_afi_adj_s,
show_bgp_updgrps_afi_adj_s_cmd,
- "show bgp "BGP_AFI_SAFI_CMD_STR" update-groups SUBGROUP-ID (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp "BGP_AFI_SAFI_CMD_STR" update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
+ IP_STR
BGP_STR
- "Address family\n"
- BGP_SAFI_HELP_STR
- "BGP update groups\n"
+ BGP_AFI_SAFI_HELP_STR
+ "Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n"
"Specific subgroup info wanted for\n")
{
- afi_t afi;
- safi_t safi;
+ int idx_afi = 2;
+ int idx_safi = 3;
+ int idx_subgroup_id = 5;
+ int idx_type = 6;
uint64_t subgrp_id;
- afi = bgp_vty_safi_from_arg(argv[0]);
- safi = bgp_vty_safi_from_arg(argv[1]);
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
+ VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx_subgroup_id]->arg);
- show_bgp_updgrps_adj_info_aux(vty, NULL, afi, safi, argv[3], subgrp_id);
+ show_bgp_updgrps_adj_info_aux(vty, NULL,
+ bgp_vty_afi_from_arg(argv[idx_afi]->arg),
+ bgp_vty_safi_from_arg(argv[idx_safi]->arg),
+ argv[idx_type]->arg, subgrp_id);
return CMD_SUCCESS;
}
DEFUN (show_bgp_updgrps_adj_s,
show_bgp_updgrps_adj_s_cmd,
- "show bgp update-groups SUBGROUP-ID (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
+ IP_STR
BGP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
+ int idx_subgroup_id = 3;
+ int idx_type = 4;
uint64_t subgrp_id;
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[0]);
+ VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx_subgroup_id]->arg);
- show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP6, SAFI_UNICAST, argv[1], subgrp_id);
+ show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP6, SAFI_UNICAST, argv[idx_type]->arg, subgrp_id);
return CMD_SUCCESS;
}
DEFUN (show_bgp_instance_updgrps_adj_s,
show_bgp_instance_updgrps_adj_s_cmd,
- "show bgp " BGP_INSTANCE_CMD " update-groups SUBGROUP-ID (advertise-queue|advertised-routes|packet-queue)",
+ "show [ip] bgp <view|vrf> WORD update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
+ IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "BGP update groups\n"
+ "Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
+ int idx_vrf = 3;
+ int idx_subgroup_id = 5;
+ int idx_type = 6;
uint64_t subgrp_id;
- VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
+ VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx_subgroup_id]->arg);
- show_bgp_updgrps_adj_info_aux(vty, argv[1], AFI_IP6, SAFI_UNICAST, argv[3], subgrp_id);
+ show_bgp_updgrps_adj_info_aux(vty, argv[idx_vrf]->arg, AFI_IP6, SAFI_UNICAST, argv[idx_type]->arg, subgrp_id);
return CMD_SUCCESS;
}
@@ -13255,52 +9326,25 @@ bgp_show_peer_group_vty (struct vty *vty, const char *name,
DEFUN (show_ip_bgp_peer_groups,
show_ip_bgp_peer_groups_cmd,
- "show ip bgp peer-group",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on all BGP peer groups\n")
-{
- return bgp_show_peer_group_vty (vty, NULL, show_all_groups, NULL);
-}
-
-DEFUN (show_ip_bgp_instance_peer_groups,
- show_ip_bgp_instance_peer_groups_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " peer-group",
+ "show [ip] bgp [<view|vrf> WORD] peer-group [PGNAME]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
- "Detailed information on all BGP peer groups\n")
+ "Detailed information on BGP peer groups\n"
+ "Peer group name\n")
{
- return bgp_show_peer_group_vty (vty, argv[1], show_all_groups, NULL);
-}
+ char *vrf, *pg;
+ vrf = pg = NULL;
+ int idx = 0;
-DEFUN (show_ip_bgp_peer_group,
- show_ip_bgp_peer_group_cmd,
- "show ip bgp peer-group WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP peer-group name\n"
- "Detailed information on a BGP peer group\n")
-{
- return bgp_show_peer_group_vty (vty, NULL, show_peer_group, argv[0]);
-}
+ vrf = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
+ pg = argv_find (argv, argc, "PGNAME", &idx) ? argv[idx]->arg : NULL;
-DEFUN (show_ip_bgp_instance_peer_group,
- show_ip_bgp_instance_peer_group_cmd,
- "show ip bgp " BGP_INSTANCE_CMD " peer-group WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "BGP peer-group name\n"
- "Detailed information on a BGP peer group\n")
-{
- return bgp_show_peer_group_vty (vty, argv[1], show_peer_group, argv[2]);
+ return bgp_show_peer_group_vty (vty, vrf, show_all_groups, pg);
}
+
/* Redistribute VTY commands. */
DEFUN (bgp_redistribute_ipv4,
@@ -13309,16 +9353,18 @@ DEFUN (bgp_redistribute_ipv4,
"Redistribute information from another routing protocol\n"
FRR_IP_REDIST_HELP_STR_BGPD)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
int type;
- type = proto_redistnum (AFI_IP, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- bgp_redist_add(vty->index, AFI_IP, type, 0);
- return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
+ bgp_redist_add(bgp, AFI_IP, type, 0);
+ return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
DEFUN (bgp_redistribute_ipv4_rmap,
@@ -13329,49 +9375,55 @@ DEFUN (bgp_redistribute_ipv4_rmap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
+ int idx_word = 3;
int type;
struct bgp_redist *red;
- type = proto_redistnum (AFI_IP, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- red = bgp_redist_add(vty->index, AFI_IP, type, 0);
- bgp_redistribute_rmap_set (red, argv[1]);
- return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
+ red = bgp_redist_add(bgp, AFI_IP, type, 0);
+ bgp_redistribute_rmap_set (red, argv[idx_word]->arg);
+ return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
DEFUN (bgp_redistribute_ipv4_metric,
bgp_redistribute_ipv4_metric_cmd,
- "redistribute " FRR_IP_REDIST_STR_BGPD " metric <0-4294967295>",
+ "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295)",
"Redistribute information from another routing protocol\n"
FRR_IP_REDIST_HELP_STR_BGPD
"Metric for redistributed routes\n"
"Default metric\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
+ int idx_number = 3;
int type;
u_int32_t metric;
struct bgp_redist *red;
- type = proto_redistnum (AFI_IP, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_INTEGER ("metric", metric, argv[1]);
+ VTY_GET_INTEGER ("metric", metric, argv[idx_number]->arg);
- red = bgp_redist_add(vty->index, AFI_IP, type, 0);
- bgp_redistribute_metric_set(vty->index, red, AFI_IP, type, metric);
- return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
+ red = bgp_redist_add(bgp, AFI_IP, type, 0);
+ bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric);
+ return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
DEFUN (bgp_redistribute_ipv4_rmap_metric,
bgp_redistribute_ipv4_rmap_metric_cmd,
- "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD metric <0-4294967295>",
+ "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD metric (0-4294967295)",
"Redistribute information from another routing protocol\n"
FRR_IP_REDIST_HELP_STR_BGPD
"Route map reference\n"
@@ -13379,27 +9431,31 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
"Metric for redistributed routes\n"
"Default metric\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
+ int idx_word = 3;
+ int idx_number = 5;
int type;
u_int32_t metric;
struct bgp_redist *red;
- type = proto_redistnum (AFI_IP, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_INTEGER ("metric", metric, argv[2]);
+ VTY_GET_INTEGER ("metric", metric, argv[idx_number]->arg);
- red = bgp_redist_add(vty->index, AFI_IP, type, 0);
- bgp_redistribute_rmap_set (red, argv[1]);
- bgp_redistribute_metric_set(vty->index, red, AFI_IP, type, metric);
- return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
+ red = bgp_redist_add(bgp, AFI_IP, type, 0);
+ bgp_redistribute_rmap_set (red, argv[idx_word]->arg);
+ bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric);
+ return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
DEFUN (bgp_redistribute_ipv4_metric_rmap,
bgp_redistribute_ipv4_metric_rmap_cmd,
- "redistribute " FRR_IP_REDIST_STR_BGPD " metric <0-4294967295> route-map WORD",
+ "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295) route-map WORD",
"Redistribute information from another routing protocol\n"
FRR_IP_REDIST_HELP_STR_BGPD
"Metric for redistributed routes\n"
@@ -13407,49 +9463,56 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
+ int idx_number = 3;
+ int idx_word = 5;
int type;
u_int32_t metric;
struct bgp_redist *red;
- type = proto_redistnum (AFI_IP, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_INTEGER ("metric", metric, argv[1]);
+ VTY_GET_INTEGER ("metric", metric, argv[idx_number]->arg);
- red = bgp_redist_add(vty->index, AFI_IP, type, 0);
- bgp_redistribute_metric_set(vty->index, red, AFI_IP, type, metric);
- bgp_redistribute_rmap_set (red, argv[2]);
- return bgp_redistribute_set (vty->index, AFI_IP, type, 0);
+ red = bgp_redist_add(bgp, AFI_IP, type, 0);
+ bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric);
+ bgp_redistribute_rmap_set (red, argv[idx_word]->arg);
+ return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
DEFUN (bgp_redistribute_ipv4_ospf,
bgp_redistribute_ipv4_ospf_cmd,
- "redistribute (ospf|table) <1-65535>",
+ "redistribute <ospf|table> (1-65535)",
"Redistribute information from another routing protocol\n"
"Open Shortest Path First (OSPFv2)\n"
"Non-main Kernel Routing Table\n"
"Instance ID/Table ID\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_ospf_table = 1;
+ int idx_number = 2;
u_short instance;
u_short protocol;
- VTY_GET_INTEGER ("Instance ID", instance, argv[1]);
+ VTY_GET_INTEGER ("Instance ID", instance, argv[idx_number]->arg);
- if (strncmp(argv[0], "o", 1) == 0)
+ if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else
protocol = ZEBRA_ROUTE_TABLE;
- bgp_redist_add(vty->index, AFI_IP, protocol, instance);
- return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
+ bgp_redist_add(bgp, AFI_IP, protocol, instance);
+ return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
DEFUN (bgp_redistribute_ipv4_ospf_rmap,
bgp_redistribute_ipv4_ospf_rmap_cmd,
- "redistribute (ospf|table) <1-65535> route-map WORD",
+ "redistribute <ospf|table> (1-65535) route-map WORD",
"Redistribute information from another routing protocol\n"
"Open Shortest Path First (OSPFv2)\n"
"Non-main Kernel Routing Table\n"
@@ -13457,24 +9520,28 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_ospf_table = 1;
+ int idx_number = 2;
+ int idx_word = 4;
struct bgp_redist *red;
u_short instance;
int protocol;
- if (strncmp(argv[0], "o", 1) == 0)
+ if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else
protocol = ZEBRA_ROUTE_TABLE;
- VTY_GET_INTEGER ("Instance ID", instance, argv[1]);
- red = bgp_redist_add(vty->index, AFI_IP, protocol, instance);
- bgp_redistribute_rmap_set (red, argv[2]);
- return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
+ VTY_GET_INTEGER ("Instance ID", instance, argv[idx_number]->arg);
+ red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
+ bgp_redistribute_rmap_set (red, argv[idx_word]->arg);
+ return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
DEFUN (bgp_redistribute_ipv4_ospf_metric,
bgp_redistribute_ipv4_ospf_metric_cmd,
- "redistribute (ospf|table) <1-65535> metric <0-4294967295>",
+ "redistribute <ospf|table> (1-65535) metric (0-4294967295)",
"Redistribute information from another routing protocol\n"
"Open Shortest Path First (OSPFv2)\n"
"Non-main Kernel Routing Table\n"
@@ -13482,27 +9549,31 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric,
"Metric for redistributed routes\n"
"Default metric\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_ospf_table = 1;
+ int idx_number = 2;
+ int idx_number_2 = 4;
u_int32_t metric;
struct bgp_redist *red;
u_short instance;
int protocol;
- if (strncmp(argv[0], "o", 1) == 0)
+ if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else
protocol = ZEBRA_ROUTE_TABLE;
- VTY_GET_INTEGER ("Instance ID", instance, argv[1]);
- VTY_GET_INTEGER ("metric", metric, argv[2]);
+ VTY_GET_INTEGER ("Instance ID", instance, argv[idx_number]->arg);
+ VTY_GET_INTEGER ("metric", metric, argv[idx_number_2]->arg);
- red = bgp_redist_add(vty->index, AFI_IP, protocol, instance);
- bgp_redistribute_metric_set(vty->index, red, AFI_IP, protocol, metric);
- return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
+ red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
+ bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, metric);
+ return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
bgp_redistribute_ipv4_ospf_rmap_metric_cmd,
- "redistribute (ospf|table) <1-65535> route-map WORD metric <0-4294967295>",
+ "redistribute <ospf|table> (1-65535) route-map WORD metric (0-4294967295)",
"Redistribute information from another routing protocol\n"
"Open Shortest Path First (OSPFv2)\n"
"Non-main Kernel Routing Table\n"
@@ -13512,28 +9583,33 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
"Metric for redistributed routes\n"
"Default metric\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_ospf_table = 1;
+ int idx_number = 2;
+ int idx_word = 4;
+ int idx_number_2 = 6;
u_int32_t metric;
struct bgp_redist *red;
u_short instance;
int protocol;
- if (strncmp(argv[0], "o", 1) == 0)
+ if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else
protocol = ZEBRA_ROUTE_TABLE;
- VTY_GET_INTEGER ("Instance ID", instance, argv[1]);
- VTY_GET_INTEGER ("metric", metric, argv[3]);
+ VTY_GET_INTEGER ("Instance ID", instance, argv[idx_number]->arg);
+ VTY_GET_INTEGER ("metric", metric, argv[idx_number_2]->arg);
- red = bgp_redist_add(vty->index, AFI_IP, protocol, instance);
- bgp_redistribute_rmap_set (red, argv[2]);
- bgp_redistribute_metric_set(vty->index, red, AFI_IP, protocol, metric);
- return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
+ red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
+ bgp_redistribute_rmap_set (red, argv[idx_word]->arg);
+ bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, metric);
+ return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
bgp_redistribute_ipv4_ospf_metric_rmap_cmd,
- "redistribute (ospf|table) <1-65535> metric <0-4294967295> route-map WORD",
+ "redistribute <ospf|table> (1-65535) metric (0-4294967295) route-map WORD",
"Redistribute information from another routing protocol\n"
"Open Shortest Path First (OSPFv2)\n"
"Non-main Kernel Routing Table\n"
@@ -13543,169 +9619,101 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_ospf_table = 1;
+ int idx_number = 2;
+ int idx_number_2 = 4;
+ int idx_word = 6;
u_int32_t metric;
struct bgp_redist *red;
u_short instance;
int protocol;
- if (strncmp(argv[0], "o", 1) == 0)
+ if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else
protocol = ZEBRA_ROUTE_TABLE;
- VTY_GET_INTEGER ("Instance ID", instance, argv[1]);
- VTY_GET_INTEGER ("metric", metric, argv[2]);
+ VTY_GET_INTEGER ("Instance ID", instance, argv[idx_number]->arg);
+ VTY_GET_INTEGER ("metric", metric, argv[idx_number_2]->arg);
- red = bgp_redist_add(vty->index, AFI_IP, protocol, instance);
- bgp_redistribute_metric_set(vty->index, red, AFI_IP, protocol, metric);
- bgp_redistribute_rmap_set (red, argv[3]);
- return bgp_redistribute_set (vty->index, AFI_IP, protocol, instance);
+ red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
+ bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, metric);
+ bgp_redistribute_rmap_set (red, argv[idx_word]->arg);
+ return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
DEFUN (no_bgp_redistribute_ipv4_ospf,
no_bgp_redistribute_ipv4_ospf_cmd,
- "no redistribute (ospf|table) <1-65535>",
+ "no redistribute <ospf|table> (1-65535) [metric (0-4294967295)] [route-map WORD]",
NO_STR
"Redistribute information from another routing protocol\n"
"Open Shortest Path First (OSPFv2)\n"
"Non-main Kernel Routing Table\n"
- "Instance ID/Table ID\n")
+ "Instance ID/Table ID\n"
+ "Metric for redistributed routes\n"
+ "Default metric\n"
+ "Route map reference\n"
+ "Pointer to route-map entries\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_ospf_table = 2;
+ int idx_number = 3;
u_short instance;
int protocol;
- if (strncmp(argv[0], "o", 1) == 0)
+ if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else
protocol = ZEBRA_ROUTE_TABLE;
- VTY_GET_INTEGER ("Instance ID", instance, argv[1]);
- return bgp_redistribute_unset (vty->index, AFI_IP, protocol, instance);
+ VTY_GET_INTEGER ("Instance ID", instance, argv[idx_number]->arg);
+ return bgp_redistribute_unset (bgp, AFI_IP, protocol, instance);
}
-ALIAS (no_bgp_redistribute_ipv4_ospf,
- no_bgp_redistribute_ipv4_ospf_rmap_cmd,
- "no redistribute (ospf|table) <1-65535> route-map WORD",
- NO_STR
- "Redistribute information from another routing protocol\n"
- "Open Shortest Path First (OSPFv2)\n"
- "Non-main Kernel Routing Table\n"
- "Instance ID/Table ID\n"
- "Route map reference\n"
- "Pointer to route-map entries\n")
-
-ALIAS (no_bgp_redistribute_ipv4_ospf,
- no_bgp_redistribute_ipv4_ospf_metric_cmd,
- "no redistribute (ospf|table) <1-65535> metric <0-4294967295>",
- NO_STR
- "Redistribute information from another routing protocol\n"
- "Open Shortest Path First (OSPFv2)\n"
- "Non-main Kernel Routing Table\n"
- "Instance ID/Table ID\n"
- "Metric for redistributed routes\n"
- "Default metric\n")
-
-ALIAS (no_bgp_redistribute_ipv4_ospf,
- no_bgp_redistribute_ipv4_ospf_rmap_metric_cmd,
- "no redistribute (ospf|table) <1-65535> route-map WORD metric <0-4294967295>",
- NO_STR
- "Redistribute information from another routing protocol\n"
- "Open Shortest Path First (OSPFv2)\n"
- "Non-main Kernel Routing Table\n"
- "Instance ID/Table ID\n"
- "Route map reference\n"
- "Pointer to route-map entries\n"
- "Metric for redistributed routes\n"
- "Default metric\n")
-
-ALIAS (no_bgp_redistribute_ipv4_ospf,
- no_bgp_redistribute_ipv4_ospf_metric_rmap_cmd,
- "no redistribute (ospf|table) <1-65535> metric <0-4294967295> route-map WORD",
+DEFUN (no_bgp_redistribute_ipv4,
+ no_bgp_redistribute_ipv4_cmd,
+ "no redistribute " FRR_IP_REDIST_STR_BGPD " [metric (0-4294967295)] [route-map WORD]",
NO_STR
"Redistribute information from another routing protocol\n"
- "Open Shortest Path First (OSPFv2)\n"
- "Non-main Kernel Routing Table\n"
- "Instance ID/Table ID\n"
+ FRR_IP_REDIST_HELP_STR_BGPD
"Metric for redistributed routes\n"
"Default metric\n"
"Route map reference\n"
"Pointer to route-map entries\n")
-
-DEFUN (no_bgp_redistribute_ipv4,
- no_bgp_redistribute_ipv4_cmd,
- "no redistribute " FRR_IP_REDIST_STR_BGPD,
- NO_STR
- "Redistribute information from another routing protocol\n"
- FRR_IP_REDIST_HELP_STR_BGPD)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 2;
int type;
- type = proto_redistnum (AFI_IP, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_redistribute_unset (vty->index, AFI_IP, type, 0);
+ return bgp_redistribute_unset (bgp, AFI_IP, type, 0);
}
-ALIAS (no_bgp_redistribute_ipv4,
- no_bgp_redistribute_ipv4_rmap_cmd,
- "no redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD",
- NO_STR
- "Redistribute information from another routing protocol\n"
- FRR_IP_REDIST_HELP_STR_BGPD
- "Route map reference\n"
- "Pointer to route-map entries\n")
-
-ALIAS (no_bgp_redistribute_ipv4,
- no_bgp_redistribute_ipv4_metric_cmd,
- "no redistribute " FRR_IP_REDIST_STR_BGPD " metric <0-4294967295>",
- NO_STR
- "Redistribute information from another routing protocol\n"
- FRR_IP_REDIST_HELP_STR_BGPD
- "Metric for redistributed routes\n"
- "Default metric\n")
-
-ALIAS (no_bgp_redistribute_ipv4,
- no_bgp_redistribute_ipv4_rmap_metric_cmd,
- "no redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD metric <0-4294967295>",
- NO_STR
- "Redistribute information from another routing protocol\n"
- FRR_IP_REDIST_HELP_STR_BGPD
- "Route map reference\n"
- "Pointer to route-map entries\n"
- "Metric for redistributed routes\n"
- "Default metric\n")
-
-ALIAS (no_bgp_redistribute_ipv4,
- no_bgp_redistribute_ipv4_metric_rmap_cmd,
- "no redistribute " FRR_IP_REDIST_STR_BGPD " metric <0-4294967295> route-map WORD",
- NO_STR
- "Redistribute information from another routing protocol\n"
- FRR_IP_REDIST_HELP_STR_BGPD
- "Metric for redistributed routes\n"
- "Default metric\n"
- "Route map reference\n"
- "Pointer to route-map entries\n")
-
DEFUN (bgp_redistribute_ipv6,
bgp_redistribute_ipv6_cmd,
"redistribute " FRR_IP6_REDIST_STR_BGPD,
"Redistribute information from another routing protocol\n"
FRR_IP6_REDIST_HELP_STR_BGPD)
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
int type;
- type = proto_redistnum (AFI_IP6, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP6, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- bgp_redist_add(vty->index, AFI_IP6, type, 0);
- return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
+ bgp_redist_add(bgp, AFI_IP6, type, 0);
+ return bgp_redistribute_set (bgp, AFI_IP6, type, 0);
}
DEFUN (bgp_redistribute_ipv6_rmap,
@@ -13716,49 +9724,55 @@ DEFUN (bgp_redistribute_ipv6_rmap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
+ int idx_word = 3;
int type;
struct bgp_redist *red;
- type = proto_redistnum (AFI_IP6, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP6, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
- bgp_redistribute_rmap_set (red, argv[1]);
- return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
+ red = bgp_redist_add(bgp, AFI_IP6, type, 0);
+ bgp_redistribute_rmap_set (red, argv[idx_word]->arg);
+ return bgp_redistribute_set (bgp, AFI_IP6, type, 0);
}
DEFUN (bgp_redistribute_ipv6_metric,
bgp_redistribute_ipv6_metric_cmd,
- "redistribute " FRR_IP6_REDIST_STR_BGPD " metric <0-4294967295>",
+ "redistribute " FRR_IP6_REDIST_STR_BGPD " metric (0-4294967295)",
"Redistribute information from another routing protocol\n"
FRR_IP6_REDIST_HELP_STR_BGPD
"Metric for redistributed routes\n"
"Default metric\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
+ int idx_number = 3;
int type;
u_int32_t metric;
struct bgp_redist *red;
- type = proto_redistnum (AFI_IP6, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP6, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_INTEGER ("metric", metric, argv[1]);
+ VTY_GET_INTEGER ("metric", metric, argv[idx_number]->arg);
- red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
- bgp_redistribute_metric_set(vty->index, red, AFI_IP6, type, metric);
- return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
+ red = bgp_redist_add(bgp, AFI_IP6, type, 0);
+ bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, metric);
+ return bgp_redistribute_set (bgp, AFI_IP6, type, 0);
}
DEFUN (bgp_redistribute_ipv6_rmap_metric,
bgp_redistribute_ipv6_rmap_metric_cmd,
- "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD metric <0-4294967295>",
+ "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD metric (0-4294967295)",
"Redistribute information from another routing protocol\n"
FRR_IP6_REDIST_HELP_STR_BGPD
"Route map reference\n"
@@ -13766,27 +9780,31 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
"Metric for redistributed routes\n"
"Default metric\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
+ int idx_word = 3;
+ int idx_number = 5;
int type;
u_int32_t metric;
struct bgp_redist *red;
- type = proto_redistnum (AFI_IP6, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP6, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_INTEGER ("metric", metric, argv[2]);
+ VTY_GET_INTEGER ("metric", metric, argv[idx_number]->arg);
- red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
- bgp_redistribute_rmap_set (red, argv[1]);
- bgp_redistribute_metric_set(vty->index, red, AFI_IP6, type, metric);
- return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
+ red = bgp_redist_add(bgp, AFI_IP6, type, 0);
+ bgp_redistribute_rmap_set (red, argv[idx_word]->arg);
+ bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, metric);
+ return bgp_redistribute_set (bgp, AFI_IP6, type, 0);
}
DEFUN (bgp_redistribute_ipv6_metric_rmap,
bgp_redistribute_ipv6_metric_rmap_cmd,
- "redistribute " FRR_IP6_REDIST_STR_BGPD " metric <0-4294967295> route-map WORD",
+ "redistribute " FRR_IP6_REDIST_STR_BGPD " metric (0-4294967295) route-map WORD",
"Redistribute information from another routing protocol\n"
FRR_IP6_REDIST_HELP_STR_BGPD
"Metric for redistributed routes\n"
@@ -13794,83 +9812,53 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 1;
+ int idx_number = 3;
+ int idx_word = 5;
int type;
u_int32_t metric;
struct bgp_redist *red;
- type = proto_redistnum (AFI_IP6, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP6, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_INTEGER ("metric", metric, argv[1]);
+ VTY_GET_INTEGER ("metric", metric, argv[idx_number]->arg);
- red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
- bgp_redistribute_metric_set(vty->index, red, AFI_IP6, SAFI_UNICAST, metric);
- bgp_redistribute_rmap_set (red, argv[2]);
- return bgp_redistribute_set (vty->index, AFI_IP6, type, 0);
+ red = bgp_redist_add(bgp, AFI_IP6, type, 0);
+ bgp_redistribute_metric_set(bgp, red, AFI_IP6, SAFI_UNICAST, metric);
+ bgp_redistribute_rmap_set (red, argv[idx_word]->arg);
+ return bgp_redistribute_set (bgp, AFI_IP6, type, 0);
}
DEFUN (no_bgp_redistribute_ipv6,
no_bgp_redistribute_ipv6_cmd,
- "no redistribute " FRR_IP6_REDIST_STR_BGPD,
+ "no redistribute " FRR_IP6_REDIST_STR_BGPD " [metric (0-4294967295)] [route-map WORD]",
NO_STR
"Redistribute information from another routing protocol\n"
- FRR_IP6_REDIST_HELP_STR_BGPD)
+ FRR_IP6_REDIST_HELP_STR_BGPD
+ "Metric for redistributed routes\n"
+ "Default metric\n"
+ "Route map reference\n"
+ "Pointer to route-map entries\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_protocol = 2;
int type;
- type = proto_redistnum (AFI_IP6, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_BGP)
+ type = proto_redistnum (AFI_IP6, argv[idx_protocol]->text);
+ if (type < 0)
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_redistribute_unset (vty->index, AFI_IP6, type, 0);
+ return bgp_redistribute_unset (bgp, AFI_IP6, type, 0);
}
-ALIAS (no_bgp_redistribute_ipv6,
- no_bgp_redistribute_ipv6_rmap_cmd,
- "no redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD",
- NO_STR
- "Redistribute information from another routing protocol\n"
- FRR_IP6_REDIST_HELP_STR_BGPD
- "Route map reference\n"
- "Pointer to route-map entries\n")
-
-ALIAS (no_bgp_redistribute_ipv6,
- no_bgp_redistribute_ipv6_metric_cmd,
- "no redistribute " FRR_IP6_REDIST_STR_BGPD " metric <0-4294967295>",
- NO_STR
- "Redistribute information from another routing protocol\n"
- FRR_IP6_REDIST_HELP_STR_BGPD
- "Metric for redistributed routes\n"
- "Default metric\n")
-
-ALIAS (no_bgp_redistribute_ipv6,
- no_bgp_redistribute_ipv6_rmap_metric_cmd,
- "no redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD metric <0-4294967295>",
- NO_STR
- "Redistribute information from another routing protocol\n"
- FRR_IP6_REDIST_HELP_STR_BGPD
- "Route map reference\n"
- "Pointer to route-map entries\n"
- "Metric for redistributed routes\n"
- "Default metric\n")
-
-ALIAS (no_bgp_redistribute_ipv6,
- no_bgp_redistribute_ipv6_metric_rmap_cmd,
- "no redistribute " FRR_IP6_REDIST_STR_BGPD " metric <0-4294967295> route-map WORD",
- NO_STR
- "Redistribute information from another routing protocol\n"
- FRR_IP6_REDIST_HELP_STR_BGPD
- "Metric for redistributed routes\n"
- "Default metric\n"
- "Route map reference\n"
- "Pointer to route-map entries\n")
-
int
bgp_config_write_redistribute (struct vty *vty, struct bgp *bgp, afi_t afi,
safi_t safi, int *write)
@@ -14004,19 +9992,18 @@ bgp_vty_init (void)
install_default (BGP_VPNV6_NODE);
install_default (BGP_ENCAP_NODE);
install_default (BGP_ENCAPV6_NODE);
-
+
/* "bgp multiple-instance" commands. */
install_element (CONFIG_NODE, &bgp_multiple_instance_cmd);
install_element (CONFIG_NODE, &no_bgp_multiple_instance_cmd);
/* "bgp config-type" commands. */
install_element (CONFIG_NODE, &bgp_config_type_cmd);
- install_element (CONFIG_NODE, &no_bgp_config_type_val_cmd);
+ install_element (CONFIG_NODE, &no_bgp_config_type_cmd);
/* bgp route-map delay-timer commands. */
install_element (CONFIG_NODE, &bgp_set_route_map_delay_timer_cmd);
install_element (CONFIG_NODE, &no_bgp_set_route_map_delay_timer_cmd);
- install_element (CONFIG_NODE, &no_bgp_set_route_map_delay_timer_val_cmd);
/* Dummy commands (Currently not supported) */
install_element (BGP_NODE, &no_synchronization_cmd);
@@ -14024,30 +10011,21 @@ bgp_vty_init (void)
/* "router bgp" commands. */
install_element (CONFIG_NODE, &router_bgp_cmd);
- install_element (CONFIG_NODE, &router_bgp_instance_cmd);
- install_element (CONFIG_NODE, &router_bgp_noasn_cmd);
/* "no router bgp" commands. */
install_element (CONFIG_NODE, &no_router_bgp_cmd);
- install_element (CONFIG_NODE, &no_router_bgp_instance_cmd);
- install_element (CONFIG_NODE, &no_router_bgp_noasn_cmd);
/* "bgp router-id" commands. */
install_element (BGP_NODE, &bgp_router_id_cmd);
install_element (BGP_NODE, &no_bgp_router_id_cmd);
- install_element (BGP_NODE, &no_bgp_router_id_val_cmd);
/* "bgp cluster-id" commands. */
install_element (BGP_NODE, &bgp_cluster_id_cmd);
- install_element (BGP_NODE, &bgp_cluster_id32_cmd);
install_element (BGP_NODE, &no_bgp_cluster_id_cmd);
- install_element (BGP_NODE, &no_bgp_cluster_id_ip_cmd);
- install_element (BGP_NODE, &no_bgp_cluster_id_decimal_cmd);
/* "bgp confederation" commands. */
install_element (BGP_NODE, &bgp_confederation_identifier_cmd);
install_element (BGP_NODE, &no_bgp_confederation_identifier_cmd);
- install_element (BGP_NODE, &no_bgp_confederation_identifier_arg_cmd);
/* "bgp confederation peers" commands. */
install_element (BGP_NODE, &bgp_confederation_peers_cmd);
@@ -14057,12 +10035,9 @@ bgp_vty_init (void)
install_element (BGP_NODE, &bgp_maxmed_admin_cmd);
install_element (BGP_NODE, &no_bgp_maxmed_admin_cmd);
install_element (BGP_NODE, &bgp_maxmed_admin_medv_cmd);
- install_element (BGP_NODE, &no_bgp_maxmed_admin_medv_cmd);
install_element (BGP_NODE, &bgp_maxmed_onstartup_cmd);
install_element (BGP_NODE, &no_bgp_maxmed_onstartup_cmd);
- install_element (BGP_NODE, &no_bgp_maxmed_onstartup_period_cmd);
install_element (BGP_NODE, &bgp_maxmed_onstartup_medv_cmd);
- install_element (BGP_NODE, &no_bgp_maxmed_onstartup_period_medv_cmd);
/* bgp disable-ebgp-connected-nh-check */
install_element (BGP_NODE, &bgp_disable_connected_route_check_cmd);
@@ -14072,7 +10047,6 @@ bgp_vty_init (void)
install_element (BGP_NODE, &bgp_update_delay_cmd);
install_element (BGP_NODE, &no_bgp_update_delay_cmd);
install_element (BGP_NODE, &bgp_update_delay_establish_wait_cmd);
- install_element (BGP_NODE, &no_bgp_update_delay_establish_wait_cmd);
install_element (BGP_NODE, &bgp_wpkt_quanta_cmd);
install_element (BGP_NODE, &no_bgp_wpkt_quanta_cmd);
@@ -14083,38 +10057,27 @@ bgp_vty_init (void)
/* "maximum-paths" commands. */
install_element (BGP_NODE, &bgp_maxpaths_cmd);
install_element (BGP_NODE, &no_bgp_maxpaths_cmd);
- install_element (BGP_NODE, &no_bgp_maxpaths_arg_cmd);
install_element (BGP_IPV4_NODE, &bgp_maxpaths_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_arg_cmd);
install_element (BGP_IPV6_NODE, &bgp_maxpaths_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_arg_cmd);
install_element (BGP_NODE, &bgp_maxpaths_ibgp_cmd);
install_element(BGP_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_NODE, &no_bgp_maxpaths_ibgp_cmd);
- install_element (BGP_NODE, &no_bgp_maxpaths_ibgp_arg_cmd);
- install_element (BGP_NODE, &no_bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_IPV4_NODE, &bgp_maxpaths_ibgp_cmd);
install_element(BGP_IPV4_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_ibgp_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_ibgp_cluster_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_ibgp_arg_cmd);
install_element (BGP_IPV6_NODE, &bgp_maxpaths_ibgp_cmd);
install_element(BGP_IPV6_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_ibgp_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_ibgp_arg_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_ibgp_cluster_cmd);
/* "timers bgp" commands. */
install_element (BGP_NODE, &bgp_timers_cmd);
install_element (BGP_NODE, &no_bgp_timers_cmd);
- install_element (BGP_NODE, &no_bgp_timers_arg_cmd);
/* route-map delay-timer commands - per instance for backwards compat. */
install_element (BGP_NODE, &bgp_set_route_map_delay_timer_cmd);
install_element (BGP_NODE, &no_bgp_set_route_map_delay_timer_cmd);
- install_element (BGP_NODE, &no_bgp_set_route_map_delay_timer_val_cmd);
/* "bgp client-to-client reflection" commands */
install_element (BGP_NODE, &no_bgp_client_to_client_reflection_cmd);
@@ -14123,7 +10086,7 @@ bgp_vty_init (void)
/* "bgp always-compare-med" commands */
install_element (BGP_NODE, &bgp_always_compare_med_cmd);
install_element (BGP_NODE, &no_bgp_always_compare_med_cmd);
-
+
/* "bgp deterministic-med" commands */
install_element (BGP_NODE, &bgp_deterministic_med_cmd);
install_element (BGP_NODE, &no_bgp_deterministic_med_cmd);
@@ -14133,10 +10096,11 @@ bgp_vty_init (void)
install_element (BGP_NODE, &no_bgp_graceful_restart_cmd);
install_element (BGP_NODE, &bgp_graceful_restart_stalepath_time_cmd);
install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_cmd);
- install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_val_cmd);
install_element (BGP_NODE, &bgp_graceful_restart_restart_time_cmd);
install_element (BGP_NODE, &no_bgp_graceful_restart_restart_time_cmd);
- install_element (BGP_NODE, &no_bgp_graceful_restart_restart_time_val_cmd);
+
+ install_element (BGP_NODE, &bgp_graceful_restart_preserve_fw_cmd);
+ install_element (BGP_NODE, &no_bgp_graceful_restart_preserve_fw_cmd);
/* "bgp fast-external-failover" commands */
install_element (BGP_NODE, &bgp_fast_external_failover_cmd);
@@ -14168,16 +10132,12 @@ bgp_vty_init (void)
/* "bgp bestpath med" commands */
install_element (BGP_NODE, &bgp_bestpath_med_cmd);
- install_element (BGP_NODE, &bgp_bestpath_med2_cmd);
- install_element (BGP_NODE, &bgp_bestpath_med3_cmd);
install_element (BGP_NODE, &no_bgp_bestpath_med_cmd);
- install_element (BGP_NODE, &no_bgp_bestpath_med2_cmd);
- install_element (BGP_NODE, &no_bgp_bestpath_med3_cmd);
/* "no bgp default ipv4-unicast" commands. */
install_element (BGP_NODE, &no_bgp_default_ipv4_unicast_cmd);
install_element (BGP_NODE, &bgp_default_ipv4_unicast_cmd);
-
+
/* "bgp network import-check" commands. */
install_element (BGP_NODE, &bgp_network_import_check_cmd);
install_element (BGP_NODE, &bgp_network_import_check_exact_cmd);
@@ -14186,7 +10146,6 @@ bgp_vty_init (void)
/* "bgp default local-preference" commands. */
install_element (BGP_NODE, &bgp_default_local_preference_cmd);
install_element (BGP_NODE, &no_bgp_default_local_preference_cmd);
- install_element (BGP_NODE, &no_bgp_default_local_preference_val_cmd);
/* bgp default show-hostname */
install_element (BGP_NODE, &bgp_default_show_hostname_cmd);
@@ -14195,7 +10154,6 @@ bgp_vty_init (void)
/* "bgp default subgroup-pkt-queue-max" commands. */
install_element (BGP_NODE, &bgp_default_subgroup_pkt_queue_max_cmd);
install_element (BGP_NODE, &no_bgp_default_subgroup_pkt_queue_max_cmd);
- install_element (BGP_NODE, &no_bgp_default_subgroup_pkt_queue_max_val_cmd);
/* bgp ibgp-allow-policy-mods command */
install_element (BGP_NODE, &bgp_rr_allow_outbound_policy_cmd);
@@ -14204,7 +10162,6 @@ bgp_vty_init (void)
/* "bgp listen limit" commands. */
install_element (BGP_NODE, &bgp_listen_limit_cmd);
install_element (BGP_NODE, &no_bgp_listen_limit_cmd);
- install_element (BGP_NODE, &no_bgp_listen_limit_val_cmd);
/* "bgp listen range" commands. */
install_element (BGP_NODE, &bgp_listen_range_cmd);
@@ -14214,18 +10171,10 @@ bgp_vty_init (void)
install_element (BGP_NODE, &neighbor_remote_as_cmd);
install_element (BGP_NODE, &neighbor_interface_config_cmd);
install_element (BGP_NODE, &neighbor_interface_config_v6only_cmd);
- install_element (BGP_NODE, &neighbor_interface_config_peergroup_cmd);
- install_element (BGP_NODE, &neighbor_interface_config_v6only_peergroup_cmd);
install_element (BGP_NODE, &neighbor_interface_config_remote_as_cmd);
install_element (BGP_NODE, &neighbor_interface_v6only_config_remote_as_cmd);
install_element (BGP_NODE, &no_neighbor_cmd);
- install_element (BGP_NODE, &no_neighbor_remote_as_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_cmd);
- install_element (BGP_NODE, &no_neighbor_interface_config_v6only_cmd);
- install_element (BGP_NODE, &no_neighbor_interface_config_peergroup_cmd);
- install_element (BGP_NODE, &no_neighbor_interface_config_v6only_peergroup_cmd);
- install_element (BGP_NODE, &no_neighbor_interface_config_remote_as_cmd);
- install_element (BGP_NODE, &no_neighbor_interface_config_v6only_remote_as_cmd);
/* "neighbor peer-group" commands. */
install_element (BGP_NODE, &neighbor_peer_group_cmd);
@@ -14237,9 +10186,6 @@ bgp_vty_init (void)
install_element (BGP_NODE, &neighbor_local_as_no_prepend_cmd);
install_element (BGP_NODE, &neighbor_local_as_no_prepend_replace_as_cmd);
install_element (BGP_NODE, &no_neighbor_local_as_cmd);
- install_element (BGP_NODE, &no_neighbor_local_as_val_cmd);
- install_element (BGP_NODE, &no_neighbor_local_as_val2_cmd);
- install_element (BGP_NODE, &no_neighbor_local_as_val3_cmd);
/* "neighbor solo" commands. */
install_element (BGP_NODE, &neighbor_solo_cmd);
@@ -14248,7 +10194,6 @@ bgp_vty_init (void)
/* "neighbor password" commands. */
install_element (BGP_NODE, &neighbor_password_cmd);
install_element (BGP_NODE, &no_neighbor_password_cmd);
- install_element (BGP_NODE, &no_neighbor_password_val_cmd);
/* "neighbor activate" commands. */
install_element (BGP_NODE, &neighbor_activate_cmd);
@@ -14298,7 +10243,7 @@ bgp_vty_init (void)
install_element (BGP_VPNV6_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_ENCAPV6_NODE, &no_neighbor_set_peer_group_cmd);
-
+
/* "neighbor softreconfiguration inbound" commands.*/
install_element (BGP_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_NODE, &no_neighbor_soft_reconfiguration_cmd);
@@ -14321,205 +10266,25 @@ bgp_vty_init (void)
/* "neighbor attribute-unchanged" commands. */
install_element (BGP_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged1_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged2_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged3_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged4_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged5_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged6_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged7_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged8_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged9_cmd);
- install_element (BGP_NODE, &neighbor_attr_unchanged10_cmd);
install_element (BGP_NODE, &no_neighbor_attr_unchanged_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged1_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged2_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged3_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged4_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged5_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged6_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged7_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged8_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged9_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged10_cmd);
install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged1_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged2_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged3_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged4_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged5_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged6_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged7_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged8_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged9_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged10_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged1_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged2_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged3_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged4_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged5_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged6_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged7_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged8_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged9_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged10_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged1_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged2_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged3_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged4_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged5_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged6_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged7_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged8_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged9_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged10_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged1_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged2_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged3_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged4_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged5_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged6_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged7_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged8_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged9_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged10_cmd);
install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged1_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged2_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged3_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged4_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged5_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged6_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged7_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged8_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged9_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged10_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged1_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged2_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged3_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged4_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged5_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged6_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged7_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged8_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged9_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged10_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged1_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged2_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged3_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged4_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged5_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged6_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged7_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged8_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged9_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged10_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged1_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged2_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged3_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged4_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged5_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged6_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged7_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged8_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged9_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged10_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged1_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged2_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged3_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged4_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged5_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged6_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged7_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged8_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged9_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged10_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged1_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged2_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged3_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged4_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged5_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged6_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged7_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged8_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged9_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged10_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged1_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged2_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged3_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged4_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged5_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged6_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged7_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged8_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged9_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged10_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged1_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged2_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged3_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged4_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged5_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged6_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged7_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged8_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged9_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_attr_unchanged10_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged1_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged2_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged3_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged4_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged5_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged6_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged7_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged8_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged9_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_attr_unchanged10_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged1_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged2_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged3_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged4_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged5_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged6_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged7_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged8_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged9_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_attr_unchanged10_cmd);
install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged1_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged2_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged3_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged4_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged5_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged6_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged7_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged8_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged9_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_attr_unchanged10_cmd);
install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged1_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged2_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged3_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged4_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged5_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged6_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged7_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged8_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged9_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_attr_unchanged10_cmd);
/* "nexthop-local unchanged" commands */
install_element (BGP_IPV6_NODE, &neighbor_nexthop_local_unchanged_cmd);
@@ -14786,18 +10551,14 @@ bgp_vty_init (void)
install_element (BGP_NODE, &neighbor_ebgp_multihop_cmd);
install_element (BGP_NODE, &neighbor_ebgp_multihop_ttl_cmd);
install_element (BGP_NODE, &no_neighbor_ebgp_multihop_cmd);
- install_element (BGP_NODE, &no_neighbor_ebgp_multihop_ttl_cmd);
/* "neighbor disable-connected-check" commands. */
install_element (BGP_NODE, &neighbor_disable_connected_check_cmd);
install_element (BGP_NODE, &no_neighbor_disable_connected_check_cmd);
- install_element (BGP_NODE, &neighbor_enforce_multihop_cmd);
- install_element (BGP_NODE, &no_neighbor_enforce_multihop_cmd);
/* "neighbor description" commands. */
install_element (BGP_NODE, &neighbor_description_cmd);
install_element (BGP_NODE, &no_neighbor_description_cmd);
- install_element (BGP_NODE, &no_neighbor_description_val_cmd);
/* "neighbor update-source" commands. "*/
install_element (BGP_NODE, &neighbor_update_source_cmd);
@@ -14807,57 +10568,43 @@ bgp_vty_init (void)
install_element (BGP_NODE, &neighbor_default_originate_cmd);
install_element (BGP_NODE, &neighbor_default_originate_rmap_cmd);
install_element (BGP_NODE, &no_neighbor_default_originate_cmd);
- install_element (BGP_NODE, &no_neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV4_NODE, &neighbor_default_originate_cmd);
install_element (BGP_IPV4_NODE, &neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_default_originate_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_default_originate_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_default_originate_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV6_NODE, &neighbor_default_originate_cmd);
install_element (BGP_IPV6_NODE, &neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_default_originate_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_default_originate_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_default_originate_rmap_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_default_originate_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_default_originate_rmap_cmd);
/* "neighbor port" commands. */
install_element (BGP_NODE, &neighbor_port_cmd);
install_element (BGP_NODE, &no_neighbor_port_cmd);
- install_element (BGP_NODE, &no_neighbor_port_val_cmd);
/* "neighbor weight" commands. */
install_element (BGP_NODE, &neighbor_weight_cmd);
install_element (BGP_NODE, &no_neighbor_weight_cmd);
- install_element (BGP_NODE, &no_neighbor_weight_val_cmd);
+
install_element (BGP_IPV4_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_weight_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_weight_val_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_weight_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_weight_val_cmd);
install_element (BGP_IPV6_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_weight_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_weight_val_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_weight_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_weight_val_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_weight_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_weight_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_weight_val_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_weight_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_weight_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_weight_val_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_weight_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_weight_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_weight_val_cmd);
install_element (BGP_ENCAPV6_NODE, &neighbor_weight_cmd);
install_element (BGP_ENCAPV6_NODE, &no_neighbor_weight_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_weight_val_cmd);
/* "neighbor override-capability" commands. */
install_element (BGP_NODE, &neighbor_override_capability_cmd);
@@ -14870,17 +10617,14 @@ bgp_vty_init (void)
/* "neighbor timers" commands. */
install_element (BGP_NODE, &neighbor_timers_cmd);
install_element (BGP_NODE, &no_neighbor_timers_cmd);
- install_element (BGP_NODE, &no_neighbor_timers_val_cmd);
/* "neighbor timers connect" commands. */
install_element (BGP_NODE, &neighbor_timers_connect_cmd);
install_element (BGP_NODE, &no_neighbor_timers_connect_cmd);
- install_element (BGP_NODE, &no_neighbor_timers_connect_val_cmd);
/* "neighbor advertisement-interval" commands. */
install_element (BGP_NODE, &neighbor_advertise_interval_cmd);
install_element (BGP_NODE, &no_neighbor_advertise_interval_cmd);
- install_element (BGP_NODE, &no_neighbor_advertise_interval_val_cmd);
/* "neighbor interface" commands. */
install_element (BGP_NODE, &neighbor_interface_cmd);
@@ -14994,12 +10738,6 @@ bgp_vty_init (void)
install_element (BGP_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_NODE, &no_neighbor_maximum_prefix_cmd);
- install_element (BGP_NODE, &no_neighbor_maximum_prefix_val_cmd);
- install_element (BGP_NODE, &no_neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_NODE, &no_neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_NODE, &no_neighbor_maximum_prefix_threshold_warning_cmd);
- install_element (BGP_NODE, &no_neighbor_maximum_prefix_restart_cmd);
- install_element (BGP_NODE, &no_neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV4_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_IPV4_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_IPV4_NODE, &neighbor_maximum_prefix_warning_cmd);
@@ -15007,12 +10745,6 @@ bgp_vty_init (void)
install_element (BGP_IPV4_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_IPV4_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_val_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_threshold_warning_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_restart_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_warning_cmd);
@@ -15020,12 +10752,6 @@ bgp_vty_init (void)
install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_val_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_threshold_warning_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_restart_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_warning_cmd);
@@ -15033,12 +10759,6 @@ bgp_vty_init (void)
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_val_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_threshold_warning_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_restart_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_maximum_prefix_warning_cmd);
@@ -15046,12 +10766,6 @@ bgp_vty_init (void)
install_element (BGP_IPV6M_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_val_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_threshold_warning_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_restart_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_warning_cmd);
@@ -15059,12 +10773,6 @@ bgp_vty_init (void)
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_val_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_threshold_warning_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_restart_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_maximum_prefix_warning_cmd);
@@ -15072,12 +10780,6 @@ bgp_vty_init (void)
install_element (BGP_VPNV6_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_val_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_threshold_warning_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_restart_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_maximum_prefix_threshold_cmd);
@@ -15086,12 +10788,6 @@ bgp_vty_init (void)
install_element (BGP_ENCAP_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_maximum_prefix_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_maximum_prefix_val_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_maximum_prefix_threshold_warning_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_maximum_prefix_restart_cmd);
- install_element (BGP_ENCAP_NODE, &no_neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_ENCAPV6_NODE, &neighbor_maximum_prefix_cmd);
install_element (BGP_ENCAPV6_NODE, &neighbor_maximum_prefix_threshold_cmd);
@@ -15100,58 +10796,36 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &neighbor_maximum_prefix_restart_cmd);
install_element (BGP_ENCAPV6_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
install_element (BGP_ENCAPV6_NODE, &no_neighbor_maximum_prefix_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_maximum_prefix_val_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_maximum_prefix_threshold_warning_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_maximum_prefix_restart_cmd);
- install_element (BGP_ENCAPV6_NODE, &no_neighbor_maximum_prefix_threshold_restart_cmd);
/* "neighbor allowas-in" */
install_element (BGP_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_NODE, &neighbor_allowas_in_arg_cmd);
install_element (BGP_NODE, &no_neighbor_allowas_in_cmd);
- install_element (BGP_NODE, &no_neighbor_allowas_in_val_cmd);
install_element (BGP_IPV4_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_allowas_in_arg_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_allowas_in_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_allowas_in_val_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_allowas_in_arg_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_allowas_in_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_allowas_in_val_cmd);
install_element (BGP_IPV6_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_allowas_in_arg_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_allowas_in_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_allowas_in_val_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_allowas_in_arg_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_allowas_in_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_allowas_in_val_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_allowas_in_arg_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_allowas_in_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_allowas_in_val_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_allowas_in_arg_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_allowas_in_cmd);
- install_element (BGP_VPNV6_NODE, &no_neighbor_allowas_in_val_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_allowas_in_arg_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_ENCAPV6_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_allowas_in_arg_cmd);
install_element (BGP_ENCAPV6_NODE, &no_neighbor_allowas_in_cmd);
/* address-family commands. */
- install_element (BGP_NODE, &address_family_ipv4_cmd);
install_element (BGP_NODE, &address_family_ipv4_safi_cmd);
- install_element (BGP_NODE, &address_family_ipv6_cmd);
install_element (BGP_NODE, &address_family_ipv6_safi_cmd);
+#ifdef KEEP_OLD_VPN_COMMANDS
install_element (BGP_NODE, &address_family_vpnv4_cmd);
install_element (BGP_NODE, &address_family_vpnv6_cmd);
+#endif /* KEEP_OLD_VPN_COMMANDS */
+
install_element (BGP_NODE, &address_family_encap_cmd);
- install_element (BGP_NODE, &address_family_encapv4_cmd);
install_element (BGP_NODE, &address_family_encapv6_cmd);
/* "exit-address-family" command. */
@@ -15166,414 +10840,91 @@ bgp_vty_init (void)
/* "clear ip bgp commands" */
install_element (ENABLE_NODE, &clear_ip_bgp_all_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_cmd);
-
- install_element (ENABLE_NODE, &clear_bgp_all_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_all_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_all_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_all_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_group_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_group_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_group_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_group_cmd);
- install_element (ENABLE_NODE, &clear_bgp_external_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_external_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_external_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_external_cmd);
- install_element (ENABLE_NODE, &clear_bgp_as_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_as_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_as_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_as_cmd);
-
- /* "clear ip bgp neighbor soft in" */
- install_element (ENABLE_NODE, &clear_ip_bgp_all_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_all_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_all_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_all_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_all_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_all_ipv4_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_ipv4_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_ipv4_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_ipv4_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_ipv4_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_ipv4_in_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_ipv4_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_all_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_all_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_all_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_all_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_group_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_group_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_group_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_group_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_group_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_external_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_external_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_external_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_external_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_external_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_as_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_as_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_as_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_as_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_as_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_all_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_all_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_all_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_all_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_all_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_group_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_group_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_group_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_group_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_group_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_external_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_external_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_external_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_external_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_external_in_prefix_filter_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_as_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_as_soft_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_as_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_as_in_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_as_in_prefix_filter_cmd);
/* clear ip bgp prefix */
install_element (ENABLE_NODE, &clear_ip_bgp_prefix_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_prefix_cmd);
install_element (ENABLE_NODE, &clear_bgp_ipv6_safi_prefix_cmd);
install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_safi_prefix_cmd);
- /* "clear ip bgp neighbor soft out" */
- install_element (ENABLE_NODE, &clear_ip_bgp_all_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_all_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_all_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_all_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_ipv4_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_ipv4_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_all_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_all_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_all_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_group_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_group_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_group_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_group_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_external_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_external_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_external_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_external_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_as_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_as_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_as_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_as_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_all_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_all_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_all_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_all_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_group_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_group_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_group_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_group_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_external_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_external_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_external_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_external_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_as_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_as_soft_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_as_out_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_as_out_cmd);
-
- /* "clear ip bgp neighbor soft" */
- install_element (ENABLE_NODE, &clear_ip_bgp_all_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_all_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_all_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_peer_group_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_peer_group_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_external_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_external_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_as_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_instance_as_ipv4_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_all_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_peer_group_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_peer_group_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_external_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_external_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_as_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_as_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_all_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_all_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_peer_group_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_peer_group_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_external_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_external_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_ipv6_as_soft_cmd);
- install_element (ENABLE_NODE, &clear_bgp_instance_ipv6_as_soft_cmd);
-
- /* "show ip bgp summary" commands. */
- install_element (VIEW_NODE, &show_ip_bgp_summary_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_updgrps_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_all_updgrps_cmd);
- install_element (VIEW_NODE, &show_bgp_updgrps_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_updgrps_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_updgrps_cmd);
+ /* "show [ip] bgp summary" commands. */
install_element (VIEW_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_updgrps_s_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_s_cmd);
- install_element (VIEW_NODE, &show_bgp_updgrps_s_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_updgrps_s_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_updgrps_s_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_cmd);
- install_element (VIEW_NODE, &show_bgp_updgrps_adj_cmd);
install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_cmd);
- install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_s_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
- install_element (VIEW_NODE, &show_bgp_updgrps_adj_s_cmd);
install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
+ install_element (VIEW_NODE, &show_bgp_instance_updgrps_stats_cmd);
+ install_element (VIEW_NODE, &show_bgp_updgrps_adj_cmd);
+ install_element (VIEW_NODE, &show_bgp_updgrps_adj_s_cmd);
+ install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_cmd);
install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_summary_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_all_summary_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_safi_summary_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv4_safi_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv4_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv4_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv4_all_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_all_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_safi_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_all_summary_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_safi_summary_cmd);
-
- /* "show ip bgp neighbors" commands. */
+ install_element (VIEW_NODE, &show_bgp_updgrps_stats_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_summary_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_s_cmd);
+ install_element (VIEW_NODE, &show_ip_bgp_updgrps_cmd);
+
+ /* "show [ip] bgp neighbors" commands. */
install_element (VIEW_NODE, &show_ip_bgp_neighbors_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbors_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_neighbors_peer_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbors_peer_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_neighbors_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_all_neighbors_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_neighbors_peer_cmd);
-
- install_element (VIEW_NODE, &show_bgp_neighbors_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_neighbors_cmd);
- install_element (VIEW_NODE, &show_bgp_neighbors_peer_cmd);
- install_element (VIEW_NODE, &show_bgp_ipv6_neighbors_peer_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_neighbors_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbors_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_neighbors_peer_cmd);
- install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbors_peer_cmd);
-
- /* Old commands. */
- install_element (VIEW_NODE, &show_ipv6_bgp_summary_cmd);
- install_element (VIEW_NODE, &show_ipv6_mbgp_summary_cmd);
-
- /* "show ip bgp peer-group" commands. */
+
+ /* "show [ip] bgp peer-group" commands. */
install_element (VIEW_NODE, &show_ip_bgp_peer_groups_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_peer_groups_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_peer_group_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_instance_peer_group_cmd);
- /* "show ip bgp paths" commands. */
+ /* "show [ip] bgp paths" commands. */
install_element (VIEW_NODE, &show_ip_bgp_paths_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_ipv4_paths_cmd);
- /* "show ip bgp community" commands. */
+ /* "show [ip] bgp community" commands. */
install_element (VIEW_NODE, &show_ip_bgp_community_info_cmd);
- /* "show ip bgp attribute-info" commands. */
+ /* "show ip bgp large-community" commands. */
+ install_element (VIEW_NODE, &show_ip_bgp_lcommunity_info_cmd);
+ /* "show [ip] bgp attribute-info" commands. */
install_element (VIEW_NODE, &show_ip_bgp_attr_info_cmd);
/* "redistribute" commands. */
install_element (BGP_NODE, &bgp_redistribute_ipv4_cmd);
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_cmd);
install_element (BGP_NODE, &bgp_redistribute_ipv4_rmap_cmd);
- install_element (BGP_NODE, &no_bgp_redistribute_ipv4_rmap_cmd);
install_element (BGP_NODE, &bgp_redistribute_ipv4_metric_cmd);
- install_element (BGP_NODE, &no_bgp_redistribute_ipv4_metric_cmd);
install_element (BGP_NODE, &bgp_redistribute_ipv4_rmap_metric_cmd);
install_element (BGP_NODE, &bgp_redistribute_ipv4_metric_rmap_cmd);
- install_element (BGP_NODE, &no_bgp_redistribute_ipv4_rmap_metric_cmd);
- install_element (BGP_NODE, &no_bgp_redistribute_ipv4_metric_rmap_cmd);
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_cmd);
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_cmd);
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_rmap_cmd);
- install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_rmap_cmd);
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_metric_cmd);
- install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_metric_cmd);
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_rmap_metric_cmd);
- install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_rmap_metric_cmd);
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_metric_rmap_cmd);
- install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_metric_rmap_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_rmap_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_rmap_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_metric_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_metric_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_rmap_metric_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_metric_rmap_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_rmap_metric_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_metric_rmap_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_ospf_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_ospf_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_ospf_rmap_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_ospf_rmap_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_ospf_metric_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_ospf_metric_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_ospf_rmap_metric_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_ospf_rmap_metric_cmd);
install_element (BGP_IPV4_NODE, &bgp_redistribute_ipv4_ospf_metric_rmap_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_redistribute_ipv4_ospf_metric_rmap_cmd);
install_element (BGP_IPV6_NODE, &bgp_redistribute_ipv6_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_cmd);
install_element (BGP_IPV6_NODE, &bgp_redistribute_ipv6_rmap_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_rmap_cmd);
install_element (BGP_IPV6_NODE, &bgp_redistribute_ipv6_metric_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_metric_cmd);
install_element (BGP_IPV6_NODE, &bgp_redistribute_ipv6_rmap_metric_cmd);
install_element (BGP_IPV6_NODE, &bgp_redistribute_ipv6_metric_rmap_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_rmap_metric_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_metric_rmap_cmd);
/* ttl_security commands */
install_element (BGP_NODE, &neighbor_ttl_security_cmd);
install_element (BGP_NODE, &no_neighbor_ttl_security_cmd);
- /* "show bgp memory" commands. */
+ /* "show [ip] bgp memory" commands. */
install_element (VIEW_NODE, &show_bgp_memory_cmd);
-
- /* "show bgp views" commands. */
+
+ /* "show [ip] bgp views" commands. */
install_element (VIEW_NODE, &show_bgp_views_cmd);
-
- /* "show bgp vrfs" commands. */
+
+ /* "show [ip] bgp vrfs" commands. */
install_element (VIEW_NODE, &show_bgp_vrfs_cmd);
-
+
/* Community-list. */
community_list_vty ();
}
@@ -15621,48 +10972,38 @@ community_list_perror (struct vty *vty, int ret)
}
}
-/* VTY interface for community_set() function. */
-static int
-community_list_set_vty (struct vty *vty, int argc, const char **argv,
- int style, int reject_all_digit_name)
-{
- int ret;
- int direct;
- char *str;
+/* "community-list" keyword help string. */
+#define COMMUNITY_LIST_STR "Add a community list entry\n"
- /* Check the list type. */
- if (strncmp (argv[1], "p", 1) == 0)
- direct = COMMUNITY_PERMIT;
- else if (strncmp (argv[1], "d", 1) == 0)
- direct = COMMUNITY_DENY;
- else
- {
- vty_out (vty, "%% Matching condition must be permit or deny%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- /* All digit name check. */
- if (reject_all_digit_name && all_digit (argv[0]))
- {
- vty_out (vty, "%% Community name cannot have all digits%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+/* ip community-list standard */
+DEFUN (ip_community_list_standard,
+ ip_community_list_standard_cmd,
+ "ip community-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+ IP_STR
+ COMMUNITY_LIST_STR
+ "Community list number (standard)\n"
+ "Add an standard community-list entry\n"
+ "Community list name\n"
+ "Specify community to reject\n"
+ "Specify community to accept\n"
+ COMMUNITY_VAL_STR)
+{
+ char *cl_name_or_number = NULL;
+ int direct = 0;
+ int style = COMMUNITY_LIST_STANDARD;
- /* Concat community string argument. */
- if (argc > 1)
- str = argv_concat (argv, argc, 2);
- else
- str = NULL;
+ int idx = 0;
+ argv_find (argv, argc, "(1-99)", &idx);
+ argv_find (argv, argc, "WORD", &idx);
+ cl_name_or_number = argv[idx]->arg;
+ direct = argv_find (argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY;
+ argv_find (argv, argc, "AA:NN", &idx);
+ char *str = argv_concat (argv, argc, idx);
- /* When community_list_set() return nevetive value, it means
- malformed community string. */
- ret = community_list_set (bgp_clist, argv[0], str, direct, style);
+ int ret = community_list_set (bgp_clist, cl_name_or_number, str, direct, style);
- /* Free temporary community list string allocated by
- argv_concat(). */
- if (str)
- XFREE (MTYPE_TMP, str);
+ XFREE (MTYPE_TMP, str);
if (ret < 0)
{
@@ -15674,40 +11015,34 @@ community_list_set_vty (struct vty *vty, int argc, const char **argv,
return CMD_SUCCESS;
}
-/* Communiyt-list entry delete. */
-static int
-community_list_unset_vty (struct vty *vty, int argc, const char **argv,
- int style, int delete_all)
+DEFUN (no_ip_community_list_standard_all,
+ no_ip_community_list_standard_all_cmd,
+ "no ip community-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+ NO_STR
+ IP_STR
+ COMMUNITY_LIST_STR
+ "Community list number (standard)\n"
+ "Add an standard community-list entry\n"
+ "Community list name\n"
+ "Specify community to reject\n"
+ "Specify community to accept\n"
+ COMMUNITY_VAL_STR)
{
- int ret;
- int direct = 0;
- char *str = NULL;
+ int delete_all = 0;
- if (argc > 1)
- {
- /* Check the list direct. */
- if (strncmp (argv[1], "p", 1) == 0)
- direct = COMMUNITY_PERMIT;
- else if (strncmp (argv[1], "d", 1) == 0)
- direct = COMMUNITY_DENY;
- else
- {
- vty_out (vty, "%% Matching condition must be permit or deny%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ char *cl_name_or_number = NULL;
+ int direct = 0;
+ int style = COMMUNITY_LIST_STANDARD;
- /* Concat community string argument. */
- str = argv_concat (argv, argc, 2);
- }
+ int idx = 0;
+ argv_find (argv, argc, "(1-99)", &idx);
+ argv_find (argv, argc, "WORD", &idx);
+ cl_name_or_number = argv[idx]->arg;
+ direct = argv_find (argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY;
+ argv_find (argv, argc, "AA:NN", &idx);
+ char *str = argv_concat (argv, argc, idx);
- /* Unset community list. */
- ret = community_list_unset (bgp_clist, argv[0], str, direct, style, delete_all);
-
- /* Free temporary community list string allocated by
- argv_concat(). */
- if (str)
- XFREE (MTYPE_TMP, str);
+ int ret = community_list_unset (bgp_clist, cl_name_or_number, str, direct, style, delete_all);
if (ret < 0)
{
@@ -15718,212 +11053,81 @@ community_list_unset_vty (struct vty *vty, int argc, const char **argv,
return CMD_SUCCESS;
}
-/* "community-list" keyword help string. */
-#define COMMUNITY_LIST_STR "Add a community list entry\n"
-
-DEFUN (ip_community_list_standard,
- ip_community_list_standard_cmd,
- "ip community-list <1-99> (deny|permit) .AA:NN",
- IP_STR
- COMMUNITY_LIST_STR
- "Community list number (standard)\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
- COMMUNITY_VAL_STR)
-{
- return community_list_set_vty (vty, argc, argv, COMMUNITY_LIST_STANDARD, 0);
-}
-
-ALIAS (ip_community_list_standard,
- ip_community_list_standard2_cmd,
- "ip community-list <1-99> (deny|permit)",
- IP_STR
- COMMUNITY_LIST_STR
- "Community list number (standard)\n"
- "Specify community to reject\n"
- "Specify community to accept\n")
-
-DEFUN (ip_community_list_expanded,
- ip_community_list_expanded_cmd,
- "ip community-list <100-500> (deny|permit) .LINE",
+/* ip community-list expanded */
+DEFUN (ip_community_list_expanded_all,
+ ip_community_list_expanded_all_cmd,
+ "ip community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...",
IP_STR
COMMUNITY_LIST_STR
"Community list number (expanded)\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
- "An ordered list as a regular-expression\n")
-{
- return community_list_set_vty (vty, argc, argv, COMMUNITY_LIST_EXPANDED, 0);
-}
-
-DEFUN (ip_community_list_name_standard,
- ip_community_list_name_standard_cmd,
- "ip community-list standard WORD (deny|permit) .AA:NN",
- IP_STR
- COMMUNITY_LIST_STR
- "Add a standard community-list entry\n"
+ "Add an expanded community-list entry\n"
"Community list name\n"
"Specify community to reject\n"
"Specify community to accept\n"
COMMUNITY_VAL_STR)
{
- return community_list_set_vty (vty, argc, argv, COMMUNITY_LIST_STANDARD, 1);
-}
+ char *cl_name_or_number = NULL;
+ int direct = 0;
+ int style = COMMUNITY_LIST_EXPANDED;
-ALIAS (ip_community_list_name_standard,
- ip_community_list_name_standard2_cmd,
- "ip community-list standard WORD (deny|permit)",
- IP_STR
- COMMUNITY_LIST_STR
- "Add a standard community-list entry\n"
- "Community list name\n"
- "Specify community to reject\n"
- "Specify community to accept\n")
+ int idx = 0;
+ argv_find (argv, argc, "(100-500)", &idx);
+ argv_find (argv, argc, "WORD", &idx);
+ cl_name_or_number = argv[idx]->arg;
+ direct = argv_find (argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY;
+ argv_find (argv, argc, "AA:NN", &idx);
+ char *str = argv_concat (argv, argc, idx);
-DEFUN (ip_community_list_name_expanded,
- ip_community_list_name_expanded_cmd,
- "ip community-list expanded WORD (deny|permit) .LINE",
- IP_STR
- COMMUNITY_LIST_STR
- "Add an expanded community-list entry\n"
- "Community list name\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
- "An ordered list as a regular-expression\n")
-{
- return community_list_set_vty (vty, argc, argv, COMMUNITY_LIST_EXPANDED, 1);
-}
+ int ret = community_list_set (bgp_clist, cl_name_or_number, str, direct, style);
-DEFUN (no_ip_community_list_standard_all,
- no_ip_community_list_standard_all_cmd,
- "no ip community-list <1-99>",
- NO_STR
- IP_STR
- COMMUNITY_LIST_STR
- "Community list number (standard)\n")
-{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_STANDARD, 1);
-}
+ XFREE (MTYPE_TMP, str);
-DEFUN (no_ip_community_list_standard_direction,
- no_ip_community_list_standard_direction_cmd,
- "no ip community-list <1-99> (deny|permit)",
- NO_STR
- IP_STR
- COMMUNITY_LIST_STR
- "Community list number (standard)\n"
- "Specify community to reject\n"
- "Specify community to accept\n")
-{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_STANDARD, 0);
-}
+ if (ret < 0)
+ {
+ /* Display error string. */
+ community_list_perror (vty, ret);
+ return CMD_WARNING;
+ }
+ return CMD_SUCCESS;
+}
DEFUN (no_ip_community_list_expanded_all,
no_ip_community_list_expanded_all_cmd,
- "no ip community-list <100-500>",
- NO_STR
- IP_STR
- COMMUNITY_LIST_STR
- "Community list number (expanded)\n")
-{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_EXPANDED, 1);
-}
-
-DEFUN (no_ip_community_list_name_standard_all,
- no_ip_community_list_name_standard_all_cmd,
- "no ip community-list standard WORD",
- NO_STR
- IP_STR
- COMMUNITY_LIST_STR
- "Add a standard community-list entry\n"
- "Community list name\n")
-{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_STANDARD, 1);
-}
-
-DEFUN (no_ip_community_list_name_expanded_all,
- no_ip_community_list_name_expanded_all_cmd,
- "no ip community-list expanded WORD",
+ "no ip community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...",
NO_STR
IP_STR
COMMUNITY_LIST_STR
+ "Community list number (expanded)\n"
"Add an expanded community-list entry\n"
- "Community list name\n")
-{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_EXPANDED, 1);
-}
-
-DEFUN (no_ip_community_list_standard,
- no_ip_community_list_standard_cmd,
- "no ip community-list <1-99> (deny|permit) .AA:NN",
- NO_STR
- IP_STR
- COMMUNITY_LIST_STR
- "Community list number (standard)\n"
+ "Community list name\n"
"Specify community to reject\n"
"Specify community to accept\n"
COMMUNITY_VAL_STR)
{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_STANDARD, 0);
-}
+ int delete_all = 0;
-DEFUN (no_ip_community_list_expanded,
- no_ip_community_list_expanded_cmd,
- "no ip community-list <100-500> (deny|permit) .LINE",
- NO_STR
- IP_STR
- COMMUNITY_LIST_STR
- "Community list number (expanded)\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
- "An ordered list as a regular-expression\n")
-{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_EXPANDED, 0);
-}
+ char *cl_name_or_number = NULL;
+ int direct = 0;
+ int style = COMMUNITY_LIST_EXPANDED;
-DEFUN (no_ip_community_list_name_standard,
- no_ip_community_list_name_standard_cmd,
- "no ip community-list standard WORD (deny|permit) .AA:NN",
- NO_STR
- IP_STR
- COMMUNITY_LIST_STR
- "Specify a standard community-list\n"
- "Community list name\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
- COMMUNITY_VAL_STR)
-{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_STANDARD, 0);
-}
+ int idx = 0;
+ argv_find (argv, argc, "(100-500)", &idx);
+ argv_find (argv, argc, "WORD", &idx);
+ cl_name_or_number = argv[idx]->arg;
+ direct = argv_find (argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY;
+ argv_find (argv, argc, "AA:NN", &idx);
+ char *str = argv_concat (argv, argc, idx);
-DEFUN (no_ip_community_list_name_standard_brief,
- no_ip_community_list_name_standard_brief_cmd,
- "no ip community-list standard WORD (deny|permit)",
- NO_STR
- IP_STR
- COMMUNITY_LIST_STR
- "Specify a standard community-list\n"
- "Community list name\n"
- "Specify community to reject\n"
- "Specify community to accept\n")
-{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_STANDARD, 0);
-}
+ int ret = community_list_unset (bgp_clist, cl_name_or_number, str, direct, style, delete_all);
-DEFUN (no_ip_community_list_name_expanded,
- no_ip_community_list_name_expanded_cmd,
- "no ip community-list expanded WORD (deny|permit) .LINE",
- NO_STR
- IP_STR
- COMMUNITY_LIST_STR
- "Specify an expanded community-list\n"
- "Community list name\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
- "An ordered list as a regular-expression\n")
-{
- return community_list_unset_vty (vty, argc, argv, COMMUNITY_LIST_EXPANDED, 0);
+ if (ret < 0)
+ {
+ community_list_perror (vty, ret);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
}
static void
@@ -15983,16 +11187,17 @@ DEFUN (show_ip_community_list,
DEFUN (show_ip_community_list_arg,
show_ip_community_list_arg_cmd,
- "show ip community-list (<1-500>|WORD)",
+ "show ip community-list <(1-500)|WORD>",
SHOW_STR
IP_STR
"List community-list\n"
"Community-list number\n"
"Community-list name\n")
{
+ int idx_comm_list = 3;
struct community_list *list;
- list = community_list_lookup (bgp_clist, argv[0], COMMUNITY_LIST_MASTER);
+ list = community_list_lookup (bgp_clist, argv[idx_comm_list]->arg, COMMUNITY_LIST_MASTER);
if (! list)
{
vty_out (vty, "%% Can't find community-list%s", VTY_NEWLINE);
@@ -16004,40 +11209,42 @@ DEFUN (show_ip_community_list_arg,
return CMD_SUCCESS;
}
+/*
+ * Large Community code.
+ */
static int
-extcommunity_list_set_vty (struct vty *vty, int argc, const char **argv,
- int style, int reject_all_digit_name)
+lcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv,
+ int style, int reject_all_digit_name)
{
int ret;
int direct;
char *str;
+ int idx = 0;
+ char *cl_name;
- /* Check the list type. */
- if (strncmp (argv[1], "p", 1) == 0)
- direct = COMMUNITY_PERMIT;
- else if (strncmp (argv[1], "d", 1) == 0)
- direct = COMMUNITY_DENY;
- else
- {
- vty_out (vty, "%% Matching condition must be permit or deny%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ direct = argv_find (argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY;
/* All digit name check. */
- if (reject_all_digit_name && all_digit (argv[0]))
+ idx = 0;
+ argv_find (argv, argc, "WORD", &idx);
+ argv_find (argv, argc, "(1-99)", &idx);
+ argv_find (argv, argc, "(100-500)", &idx);
+ cl_name = argv[idx]->arg;
+ if (reject_all_digit_name && all_digit (cl_name))
{
vty_out (vty, "%% Community name cannot have all digits%s", VTY_NEWLINE);
return CMD_WARNING;
}
- /* Concat community string argument. */
- if (argc > 1)
- str = argv_concat (argv, argc, 2);
+ argv_find (argv, argc, "AA:BB:CC", &idx);
+ argv_find (argv, argc, "LINE", &idx);
+ /* Concat community string argument. */
+ if (idx)
+ str = argv_concat (argv, argc, idx);
else
str = NULL;
- ret = extcommunity_list_set (bgp_clist, argv[0], str, direct, style);
+ ret = lcommunity_list_set (bgp_clist, cl_name, str, direct, style);
/* Free temporary community list string allocated by
argv_concat(). */
@@ -16053,33 +11260,39 @@ extcommunity_list_set_vty (struct vty *vty, int argc, const char **argv,
}
static int
-extcommunity_list_unset_vty (struct vty *vty, int argc, const char **argv,
- int style, int delete_all)
+lcommunity_list_unset_vty (struct vty *vty, int argc, struct cmd_token **argv,
+ int style)
{
int ret;
int direct = 0;
char *str = NULL;
+ int idx = 0;
+
+ argv_find (argv, argc, "permit", &idx);
+ argv_find (argv, argc, "deny", &idx);
- if (argc > 1)
+ if (idx)
{
/* Check the list direct. */
- if (strncmp (argv[1], "p", 1) == 0)
- direct = COMMUNITY_PERMIT;
- else if (strncmp (argv[1], "d", 1) == 0)
- direct = COMMUNITY_DENY;
+ if (strncmp (argv[idx]->arg, "p", 1) == 0)
+ direct = COMMUNITY_PERMIT;
else
- {
- vty_out (vty, "%% Matching condition must be permit or deny%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ direct = COMMUNITY_DENY;
+ idx = 0;
+ argv_find (argv, argc, "LINE", &idx);
+ argv_find (argv, argc, "AA:AA:NN", &idx);
/* Concat community string argument. */
- str = argv_concat (argv, argc, 2);
+ str = argv_concat (argv, argc, idx);
}
+ idx = 0;
+ argv_find (argv, argc, "(1-99)", &idx);
+ argv_find (argv, argc, "(100-500)", &idx);
+ argv_find (argv, argc, "WORD", &idx);
+
/* Unset community list. */
- ret = extcommunity_list_unset (bgp_clist, argv[0], str, direct, style, delete_all);
+ ret = lcommunity_list_unset (bgp_clist, argv[idx]->arg, str, direct, style);
/* Free temporary community list string allocated by
argv_concat(). */
@@ -16095,212 +11308,407 @@ extcommunity_list_unset_vty (struct vty *vty, int argc, const char **argv,
return CMD_SUCCESS;
}
-/* "extcommunity-list" keyword help string. */
-#define EXTCOMMUNITY_LIST_STR "Add a extended community list entry\n"
-#define EXTCOMMUNITY_VAL_STR "Extended community attribute in 'rt aa:nn_or_IPaddr:nn' OR 'soo aa:nn_or_IPaddr:nn' format\n"
+/* "large-community-list" keyword help string. */
+#define LCOMMUNITY_LIST_STR "Add a large community list entry\n"
+#define LCOMMUNITY_VAL_STR "large community in 'aa:bb:cc' format\n"
-DEFUN (ip_extcommunity_list_standard,
- ip_extcommunity_list_standard_cmd,
- "ip extcommunity-list <1-99> (deny|permit) .AA:NN",
+DEFUN (ip_lcommunity_list_standard,
+ ip_lcommunity_list_standard_cmd,
+ "ip large-community-list (1-99) <deny|permit>",
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Extended Community list number (standard)\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
- EXTCOMMUNITY_VAL_STR)
+ LCOMMUNITY_LIST_STR
+ "Large Community list number (standard)\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n"
+ LCOMMUNITY_VAL_STR)
{
- return extcommunity_list_set_vty (vty, argc, argv, EXTCOMMUNITY_LIST_STANDARD, 0);
+ return lcommunity_list_set_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD, 0);
}
-ALIAS (ip_extcommunity_list_standard,
- ip_extcommunity_list_standard2_cmd,
- "ip extcommunity-list <1-99> (deny|permit)",
+DEFUN (ip_lcommunity_list_standard1,
+ ip_lcommunity_list_standard1_cmd,
+ "ip large-community-list (1-99) <deny|permit> AA:BB:CC...",
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Extended Community list number (standard)\n"
- "Specify community to reject\n"
- "Specify community to accept\n")
+ LCOMMUNITY_LIST_STR
+ "Large Community list number (standard)\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n"
+ LCOMMUNITY_VAL_STR)
+{
+ return lcommunity_list_set_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD, 0);
+}
-DEFUN (ip_extcommunity_list_expanded,
- ip_extcommunity_list_expanded_cmd,
- "ip extcommunity-list <100-500> (deny|permit) .LINE",
+DEFUN (ip_lcommunity_list_expanded,
+ ip_lcommunity_list_expanded_cmd,
+ "ip large-community-list (100-500) <deny|permit> LINE...",
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Extended Community list number (expanded)\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
+ LCOMMUNITY_LIST_STR
+ "Large Community list number (expanded)\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n"
"An ordered list as a regular-expression\n")
{
- return extcommunity_list_set_vty (vty, argc, argv, EXTCOMMUNITY_LIST_EXPANDED, 0);
+ return lcommunity_list_set_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_EXPANDED, 0);
}
-DEFUN (ip_extcommunity_list_name_standard,
- ip_extcommunity_list_name_standard_cmd,
- "ip extcommunity-list standard WORD (deny|permit) .AA:NN",
+DEFUN (ip_lcommunity_list_name_standard,
+ ip_lcommunity_list_name_standard_cmd,
+ "ip large-community-list standard WORD <deny|permit>",
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Specify standard extcommunity-list\n"
- "Extended Community list name\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
- EXTCOMMUNITY_VAL_STR)
+ LCOMMUNITY_LIST_STR
+ "Specify standard large-community-list\n"
+ "Large Community list name\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n")
{
- return extcommunity_list_set_vty (vty, argc, argv, EXTCOMMUNITY_LIST_STANDARD, 1);
+ return lcommunity_list_set_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD, 1);
}
-ALIAS (ip_extcommunity_list_name_standard,
- ip_extcommunity_list_name_standard2_cmd,
- "ip extcommunity-list standard WORD (deny|permit)",
+DEFUN (ip_lcommunity_list_name_standard1,
+ ip_lcommunity_list_name_standard1_cmd,
+ "ip large-community-list standard WORD <deny|permit> AA:BB:CC...",
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Specify standard extcommunity-list\n"
- "Extended Community list name\n"
- "Specify community to reject\n"
- "Specify community to accept\n")
+ LCOMMUNITY_LIST_STR
+ "Specify standard large-community-list\n"
+ "Large Community list name\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n"
+ LCOMMUNITY_VAL_STR)
+{
+ return lcommunity_list_set_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD, 1);
+}
-DEFUN (ip_extcommunity_list_name_expanded,
- ip_extcommunity_list_name_expanded_cmd,
- "ip extcommunity-list expanded WORD (deny|permit) .LINE",
+DEFUN (ip_lcommunity_list_name_expanded,
+ ip_lcommunity_list_name_expanded_cmd,
+ "ip large-community-list expanded WORD <deny|permit> LINE...",
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Specify expanded extcommunity-list\n"
- "Extended Community list name\n"
- "Specify community to reject\n"
- "Specify community to accept\n"
+ LCOMMUNITY_LIST_STR
+ "Specify expanded large-community-list\n"
+ "Large Community list name\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n"
"An ordered list as a regular-expression\n")
{
- return extcommunity_list_set_vty (vty, argc, argv, EXTCOMMUNITY_LIST_EXPANDED, 1);
+ return lcommunity_list_set_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_EXPANDED, 1);
}
-DEFUN (no_ip_extcommunity_list_standard_all,
- no_ip_extcommunity_list_standard_all_cmd,
- "no ip extcommunity-list <1-99>",
+DEFUN (no_ip_lcommunity_list_standard_all,
+ no_ip_lcommunity_list_standard_all_cmd,
+ "no ip large-community-list <(1-99)|(100-500)|WORD>",
NO_STR
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Extended Community list number (standard)\n")
+ LCOMMUNITY_LIST_STR
+ "Large Community list number (standard)\n"
+ "Large Community list number (expanded)\n"
+ "Large Community list name\n")
{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_STANDARD, 1);
+ return lcommunity_list_unset_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD);
}
-DEFUN (no_ip_extcommunity_list_standard_direction,
- no_ip_extcommunity_list_standard_direction_cmd,
- "no ip extcommunity-list <1-99> (deny|permit)",
+DEFUN (no_ip_lcommunity_list_name_expanded_all,
+ no_ip_lcommunity_list_name_expanded_all_cmd,
+ "no ip large-community-list expanded WORD",
NO_STR
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Extended Community list number (standard)\n"
- "Specify community to reject\n"
- "Specify community to accept\n")
+ LCOMMUNITY_LIST_STR
+ "Specify expanded large-community-list\n"
+ "Large Community list name\n")
{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_STANDARD, 0);
+ return lcommunity_list_unset_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_EXPANDED);
}
-DEFUN (no_ip_extcommunity_list_expanded_all,
- no_ip_extcommunity_list_expanded_all_cmd,
- "no ip extcommunity-list <100-500>",
+DEFUN (no_ip_lcommunity_list_standard,
+ no_ip_lcommunity_list_standard_cmd,
+ "no ip large-community-list (1-99) <deny|permit> AA:AA:NN...",
NO_STR
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Extended Community list number (expanded)\n")
+ LCOMMUNITY_LIST_STR
+ "Large Community list number (standard)\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n"
+ LCOMMUNITY_VAL_STR)
{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_EXPANDED, 1);
+ return lcommunity_list_unset_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD);
}
-DEFUN (no_ip_extcommunity_list_name_standard_all,
- no_ip_extcommunity_list_name_standard_all_cmd,
- "no ip extcommunity-list standard WORD",
+DEFUN (no_ip_lcommunity_list_expanded,
+ no_ip_lcommunity_list_expanded_cmd,
+ "no ip large-community-list (100-500) <deny|permit> LINE...",
NO_STR
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Specify standard extcommunity-list\n"
- "Extended Community list name\n")
+ LCOMMUNITY_LIST_STR
+ "Large Community list number (expanded)\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n"
+ "An ordered list as a regular-expression\n")
{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_STANDARD, 1);
+ return lcommunity_list_unset_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_EXPANDED);
}
-DEFUN (no_ip_extcommunity_list_name_expanded_all,
- no_ip_extcommunity_list_name_expanded_all_cmd,
- "no ip extcommunity-list expanded WORD",
+DEFUN (no_ip_lcommunity_list_name_standard,
+ no_ip_lcommunity_list_name_standard_cmd,
+ "no ip large-community-list standard WORD <deny|permit> AA:AA:NN...",
NO_STR
IP_STR
- EXTCOMMUNITY_LIST_STR
- "Specify expanded extcommunity-list\n"
- "Extended Community list name\n")
+ LCOMMUNITY_LIST_STR
+ "Specify standard large-community-list\n"
+ "Large Community list name\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n"
+ LCOMMUNITY_VAL_STR)
{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_EXPANDED, 1);
+ return lcommunity_list_unset_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_STANDARD);
}
-DEFUN (no_ip_extcommunity_list_standard,
- no_ip_extcommunity_list_standard_cmd,
- "no ip extcommunity-list <1-99> (deny|permit) .AA:NN",
+DEFUN (no_ip_lcommunity_list_name_expanded,
+ no_ip_lcommunity_list_name_expanded_cmd,
+ "no ip large-community-list expanded WORD <deny|permit> LINE...",
NO_STR
IP_STR
+ LCOMMUNITY_LIST_STR
+ "Specify expanded large-community-list\n"
+ "Large community list name\n"
+ "Specify large community to reject\n"
+ "Specify large community to accept\n"
+ "An ordered list as a regular-expression\n")
+{
+ return lcommunity_list_unset_vty (vty, argc, argv, LARGE_COMMUNITY_LIST_EXPANDED);
+}
+
+static void
+lcommunity_list_show (struct vty *vty, struct community_list *list)
+{
+ struct community_entry *entry;
+
+ for (entry = list->head; entry; entry = entry->next)
+ {
+ if (entry == list->head)
+ {
+ if (all_digit (list->name))
+ vty_out (vty, "Large community %s list %s%s",
+ entry->style == EXTCOMMUNITY_LIST_STANDARD ?
+ "standard" : "(expanded) access",
+ list->name, VTY_NEWLINE);
+ else
+ vty_out (vty, "Named large community %s list %s%s",
+ entry->style == EXTCOMMUNITY_LIST_STANDARD ?
+ "standard" : "expanded",
+ list->name, VTY_NEWLINE);
+ }
+ if (entry->any)
+ vty_out (vty, " %s%s",
+ community_direct_str (entry->direct), VTY_NEWLINE);
+ else
+ vty_out (vty, " %s %s%s",
+ community_direct_str (entry->direct),
+ entry->style == EXTCOMMUNITY_LIST_STANDARD ?
+ entry->u.ecom->str : entry->config,
+ VTY_NEWLINE);
+ }
+}
+
+DEFUN (show_ip_lcommunity_list,
+ show_ip_lcommunity_list_cmd,
+ "show ip large-community-list",
+ SHOW_STR
+ IP_STR
+ "List large-community list\n")
+{
+ struct community_list *list;
+ struct community_list_master *cm;
+
+ cm = community_list_master_lookup (bgp_clist, LARGE_COMMUNITY_LIST_MASTER);
+ if (! cm)
+ return CMD_SUCCESS;
+
+ for (list = cm->num.head; list; list = list->next)
+ lcommunity_list_show (vty, list);
+
+ for (list = cm->str.head; list; list = list->next)
+ lcommunity_list_show (vty, list);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_lcommunity_list_arg,
+ show_ip_lcommunity_list_arg_cmd,
+ "show ip large-community-list <(1-500)|WORD>",
+ SHOW_STR
+ IP_STR
+ "List large-community list\n"
+ "large-community-list number\n"
+ "large-community-list name\n")
+{
+ struct community_list *list;
+
+ list = community_list_lookup (bgp_clist, argv[3]->arg, LARGE_COMMUNITY_LIST_MASTER);
+ if (! list)
+ {
+ vty_out (vty, "%% Can't find extcommunity-list%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ lcommunity_list_show (vty, list);
+
+ return CMD_SUCCESS;
+}
+
+/* "extcommunity-list" keyword help string. */
+#define EXTCOMMUNITY_LIST_STR "Add a extended community list entry\n"
+#define EXTCOMMUNITY_VAL_STR "Extended community attribute in 'rt aa:nn_or_IPaddr:nn' OR 'soo aa:nn_or_IPaddr:nn' format\n"
+
+DEFUN (ip_extcommunity_list_standard,
+ ip_extcommunity_list_standard_cmd,
+ "ip extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+ IP_STR
EXTCOMMUNITY_LIST_STR
"Extended Community list number (standard)\n"
+ "Specify standard extcommunity-list\n"
+ "Community list name\n"
"Specify community to reject\n"
"Specify community to accept\n"
EXTCOMMUNITY_VAL_STR)
{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_STANDARD, 0);
+ int style = EXTCOMMUNITY_LIST_STANDARD;
+ int direct = 0;
+ char *cl_number_or_name = NULL;
+
+ int idx = 0;
+ argv_find (argv, argc, "(1-99)", &idx);
+ argv_find (argv, argc, "WORD", &idx);
+ cl_number_or_name = argv[idx]->arg;
+ direct = argv_find (argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY;
+ argv_find (argv, argc, "AA:NN", &idx);
+ char *str = argv_concat (argv, argc, idx);
+
+ int ret = extcommunity_list_set (bgp_clist, cl_number_or_name, str, direct, style);
+
+ XFREE (MTYPE_TMP, str);
+
+ if (ret < 0)
+ {
+ community_list_perror (vty, ret);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
}
-DEFUN (no_ip_extcommunity_list_expanded,
- no_ip_extcommunity_list_expanded_cmd,
- "no ip extcommunity-list <100-500> (deny|permit) .LINE",
- NO_STR
+DEFUN (ip_extcommunity_list_name_expanded,
+ ip_extcommunity_list_name_expanded_cmd,
+ "ip extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...",
IP_STR
EXTCOMMUNITY_LIST_STR
"Extended Community list number (expanded)\n"
+ "Specify expanded extcommunity-list\n"
+ "Extended Community list name\n"
"Specify community to reject\n"
"Specify community to accept\n"
"An ordered list as a regular-expression\n")
{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_EXPANDED, 0);
+ int style = EXTCOMMUNITY_LIST_EXPANDED;
+ int direct = 0;
+ char *cl_number_or_name = NULL;
+
+ int idx = 0;
+ argv_find (argv, argc, "(100-500)", &idx);
+ argv_find (argv, argc, "WORD", &idx);
+ cl_number_or_name = argv[idx]->arg;
+ direct = argv_find (argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY;
+ argv_find (argv, argc, "LINE", &idx);
+ char *str = argv_concat (argv, argc, idx);
+
+ int ret = extcommunity_list_set (bgp_clist, cl_number_or_name, str, direct, style);
+
+ XFREE (MTYPE_TMP, str);
+
+ if (ret < 0)
+ {
+ community_list_perror (vty, ret);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
}
-DEFUN (no_ip_extcommunity_list_name_standard,
- no_ip_extcommunity_list_name_standard_cmd,
- "no ip extcommunity-list standard WORD (deny|permit) .AA:NN",
+DEFUN (no_ip_extcommunity_list_standard_all,
+ no_ip_extcommunity_list_standard_all_cmd,
+ "no ip extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
NO_STR
IP_STR
EXTCOMMUNITY_LIST_STR
+ "Extended Community list number (standard)\n"
"Specify standard extcommunity-list\n"
- "Extended Community list name\n"
+ "Community list name\n"
"Specify community to reject\n"
"Specify community to accept\n"
EXTCOMMUNITY_VAL_STR)
{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_STANDARD, 0);
-}
+ int deleteall = 0;
-DEFUN (no_ip_extcommunity_list_name_standard_brief,
- no_ip_extcommunity_list_name_standard_brief_cmd,
- "no ip extcommunity-list standard WORD (deny|permit)",
- NO_STR
- IP_STR
- EXTCOMMUNITY_LIST_STR
- "Specify standard extcommunity-list\n"
- "Extended Community list name\n"
- "Specify community to reject\n"
- "Specify community to accept\n")
-{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_STANDARD, 0);
+ int style = EXTCOMMUNITY_LIST_STANDARD;
+ int direct = 0;
+ char *cl_number_or_name = NULL;
+
+ int idx = 0;
+ argv_find (argv, argc, "(1-99)", &idx);
+ argv_find (argv, argc, "WORD", &idx);
+ cl_number_or_name = argv[idx]->arg;
+ direct = argv_find (argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY;
+ argv_find (argv, argc, "AA:NN", &idx);
+ char *str = argv_concat (argv, argc, idx);
+
+ int ret = extcommunity_list_unset (bgp_clist, cl_number_or_name, str, direct, style, deleteall);
+
+ XFREE (MTYPE_TMP, str);
+
+ if (ret < 0)
+ {
+ community_list_perror (vty, ret);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
}
-DEFUN (no_ip_extcommunity_list_name_expanded,
- no_ip_extcommunity_list_name_expanded_cmd,
- "no ip extcommunity-list expanded WORD (deny|permit) .LINE",
+DEFUN (no_ip_extcommunity_list_expanded_all,
+ no_ip_extcommunity_list_expanded_all_cmd,
+ "no ip extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...",
NO_STR
IP_STR
EXTCOMMUNITY_LIST_STR
+ "Extended Community list number (expanded)\n"
"Specify expanded extcommunity-list\n"
- "Community list name\n"
+ "Extended Community list name\n"
"Specify community to reject\n"
"Specify community to accept\n"
"An ordered list as a regular-expression\n")
{
- return extcommunity_list_unset_vty (vty, argc, argv, EXTCOMMUNITY_LIST_EXPANDED, 0);
+ int deleteall = 0;
+
+ int style = EXTCOMMUNITY_LIST_EXPANDED;
+ int direct = 0;
+ char *cl_number_or_name = NULL;
+
+ int idx = 0;
+ argv_find (argv, argc, "(100-500)", &idx);
+ argv_find (argv, argc, "WORD", &idx);
+ cl_number_or_name = argv[idx]->arg;
+ direct = argv_find (argv, argc, "permit", &idx) ? COMMUNITY_PERMIT : COMMUNITY_DENY;
+ argv_find (argv, argc, "LINE", &idx);
+ char *str = argv_concat (argv, argc, idx);
+
+ int ret = extcommunity_list_unset (bgp_clist, cl_number_or_name, str, direct, style, deleteall);
+
+ XFREE (MTYPE_TMP, str);
+
+ if (ret < 0)
+ {
+ community_list_perror (vty, ret);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
}
static void
@@ -16360,16 +11768,17 @@ DEFUN (show_ip_extcommunity_list,
DEFUN (show_ip_extcommunity_list_arg,
show_ip_extcommunity_list_arg_cmd,
- "show ip extcommunity-list (<1-500>|WORD)",
+ "show ip extcommunity-list <(1-500)|WORD>",
SHOW_STR
IP_STR
"List extended-community list\n"
"Extcommunity-list number\n"
"Extcommunity-list name\n")
{
+ int idx_comm_list = 3;
struct community_list *list;
- list = community_list_lookup (bgp_clist, argv[0], EXTCOMMUNITY_LIST_MASTER);
+ list = community_list_lookup (bgp_clist, argv[idx_comm_list]->arg, EXTCOMMUNITY_LIST_MASTER);
if (! list)
{
vty_out (vty, "%% Can't find extcommunity-list%s", VTY_NEWLINE);
@@ -16453,6 +11862,30 @@ community_list_config_write (struct vty *vty)
community_list_config_str (entry), VTY_NEWLINE);
write++;
}
+
+
+ /* lcommunity-list. */
+ cm = community_list_master_lookup (bgp_clist, LARGE_COMMUNITY_LIST_MASTER);
+
+ for (list = cm->num.head; list; list = list->next)
+ for (entry = list->head; entry; entry = entry->next)
+ {
+ vty_out (vty, "ip large-community-list %s %s %s%s",
+ list->name, community_direct_str (entry->direct),
+ community_list_config_str (entry), VTY_NEWLINE);
+ write++;
+ }
+ for (list = cm->str.head; list; list = list->next)
+ for (entry = list->head; entry; entry = entry->next)
+ {
+ vty_out (vty, "ip large-community-list %s %s %s %s%s",
+ entry->style == LARGE_COMMUNITY_LIST_STANDARD
+ ? "standard" : "expanded",
+ list->name, community_direct_str (entry->direct),
+ community_list_config_str (entry), VTY_NEWLINE);
+ write++;
+ }
+
return write;
}
@@ -16470,41 +11903,33 @@ community_list_vty (void)
/* Community-list. */
install_element (CONFIG_NODE, &ip_community_list_standard_cmd);
- install_element (CONFIG_NODE, &ip_community_list_standard2_cmd);
- install_element (CONFIG_NODE, &ip_community_list_expanded_cmd);
- install_element (CONFIG_NODE, &ip_community_list_name_standard_cmd);
- install_element (CONFIG_NODE, &ip_community_list_name_standard2_cmd);
- install_element (CONFIG_NODE, &ip_community_list_name_expanded_cmd);
+ install_element (CONFIG_NODE, &ip_community_list_expanded_all_cmd);
install_element (CONFIG_NODE, &no_ip_community_list_standard_all_cmd);
- install_element (CONFIG_NODE, &no_ip_community_list_standard_direction_cmd);
install_element (CONFIG_NODE, &no_ip_community_list_expanded_all_cmd);
- install_element (CONFIG_NODE, &no_ip_community_list_name_standard_all_cmd);
- install_element (CONFIG_NODE, &no_ip_community_list_name_expanded_all_cmd);
- install_element (CONFIG_NODE, &no_ip_community_list_standard_cmd);
- install_element (CONFIG_NODE, &no_ip_community_list_expanded_cmd);
- install_element (CONFIG_NODE, &no_ip_community_list_name_standard_cmd);
- install_element (CONFIG_NODE, &no_ip_community_list_name_standard_brief_cmd);
- install_element (CONFIG_NODE, &no_ip_community_list_name_expanded_cmd);
install_element (VIEW_NODE, &show_ip_community_list_cmd);
install_element (VIEW_NODE, &show_ip_community_list_arg_cmd);
/* Extcommunity-list. */
install_element (CONFIG_NODE, &ip_extcommunity_list_standard_cmd);
- install_element (CONFIG_NODE, &ip_extcommunity_list_standard2_cmd);
- install_element (CONFIG_NODE, &ip_extcommunity_list_expanded_cmd);
- install_element (CONFIG_NODE, &ip_extcommunity_list_name_standard_cmd);
- install_element (CONFIG_NODE, &ip_extcommunity_list_name_standard2_cmd);
install_element (CONFIG_NODE, &ip_extcommunity_list_name_expanded_cmd);
install_element (CONFIG_NODE, &no_ip_extcommunity_list_standard_all_cmd);
- install_element (CONFIG_NODE, &no_ip_extcommunity_list_standard_direction_cmd);
install_element (CONFIG_NODE, &no_ip_extcommunity_list_expanded_all_cmd);
- install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_standard_all_cmd);
- install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_expanded_all_cmd);
- install_element (CONFIG_NODE, &no_ip_extcommunity_list_standard_cmd);
- install_element (CONFIG_NODE, &no_ip_extcommunity_list_expanded_cmd);
- install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_standard_cmd);
- install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_standard_brief_cmd);
- install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_expanded_cmd);
install_element (VIEW_NODE, &show_ip_extcommunity_list_cmd);
install_element (VIEW_NODE, &show_ip_extcommunity_list_arg_cmd);
+
+ /* Large Community List */
+ install_element (CONFIG_NODE, &ip_lcommunity_list_standard_cmd);
+ install_element (CONFIG_NODE, &ip_lcommunity_list_standard1_cmd);
+ install_element (CONFIG_NODE, &ip_lcommunity_list_expanded_cmd);
+ install_element (CONFIG_NODE, &ip_lcommunity_list_name_standard_cmd);
+ install_element (CONFIG_NODE, &ip_lcommunity_list_name_standard1_cmd);
+ install_element (CONFIG_NODE, &ip_lcommunity_list_name_expanded_cmd);
+ install_element (CONFIG_NODE, &no_ip_lcommunity_list_standard_all_cmd);
+ install_element (CONFIG_NODE, &no_ip_lcommunity_list_name_expanded_all_cmd);
+ install_element (CONFIG_NODE, &no_ip_lcommunity_list_standard_cmd);
+ install_element (CONFIG_NODE, &no_ip_lcommunity_list_expanded_cmd);
+ install_element (CONFIG_NODE, &no_ip_lcommunity_list_name_standard_cmd);
+ install_element (CONFIG_NODE, &no_ip_lcommunity_list_name_expanded_cmd);
+ install_element (VIEW_NODE, &show_ip_lcommunity_list_cmd);
+ install_element (VIEW_NODE, &show_ip_lcommunity_list_arg_cmd);
}
diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h
index e3a51ac450..13e67d112e 100644
--- a/bgpd/bgp_vty.h
+++ b/bgpd/bgp_vty.h
@@ -23,16 +23,12 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
struct bgp;
-#define CMD_AS_RANGE "<1-4294967295>"
-#define DYNAMIC_NEIGHBOR_LIMIT_RANGE "<1-5000>"
-#define BGP_INSTANCE_CMD "(view|vrf) WORD"
#define BGP_INSTANCE_HELP_STR "BGP view\nBGP VRF\nView/VRF name\n"
-#define BGP_INSTANCE_ALL_CMD "(view|vrf) all"
#define BGP_INSTANCE_ALL_HELP_STR "BGP view\nBGP VRF\nAll Views/VRFs\n"
-#define BGP_AFI_CMD_STR "(ipv4|ipv6)"
+#define BGP_AFI_CMD_STR "<ipv4|ipv6>"
#define BGP_AFI_HELP_STR "Address Family\nAddress Family\n"
-#define BGP_SAFI_CMD_STR "(unicast|multicast|vpn|encap)"
+#define BGP_SAFI_CMD_STR "<unicast|multicast|vpn|encap>"
#define BGP_SAFI_HELP_STR \
"Address Family modifier\n" \
"Address Family modifier\n" \
@@ -55,13 +51,19 @@ peer_and_group_lookup_vty (struct vty *vty, const char *peer_str);
extern int
bgp_parse_afi(const char *str, afi_t *afi);
-extern int
-bgp_parse_safi(const char *str, safi_t *safi);
-
extern afi_t
bgp_vty_afi_from_arg(const char *afi_str);
extern safi_t
bgp_vty_safi_from_arg(const char *safi_str);
+extern int
+argv_find_and_parse_afi(struct cmd_token **argv, int argc, int *index, afi_t *afi);
+
+extern int
+argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index, safi_t *safi);
+
+extern int
+bgp_vty_find_and_parse_afi_safi_vrf (struct vty *vty, struct cmd_token **argv, int argc, int *idx,
+ afi_t *afi, safi_t *safi, vrf_id_t *vrf);
#endif /* _QUAGGA_BGP_VTY_H */
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 3d3bd90f5b..822f459c28 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -698,7 +698,6 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
return 0;
}
-#ifdef HAVE_IPV6
/* Zebra route add and delete treatment. */
static int
zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
@@ -707,7 +706,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
struct stream *s;
struct zapi_ipv6 api;
struct in6_addr nexthop;
- struct prefix_ipv6 p;
+ struct prefix_ipv6 p, src_p;
unsigned int ifindex;
int i;
struct bgp *bgp;
@@ -731,6 +730,18 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s));
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
+ {
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ }
+
+ if (src_p.prefixlen)
+ /* we completely ignore srcdest routes for now. */
+ return 0;
+
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
@@ -817,7 +828,6 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
return 0;
}
-#endif /* HAVE_IPV6 */
struct interface *
if_lookup_by_ipv4 (struct in_addr *addr, vrf_id_t vrf_id)
@@ -870,7 +880,6 @@ if_lookup_by_ipv4_exact (struct in_addr *addr, vrf_id_t vrf_id)
return NULL;
}
-#ifdef HAVE_IPV6
struct interface *
if_lookup_by_ipv6 (struct in6_addr *addr, ifindex_t ifindex, vrf_id_t vrf_id)
{
@@ -979,7 +988,6 @@ if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
}
return 0;
}
-#endif /* HAVE_IPV6 */
static int
if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
@@ -1022,7 +1030,6 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
else
ifp = if_lookup_by_ipv4_exact (&local->sin.sin_addr, peer->bgp->vrf_id);
}
-#ifdef HAVE_IPV6
if (local->sa.sa_family == AF_INET6)
{
if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
@@ -1037,7 +1044,6 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
local->sin6.sin6_scope_id,
peer->bgp->vrf_id);
}
-#endif /* HAVE_IPV6 */
if (!ifp)
return -1;
@@ -1047,7 +1053,6 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
/* IPv4 connection, fetch and store IPv6 local address(es) if any. */
if (local->sa.sa_family == AF_INET)
{
-#ifdef HAVE_IPV6
/* IPv6 nexthop*/
ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
@@ -1069,10 +1074,8 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
peer->shared_network = 1;
else
peer->shared_network = 0;
-#endif /* HAVE_IPV6 */
}
-#ifdef HAVE_IPV6
/* IPv6 connection, fetch and store IPv4 local address if any. */
if (local->sa.sa_family == AF_INET6)
{
@@ -1135,7 +1138,6 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote,
SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
}
#endif /* KAME */
-#endif /* HAVE_IPV6 */
/* If we have identified the local interface, there is no error for now. */
return 0;
@@ -1390,7 +1392,6 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
zapi_ipv4_route (valid_nh_count ? ZEBRA_IPV4_ROUTE_ADD: ZEBRA_IPV4_ROUTE_DELETE,
zclient, (struct prefix_ipv4 *) p, &api);
}
-#ifdef HAVE_IPV6
/* We have to think about a IPv6 link-local address curse. */
if (p->family == AF_INET6 ||
@@ -1598,10 +1599,9 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
zapi_ipv6_route (valid_nh_count ?
ZEBRA_IPV6_ROUTE_ADD : ZEBRA_IPV6_ROUTE_DELETE,
- zclient, (struct prefix_ipv6 *) p, &api);
+ zclient, (struct prefix_ipv6 *) p, NULL, &api);
}
}
-#endif /* HAVE_IPV6 */
}
/* Announce all routes of a table to zebra */
@@ -1700,7 +1700,6 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
(struct prefix_ipv4 *) p, &api);
}
-#ifdef HAVE_IPV6
/* We have to think about a IPv6 link-local address curse. */
if (p->family == AF_INET6)
{
@@ -1738,10 +1737,10 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
}
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
- (struct prefix_ipv6 *) p, &api);
+ (struct prefix_ipv6 *) p, NULL, &api);
}
-#endif /* HAVE_IPV6 */
}
+
struct bgp_redist *
bgp_redist_lookup (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
{
diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h
index 24b4634eb6..d22a00e8fb 100644
--- a/bgpd/bgp_zebra.h
+++ b/bgpd/bgp_zebra.h
@@ -57,10 +57,8 @@ extern int bgp_redistribute_unreg (struct bgp *, afi_t, int, u_short);
extern struct interface *if_lookup_by_ipv4 (struct in_addr *, vrf_id_t);
extern struct interface *if_lookup_by_ipv4_exact (struct in_addr *, vrf_id_t);
-#ifdef HAVE_IPV6
extern struct interface *if_lookup_by_ipv6 (struct in6_addr *, ifindex_t, vrf_id_t);
extern struct interface *if_lookup_by_ipv6_exact (struct in6_addr *, ifindex_t, vrf_id_t);
-#endif /* HAVE_IPV6 */
extern int bgp_zebra_num_connects(void);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index ef633c16e7..fc6968e9d9 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -20,7 +20,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include <zebra.h>
-#include "lib/json.h"
#include "prefix.h"
#include "thread.h"
#include "buffer.h"
@@ -42,6 +41,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "hash.h"
#include "jhash.h"
#include "table.h"
+#include "lib/json.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@@ -78,6 +78,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_bfd.h"
#include "bgpd/bgp_memory.h"
+DEFINE_QOBJ_TYPE(bgp_master)
+DEFINE_QOBJ_TYPE(bgp)
+DEFINE_QOBJ_TYPE(peer)
+
/* BGP process wide configuration. */
static struct bgp_master bgp_master;
@@ -344,7 +348,7 @@ time_t bgp_clock (void)
{
struct timeval tv;
- quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv);
+ monotime(&tv);
return tv.tv_sec;
}
@@ -647,6 +651,35 @@ bgp_listen_limit_unset (struct bgp *bgp)
return 0;
}
+int
+bgp_map_afi_safi_iana2int (iana_afi_t pkt_afi, safi_t pkt_safi,
+ afi_t *afi, safi_t *safi)
+{
+ /* Map from IANA values to internal values, return error if
+ * values are unrecognized.
+ */
+ *afi = afi_iana2int (pkt_afi);
+ *safi = safi_iana2int (pkt_safi);
+ if (*afi == AFI_MAX || *safi == SAFI_MAX)
+ return -1;
+
+ return 0;
+}
+
+int
+bgp_map_afi_safi_int2iana (afi_t afi, safi_t safi,
+ iana_afi_t *pkt_afi, safi_t *pkt_safi)
+{
+ /* Map from internal values to IANA values, return error if
+ * internal values are bad (unexpected).
+ */
+ if (afi == AFI_MAX || safi == SAFI_MAX)
+ return -1;
+ *pkt_afi = afi_int2iana (afi);
+ *pkt_safi = safi_int2iana (safi);
+ return 0;
+}
+
struct peer_af *
peer_af_create (struct peer *peer, afi_t afi, safi_t safi)
{
@@ -869,6 +902,7 @@ peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi)
{
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
+ SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY);
}
/* Clear neighbor default_originate_rmap */
@@ -1018,6 +1052,8 @@ peer_free (struct peer *peer)
{
assert (peer->status == Deleted);
+ QOBJ_UNREG (peer);
+
/* this /ought/ to have been done already through bgp_stop earlier,
* but just to be sure..
*/
@@ -1171,6 +1207,7 @@ peer_new (struct bgp *bgp)
{
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
+ SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY);
}
peer->orf_plist[afi][safi] = NULL;
}
@@ -1201,6 +1238,7 @@ peer_new (struct bgp *bgp)
sp = getservbyname ("bgp", "tcp");
peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port);
+ QOBJ_REG (peer, peer);
return peer;
}
@@ -1895,7 +1933,7 @@ peer_nsf_stop (struct peer *peer)
UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
- for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
+ for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++)
peer->nsf[afi][safi] = 0;
if (peer->t_gr_restart)
@@ -2917,6 +2955,8 @@ bgp_create (as_t *as, const char *name, enum bgp_instance_type inst_type)
bgp->wpkt_quanta = BGP_WRITE_PACKET_MAX;
bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
+ QOBJ_REG (bgp, bgp);
+
update_bgp_group_init(bgp);
return bgp;
}
@@ -3233,6 +3273,8 @@ bgp_free (struct bgp *bgp)
afi_t afi;
safi_t safi;
+ QOBJ_UNREG (bgp);
+
list_delete (bgp->group);
list_delete (bgp->peer);
@@ -3662,6 +3704,7 @@ static const struct peer_flag_action peer_af_flag_action_list[] =
{
{ PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out },
{ PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out },
+ { PEER_FLAG_SEND_LARGE_COMMUNITY, 1, peer_change_reset_out },
{ PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out },
{ PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset },
{ PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset },
@@ -4575,7 +4618,7 @@ peer_weight_set (struct peer *peer, afi_t afi, safi_t safi, u_int16_t weight)
peer->weight[afi][safi] = weight;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT);
peer_on_policy_change (peer, afi, safi, 0);
- }
+ }
}
return 0;
}
@@ -4587,7 +4630,7 @@ peer_weight_unset (struct peer *peer, afi_t afi, safi_t safi)
struct listnode *node, *nnode;
/* not the peer-group itself but a peer in a peer-group */
- if (peer_group_active(peer))
+ if (peer_group_active (peer))
{
group = peer->group;
@@ -4618,13 +4661,13 @@ peer_weight_unset (struct peer *peer, afi_t afi, safi_t safi)
peer_on_policy_change (peer, afi, safi, 0);
}
- /* peer-group member updates. */
- group = peer->group;
+ /* peer-group member updates. */
+ group = peer->group;
if (group)
{
- for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
- {
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
+ {
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
{
peer->weight[afi][safi] = 0;
@@ -4632,7 +4675,7 @@ peer_weight_unset (struct peer *peer, afi_t afi, safi_t safi)
peer_on_policy_change (peer, afi, safi, 0);
}
}
- }
+ }
}
return 0;
}
@@ -6943,10 +6986,17 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
{
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
- && peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
+ && peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)
+ && peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
+ {
+ afi_header_vty_out (vty, afi, safi, write,
+ " neighbor %s send-community all%s",
+ addr, VTY_NEWLINE);
+ }
+ else if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
{
afi_header_vty_out (vty, afi, safi, write,
- " neighbor %s send-community both%s",
+ " neighbor %s send-community large%s",
addr, VTY_NEWLINE);
}
else if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
@@ -6967,10 +7017,19 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) &&
(!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)) &&
!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY) &&
- (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)))
+ (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)) &&
+ !peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY) &&
+ (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY)))
{
afi_header_vty_out (vty, afi, safi, write,
- " no neighbor %s send-community both%s",
+ " no neighbor %s send-community all%s",
+ addr, VTY_NEWLINE);
+ }
+ else if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY) &&
+ (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY)))
+ {
+ afi_header_vty_out (vty, afi, safi, write,
+ " no neighbor %s send-community large%s",
addr, VTY_NEWLINE);
}
else if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY) &&
@@ -7361,6 +7420,10 @@ bgp_config_write (struct vty *vty)
if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
+ /* BGP graceful-restart Preserve State F bit. */
+ if (bgp_flag_check (bgp, BGP_FLAG_GR_PRESERVE_FWD))
+ vty_out (vty, " bgp graceful-restart preserve-fw-state%s", VTY_NEWLINE);
+
/* BGP bestpath method. */
if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
@@ -7467,6 +7530,8 @@ bgp_config_write (struct vty *vty)
void
bgp_master_init (void)
{
+ qobj_init ();
+
memset (&bgp_master, 0, sizeof (struct bgp_master));
bm = &bgp_master;
@@ -7482,6 +7547,8 @@ bgp_master_init (void)
/* Enable multiple instances by default. */
bgp_option_set (BGP_OPT_MULTIPLE_INSTANCE);
+
+ QOBJ_REG (bm, bgp_master);
}
/*
@@ -7583,6 +7650,8 @@ bgp_terminate (void)
struct listnode *node, *nnode;
struct listnode *mnode, *mnnode;
+ QOBJ_UNREG (bm);
+
/* Close the listener sockets first as this prevents peers from attempting
* to reconnect on receiving the peer unconfig message. In the presence
* of a large number of peers this will ensure that no peer is left with
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 510082fdc2..2eef04e1d1 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -21,6 +21,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGPD_H
#define _QUAGGA_BGPD_H
+#include "qobj.h"
#include "lib/json.h"
#include "vrf.h"
@@ -120,7 +121,10 @@ struct bgp_master
struct thread *t_rmap_update; /* Handle route map updates */
u_int32_t rmap_update_timer; /* Route map update timer */
#define RMAP_DEFAULT_UPDATE_TIMER 5 /* disabled by default */
+
+ QOBJ_FIELDS
};
+DECLARE_QOBJ_TYPE(bgp_master)
/* BGP route-map structure. */
struct bgp_rmap
@@ -285,6 +289,7 @@ struct bgp
#define BGP_FLAG_MULTIPATH_RELAX_AS_SET (1 << 17)
#define BGP_FLAG_FORCE_STATIC_PROCESS (1 << 18)
#define BGP_FLAG_SHOW_HOSTNAME (1 << 19)
+#define BGP_FLAG_GR_PRESERVE_FWD (1 << 20)
/* BGP Per AF flags */
u_int16_t af_flags[AFI_MAX][SAFI_MAX];
@@ -356,7 +361,10 @@ struct bgp
struct rfapi_cfg *rfapi_cfg;
struct rfapi *rfapi;
#endif
+
+ QOBJ_FIELDS
};
+DECLARE_QOBJ_TYPE(bgp)
#define BGP_ROUTE_ADV_HOLD(bgp) (bgp->main_peers_update_hold)
@@ -397,10 +405,8 @@ struct bgp_nexthop
{
struct interface *ifp;
struct in_addr v4;
-#ifdef HAVE_IPV6
struct in6_addr v6_global;
struct in6_addr v6_local;
-#endif /* HAVE_IPV6 */
};
/* BGP addpath values */
@@ -699,6 +705,7 @@ struct peer
#define PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS (1 << 23) /* addpath-tx-bestpath-per-AS */
#define PEER_FLAG_WEIGHT (1 << 24) /* weight */
#define PEER_FLAG_ALLOWAS_IN_ORIGIN (1 << 25) /* allowas-in origin */
+#define PEER_FLAG_SEND_LARGE_COMMUNITY (1 << 26) /* Send large Communities */
/* MD5 password */
char *password;
@@ -879,7 +886,10 @@ u_char last_reset_cause[BGP_MAX_PACKET_SIZE];
/* hostname and domainname advertised by host */
char *hostname;
char *domainname;
+
+ QOBJ_FIELDS
};
+DECLARE_QOBJ_TYPE(peer)
/* Check if suppress start/restart of sessions to peer. */
#define BGP_PEER_START_SUPPRESSED(P) \
@@ -954,6 +964,7 @@ struct bgp_nlri
#define BGP_ATTR_AS4_AGGREGATOR 18
#define BGP_ATTR_AS_PATHLIMIT 21
#define BGP_ATTR_ENCAP 23
+#define BGP_ATTR_LARGE_COMMUNITIES 32
#if ENABLE_BGP_VNC
#define BGP_ATTR_VNC 255
#endif
@@ -1069,10 +1080,6 @@ struct bgp_nlri
#define BGP_DEFAULT_RESTART_TIME 120
#define BGP_DEFAULT_STALEPATH_TIME 360
-/* RFC4364 */
-#define SAFI_MPLS_LABELED_VPN 128
-#define BGP_SAFI_VPN 128
-
/* BGP uptime string length. */
#define BGP_UPTIME_LEN 25
@@ -1349,6 +1356,13 @@ extern void bgp_route_map_terminate(void);
extern int peer_cmp (struct peer *p1, struct peer *p2);
+extern int
+bgp_map_afi_safi_iana2int (iana_afi_t pkt_afi, safi_t pkt_safi,
+ afi_t *afi, safi_t *safi);
+extern int
+bgp_map_afi_safi_int2iana (afi_t afi, safi_t safi,
+ iana_afi_t *pkt_afi, safi_t *pkt_safi);
+
extern struct peer_af * peer_af_create (struct peer *, afi_t, safi_t);
extern struct peer_af * peer_af_find (struct peer *, afi_t, safi_t);
extern int peer_af_delete (struct peer *, afi_t, safi_t);
@@ -1448,13 +1462,9 @@ peer_group_af_configured (struct peer_group *group)
static inline char *
timestamp_string (time_t ts)
{
-#ifdef HAVE_CLOCK_MONOTONIC
time_t tbuf;
tbuf = time(NULL) - (bgp_clock() - ts);
return ctime(&tbuf);
-#else
- return ctime(&ts);
-#endif /* HAVE_CLOCK_MONOTONIC */
}
static inline int
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c
index 202abc61d1..50693659b6 100644
--- a/bgpd/rfapi/bgp_rfapi_cfg.c
+++ b/bgpd/rfapi/bgp_rfapi_cfg.c
@@ -30,8 +30,8 @@
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
-#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/rfapi/rfapi.h"
@@ -291,19 +291,13 @@ bgp_rfapi_is_vnc_configured (struct bgp *bgp)
DEFUN (vnc_advertise_un_method,
vnc_advertise_un_method_cmd,
- "vnc advertise-un-method (encap-safi|encap-attr)",
+ "vnc advertise-un-method <encap-safi|encap-attr>",
VNC_CONFIG_STR
"Method of advertising UN addresses\n"
"Via Encapsulation SAFI\n"
"Via Tunnel Encap attribute (in VPN SAFI)\n")
{
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp->rfapi_cfg)
{
@@ -312,7 +306,7 @@ DEFUN (vnc_advertise_un_method,
}
- if (!strncmp (argv[0], "encap-safi", 7))
+ if (!strncmp (argv[2]->arg, "encap-safi", 7))
{
bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP;
}
@@ -341,7 +335,7 @@ static int
set_ecom_list (
struct vty *vty,
int argc,
- const char **argv,
+ struct cmd_token **argv,
struct ecommunity **list)
{
struct ecommunity *ecom = NULL;
@@ -350,7 +344,7 @@ set_ecom_list (
for (; argc; --argc, ++argv)
{
- ecomadd = ecommunity_str2com (*argv, ECOMMUNITY_ROUTE_TARGET, 0);
+ ecomadd = ecommunity_str2com (argv[0]->arg, ECOMMUNITY_ROUTE_TARGET, 0);
if (!ecomadd)
{
vty_out (vty, "Malformed community-list value%s", VTY_NEWLINE);
@@ -381,58 +375,43 @@ set_ecom_list (
DEFUN (vnc_defaults_rt_import,
vnc_defaults_rt_import_cmd,
- "rt import .RTLIST",
+ "rt import RTLIST...",
"Specify default route targets\n"
"Import filter\n"
"Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
{
- struct bgp *bgp = vty->index;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return set_ecom_list (vty, argc, argv,
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ return set_ecom_list (vty, argc - 2, argv + 2,
&bgp->rfapi_cfg->default_rt_import_list);
}
DEFUN (vnc_defaults_rt_export,
vnc_defaults_rt_export_cmd,
- "rt export .RTLIST",
+ "rt export RTLIST...",
"Configure default route targets\n"
"Export filter\n"
"Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
{
- struct bgp *bgp = vty->index;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return set_ecom_list (vty, argc, argv,
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ return set_ecom_list (vty, argc - 2, argv + 2,
&bgp->rfapi_cfg->default_rt_export_list);
}
DEFUN (vnc_defaults_rt_both,
vnc_defaults_rt_both_cmd,
- "rt both .RTLIST",
+ "rt both RTLIST...",
"Configure default route targets\n"
"Export+import filters\n"
"Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int rc;
- struct bgp *bgp = vty->index;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- rc =
- set_ecom_list (vty, argc, argv, &bgp->rfapi_cfg->default_rt_import_list);
+ rc = set_ecom_list (vty, argc - 2, argv + 2,
+ &bgp->rfapi_cfg->default_rt_import_list);
if (rc != CMD_SUCCESS)
return rc;
- return set_ecom_list (vty, argc, argv,
+ return set_ecom_list (vty, argc - 2, argv + 2,
&bgp->rfapi_cfg->default_rt_export_list);
}
@@ -442,27 +421,21 @@ DEFUN (vnc_defaults_rd,
"Specify default route distinguisher\n"
"Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
struct prefix_rd prd;
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (!strncmp (argv[0], "auto:vn:", 8))
+ if (!strncmp (argv[1]->arg, "auto:vn:", 8))
{
/*
* use AF_UNIX to designate automatically-assigned RD
* auto:vn:nn where nn is a 2-octet quantity
*/
char *end = NULL;
- uint32_t value32 = strtoul (argv[0] + 8, &end, 10);
+ uint32_t value32 = strtoul (argv[1]->arg + 8, &end, 10);
uint16_t value = value32 & 0xffff;
- if (!*(argv[0] + 5) || *end)
+ if (!argv[1]->arg[8] || *end)
{
vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -486,7 +459,7 @@ DEFUN (vnc_defaults_rd,
else
{
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[1]->arg, &prd);
if (!ret)
{
vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
@@ -500,33 +473,27 @@ DEFUN (vnc_defaults_rd,
DEFUN (vnc_defaults_l2rd,
vnc_defaults_l2rd_cmd,
- "l2rd (ID|auto:vn)",
+ "l2rd <(1-255)|auto-vn>",
"Specify default Local Nve ID value to use in RD for L2 routes\n"
"Fixed value 1-255\n"
"use the low-order octet of the NVE's VN address\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
uint8_t value = 0;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (!strcmp (argv[0], "auto:vn"))
+ if (!strcmp (argv[1]->arg, "auto-vn"))
{
value = 0;
}
else
{
char *end = NULL;
- unsigned long value_l = strtoul (argv[0], &end, 10);
+ unsigned long value_l = strtoul (argv[1]->arg, &end, 10);
value = value_l & 0xff;
- if (!*(argv[0]) || *end)
+ if (!argv[1]->arg[0] || *end)
{
- vty_out (vty, "%% Malformed l2 nve ID \"%s\"%s", argv[0],
+ vty_out (vty, "%% Malformed l2 nve ID \"%s\"%s", argv[1]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -550,13 +517,7 @@ DEFUN (vnc_defaults_no_l2rd,
NO_STR
"Specify default Local Nve ID value to use in RD for L2 routes\n")
{
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp->rfapi_cfg->default_l2rd = 0;
bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_L2RD;
@@ -566,33 +527,27 @@ DEFUN (vnc_defaults_no_l2rd,
DEFUN (vnc_defaults_responselifetime,
vnc_defaults_responselifetime_cmd,
- "response-lifetime (LIFETIME|infinite)",
+ "response-lifetime <LIFETIME|infinite>",
"Specify default response lifetime\n"
"Response lifetime in seconds\n" "Infinite response lifetime\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
uint32_t rspint;
- struct bgp *bgp = vty->index;
struct rfapi *h = NULL;
struct listnode *hdnode;
struct rfapi_descriptor *rfd;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
h = bgp->rfapi;
if (!h)
return CMD_WARNING;
- if (!strcmp (argv[0], "infinite"))
+ if (!strcmp (argv[1]->arg, "infinite"))
{
rspint = RFAPI_INFINITE_LIFETIME;
}
else
{
- VTY_GET_INTEGER ("Response Lifetime", rspint, argv[0]);
+ VTY_GET_INTEGER ("Response Lifetime", rspint, argv[1]->arg);
if (rspint > INT32_MAX)
rspint = INT32_MAX; /* is really an int, not an unsigned int */
}
@@ -606,8 +561,9 @@ DEFUN (vnc_defaults_responselifetime,
return CMD_SUCCESS;
}
-static struct rfapi_nve_group_cfg *
-rfapi_group_lookup_byname (struct bgp *bgp, const char *name)
+struct rfapi_nve_group_cfg *
+bgp_rfapi_cfg_match_byname (struct bgp *bgp, const char *name,
+ rfapi_group_cfg_type_t type) /* _MAX = any */
{
struct rfapi_nve_group_cfg *rfg;
struct listnode *node, *nnode;
@@ -615,18 +571,29 @@ rfapi_group_lookup_byname (struct bgp *bgp, const char *name)
for (ALL_LIST_ELEMENTS
(bgp->rfapi_cfg->nve_groups_sequential, node, nnode, rfg))
{
- if (!strcmp (rfg->name, name))
+ if ((type == RFAPI_GROUP_CFG_MAX || type == rfg->type) &&
+ !strcmp (rfg->name, name))
return rfg;
}
return NULL;
}
static struct rfapi_nve_group_cfg *
-rfapi_group_new ()
+rfapi_group_new (struct bgp *bgp,
+ rfapi_group_cfg_type_t type,
+ const char *name)
{
struct rfapi_nve_group_cfg *rfg;
rfg = XCALLOC (MTYPE_RFAPI_GROUP_CFG, sizeof (struct rfapi_nve_group_cfg));
+ if (rfg)
+ {
+ rfg->type = type;
+ rfg->name = strdup (name);
+ /* add to tail of list */
+ listnode_add (bgp->rfapi_cfg->nve_groups_sequential, rfg);
+ }
+ rfg->label = MPLS_LABEL_ILLEGAL;
QOBJ_REG (rfg, rfapi_nve_group_cfg);
return rfg;
@@ -824,29 +791,24 @@ vnc_redistribute_postchange (struct bgp *bgp)
DEFUN (vnc_redistribute_rh_roo_localadmin,
vnc_redistribute_rh_roo_localadmin_cmd,
- "vnc redistribute resolve-nve roo-ec-local-admin <0-65535>",
+ "vnc redistribute resolve-nve roo-ec-local-admin (0-65535)",
VNC_CONFIG_STR
"Redistribute routes into VNC\n"
"Resolve-NVE mode\n"
"Route Origin Extended Community Local Admin Field\n" "Field value\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
uint32_t localadmin;
char *endptr;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
if (!bgp->rfapi_cfg)
{
vty_out (vty, "RFAPI not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- localadmin = strtoul (argv[0], &endptr, 0);
- if (!*(argv[0]) || *endptr)
+ localadmin = strtoul (argv[4]->arg, &endptr, 0);
+ if (!argv[4]->arg[0] || *endptr)
{
vty_out (vty, "%% Malformed value%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -885,21 +847,16 @@ DEFUN (vnc_redistribute_rh_roo_localadmin,
DEFUN (vnc_redistribute_mode,
vnc_redistribute_mode_cmd,
- "vnc redistribute mode (nve-group|plain|resolve-nve)",
+ "vnc redistribute mode <nve-group|plain|resolve-nve>",
VNC_CONFIG_STR
"Redistribute routes into VNC\n"
"Redistribution mode\n"
"Based on redistribute nve-group\n"
"Unmodified\n" "Resolve each nexthop to connected NVEs\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
vnc_redist_mode_t newmode;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
if (!bgp->rfapi_cfg)
{
vty_out (vty, "RFAPI not configured%s", VTY_NEWLINE);
@@ -907,7 +864,7 @@ DEFUN (vnc_redistribute_mode,
}
- switch (*argv[0])
+ switch (argv[3]->arg[0])
{
case 'n':
newmode = VNC_REDIST_MODE_RFG;
@@ -938,7 +895,7 @@ DEFUN (vnc_redistribute_mode,
DEFUN (vnc_redistribute_protocol,
vnc_redistribute_protocol_cmd,
- "vnc redistribute (ipv4|ipv6) (bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static)",
+ "vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
VNC_CONFIG_STR
"Redistribute routes into VNC\n"
"IPv4 routes\n"
@@ -951,22 +908,17 @@ DEFUN (vnc_redistribute_protocol,
"From Open Shortest Path First (OSPF)\n"
"From Routing Information Protocol (RIP)\n" "From Static routes\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int type = ZEBRA_ROUTE_MAX; /* init to bogus value */
- struct bgp *bgp = vty->index;
afi_t afi;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
if (!bgp->rfapi_cfg)
{
vty_out (vty, "RFAPI not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (rfapi_str2route_type (argv[0], argv[1], &afi, &type))
+ if (rfapi_str2route_type (argv[2]->arg, argv[3]->arg, &afi, &type))
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -990,7 +942,7 @@ DEFUN (vnc_redistribute_protocol,
DEFUN (vnc_no_redistribute_protocol,
vnc_no_redistribute_protocol_cmd,
- "no vnc redistribute (ipv4|ipv6) (bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static)",
+ "no vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
NO_STR
VNC_CONFIG_STR
"Redistribute from other protocol\n"
@@ -1004,22 +956,17 @@ DEFUN (vnc_no_redistribute_protocol,
"From Open Shortest Path First (OSPF)\n"
"From Routing Information Protocol (RIP)\n" "From Static routes\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int type;
- struct bgp *bgp = vty->index;
afi_t afi;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
if (!bgp->rfapi_cfg)
{
vty_out (vty, "RFAPI not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (rfapi_str2route_type (argv[0], argv[1], &afi, &type))
+ if (rfapi_str2route_type (argv[3]->arg, argv[4]->arg, &afi, &type))
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -1042,7 +989,7 @@ DEFUN (vnc_no_redistribute_protocol,
DEFUN (vnc_redistribute_bgp_exterior,
vnc_redistribute_bgp_exterior_cmd,
- "vnc redistribute (ipv4|ipv6) bgp-direct-to-nve-groups view NAME",
+ "vnc redistribute <ipv4|ipv6> bgp-direct-to-nve-groups view NAME",
VNC_CONFIG_STR
"Redistribute routes into VNC\n"
"IPv4 routes\n"
@@ -1050,22 +997,17 @@ DEFUN (vnc_redistribute_bgp_exterior,
"From BGP without Zebra, only to configured NVE groups\n"
"From BGP view\n" "BGP view name\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int type;
- struct bgp *bgp = vty->index;
afi_t afi;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
if (!bgp->rfapi_cfg)
{
vty_out (vty, "RFAPI not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (rfapi_str2route_type (argv[0], "bgp-direct-to-nve-groups", &afi, &type))
+ if (rfapi_str2route_type (argv[2]->arg, "bgp-direct-to-nve-groups", &afi, &type))
{
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -1073,9 +1015,9 @@ DEFUN (vnc_redistribute_bgp_exterior,
if (bgp->rfapi_cfg->redist_bgp_exterior_view_name)
free (bgp->rfapi_cfg->redist_bgp_exterior_view_name);
- bgp->rfapi_cfg->redist_bgp_exterior_view_name = strdup (argv[1]);
+ bgp->rfapi_cfg->redist_bgp_exterior_view_name = strdup (argv[5]->arg);
/* could be NULL if name is not defined yet */
- bgp->rfapi_cfg->redist_bgp_exterior_view = bgp_lookup_by_name (argv[1]);
+ bgp->rfapi_cfg->redist_bgp_exterior_view = bgp_lookup_by_name (argv[5]->arg);
VNC_REDIST_ENABLE (bgp, afi, type);
@@ -1089,13 +1031,7 @@ DEFUN (vnc_redistribute_nvegroup,
"Assign a NVE group to routes redistributed from another routing protocol\n"
"NVE group\n" "Group name\n")
{
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp->rfapi_cfg)
{
@@ -1109,10 +1045,11 @@ DEFUN (vnc_redistribute_nvegroup,
* OK if nve group doesn't exist yet; we'll set the pointer
* when the group is defined later
*/
- bgp->rfapi_cfg->rfg_redist = rfapi_group_lookup_byname (bgp, argv[0]);
+ bgp->rfapi_cfg->rfg_redist = bgp_rfapi_cfg_match_byname (bgp, argv[3]->arg,
+ RFAPI_GROUP_CFG_NVE);
if (bgp->rfapi_cfg->rfg_redist_name)
free (bgp->rfapi_cfg->rfg_redist_name);
- bgp->rfapi_cfg->rfg_redist_name = strdup (argv[0]);
+ bgp->rfapi_cfg->rfg_redist_name = strdup (argv[3]->arg);
vnc_redistribute_postchange (bgp);
@@ -1127,13 +1064,7 @@ DEFUN (vnc_redistribute_no_nvegroup,
"Redistribute from other protocol\n"
"Assign a NVE group to routes redistributed from another routing protocol\n")
{
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp->rfapi_cfg)
{
@@ -1156,18 +1087,14 @@ DEFUN (vnc_redistribute_no_nvegroup,
DEFUN (vnc_redistribute_lifetime,
vnc_redistribute_lifetime_cmd,
- "vnc redistribute lifetime (LIFETIME|infinite)",
+ "vnc redistribute lifetime <LIFETIME|infinite>",
VNC_CONFIG_STR
+ "Redistribute\n"
"Assign a lifetime to routes redistributed from another routing protocol\n"
- "lifetime value (32 bit)\n")
+ "lifetime value (32 bit)\n"
+ "Allow lifetime to never expire\n")
{
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp->rfapi_cfg)
{
@@ -1177,14 +1104,14 @@ DEFUN (vnc_redistribute_lifetime,
vnc_redistribute_prechange (bgp);
- if (!strcmp (argv[0], "infinite"))
+ if (!strcmp (argv[3]->arg, "infinite"))
{
bgp->rfapi_cfg->redist_lifetime = RFAPI_INFINITE_LIFETIME;
}
else
{
VTY_GET_INTEGER ("Response Lifetime", bgp->rfapi_cfg->redist_lifetime,
- argv[0]);
+ argv[3]->arg);
}
vnc_redistribute_postchange (bgp);
@@ -1196,7 +1123,7 @@ DEFUN (vnc_redistribute_lifetime,
DEFUN (vnc_redist_bgpdirect_no_prefixlist,
vnc_redist_bgpdirect_no_prefixlist_cmd,
- "no vnc redistribute (bgp-direct|bgp-direct-to-nve-groups) (ipv4|ipv6) prefix-list",
+ "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list",
NO_STR
VNC_CONFIG_STR
"Redistribute from other protocol\n"
@@ -1205,24 +1132,18 @@ DEFUN (vnc_redist_bgpdirect_no_prefixlist,
"IPv4 routes\n"
"IPv6 routes\n" "Prefix-list for filtering redistributed routes\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
afi_t afi;
struct rfapi_cfg *hc;
uint8_t route_type = 0;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!(hc = bgp->rfapi_cfg))
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!strcmp (argv[0], "bgp-direct"))
+ if (!strcmp (argv[3]->arg, "bgp-direct"))
{
route_type = ZEBRA_ROUTE_BGP_DIRECT;
}
@@ -1231,7 +1152,7 @@ DEFUN (vnc_redist_bgpdirect_no_prefixlist,
route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
}
- if (!strcmp (argv[1], "ipv4"))
+ if (!strcmp (argv[4]->arg, "ipv4"))
{
afi = AFI_IP;
}
@@ -1254,7 +1175,7 @@ DEFUN (vnc_redist_bgpdirect_no_prefixlist,
DEFUN (vnc_redist_bgpdirect_prefixlist,
vnc_redist_bgpdirect_prefixlist_cmd,
- "vnc redistribute (bgp-direct|bgp-direct-to-nve-groups) (ipv4|ipv6) prefix-list NAME",
+ "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list NAME",
VNC_CONFIG_STR
"Redistribute from other protocol\n"
"Redistribute from BGP directly\n"
@@ -1264,24 +1185,18 @@ DEFUN (vnc_redist_bgpdirect_prefixlist,
"Prefix-list for filtering redistributed routes\n"
"prefix list name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct rfapi_cfg *hc;
afi_t afi;
uint8_t route_type = 0;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!(hc = bgp->rfapi_cfg))
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!strcmp (argv[0], "bgp-direct"))
+ if (!strcmp (argv[2]->arg, "bgp-direct"))
{
route_type = ZEBRA_ROUTE_BGP_DIRECT;
}
@@ -1290,7 +1205,7 @@ DEFUN (vnc_redist_bgpdirect_prefixlist,
route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
}
- if (!strcmp (argv[1], "ipv4"))
+ if (!strcmp (argv[3]->arg, "ipv4"))
{
afi = AFI_IP;
}
@@ -1303,8 +1218,8 @@ DEFUN (vnc_redist_bgpdirect_prefixlist,
if (hc->plist_redist_name[route_type][afi])
free (hc->plist_redist_name[route_type][afi]);
- hc->plist_redist_name[route_type][afi] = strdup (argv[2]);
- hc->plist_redist[route_type][afi] = prefix_list_lookup (afi, argv[2]);
+ hc->plist_redist_name[route_type][afi] = strdup (argv[5]->arg);
+ hc->plist_redist[route_type][afi] = prefix_list_lookup (afi, argv[5]->arg);
vnc_redistribute_postchange (bgp);
@@ -1313,7 +1228,7 @@ DEFUN (vnc_redist_bgpdirect_prefixlist,
DEFUN (vnc_redist_bgpdirect_no_routemap,
vnc_redist_bgpdirect_no_routemap_cmd,
- "no vnc redistribute (bgp-direct|bgp-direct-to-nve-groups) route-map",
+ "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map",
NO_STR
VNC_CONFIG_STR
"Redistribute from other protocols\n"
@@ -1321,23 +1236,17 @@ DEFUN (vnc_redist_bgpdirect_no_routemap,
"Redistribute from BGP without Zebra, only to configured NVE groups\n"
"Route-map for filtering redistributed routes\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct rfapi_cfg *hc;
uint8_t route_type = 0;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!(hc = bgp->rfapi_cfg))
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!strcmp (argv[0], "bgp-direct"))
+ if (!strcmp (argv[3]->arg, "bgp-direct"))
{
route_type = ZEBRA_ROUTE_BGP_DIRECT;
}
@@ -1360,30 +1269,24 @@ DEFUN (vnc_redist_bgpdirect_no_routemap,
DEFUN (vnc_redist_bgpdirect_routemap,
vnc_redist_bgpdirect_routemap_cmd,
- "vnc redistribute (bgp-direct|bgp-direct-to-nve-groups) route-map NAME",
+ "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map NAME",
VNC_CONFIG_STR
"Redistribute from other protocols\n"
"Redistribute from BGP directly\n"
"Redistribute from BGP without Zebra, only to configured NVE groups\n"
"Route-map for filtering exported routes\n" "route map name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct rfapi_cfg *hc;
uint8_t route_type = 0;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!(hc = bgp->rfapi_cfg))
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!strcmp (argv[0], "bgp-direct"))
+ if (!strcmp (argv[2]->arg, "bgp-direct"))
{
route_type = ZEBRA_ROUTE_BGP_DIRECT;
}
@@ -1396,8 +1299,8 @@ DEFUN (vnc_redist_bgpdirect_routemap,
if (hc->routemap_redist_name[route_type])
free (hc->routemap_redist_name[route_type]);
- hc->routemap_redist_name[route_type] = strdup (argv[1]);
- hc->routemap_redist[route_type] = route_map_lookup_by_name (argv[1]);
+ hc->routemap_redist_name[route_type] = strdup (argv[4]->arg);
+ hc->routemap_redist[route_type] = route_map_lookup_by_name (argv[4]->arg);
vnc_redistribute_postchange (bgp);
@@ -1410,7 +1313,7 @@ DEFUN (vnc_redist_bgpdirect_routemap,
DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist,
vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd,
- "no redistribute bgp-direct (ipv4|ipv6) prefix-list",
+ "no redistribute bgp-direct <ipv4|ipv6> prefix-list",
NO_STR
"Redistribute from other protocol\n"
"Redistribute from BGP directly\n"
@@ -1418,16 +1321,10 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist,
"IPv4 routes\n"
"IPv6 routes\n" "Prefix-list for filtering redistributed routes\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg)
afi_t afi;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
@@ -1442,7 +1339,7 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist,
return CMD_WARNING;
}
- if (!strcmp (argv[0], "ipv4"))
+ if (!strcmp (argv[3]->arg, "ipv4"))
{
afi = AFI_IP;
}
@@ -1465,7 +1362,7 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist,
DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist,
vnc_nve_group_redist_bgpdirect_prefixlist_cmd,
- "redistribute bgp-direct (ipv4|ipv6) prefix-list NAME",
+ "redistribute bgp-direct <ipv4|ipv6> prefix-list NAME",
"Redistribute from other protocol\n"
"Redistribute from BGP directly\n"
"IPv4 routes\n"
@@ -1473,16 +1370,10 @@ DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist,
"Prefix-list for filtering redistributed routes\n"
"prefix list name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
afi_t afi;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
@@ -1497,7 +1388,7 @@ DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist,
return CMD_WARNING;
}
- if (!strcmp (argv[0], "ipv4"))
+ if (!strcmp (argv[2]->arg, "ipv4"))
{
afi = AFI_IP;
}
@@ -1510,9 +1401,9 @@ DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist,
if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi])
free (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]);
- rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = strdup (argv[1]);
+ rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = strdup (argv[4]->arg);
rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] =
- prefix_list_lookup (afi, argv[1]);
+ prefix_list_lookup (afi, argv[4]->arg);
vnc_redistribute_postchange (bgp);
@@ -1528,15 +1419,9 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap,
"Disable redistribute filter\n"
"Route-map for filtering redistributed routes\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
@@ -1570,15 +1455,9 @@ DEFUN (vnc_nve_group_redist_bgpdirect_routemap,
"Redistribute from BGP directly\n"
"Route-map for filtering exported routes\n" "route map name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
@@ -1597,9 +1476,9 @@ DEFUN (vnc_nve_group_redist_bgpdirect_routemap,
if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT])
free (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
- rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = strdup (argv[0]);
+ rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = strdup (argv[3]->arg);
rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] =
- route_map_lookup_by_name (argv[0]);
+ route_map_lookup_by_name (argv[3]->arg);
vnc_redistribute_postchange (bgp);
@@ -1614,7 +1493,7 @@ DEFUN (vnc_nve_group_redist_bgpdirect_routemap,
DEFUN (vnc_export_mode,
vnc_export_mode_cmd,
- "vnc export (bgp|zebra) mode (group-nve|ce|none|registering-nve)",
+ "vnc export <bgp|zebra> mode <group-nve|ce|none|registering-nve>",
VNC_CONFIG_STR
"Export to other protocols\n"
"Export to BGP\n"
@@ -1624,26 +1503,20 @@ DEFUN (vnc_export_mode,
"Export routes with NVE connected router next-hops\n"
"Disable export\n" "Export routes with registering NVE as next-hop\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
uint32_t oldmode = 0;
uint32_t newmode = 0;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "VNC not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (*argv[0] == 'b')
+ if (argv[2]->arg[0] == 'b')
{
oldmode = bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS;
- switch (*argv[1])
+ switch (argv[4]->arg[0])
{
case 'g':
newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP;
@@ -1688,7 +1561,7 @@ DEFUN (vnc_export_mode,
oldmode = bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS;
bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS;
- switch (*argv[1])
+ switch (argv[4]->arg[0])
{
case 'g':
if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH)
@@ -1745,7 +1618,7 @@ rfgn_free (struct rfapi_rfg_name *rfgn)
DEFUN (vnc_export_nvegroup,
vnc_export_nvegroup_cmd,
- "vnc export (bgp|zebra) group-nve group NAME",
+ "vnc export <bgp|zebra> group-nve group NAME",
VNC_CONFIG_STR
"Export to other protocols\n"
"Export to BGP\n"
@@ -1753,24 +1626,18 @@ DEFUN (vnc_export_nvegroup,
"NVE group, used in 'group-nve' export mode\n"
"NVE group\n" "Group name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct rfapi_nve_group_cfg *rfg_new;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- rfg_new = rfapi_group_lookup_byname (bgp, argv[1]);
+ rfg_new = bgp_rfapi_cfg_match_byname (bgp, argv[5]->arg, RFAPI_GROUP_CFG_NVE);
- if (*argv[0] == 'b')
+ if (argv[2]->arg[0] == 'b')
{
struct listnode *node;
@@ -1785,7 +1652,7 @@ DEFUN (vnc_export_nvegroup,
node, rfgn))
{
- if (!strcmp (rfgn->name, argv[1]))
+ if (!strcmp (rfgn->name, argv[5]->arg))
{
/* already in the list: we're done */
return CMD_SUCCESS;
@@ -1793,7 +1660,7 @@ DEFUN (vnc_export_nvegroup,
}
rfgn = rfgn_new ();
- rfgn->name = strdup (argv[1]);
+ rfgn->name = strdup (argv[5]->arg);
rfgn->rfg = rfg_new; /* OK if not set yet */
listnode_add (bgp->rfapi_cfg->rfg_export_direct_bgp_l, rfgn);
@@ -1823,7 +1690,7 @@ DEFUN (vnc_export_nvegroup,
node, rfgn))
{
- if (!strcmp (rfgn->name, argv[1]))
+ if (!strcmp (rfgn->name, argv[5]->arg))
{
/* already in the list: we're done */
return CMD_SUCCESS;
@@ -1831,7 +1698,7 @@ DEFUN (vnc_export_nvegroup,
}
rfgn = rfgn_new ();
- rfgn->name = strdup (argv[1]);
+ rfgn->name = strdup (argv[5]->arg);
rfgn->rfg = rfg_new; /* OK if not set yet */
listnode_add (bgp->rfapi_cfg->rfg_export_zebra_l, rfgn);
@@ -1852,7 +1719,7 @@ DEFUN (vnc_export_nvegroup,
*/
DEFUN (vnc_no_export_nvegroup,
vnc_no_export_nvegroup_cmd,
- "vnc export (bgp|zebra) group-nve no group NAME",
+ "vnc export <bgp|zebra> group-nve no group NAME",
VNC_CONFIG_STR
"Export to other protocols\n"
"Export to BGP\n"
@@ -1860,29 +1727,23 @@ DEFUN (vnc_no_export_nvegroup,
"NVE group, used in 'group-nve' export mode\n"
"Disable export of VNC routes\n" "NVE group\n" "Group name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct listnode *node, *nnode;
struct rfapi_rfg_name *rfgn;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (*argv[0] == 'b')
+ if (argv[2]->arg[0] == 'b')
{
for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l,
node, nnode, rfgn))
{
- if (rfgn->name && !strcmp (rfgn->name, argv[1]))
+ if (rfgn->name && !strcmp (rfgn->name, argv[6]->arg))
{
vnc_zlog_debug_verbose ("%s: matched \"%s\"", __func__, rfgn->name);
if (rfgn->rfg)
@@ -1902,7 +1763,7 @@ DEFUN (vnc_no_export_nvegroup,
{
vnc_zlog_debug_verbose ("does rfg \"%s\" match?", rfgn->name);
- if (rfgn->name && !strcmp (rfgn->name, argv[1]))
+ if (rfgn->name && !strcmp (rfgn->name, argv[6]->arg))
{
if (rfgn->rfg)
vnc_zebra_del_group (bgp, rfgn->rfg);
@@ -1918,7 +1779,7 @@ DEFUN (vnc_no_export_nvegroup,
DEFUN (vnc_nve_group_export_no_prefixlist,
vnc_nve_group_export_no_prefixlist_cmd,
- "no export (bgp|zebra) (ipv4|ipv6) prefix-list [NAME]",
+ "no export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
NO_STR
"Export to other protocols\n"
"Export to BGP\n"
@@ -1927,16 +1788,10 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
"IPv6 routes\n"
"Prefix-list for filtering exported routes\n" "prefix list name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
afi_t afi;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
@@ -1951,7 +1806,7 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
return CMD_WARNING;
}
- if (!strcmp (argv[1], "ipv4"))
+ if (!strcmp (argv[3]->arg, "ipv4"))
{
afi = AFI_IP;
}
@@ -1960,10 +1815,11 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
afi = AFI_IP6;
}
- if (*argv[0] == 'b')
+ if (argv[2]->arg[0] == 'b')
{
- if (((argc >= 3) && !strcmp (argv[2], rfg->plist_export_bgp_name[afi]))
- || (argc < 3))
+ if (((argc > 5)
+ && !strcmp (argv[5]->arg, rfg->plist_export_bgp_name[afi]))
+ || (argc <= 5))
{
if (rfg->plist_export_bgp_name[afi])
@@ -1976,9 +1832,9 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
}
else
{
- if (((argc >= 3)
- && !strcmp (argv[2], rfg->plist_export_zebra_name[afi]))
- || (argc < 3))
+ if (((argc > 5)
+ && !strcmp (argv[5]->arg, rfg->plist_export_zebra_name[afi]))
+ || (argc <= 5))
{
if (rfg->plist_export_zebra_name[afi])
free (rfg->plist_export_zebra_name[afi]);
@@ -1993,7 +1849,7 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
DEFUN (vnc_nve_group_export_prefixlist,
vnc_nve_group_export_prefixlist_cmd,
- "export (bgp|zebra) (ipv4|ipv6) prefix-list NAME",
+ "export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
"Export to other protocols\n"
"Export to BGP\n"
"Export to Zebra (experimental)\n"
@@ -2001,16 +1857,10 @@ DEFUN (vnc_nve_group_export_prefixlist,
"IPv6 routes\n"
"Prefix-list for filtering exported routes\n" "prefix list name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
afi_t afi;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
@@ -2025,7 +1875,7 @@ DEFUN (vnc_nve_group_export_prefixlist,
return CMD_WARNING;
}
- if (!strcmp (argv[1], "ipv4"))
+ if (!strcmp (argv[2]->arg, "ipv4"))
{
afi = AFI_IP;
}
@@ -2034,12 +1884,12 @@ DEFUN (vnc_nve_group_export_prefixlist,
afi = AFI_IP6;
}
- if (*argv[0] == 'b')
+ if (argv[1]->arg[0] == 'b')
{
if (rfg->plist_export_bgp_name[afi])
free (rfg->plist_export_bgp_name[afi]);
- rfg->plist_export_bgp_name[afi] = strdup (argv[2]);
- rfg->plist_export_bgp[afi] = prefix_list_lookup (afi, argv[2]);
+ rfg->plist_export_bgp_name[afi] = strdup (argv[4]->arg);
+ rfg->plist_export_bgp[afi] = prefix_list_lookup (afi, argv[4]->arg);
vnc_direct_bgp_reexport_group_afi (bgp, rfg, afi);
@@ -2048,8 +1898,8 @@ DEFUN (vnc_nve_group_export_prefixlist,
{
if (rfg->plist_export_zebra_name[afi])
free (rfg->plist_export_zebra_name[afi]);
- rfg->plist_export_zebra_name[afi] = strdup (argv[2]);
- rfg->plist_export_zebra[afi] = prefix_list_lookup (afi, argv[2]);
+ rfg->plist_export_zebra_name[afi] = strdup (argv[4]->arg);
+ rfg->plist_export_zebra[afi] = prefix_list_lookup (afi, argv[4]->arg);
vnc_zebra_reexport_group_afi (bgp, rfg, afi);
}
@@ -2058,22 +1908,16 @@ DEFUN (vnc_nve_group_export_prefixlist,
DEFUN (vnc_nve_group_export_no_routemap,
vnc_nve_group_export_no_routemap_cmd,
- "no export (bgp|zebra) route-map [NAME]",
+ "no export <bgp|zebra> route-map [NAME]",
NO_STR
"Export to other protocols\n"
"Export to BGP\n"
"Export to Zebra (experimental)\n"
"Route-map for filtering exported routes\n" "route map name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
@@ -2088,10 +1932,11 @@ DEFUN (vnc_nve_group_export_no_routemap,
return CMD_WARNING;
}
- if (*argv[0] == 'b')
+ if (argv[2]->arg[0] == 'b')
{
- if (((argc >= 2) && !strcmp (argv[1], rfg->routemap_export_bgp_name)) ||
- (argc < 2))
+ if (((argc > 4)
+ && !strcmp (argv[4]->arg, rfg->routemap_export_bgp_name))
+ || (argc <= 4))
{
if (rfg->routemap_export_bgp_name)
@@ -2105,8 +1950,9 @@ DEFUN (vnc_nve_group_export_no_routemap,
}
else
{
- if (((argc >= 2) && !strcmp (argv[1], rfg->routemap_export_zebra_name))
- || (argc < 2))
+ if (((argc > 4)
+ && !strcmp (argv[4]->arg, rfg->routemap_export_zebra_name))
+ || (argc <= 4))
{
if (rfg->routemap_export_zebra_name)
free (rfg->routemap_export_zebra_name);
@@ -2122,21 +1968,15 @@ DEFUN (vnc_nve_group_export_no_routemap,
DEFUN (vnc_nve_group_export_routemap,
vnc_nve_group_export_routemap_cmd,
- "export (bgp|zebra) route-map NAME",
+ "export <bgp|zebra> route-map NAME",
"Export to other protocols\n"
"Export to BGP\n"
"Export to Zebra (experimental)\n"
"Route-map for filtering exported routes\n" "route map name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!bgp->rfapi_cfg)
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
@@ -2151,12 +1991,12 @@ DEFUN (vnc_nve_group_export_routemap,
return CMD_WARNING;
}
- if (*argv[0] == 'b')
+ if (argv[1]->arg[0] == 'b')
{
if (rfg->routemap_export_bgp_name)
free (rfg->routemap_export_bgp_name);
- rfg->routemap_export_bgp_name = strdup (argv[1]);
- rfg->routemap_export_bgp = route_map_lookup_by_name (argv[1]);
+ rfg->routemap_export_bgp_name = strdup (argv[3]->arg);
+ rfg->routemap_export_bgp = route_map_lookup_by_name (argv[3]->arg);
vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP);
vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP6);
}
@@ -2164,8 +2004,8 @@ DEFUN (vnc_nve_group_export_routemap,
{
if (rfg->routemap_export_zebra_name)
free (rfg->routemap_export_zebra_name);
- rfg->routemap_export_zebra_name = strdup (argv[1]);
- rfg->routemap_export_zebra = route_map_lookup_by_name (argv[1]);
+ rfg->routemap_export_zebra_name = strdup (argv[3]->arg);
+ rfg->routemap_export_zebra = route_map_lookup_by_name (argv[3]->arg);
vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP);
vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP6);
}
@@ -2174,7 +2014,7 @@ DEFUN (vnc_nve_group_export_routemap,
DEFUN (vnc_nve_export_no_prefixlist,
vnc_nve_export_no_prefixlist_cmd,
- "no vnc export (bgp|zebra) (ipv4|ipv6) prefix-list [NAME]",
+ "no vnc export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
NO_STR
VNC_CONFIG_STR
"Export to other protocols\n"
@@ -2184,23 +2024,17 @@ DEFUN (vnc_nve_export_no_prefixlist,
"IPv6 prefixes\n"
"Prefix-list for filtering exported routes\n" "Prefix list name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct rfapi_cfg *hc;
afi_t afi;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!(hc = bgp->rfapi_cfg))
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!strcmp (argv[1], "ipv4"))
+ if (!strcmp (argv[4]->arg, "ipv4"))
{
afi = AFI_IP;
}
@@ -2209,10 +2043,11 @@ DEFUN (vnc_nve_export_no_prefixlist,
afi = AFI_IP6;
}
- if (*argv[0] == 'b')
+ if (argv[3]->arg[0] == 'b')
{
- if (((argc >= 3) && !strcmp (argv[2], hc->plist_export_bgp_name[afi]))
- || (argc < 3))
+ if (((argc > 6)
+ && !strcmp (argv[6]->arg, hc->plist_export_bgp_name[afi]))
+ || (argc <= 6))
{
if (hc->plist_export_bgp_name[afi])
@@ -2224,8 +2059,9 @@ DEFUN (vnc_nve_export_no_prefixlist,
}
else
{
- if (((argc >= 3) && !strcmp (argv[2], hc->plist_export_zebra_name[afi]))
- || (argc < 3))
+ if (((argc > 6)
+ && !strcmp (argv[6]->arg, hc->plist_export_zebra_name[afi]))
+ || (argc <= 6))
{
if (hc->plist_export_zebra_name[afi])
@@ -2240,7 +2076,7 @@ DEFUN (vnc_nve_export_no_prefixlist,
DEFUN (vnc_nve_export_prefixlist,
vnc_nve_export_prefixlist_cmd,
- "vnc export (bgp|zebra) (ipv4|ipv6) prefix-list NAME",
+ "vnc export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
VNC_CONFIG_STR
"Export to other protocols\n"
"Export to BGP\n"
@@ -2250,23 +2086,17 @@ DEFUN (vnc_nve_export_prefixlist,
"IPv6 prefixes\n"
"Prefix-list for filtering exported routes\n" "Prefix list name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct rfapi_cfg *hc;
afi_t afi;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!(hc = bgp->rfapi_cfg))
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (!strcmp (argv[1], "ipv4"))
+ if (!strcmp (argv[3]->arg, "ipv4"))
{
afi = AFI_IP;
}
@@ -2275,20 +2105,20 @@ DEFUN (vnc_nve_export_prefixlist,
afi = AFI_IP6;
}
- if (*argv[0] == 'b')
+ if (argv[2]->arg[0] == 'b')
{
if (hc->plist_export_bgp_name[afi])
free (hc->plist_export_bgp_name[afi]);
- hc->plist_export_bgp_name[afi] = strdup (argv[2]);
- hc->plist_export_bgp[afi] = prefix_list_lookup (afi, argv[2]);
+ hc->plist_export_bgp_name[afi] = strdup (argv[5]->arg);
+ hc->plist_export_bgp[afi] = prefix_list_lookup (afi, argv[5]->arg);
vnc_direct_bgp_reexport (bgp, afi);
}
else
{
if (hc->plist_export_zebra_name[afi])
free (hc->plist_export_zebra_name[afi]);
- hc->plist_export_zebra_name[afi] = strdup (argv[2]);
- hc->plist_export_zebra[afi] = prefix_list_lookup (afi, argv[2]);
+ hc->plist_export_zebra_name[afi] = strdup (argv[5]->arg);
+ hc->plist_export_zebra[afi] = prefix_list_lookup (afi, argv[5]->arg);
/* TBD vnc_zebra_rh_reexport(bgp, afi); */
}
return CMD_SUCCESS;
@@ -2296,7 +2126,7 @@ DEFUN (vnc_nve_export_prefixlist,
DEFUN (vnc_nve_export_no_routemap,
vnc_nve_export_no_routemap_cmd,
- "no vnc export (bgp|zebra) route-map [NAME]",
+ "no vnc export <bgp|zebra> route-map [NAME]",
NO_STR
VNC_CONFIG_STR
"Export to other protocols\n"
@@ -2304,25 +2134,20 @@ DEFUN (vnc_nve_export_no_routemap,
"Export to Zebra (experimental)\n"
"Route-map for filtering exported routes\n" "Route map name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct rfapi_cfg *hc;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!(hc = bgp->rfapi_cfg))
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (*argv[0] == 'b')
+ if (argv[3]->arg[0] == 'b')
{
- if (((argc >= 2) && !strcmp (argv[1], hc->routemap_export_bgp_name)) ||
- (argc < 2))
+ if (((argc > 5)
+ && !strcmp (argv[5]->arg, hc->routemap_export_bgp_name))
+ || (argc <= 5))
{
if (hc->routemap_export_bgp_name)
@@ -2335,8 +2160,9 @@ DEFUN (vnc_nve_export_no_routemap,
}
else
{
- if (((argc >= 2) && !strcmp (argv[1], hc->routemap_export_zebra_name))
- || (argc < 2))
+ if (((argc > 5)
+ && !strcmp (argv[5]->arg, hc->routemap_export_zebra_name))
+ || (argc <= 5))
{
if (hc->routemap_export_zebra_name)
@@ -2352,7 +2178,7 @@ DEFUN (vnc_nve_export_no_routemap,
DEFUN (vnc_nve_export_routemap,
vnc_nve_export_routemap_cmd,
- "vnc export (bgp|zebra) route-map NAME",
+ "vnc export <bgp|zebra> route-map NAME",
VNC_CONFIG_STR
"Export to other protocols\n"
"Export to BGP\n"
@@ -2360,27 +2186,21 @@ DEFUN (vnc_nve_export_routemap,
"Filters, used in 'registering-nve' export mode\n"
"Route-map for filtering exported routes\n" "Route map name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct rfapi_cfg *hc;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
if (!(hc = bgp->rfapi_cfg))
{
vty_out (vty, "rfapi not configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (*argv[0] == 'b')
+ if (argv[2]->arg[0] == 'b')
{
if (hc->routemap_export_bgp_name)
free (hc->routemap_export_bgp_name);
- hc->routemap_export_bgp_name = strdup (argv[1]);
- hc->routemap_export_bgp = route_map_lookup_by_name (argv[1]);
+ hc->routemap_export_bgp_name = strdup (argv[4]->arg);
+ hc->routemap_export_bgp = route_map_lookup_by_name (argv[4]->arg);
vnc_direct_bgp_reexport (bgp, AFI_IP);
vnc_direct_bgp_reexport (bgp, AFI_IP6);
}
@@ -2388,8 +2208,8 @@ DEFUN (vnc_nve_export_routemap,
{
if (hc->routemap_export_zebra_name)
free (hc->routemap_export_zebra_name);
- hc->routemap_export_zebra_name = strdup (argv[1]);
- hc->routemap_export_zebra = route_map_lookup_by_name (argv[1]);
+ hc->routemap_export_zebra_name = strdup (argv[4]->arg);
+ hc->routemap_export_zebra = route_map_lookup_by_name (argv[4]->arg);
/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
}
@@ -2604,32 +2424,23 @@ DEFUN (vnc_nve_group,
"vnc nve-group NAME",
VNC_CONFIG_STR "Configure a NVE group\n" "Group name\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct rfapi_nve_group_cfg *rfg;
- struct bgp *bgp = vty->index;
struct listnode *node, *nnode;
struct rfapi_rfg_name *rfgn;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
/* Search for name */
- rfg = rfapi_group_lookup_byname (bgp, argv[0]);
+ rfg = bgp_rfapi_cfg_match_byname (bgp, argv[2]->arg, RFAPI_GROUP_CFG_NVE);
if (!rfg)
{
- rfg = rfapi_group_new ();
+ rfg = rfapi_group_new (bgp, RFAPI_GROUP_CFG_NVE, argv[2]->arg);
if (!rfg)
{
/* Error out of memory */
vty_out (vty, "Can't allocate memory for NVE group%s", VTY_NEWLINE);
return CMD_WARNING;
}
- rfg->name = strdup (argv[0]);
- /* add to tail of list */
- listnode_add (bgp->rfapi_cfg->nve_groups_sequential, rfg);
/* Copy defaults from struct rfapi_cfg */
rfg->rd = bgp->rfapi_cfg->default_rd;
@@ -2652,7 +2463,7 @@ DEFUN (vnc_nve_group,
rfg->rt_import_list =
ecommunity_dup (bgp->rfapi_cfg->default_rt_import_list);
rfg->rfapi_import_table =
- rfapiImportTableRefAdd (bgp, rfg->rt_import_list);
+ rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg);
}
/*
@@ -2828,7 +2639,8 @@ static int
bgp_rfapi_delete_named_nve_group (
struct vty *vty, /* NULL = no output */
struct bgp *bgp,
- const char *rfg_name) /* NULL = any */
+ const char *rfg_name, /* NULL = any */
+ rfapi_group_cfg_type_t type) /* _MAX = any */
{
struct rfapi_nve_group_cfg *rfg = NULL;
struct listnode *node, *nnode;
@@ -2837,7 +2649,7 @@ bgp_rfapi_delete_named_nve_group (
/* Search for name */
if (rfg_name)
{
- rfg = rfapi_group_lookup_byname (bgp, rfg_name);
+ rfg = bgp_rfapi_cfg_match_byname (bgp, rfg_name, type);
if (!rfg)
{
if (vty)
@@ -2864,7 +2676,8 @@ bgp_rfapi_delete_named_nve_group (
for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l,
node, rfgn))
{
- if (rfg_name == NULL || !strcmp (rfgn->name, rfg_name))
+ if (rfg_name == NULL ||
+ (type == RFAPI_GROUP_CFG_NVE && !strcmp (rfgn->name, rfg_name)))
{
rfgn->rfg = NULL;
/* remove exported routes from this group */
@@ -2879,7 +2692,8 @@ bgp_rfapi_delete_named_nve_group (
for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn))
{
- if (rfg_name == NULL || !strcmp (rfgn->name, rfg_name))
+ if (rfg_name == NULL ||
+ (type == RFAPI_GROUP_CFG_NVE && !strcmp (rfgn->name, rfg_name)))
{
rfgn->rfg = NULL;
/* remove exported routes from this group */
@@ -2904,25 +2718,21 @@ DEFUN (vnc_no_nve_group,
"Configure a NVE group\n"
"Group name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_rfapi_delete_named_nve_group (vty, bgp, argv[0]);
+ return bgp_rfapi_delete_named_nve_group (vty, bgp, argv[3]->arg, RFAPI_GROUP_CFG_NVE);
}
DEFUN (vnc_nve_group_prefix,
vnc_nve_group_prefix_cmd,
- "prefix (vn|un) (A.B.C.D/M|X:X::X:X/M)",
+ "prefix <vn|un> <A.B.C.D/M|X:X::X:X/M>",
"Specify prefixes matching NVE VN or UN interfaces\n"
"VN prefix\n"
"UN prefix\n"
"IPv4 prefix\n"
"IPv6 prefix\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
struct prefix p;
int afi;
@@ -2930,14 +2740,6 @@ DEFUN (vnc_nve_group_prefix,
struct route_node *rn;
int is_un_prefix = 0;
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
/* make sure it's still in list */
if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
{
@@ -2946,9 +2748,9 @@ DEFUN (vnc_nve_group_prefix,
return CMD_WARNING;
}
- if (!str2prefix (argv[1], &p))
+ if (!str2prefix (argv[2]->arg, &p))
{
- vty_out (vty, "Malformed prefix \"%s\"%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "Malformed prefix \"%s\"%s", argv[2]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -2959,7 +2761,7 @@ DEFUN (vnc_nve_group_prefix,
return CMD_WARNING;
}
- if (*(argv[0]) == 'u')
+ if (argv[1]->arg[0] == 'u')
{
rt = &(bgp->rfapi_cfg->nve_groups_un[afi]);
is_un_prefix = 1;
@@ -2983,7 +2785,7 @@ DEFUN (vnc_nve_group_prefix,
*/
vty_out (vty, "nve group \"%s\" already has \"%s\" prefix %s%s",
((struct rfapi_nve_group_cfg *) (rn->info))->name,
- argv[0], argv[1], VTY_NEWLINE);
+ argv[1]->arg, argv[2]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
else
@@ -3044,25 +2846,19 @@ DEFUN (vnc_nve_group_prefix,
DEFUN (vnc_nve_group_rt_import,
vnc_nve_group_rt_import_cmd,
- "rt import .RTLIST",
+ "rt import RTLIST...",
"Specify route targets\n"
"Import filter\n"
"Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- struct bgp *bgp = vty->index;
int rc;
struct listnode *node;
struct rfapi_rfg_name *rfgn;
int is_export_bgp = 0;
int is_export_zebra = 0;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
/* make sure it's still in list */
if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
{
@@ -3071,7 +2867,7 @@ DEFUN (vnc_nve_group_rt_import,
return CMD_WARNING;
}
- rc = set_ecom_list (vty, argc, argv, &rfg->rt_import_list);
+ rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_import_list);
if (rc != CMD_SUCCESS)
return rc;
@@ -3107,7 +2903,7 @@ DEFUN (vnc_nve_group_rt_import,
*/
if (rfg->rfapi_import_table)
rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table);
- rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list);
+ rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg);
if (is_export_bgp)
vnc_direct_bgp_add_group (bgp, rfg);
@@ -3120,21 +2916,15 @@ DEFUN (vnc_nve_group_rt_import,
DEFUN (vnc_nve_group_rt_export,
vnc_nve_group_rt_export_cmd,
- "rt export .RTLIST",
+ "rt export RTLIST...",
"Specify route targets\n"
"Export filter\n"
"Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- struct bgp *bgp = vty->index;
int rc;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
/* make sure it's still in list */
if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
{
@@ -3148,7 +2938,7 @@ DEFUN (vnc_nve_group_rt_export,
vnc_redistribute_prechange (bgp);
}
- rc = set_ecom_list (vty, argc, argv, &rfg->rt_export_list);
+ rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_export_list);
if (bgp->rfapi_cfg->rfg_redist == rfg)
{
@@ -3160,25 +2950,19 @@ DEFUN (vnc_nve_group_rt_export,
DEFUN (vnc_nve_group_rt_both,
vnc_nve_group_rt_both_cmd,
- "rt both .RTLIST",
+ "rt both RTLIST...",
"Specify route targets\n"
"Export+import filters\n"
"Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- struct bgp *bgp = vty->index;
int rc;
int is_export_bgp = 0;
int is_export_zebra = 0;
struct listnode *node;
struct rfapi_rfg_name *rfgn;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
/* make sure it's still in list */
if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
{
@@ -3187,7 +2971,7 @@ DEFUN (vnc_nve_group_rt_both,
return CMD_WARNING;
}
- rc = set_ecom_list (vty, argc, argv, &rfg->rt_import_list);
+ rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_import_list);
if (rc != CMD_SUCCESS)
return rc;
@@ -3226,7 +3010,7 @@ DEFUN (vnc_nve_group_rt_both,
*/
if (rfg->rfapi_import_table)
rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table);
- rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list);
+ rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg);
if (is_export_bgp)
vnc_direct_bgp_add_group (bgp, rfg);
@@ -3239,7 +3023,7 @@ DEFUN (vnc_nve_group_rt_both,
vnc_redistribute_prechange (bgp);
}
- rc = set_ecom_list (vty, argc, argv, &rfg->rt_export_list);
+ rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_export_list);
if (bgp->rfapi_cfg->rfg_redist == rfg)
{
@@ -3252,19 +3036,13 @@ DEFUN (vnc_nve_group_rt_both,
DEFUN (vnc_nve_group_l2rd,
vnc_nve_group_l2rd_cmd,
- "l2rd (ID|auto:vn)",
+ "l2rd <(1-255)|auto-vn>",
"Specify default Local Nve ID value to use in RD for L2 routes\n"
"Fixed value 1-255\n"
"use the low-order octet of the NVE's VN address\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
/* make sure it's still in list */
if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
@@ -3274,19 +3052,19 @@ DEFUN (vnc_nve_group_l2rd,
return CMD_WARNING;
}
- if (!strcmp (argv[0], "auto:vn"))
+ if (!strcmp (argv[1]->arg, "auto:vn"))
{
rfg->l2rd = 0;
}
else
{
char *end = NULL;
- unsigned long value_l = strtoul (argv[0], &end, 10);
+ unsigned long value_l = strtoul (argv[1]->arg, &end, 10);
uint8_t value = value_l & 0xff;
- if (!*(argv[0]) || *end)
+ if (!argv[1]->arg[0] || *end)
{
- vty_out (vty, "%% Malformed l2 nve ID \"%s\"%s", argv[0],
+ vty_out (vty, "%% Malformed l2 nve ID \"%s\"%s", argv[1]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3311,14 +3089,8 @@ DEFUN (vnc_nve_group_no_l2rd,
NO_STR
"Specify default Local Nve ID value to use in RD for L2 routes\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
/* make sure it's still in list */
if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
@@ -3340,16 +3112,10 @@ DEFUN (vnc_nve_group_rd,
"Specify route distinguisher\n"
"Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
struct prefix_rd prd;
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- struct bgp *bgp = vty->index;
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
/* make sure it's still in list */
if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
@@ -3359,17 +3125,17 @@ DEFUN (vnc_nve_group_rd,
return CMD_WARNING;
}
- if (!strncmp (argv[0], "auto:vn:", 8))
+ if (!strncmp (argv[1]->arg, "auto:vn:", 8))
{
/*
* use AF_UNIX to designate automatically-assigned RD
* auto:vn:nn where nn is a 2-octet quantity
*/
char *end = NULL;
- uint32_t value32 = strtoul (argv[0] + 8, &end, 10);
+ uint32_t value32 = strtoul (argv[1]->arg + 8, &end, 10);
uint16_t value = value32 & 0xffff;
- if (!*(argv[0] + 5) || *end)
+ if (!argv[1]->arg[8] || *end)
{
vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -3393,7 +3159,7 @@ DEFUN (vnc_nve_group_rd,
else
{
- ret = str2prefix_rd (argv[0], &prd);
+ ret = str2prefix_rd (argv[1]->arg, &prd);
if (!ret)
{
vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
@@ -3417,22 +3183,16 @@ DEFUN (vnc_nve_group_rd,
DEFUN (vnc_nve_group_responselifetime,
vnc_nve_group_responselifetime_cmd,
- "response-lifetime (LIFETIME|infinite)",
+ "response-lifetime <LIFETIME|infinite>",
"Specify response lifetime\n"
"Response lifetime in seconds\n" "Infinite response lifetime\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
unsigned int rspint;
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
- struct bgp *bgp = vty->index;
struct rfapi_descriptor *rfd;
struct listnode *hdnode;
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
/* make sure it's still in list */
if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
{
@@ -3441,13 +3201,13 @@ DEFUN (vnc_nve_group_responselifetime,
return CMD_WARNING;
}
- if (!strcmp (argv[0], "infinite"))
+ if (!strcmp (argv[1]->arg, "infinite"))
{
rspint = RFAPI_INFINITE_LIFETIME;
}
else
{
- VTY_GET_INTEGER ("Response Lifetime", rspint, argv[0]);
+ VTY_GET_INTEGER ("Response Lifetime", rspint, argv[1]->arg);
}
rfg->response_lifetime = rspint;
@@ -3491,6 +3251,494 @@ static struct cmd_node bgp_vnc_nve_group_node = {
};
/*-------------------------------------------------------------------------
+ * VNC nve-group
+ * Note there are two types of NVEs, one for VPNs one for RFP NVEs
+ *-----------------------------------------------------------------------*/
+
+DEFUN (vnc_vrf_policy,
+ vnc_vrf_policy_cmd,
+ "vrf-policy NAME",
+ "Configure a VRF policy group\n"
+ "VRF name\n")
+{
+ struct rfapi_nve_group_cfg *rfg;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ if (!bgp)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* Search for name */
+ rfg = bgp_rfapi_cfg_match_byname (bgp, argv[1]->arg, RFAPI_GROUP_CFG_VRF);
+
+ if (!rfg)
+ {
+ rfg = rfapi_group_new (bgp, RFAPI_GROUP_CFG_VRF, argv[1]->arg);
+ if (!rfg)
+ {
+ /* Error out of memory */
+ vty_out (vty, "Can't allocate memory for NVE group%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ /*
+ * XXX subsequent calls will need to make sure this item is still
+ * in the linked list and has the same name
+ */
+ VTY_PUSH_CONTEXT_SUB (BGP_VRF_POLICY_NODE, rfg);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (vnc_no_vrf_policy,
+ vnc_no_vrf_policy_cmd,
+ "no vrf-policy NAME",
+ NO_STR
+ "Remove a VRF policy group\n"
+ "VRF name\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ if (!bgp)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_rfapi_delete_named_nve_group (vty, bgp, argv[2]->arg, RFAPI_GROUP_CFG_VRF);
+}
+
+DEFUN (vnc_vrf_policy_label,
+ vnc_vrf_policy_label_cmd,
+ "label (0-1048575)",
+ "Default label value for VRF\n"
+ "Label Value <0-1048575>\n")
+{
+ VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
+
+ uint32_t label;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ if (!bgp)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* make sure it's still in list */
+ if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
+ {
+ /* Not in list anymore */
+ vty_out (vty, "Current NVE group no longer exists%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ VTY_GET_INTEGER_RANGE ("Label value", label, argv[1]->arg, 0, MPLS_LABEL_MAX);
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_prechange (bgp);
+ }
+
+ rfg->label = label;
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_postchange (bgp);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN (vnc_vrf_policy_no_label,
+ vnc_vrf_policy_no_label_cmd,
+ "no label",
+ NO_STR
+ "Remove VRF default label\n")
+{
+ VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ /* make sure it's still in list */
+ if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
+ {
+ /* Not in list anymore */
+ vty_out (vty, "Current VRF group no longer exists%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_prechange (bgp);
+ }
+
+ rfg->label = MPLS_LABEL_ILLEGAL;
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_postchange (bgp);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN (vnc_vrf_policy_nexthop,
+ vnc_vrf_policy_nexthop_cmd,
+ "nexthop <A.B.C.D|X:X::X:X|self>",
+ "Specify next hop to use for VRF advertised prefixes\n"
+ "IPv4 prefix\n"
+ "IPv6 prefix\n"
+ "Use configured router-id (default)")
+{
+ VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
+ struct prefix p;
+
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ /* make sure it's still in list */
+ if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
+ {
+ /* Not in list anymore */
+ vty_out (vty, "Current VRF no longer exists%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_prechange (bgp);
+ }
+
+ if (!str2prefix (argv[1]->arg, &p) && p.family)
+ {
+ //vty_out (vty, "Nexthop set to self%s", VTY_NEWLINE);
+ SET_FLAG (rfg->flags, RFAPI_RFG_VPN_NH_SELF);
+ memset(&rfg->vn_prefix, 0, sizeof(struct prefix));
+ }
+ else
+ {
+ UNSET_FLAG (rfg->flags, RFAPI_RFG_VPN_NH_SELF);
+ rfg->vn_prefix = p;
+ rfg->un_prefix = p;
+ }
+
+ /* TBD handle router-id/ nexthop changes when have advertised prefixes */
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_postchange (bgp);
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* The RT code should be refactored/simplified with above... */
+DEFUN (vnc_vrf_policy_rt_import,
+ vnc_vrf_policy_rt_import_cmd,
+ "rt import RTLIST...",
+ "Specify route targets\n"
+ "Import filter\n"
+ "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
+{
+ VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int rc;
+ struct listnode *node;
+ struct rfapi_rfg_name *rfgn;
+ int is_export_bgp = 0;
+ int is_export_zebra = 0;
+
+ if (!bgp)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* make sure it's still in list */
+ if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
+ {
+ /* Not in list anymore */
+ vty_out (vty, "Current NVE group no longer exists%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_import_list);
+ if (rc != CMD_SUCCESS)
+ return rc;
+
+ for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l,
+ node, rfgn))
+ {
+
+ if (rfgn->rfg == rfg)
+ {
+ is_export_bgp = 1;
+ break;
+ }
+ }
+
+ if (is_export_bgp)
+ vnc_direct_bgp_del_group (bgp, rfg);
+
+ for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn))
+ {
+
+ if (rfgn->rfg == rfg)
+ {
+ is_export_zebra = 1;
+ break;
+ }
+ }
+
+ if (is_export_zebra)
+ vnc_zebra_del_group (bgp, rfg);
+
+ /*
+ * stop referencing old import table, now reference new one
+ */
+ if (rfg->rfapi_import_table)
+ rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table);
+ rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg);
+
+ if (is_export_bgp)
+ vnc_direct_bgp_add_group (bgp, rfg);
+
+ if (is_export_zebra)
+ vnc_zebra_add_group (bgp, rfg);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (vnc_vrf_policy_rt_export,
+ vnc_vrf_policy_rt_export_cmd,
+ "rt export RTLIST...",
+ "Specify route targets\n"
+ "Export filter\n"
+ "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
+{
+ VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int rc;
+
+ if (!bgp)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* make sure it's still in list */
+ if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
+ {
+ /* Not in list anymore */
+ vty_out (vty, "Current NVE group no longer exists%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_prechange (bgp);
+ }
+
+ rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_export_list);
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_postchange (bgp);
+ }
+
+ return rc;
+}
+
+DEFUN (vnc_vrf_policy_rt_both,
+ vnc_vrf_policy_rt_both_cmd,
+ "rt both RTLIST...",
+ "Specify route targets\n"
+ "Export+import filters\n"
+ "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
+{
+ VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int rc;
+ int is_export_bgp = 0;
+ int is_export_zebra = 0;
+ struct listnode *node;
+ struct rfapi_rfg_name *rfgn;
+
+ if (!bgp)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* make sure it's still in list */
+ if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
+ {
+ /* Not in list anymore */
+ vty_out (vty, "Current NVE group no longer exists%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_import_list);
+ if (rc != CMD_SUCCESS)
+ return rc;
+
+ for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l,
+ node, rfgn))
+ {
+
+ if (rfgn->rfg == rfg)
+ {
+ is_export_bgp = 1;
+ break;
+ }
+ }
+
+ if (is_export_bgp)
+ vnc_direct_bgp_del_group (bgp, rfg);
+
+ for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn))
+ {
+
+ if (rfgn->rfg == rfg)
+ {
+ is_export_zebra = 1;
+ break;
+ }
+ }
+
+ if (is_export_zebra)
+ {
+ vnc_zlog_debug_verbose ("%s: is_export_zebra", __func__);
+ vnc_zebra_del_group (bgp, rfg);
+ }
+
+ /*
+ * stop referencing old import table, now reference new one
+ */
+ if (rfg->rfapi_import_table)
+ rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table);
+ rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg);
+
+ if (is_export_bgp)
+ vnc_direct_bgp_add_group (bgp, rfg);
+
+ if (is_export_zebra)
+ vnc_zebra_add_group (bgp, rfg);
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_prechange (bgp);
+ }
+
+ rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_export_list);
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_postchange (bgp);
+ }
+
+ return rc;
+
+}
+
+DEFUN (vnc_vrf_policy_rd,
+ vnc_vrf_policy_rd_cmd,
+ "rd ASN:nn_or_IP-address:nn",
+ "Specify default VRF route distinguisher\n"
+ "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:nh:<number> )\n")
+{
+ int ret;
+ struct prefix_rd prd;
+ VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ if (!bgp)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* make sure it's still in list */
+ if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg))
+ {
+ /* Not in list anymore */
+ vty_out (vty, "Current NVE group no longer exists%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (!strncmp (argv[1]->arg, "auto:nh:", 8))
+ {
+ /*
+ * use AF_UNIX to designate automatically-assigned RD
+ * auto:vn:nn where nn is a 2-octet quantity
+ */
+ char *end = NULL;
+ uint32_t value32 = strtoul (argv[1]->arg + 8, &end, 10);
+ uint16_t value = value32 & 0xffff;
+
+ if (!*(argv[1]->arg + 5) || *end)
+ {
+ vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (value32 > 0xffff)
+ {
+ vty_out (vty, "%% Malformed rd (must be less than %u%s",
+ 0x0ffff, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ memset (&prd, 0, sizeof (prd));
+ prd.family = AF_UNIX;
+ prd.prefixlen = 64;
+ prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
+ prd.val[1] = RD_TYPE_IP & 0x0ff;
+ prd.val[6] = (value >> 8) & 0x0ff;
+ prd.val[7] = value & 0x0ff;
+
+ }
+ else
+ {
+
+ ret = str2prefix_rd (argv[1]->arg, &prd);
+ if (!ret)
+ {
+ vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_prechange (bgp);
+ }
+
+ rfg->rd = prd;
+
+ if (bgp->rfapi_cfg->rfg_redist == rfg)
+ {
+ vnc_redistribute_postchange (bgp);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN (exit_vrf_policy,
+ exit_vrf_policy_cmd,
+ "exit-vrf-policy",
+ "Exit VRF policy configuration mode\n")
+{
+ if (vty->node == BGP_VRF_POLICY_NODE)
+ {
+ vty->node = BGP_NODE;
+ }
+ return CMD_SUCCESS;
+}
+
+static struct cmd_node bgp_vrf_policy_node = {
+ BGP_VRF_POLICY_NODE,
+ "%s(config-router-vrf-policy)# ",
+ 1
+};
+
+/*-------------------------------------------------------------------------
* vnc-l2-group
*-----------------------------------------------------------------------*/
@@ -3501,7 +3749,7 @@ DEFUN (vnc_l2_group,
VNC_CONFIG_STR "Configure a L2 group\n" "Group name\n")
{
struct rfapi_l2_group_cfg *rfg;
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp)
{
@@ -3510,7 +3758,7 @@ DEFUN (vnc_l2_group,
}
/* Search for name */
- rfg = rfapi_l2_group_lookup_byname (bgp, argv[0]);
+ rfg = rfapi_l2_group_lookup_byname (bgp, argv[1]->arg);
if (!rfg)
{
@@ -3521,7 +3769,7 @@ DEFUN (vnc_l2_group,
vty_out (vty, "Can't allocate memory for L2 group%s", VTY_NEWLINE);
return CMD_WARNING;
}
- rfg->name = strdup (argv[0]);
+ rfg->name = strdup (argv[1]->arg);
/* add to tail of list */
listnode_add (bgp->rfapi_cfg->l2_groups, rfg);
}
@@ -3593,14 +3841,14 @@ DEFUN (vnc_no_l2_group,
"Configure a L2 group\n"
"Group name\n")
{
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp)
{
vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return bgp_rfapi_delete_named_l2_group (vty, bgp, argv[0]);
+ return bgp_rfapi_delete_named_l2_group (vty, bgp, argv[3]->arg);
}
@@ -3611,7 +3859,7 @@ DEFUN (vnc_l2_group_lni,
"value\n")
{
VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
if (!bgp)
{
@@ -3627,19 +3875,19 @@ DEFUN (vnc_l2_group_lni,
return CMD_WARNING;
}
- VTY_GET_INTEGER ("logical-network-id", rfg->logical_net_id, argv[0]);
+ VTY_GET_INTEGER ("logical-network-id", rfg->logical_net_id, argv[1]->arg);
return CMD_SUCCESS;
}
DEFUN (vnc_l2_group_labels,
vnc_l2_group_labels_cmd,
- "labels .LABELLIST",
+ "labels LABELLIST...",
"Specify label values associated with group\n"
"Space separated list of label values <0-1048575>\n")
{
VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct list *ll;
if (!bgp)
@@ -3662,10 +3910,12 @@ DEFUN (vnc_l2_group_labels,
ll = list_new ();
rfg->labels = ll;
}
+ argc--;
+ argv++;
for (; argc; --argc, ++argv)
{
uint32_t label;
- VTY_GET_INTEGER_RANGE ("Label value", label, argv[0], 0, 1048575);
+ VTY_GET_INTEGER_RANGE ("Label value", label, argv[0]->arg, 0, MPLS_LABEL_MAX);
if (!listnode_lookup (ll, (void *) (uintptr_t) label))
listnode_add (ll, (void *) (uintptr_t) label);
}
@@ -3675,14 +3925,14 @@ DEFUN (vnc_l2_group_labels,
DEFUN (vnc_l2_group_no_labels,
vnc_l2_group_no_labels_cmd,
- "no labels .LABELLIST",
+ "no labels LABELLIST...",
NO_STR
"Remove label values associated with L2 group\n"
"Specify label values associated with L2 group\n"
"Space separated list of label values <0-1048575>\n")
{
VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
struct list *ll;
if (!bgp)
@@ -3706,10 +3956,12 @@ DEFUN (vnc_l2_group_no_labels,
return CMD_WARNING;
}
+ argc-=2;
+ argv+=2;
for (; argc; --argc, ++argv)
{
uint32_t label;
- VTY_GET_INTEGER_RANGE ("Label value", label, argv[0], 0, 1048575);
+ VTY_GET_INTEGER_RANGE ("Label value", label, argv[0]->arg, 0, MPLS_LABEL_MAX);
listnode_delete (ll, (void *) (uintptr_t) label);
}
@@ -3718,7 +3970,7 @@ DEFUN (vnc_l2_group_no_labels,
DEFUN (vnc_l2_group_rt,
vnc_l2_group_rt_cmd,
- "rt (both|export|import) ASN:nn_or_IP-address:nn",
+ "rt <both|export|import> ASN:nn_or_IP-address:nn",
"Specify route targets\n"
"Export+import filters\n"
"Export filters\n"
@@ -3726,12 +3978,12 @@ DEFUN (vnc_l2_group_rt,
"A route target\n")
{
VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
- struct bgp *bgp = vty->index;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int rc = CMD_SUCCESS;
int do_import = 0;
int do_export = 0;
- switch (argv[0][0])
+ switch (argv[1]->arg[0])
{
case 'b':
do_export = 1; /* fall through */
@@ -3742,14 +3994,10 @@ DEFUN (vnc_l2_group_rt,
do_export = 1;
break;
default:
- vty_out (vty, "Unknown option, %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Unknown option, %s%s", argv[1]->arg, VTY_NEWLINE);
return CMD_ERR_NO_MATCH;
- }
- argc--;
- argv++;
- if (argc < 1)
- return CMD_ERR_INCOMPLETE;
+ }
if (!bgp)
{
vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
@@ -3765,9 +4013,9 @@ DEFUN (vnc_l2_group_rt,
}
if (do_import)
- rc = set_ecom_list (vty, argc, argv, &rfg->rt_import_list);
+ rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_import_list);
if (rc == CMD_SUCCESS && do_export)
- rc = set_ecom_list (vty, argc, argv, &rfg->rt_export_list);
+ rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_export_list);
return rc;
}
@@ -3850,7 +4098,9 @@ bgp_rfapi_cfg_init (void)
install_node (&bgp_vnc_defaults_node, NULL);
install_node (&bgp_vnc_nve_group_node, NULL);
+ install_node (&bgp_vrf_policy_node, NULL);
install_node (&bgp_vnc_l2_group_node, NULL);
+ install_default (BGP_VRF_POLICY_NODE);
install_default (BGP_VNC_DEFAULTS_NODE);
install_default (BGP_VNC_NVE_GROUP_NODE);
install_default (BGP_VNC_L2_GROUP_NODE);
@@ -3861,6 +4111,8 @@ bgp_rfapi_cfg_init (void)
install_element (BGP_NODE, &vnc_defaults_cmd);
install_element (BGP_NODE, &vnc_nve_group_cmd);
install_element (BGP_NODE, &vnc_no_nve_group_cmd);
+ install_element (BGP_NODE, &vnc_vrf_policy_cmd);
+ install_element (BGP_NODE, &vnc_no_vrf_policy_cmd);
install_element (BGP_NODE, &vnc_l2_group_cmd);
install_element (BGP_NODE, &vnc_no_l2_group_cmd);
install_element (BGP_NODE, &vnc_advertise_un_method_cmd);
@@ -3924,6 +4176,16 @@ bgp_rfapi_cfg_init (void)
&vnc_nve_group_export_no_routemap_cmd);
install_element (BGP_VNC_NVE_GROUP_NODE, &exit_vnc_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_label_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_no_label_cmd);
+ //Reenable to support VRF controller use case and testing
+ install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_nexthop_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_import_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_export_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_both_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rd_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd);
+
install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_lni_cmd);
install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_labels_cmd);
install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_no_labels_cmd);
@@ -3992,7 +4254,7 @@ bgp_rfapi_cfg_destroy (struct bgp *bgp, struct rfapi_cfg *h)
if (h == NULL)
return;
- bgp_rfapi_delete_named_nve_group (NULL, bgp, NULL);
+ bgp_rfapi_delete_named_nve_group (NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX);
bgp_rfapi_delete_named_l2_group (NULL, bgp, NULL);
if (h->l2_groups != NULL)
list_delete (h->l2_groups);
@@ -4020,6 +4282,166 @@ bgp_rfapi_cfg_write (struct vty *vty, struct bgp *bgp)
afi_t afi;
int type;
+ vty_out (vty, "!%s", VTY_NEWLINE);
+ for (ALL_LIST_ELEMENTS (hc->nve_groups_sequential, node, nnode, rfg))
+ if (rfg->type == RFAPI_GROUP_CFG_VRF)
+ {
+ ++write;
+ vty_out (vty, " vrf-policy %s%s", rfg->name, VTY_NEWLINE);
+ if (rfg->label <= MPLS_LABEL_MAX)
+ {
+ vty_out (vty, " label %u%s", rfg->label, VTY_NEWLINE);
+
+ }
+ if (CHECK_FLAG (rfg->flags, RFAPI_RFG_VPN_NH_SELF))
+ {
+ vty_out (vty, " nexthop self%s", VTY_NEWLINE);
+
+ }
+ else
+ {
+ if (rfg->vn_prefix.family)
+ {
+ char buf[BUFSIZ];
+ buf[0] = buf[BUFSIZ - 1] = 0;
+ inet_ntop(rfg->vn_prefix.family, &rfg->vn_prefix.u.prefix, buf, sizeof(buf));
+ if (!buf[0] || buf[BUFSIZ - 1])
+ {
+ //vty_out (vty, "nexthop self%s", VTY_NEWLINE);
+ }
+ else
+ {
+ vty_out (vty, " nexthop %s%s", buf, VTY_NEWLINE);
+ }
+ }
+ }
+
+ if (rfg->rd.prefixlen)
+ {
+ char buf[BUFSIZ];
+ buf[0] = buf[BUFSIZ - 1] = 0;
+
+ if (AF_UNIX == rfg->rd.family)
+ {
+
+ uint16_t value = 0;
+
+ value = ((rfg->rd.val[6] << 8) & 0x0ff00) |
+ (rfg->rd.val[7] & 0x0ff);
+
+ vty_out (vty, " rd auto:nh:%d%s", value, VTY_NEWLINE);
+
+ }
+ else
+ {
+
+ if (!prefix_rd2str (&rfg->rd, buf, BUFSIZ) ||
+ !buf[0] || buf[BUFSIZ - 1])
+ {
+
+ vty_out (vty, "!Error: Can't convert rd%s", VTY_NEWLINE);
+ }
+ else
+ {
+ vty_out (vty, " rd %s%s", buf, VTY_NEWLINE);
+ }
+ }
+ }
+
+ if (rfg->rt_import_list && rfg->rt_export_list &&
+ ecommunity_cmp (rfg->rt_import_list, rfg->rt_export_list))
+ {
+ char *b = ecommunity_ecom2str (rfg->rt_import_list,
+ ECOMMUNITY_FORMAT_ROUTE_MAP);
+ vty_out (vty, " rt both %s%s", b, VTY_NEWLINE);
+ XFREE (MTYPE_ECOMMUNITY_STR, b);
+ }
+ else
+ {
+ if (rfg->rt_import_list)
+ {
+ char *b = ecommunity_ecom2str (rfg->rt_import_list,
+ ECOMMUNITY_FORMAT_ROUTE_MAP);
+ vty_out (vty, " rt import %s%s", b, VTY_NEWLINE);
+ XFREE (MTYPE_ECOMMUNITY_STR, b);
+ }
+ if (rfg->rt_export_list)
+ {
+ char *b = ecommunity_ecom2str (rfg->rt_export_list,
+ ECOMMUNITY_FORMAT_ROUTE_MAP);
+ vty_out (vty, " rt export %s%s", b, VTY_NEWLINE);
+ XFREE (MTYPE_ECOMMUNITY_STR, b);
+ }
+ }
+
+ /*
+ * route filtering: prefix-lists and route-maps
+ */
+ for (afi = AFI_IP; afi < AFI_MAX; ++afi)
+ {
+
+ const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6";
+
+ if (rfg->plist_export_bgp_name[afi])
+ {
+ vty_out (vty, " export bgp %s prefix-list %s%s",
+ afistr, rfg->plist_export_bgp_name[afi],
+ VTY_NEWLINE);
+ }
+ if (rfg->plist_export_zebra_name[afi])
+ {
+ vty_out (vty, " export zebra %s prefix-list %s%s",
+ afistr, rfg->plist_export_zebra_name[afi],
+ VTY_NEWLINE);
+ }
+ /*
+ * currently we only support redist plists for bgp-direct.
+ * If we later add plist support for redistributing other
+ * protocols, we'll need to loop over protocols here
+ */
+ if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi])
+ {
+ vty_out (vty, " redistribute bgp-direct %s prefix-list %s%s",
+ afistr,
+ rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi],
+ VTY_NEWLINE);
+ }
+ if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT][afi])
+ {
+ vty_out (vty,
+ " redistribute bgp-direct-to-nve-groups %s prefix-list %s%s",
+ afistr,
+ rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT]
+ [afi], VTY_NEWLINE);
+ }
+ }
+
+ if (rfg->routemap_export_bgp_name)
+ {
+ vty_out (vty, " export bgp route-map %s%s",
+ rfg->routemap_export_bgp_name, VTY_NEWLINE);
+ }
+ if (rfg->routemap_export_zebra_name)
+ {
+ vty_out (vty, " export zebra route-map %s%s",
+ rfg->routemap_export_zebra_name, VTY_NEWLINE);
+ }
+ if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT])
+ {
+ vty_out (vty, " redistribute bgp-direct route-map %s%s",
+ rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT],
+ VTY_NEWLINE);
+ }
+ if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT])
+ {
+ vty_out (vty,
+ " redistribute bgp-direct-to-nve-groups route-map %s%s",
+ rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT],
+ VTY_NEWLINE);
+ }
+ vty_out (vty, " exit-vrf-policy%s", VTY_NEWLINE);
+ vty_out (vty, "!%s", VTY_NEWLINE);
+ }
if (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)
{
vty_out (vty, " vnc advertise-un-method encap-safi%s", VTY_NEWLINE);
@@ -4181,6 +4603,7 @@ bgp_rfapi_cfg_write (struct vty *vty, struct bgp *bgp)
}
for (ALL_LIST_ELEMENTS (hc->nve_groups_sequential, node, nnode, rfg))
+ if (rfg->type == RFAPI_GROUP_CFG_NVE)
{
++write;
vty_out (vty, " vnc nve-group %s%s", rfg->name, VTY_NEWLINE);
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.h b/bgpd/rfapi/bgp_rfapi_cfg.h
index 897b4be764..8f93d69f6b 100644
--- a/bgpd/rfapi/bgp_rfapi_cfg.h
+++ b/bgpd/rfapi/bgp_rfapi_cfg.h
@@ -41,12 +41,21 @@ struct rfapi_l2_group_cfg
};
DECLARE_QOBJ_TYPE(rfapi_l2_group_cfg)
+typedef enum
+{
+ RFAPI_GROUP_CFG_NVE = 1,
+ RFAPI_GROUP_CFG_VRF,
+ RFAPI_GROUP_CFG_L2,
+ RFAPI_GROUP_CFG_MAX
+} rfapi_group_cfg_type_t;
+
struct rfapi_nve_group_cfg
{
struct route_node *vn_node; /* backref */
struct route_node *un_node; /* backref */
- char *name;
+ rfapi_group_cfg_type_t type; /* NVE|VPN */
+ char *name; /* unique by type! */
struct prefix vn_prefix;
struct prefix un_prefix;
@@ -54,8 +63,9 @@ struct rfapi_nve_group_cfg
uint8_t l2rd; /* 0 = VN addr LSB */
uint32_t response_lifetime;
uint32_t flags;
-#define RFAPI_RFG_RESPONSE_LIFETIME 0x1
+#define RFAPI_RFG_RESPONSE_LIFETIME 0x01 /* bits */
#define RFAPI_RFG_L2RD 0x02
+#define RFAPI_RFG_VPN_NH_SELF 0x04
struct ecommunity *rt_import_list;
struct ecommunity *rt_export_list;
struct rfapi_import_table *rfapi_import_table;
@@ -99,6 +109,9 @@ struct rfapi_nve_group_cfg
char *routemap_redist_name[ZEBRA_ROUTE_MAX];
struct route_map *routemap_redist[ZEBRA_ROUTE_MAX];
+ /* for VRF type groups */
+ uint32_t label;
+ struct rfapi_descriptor *rfd;
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(rfapi_nve_group_cfg)
@@ -288,6 +301,12 @@ bgp_rfapi_cfg_match_group (
struct prefix *vn,
struct prefix *un);
+struct rfapi_nve_group_cfg *
+bgp_rfapi_cfg_match_byname (
+ struct bgp *bgp,
+ const char *name,
+ rfapi_group_cfg_type_t type); /* _MAX = any */
+
extern void
vnc_prefix_list_update (struct bgp *bgp);
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index e32b407ba2..3cf09e240e 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -36,13 +36,13 @@
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_attr.h"
-#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
#include "bgpd/rfapi/rfapi.h"
#include "bgpd/rfapi/rfapi_backend.h"
#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_vnc_types.h"
@@ -335,6 +335,9 @@ is_valid_rfd (struct rfapi_descriptor *rfd)
if (!rfd || rfd->bgp == NULL)
return 0;
+ if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */
+ return 1;
+
if (rfapi_find_handle (rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh))
return 0;
@@ -357,6 +360,9 @@ rfapi_check (void *handle)
if (!rfd || rfd->bgp == NULL)
return EINVAL;
+ if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */
+ return 0;
+
if ((rc = rfapi_find_handle (rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh)))
return rc;
@@ -1349,7 +1355,6 @@ rfapi_rfp_set_cb_methods (void *rfp_start_val,
/***********************************************************************
* NVE Sessions
***********************************************************************/
-
/*
* Caller must supply an already-allocated rfd with the "caller"
* fields already set (vn_addr, un_addr, callback, cookie)
@@ -1476,6 +1481,57 @@ rfapi_open_inner (
return 0;
}
+/* moved from rfapi_register */
+int
+rfapi_init_and_open(
+ struct bgp *bgp,
+ struct rfapi_descriptor *rfd,
+ struct rfapi_nve_group_cfg *rfg)
+{
+ struct rfapi *h = bgp->rfapi;
+ char buf_vn[BUFSIZ];
+ char buf_un[BUFSIZ];
+ afi_t afi_vn, afi_un;
+ struct prefix pfx_un;
+ struct route_node *rn;
+
+
+ rfapi_time (&rfd->open_time);
+
+ if (rfg->type == RFAPI_GROUP_CFG_VRF)
+ SET_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF);
+
+ rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ);
+ rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ);
+
+ vnc_zlog_debug_verbose ("%s: new RFD with VN=%s UN=%s cookie=%p",
+ __func__, buf_vn, buf_un, rfd->cookie);
+
+ if (rfg->type != RFAPI_GROUP_CFG_VRF) /* unclear if needed for VRF */
+ {
+ listnode_add (&h->descriptors, rfd);
+ if (h->descriptors.count > h->stat.max_descriptors)
+ {
+ h->stat.max_descriptors = h->descriptors.count;
+ }
+
+ /*
+ * attach to UN radix tree
+ */
+ afi_vn = family2afi (rfd->vn_addr.addr_family);
+ afi_un = family2afi (rfd->un_addr.addr_family);
+ assert (afi_vn && afi_un);
+ assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx_un));
+
+ rn = route_node_get (&(h->un[afi_un]), &pfx_un);
+ assert (rn);
+ rfd->next = rn->info;
+ rn->info = rfd;
+ rfd->un_node = rn;
+ }
+ return rfapi_open_inner (rfd, bgp, h, rfg);
+}
+
struct rfapi_vn_option *
rfapiVnOptionsDup (struct rfapi_vn_option *orig)
{
@@ -1669,11 +1725,17 @@ rfapi_query_inner (
{
char buf[BUFSIZ];
+ char *s;
prefix2str (&p, buf, BUFSIZ);
buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
vnc_zlog_debug_verbose ("%s(rfd=%p, target=%s, ppNextHop=%p)",
__func__, rfd, buf, ppNextHopEntry);
+
+ s = ecommunity_ecom2str(rfd->import_table->rt_import_list,
+ ECOMMUNITY_FORMAT_ROUTE_MAP);
+ vnc_zlog_debug_verbose("%s rfd->import_table=%p, rfd->import_table->rt_import_list: %s",
+ __func__, rfd->import_table, s); XFREE (MTYPE_ECOMMUNITY_STR, s);
}
afi = family2afi (p.family);
@@ -1993,14 +2055,10 @@ rfapi_open (
struct prefix pfx_vn;
struct prefix pfx_un;
- struct route_node *rn;
int rc;
rfapi_handle hh = NULL;
int reusing_provisional = 0;
- afi_t afi_vn;
- afi_t afi_un;
-
{
char buf[2][INET_ADDRSTRLEN];
vnc_zlog_debug_verbose ("%s: VN=%s UN=%s", __func__,
@@ -2131,40 +2189,7 @@ rfapi_open (
if (!reusing_provisional)
{
- rfapi_time (&rfd->open_time);
-
- {
- char buf_vn[BUFSIZ];
- char buf_un[BUFSIZ];
-
- rfapiRfapiIpAddr2Str (vn, buf_vn, BUFSIZ);
- rfapiRfapiIpAddr2Str (un, buf_un, BUFSIZ);
-
- vnc_zlog_debug_verbose ("%s: new HD with VN=%s UN=%s cookie=%p",
- __func__, buf_vn, buf_un, userdata);
- }
-
- listnode_add (&h->descriptors, rfd);
- if (h->descriptors.count > h->stat.max_descriptors)
- {
- h->stat.max_descriptors = h->descriptors.count;
- }
-
- /*
- * attach to UN radix tree
- */
- afi_vn = family2afi (rfd->vn_addr.addr_family);
- afi_un = family2afi (rfd->un_addr.addr_family);
- assert (afi_vn && afi_un);
- assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx_un));
-
- rn = route_node_get (&(h->un[afi_un]), &pfx_un);
- assert (rn);
- rfd->next = rn->info;
- rn->info = rfd;
- rfd->un_node = rn;
-
- rc = rfapi_open_inner (rfd, bgp, h, rfg);
+ rc = rfapi_init_and_open(bgp, rfd, rfg);
/*
* This can fail only if the VN address is IPv6 and the group
* specified auto-assignment of RDs, which only works for v4,
@@ -3062,28 +3087,30 @@ DEFUN (debug_rfapi_show_nves,
DEFUN (
debug_rfapi_show_nves_vn_un,
debug_rfapi_show_nves_vn_un_cmd,
- "debug rfapi-dev show nves (vn|un) (A.B.C.D|X:X::X:X)", /* prefix also ok */
+ "debug rfapi-dev show nves <vn|un> <A.B.C.D|X:X::X:X>", /* prefix also ok */
DEBUG_STR
DEBUG_RFAPI_STR
SHOW_STR
"NVE Information\n"
- "Specify virtual network or underlay network interface\n"
- "IPv4 or IPv6 address\n")
+ "Specify virtual network\n"
+ "Specify underlay network interface\n"
+ "IPv4 address\n"
+ "IPv6 address\n")
{
struct prefix pfx;
- if (!str2prefix (argv[1], &pfx))
+ if (!str2prefix (argv[5]->arg, &pfx))
{
- vty_out (vty, "Malformed address \"%s\"%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "Malformed address \"%s\"%s", argv[5]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
if (pfx.family != AF_INET && pfx.family != AF_INET6)
{
- vty_out (vty, "Invalid address \"%s\"%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "Invalid address \"%s\"%s", argv[5]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
- if (*(argv[0]) == 'c')
+ if (argv[4]->arg[0] == 'u')
{
rfapiPrintMatchingDescriptors (vty, NULL, &pfx);
}
@@ -3126,13 +3153,16 @@ test_nexthops_callback (
DEFUN (debug_rfapi_open,
debug_rfapi_open_cmd,
- "debug rfapi-dev open vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X)",
+ "debug rfapi-dev open vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
DEBUG_STR
DEBUG_RFAPI_STR
"rfapi_open\n"
"indicate vn addr follows\n"
- "virtual network interface address\n"
- "indicate xt addr follows\n" "underlay network interface address\n")
+ "virtual network interface IPv4 address\n"
+ "virtual network interface IPv6 address\n"
+ "indicate xt addr follows\n"
+ "underlay network interface IPv4 address\n"
+ "underlay network interface IPv6 address\n")
{
struct rfapi_ip_addr vn;
struct rfapi_ip_addr un;
@@ -3143,13 +3173,13 @@ DEFUN (debug_rfapi_open,
/*
* Get VN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[0], &vn)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
return rc;
/*
* Get UN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[1], &un)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
return rc;
rc = rfapi_open (rfapi_get_rfp_start_val_by_bgp (bgp_get_default ()),
@@ -3168,13 +3198,16 @@ DEFUN (debug_rfapi_open,
DEFUN (debug_rfapi_close_vn_un,
debug_rfapi_close_vn_un_cmd,
- "debug rfapi-dev close vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X)",
+ "debug rfapi-dev close vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
DEBUG_STR
DEBUG_RFAPI_STR
"rfapi_close\n"
"indicate vn addr follows\n"
- "virtual network interface address\n"
- "indicate xt addr follows\n" "underlay network interface address\n")
+ "virtual network interface IPv4 address\n"
+ "virtual network interface IPv6 address\n"
+ "indicate xt addr follows\n"
+ "underlay network interface IPv4 address\n"
+ "underlay network interface IPv6 address\n")
{
struct rfapi_ip_addr vn;
struct rfapi_ip_addr un;
@@ -3184,21 +3217,21 @@ DEFUN (debug_rfapi_close_vn_un,
/*
* Get VN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[0], &vn)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
return rc;
/*
* Get UN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[1], &un)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
return rc;
if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
{
vty_out (vty, "can't locate handle matching vn=%s, un=%s%s",
- argv[0], argv[1], VTY_NEWLINE);
+ argv[4]->arg, argv[6]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3222,11 +3255,11 @@ DEFUN (debug_rfapi_close_rfd,
int rc;
char *endptr = NULL;
- handle = (rfapi_handle) (uintptr_t) (strtoull (argv[0], &endptr, 16));
+ handle = (rfapi_handle) (uintptr_t) (strtoull (argv[4]->arg, &endptr, 16));
if (*endptr != '\0' || (uintptr_t) handle == UINTPTR_MAX)
{
- vty_out (vty, "Invalid value: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Invalid value: %s%s", argv[4]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3240,7 +3273,7 @@ DEFUN (debug_rfapi_close_rfd,
DEFUN (debug_rfapi_register_vn_un,
debug_rfapi_register_vn_un_cmd,
- "debug rfapi-dev register vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) lifetime SECONDS",
+ "debug rfapi-dev register vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime SECONDS",
DEBUG_STR
DEBUG_RFAPI_STR
"rfapi_register\n"
@@ -3252,7 +3285,9 @@ DEFUN (debug_rfapi_register_vn_un,
"underlay network IPv6 interface address\n"
"indicate prefix follows\n"
"IPv4 prefix\n"
- "IPv6 prefix\n" "indicate lifetime follows\n" "lifetime\n")
+ "IPv6 prefix\n"
+ "indicate lifetime follows\n"
+ "lifetime\n")
{
struct rfapi_ip_addr vn;
struct rfapi_ip_addr un;
@@ -3265,46 +3300,46 @@ DEFUN (debug_rfapi_register_vn_un,
/*
* Get VN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[0], &vn)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
return rc;
/*
* Get UN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[1], &un)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
return rc;
if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
{
vty_out (vty, "can't locate handle matching vn=%s, un=%s%s",
- argv[0], argv[1], VTY_NEWLINE);
+ argv[4]->arg, argv[6]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
/*
* Get prefix to advertise
*/
- if (!str2prefix (argv[2], &pfx))
+ if (!str2prefix (argv[8]->arg, &pfx))
{
- vty_out (vty, "Malformed prefix \"%s\"%s", argv[2], VTY_NEWLINE);
+ vty_out (vty, "Malformed prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
if (pfx.family != AF_INET && pfx.family != AF_INET6)
{
- vty_out (vty, "Bad family for prefix \"%s\"%s", argv[2], VTY_NEWLINE);
+ vty_out (vty, "Bad family for prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
rfapiQprefix2Rprefix (&pfx, &hpfx);
- if (!strcmp (argv[3], "infinite"))
+ if (!strcmp (argv[10]->arg, "infinite"))
{
lifetime = RFAPI_INFINITE_LIFETIME;
}
else
{
- VTY_GET_INTEGER ("Lifetime", lifetime, argv[3]);
+ VTY_GET_INTEGER ("Lifetime", lifetime, argv[10]->arg);
}
@@ -3320,13 +3355,7 @@ DEFUN (debug_rfapi_register_vn_un,
DEFUN (debug_rfapi_register_vn_un_l2o,
debug_rfapi_register_vn_un_l2o_cmd,
- "debug rfapi-dev register"
- " vn (A.B.C.D|X:X::X:X)"
- " un (A.B.C.D|X:X::X:X)"
- " prefix (A.B.C.D/M|X:X::X:X/M)"
- " lifetime SECONDS"
- " macaddr YY:YY:YY:YY:YY:YY"
- " lni <0-16777215>",
+ "debug rfapi-dev register vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime SECONDS macaddr YY:YY:YY:YY:YY:YY lni (0-16777215)",
DEBUG_STR
DEBUG_RFAPI_STR
"rfapi_register\n"
@@ -3338,7 +3367,13 @@ DEFUN (debug_rfapi_register_vn_un_l2o,
"underlay network IPv6 interface address\n"
"indicate prefix follows\n"
"IPv4 prefix\n"
- "IPv6 prefix\n" "indicate lifetime follows\n" "lifetime\n")
+ "IPv6 prefix\n"
+ "indicate lifetime follows\n"
+ "Seconds of lifetime\n"
+ "indicate MAC address follows\n"
+ "MAC address\n"
+ "indicate lni follows\n"
+ "lni value range\n")
{
struct rfapi_ip_addr vn;
struct rfapi_ip_addr un;
@@ -3354,55 +3389,55 @@ DEFUN (debug_rfapi_register_vn_un_l2o,
/*
* Get VN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[0], &vn)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
return rc;
/*
* Get UN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[1], &un)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
return rc;
if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
{
vty_out (vty, "can't locate handle matching vn=%s, un=%s%s",
- argv[0], argv[1], VTY_NEWLINE);
+ argv[4]->arg, argv[6]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
/*
* Get prefix to advertise
*/
- if (!str2prefix (argv[2], &pfx))
+ if (!str2prefix (argv[8]->arg, &pfx))
{
- vty_out (vty, "Malformed prefix \"%s\"%s", argv[2], VTY_NEWLINE);
+ vty_out (vty, "Malformed prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
if (pfx.family != AF_INET && pfx.family != AF_INET6)
{
- vty_out (vty, "Bad family for prefix \"%s\"%s", argv[2], VTY_NEWLINE);
+ vty_out (vty, "Bad family for prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
rfapiQprefix2Rprefix (&pfx, &hpfx);
- if (!strcmp (argv[3], "infinite"))
+ if (!strcmp (argv[10]->arg, "infinite"))
{
lifetime = RFAPI_INFINITE_LIFETIME;
}
else
{
- VTY_GET_INTEGER ("Lifetime", lifetime, argv[3]);
+ VTY_GET_INTEGER ("Lifetime", lifetime, argv[10]->arg);
}
/* L2 option parsing START */
memset (optary, 0, sizeof (optary));
VTY_GET_INTEGER ("Logical Network ID",
- optary[opt_next].v.l2addr.logical_net_id, argv[5]);
- if ((rc = rfapiStr2EthAddr (argv[4], &optary[opt_next].v.l2addr.macaddr)))
+ optary[opt_next].v.l2addr.logical_net_id, argv[14]->arg);
+ if ((rc = rfapiStr2EthAddr (argv[12]->arg, &optary[opt_next].v.l2addr.macaddr)))
{
- vty_out (vty, "Bad mac address \"%s\"%s", argv[4], VTY_NEWLINE);
+ vty_out (vty, "Bad mac address \"%s\"%s", argv[12]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR;
@@ -3431,7 +3466,7 @@ DEFUN (debug_rfapi_register_vn_un_l2o,
DEFUN (debug_rfapi_unregister_vn_un,
debug_rfapi_unregister_vn_un_cmd,
- "debug rfapi-dev unregister vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M)",
+ "debug rfapi-dev unregister vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>",
DEBUG_STR
DEBUG_RFAPI_STR
"rfapi_register\n"
@@ -3451,35 +3486,35 @@ DEFUN (debug_rfapi_unregister_vn_un,
/*
* Get VN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[0], &vn)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
return rc;
/*
* Get UN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[1], &un)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
return rc;
if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
{
vty_out (vty, "can't locate handle matching vn=%s, un=%s%s",
- argv[0], argv[1], VTY_NEWLINE);
+ argv[4]->arg, argv[6]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
/*
* Get prefix to advertise
*/
- if (!str2prefix (argv[2], &pfx))
+ if (!str2prefix (argv[8]->arg, &pfx))
{
- vty_out (vty, "Malformed prefix \"%s\"%s", argv[2], VTY_NEWLINE);
+ vty_out (vty, "Malformed prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
if (pfx.family != AF_INET && pfx.family != AF_INET6)
{
- vty_out (vty, "Bad family for prefix \"%s\"%s", argv[2], VTY_NEWLINE);
+ vty_out (vty, "Bad family for prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
rfapiQprefix2Rprefix (&pfx, &hpfx);
@@ -3491,15 +3526,19 @@ DEFUN (debug_rfapi_unregister_vn_un,
DEFUN (debug_rfapi_query_vn_un,
debug_rfapi_query_vn_un_cmd,
- "debug rfapi-dev query vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) target (A.B.C.D|X:X::X:X)",
+ "debug rfapi-dev query vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> target <A.B.C.D|X:X::X:X>",
DEBUG_STR
DEBUG_RFAPI_STR
"rfapi_query\n"
"indicate vn addr follows\n"
- "virtual network interface address\n"
- "indicate xt addr follows\n"
- "underlay network interface address\n"
- "indicate target follows\n" "target\n")
+ "virtual network interface IPv4 address\n"
+ "virtual network interface IPv6 address\n"
+ "indicate un addr follows\n"
+ "IPv4 un address\n"
+ "IPv6 un address\n"
+ "indicate target follows\n"
+ "target IPv4 address\n"
+ "target IPv6 address\n")
{
struct rfapi_ip_addr vn;
struct rfapi_ip_addr un;
@@ -3511,28 +3550,28 @@ DEFUN (debug_rfapi_query_vn_un,
/*
* Get VN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[0], &vn)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
return rc;
/*
* Get UN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[1], &un)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
return rc;
/*
* Get target addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[2], &target)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[8]->arg, &target)))
return rc;
if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
{
vty_out (vty, "can't locate handle matching vn=%s, un=%s%s",
- argv[0], argv[1], VTY_NEWLINE);
+ argv[4]->arg, argv[6]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3560,17 +3599,20 @@ DEFUN (debug_rfapi_query_vn_un,
DEFUN (debug_rfapi_query_vn_un_l2o,
debug_rfapi_query_vn_un_l2o_cmd,
- "debug rfapi-dev query vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lni LNI target YY:YY:YY:YY:YY:YY",
+ "debug rfapi-dev query vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lni LNI target YY:YY:YY:YY:YY:YY",
DEBUG_STR
DEBUG_RFAPI_STR
"rfapi_query\n"
"indicate vn addr follows\n"
- "virtual network interface address\n"
+ "virtual network interface IPv4 address\n"
+ "virtual network interface IPv6 address\n"
"indicate xt addr follows\n"
- "underlay network interface address\n"
+ "underlay network interface IPv4 address\n"
+ "underlay network interface IPv6 address\n"
"logical network ID follows\n"
"logical network ID\n"
- "indicate target MAC addr follows\n" "target MAC addr\n")
+ "indicate target MAC addr follows\n"
+ "target MAC addr\n")
{
struct rfapi_ip_addr vn;
struct rfapi_ip_addr un;
@@ -3585,28 +3627,32 @@ DEFUN (debug_rfapi_query_vn_un_l2o,
/*
* Get VN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[0], &vn)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
return rc;
/*
* Get UN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[1], &un)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
return rc;
+#if 0 /* there is no IP target arg here ?????? */
/*
* Get target addr
*/
if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[2], &target)))
return rc;
-
+#else
+ vty_out (vty, "%% This command is broken.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+#endif
if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
{
vty_out (vty, "can't locate handle matching vn=%s, un=%s%s",
- argv[0], argv[1], VTY_NEWLINE);
+ argv[4]->arg, argv[6]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3614,13 +3660,13 @@ DEFUN (debug_rfapi_query_vn_un_l2o,
* Set up L2 parameters
*/
memset (&l2o_buf, 0, sizeof (l2o_buf));
- if (rfapiStr2EthAddr (argv[3], &l2o_buf.macaddr))
+ if (rfapiStr2EthAddr (argv[10]->arg, &l2o_buf.macaddr))
{
- vty_out (vty, "Bad mac address \"%s\"%s", argv[3], VTY_NEWLINE);
+ vty_out (vty, "Bad mac address \"%s\"%s", argv[10]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_INTEGER ("Logical Network ID", l2o_buf.logical_net_id, argv[2]);
+ VTY_GET_INTEGER ("Logical Network ID", l2o_buf.logical_net_id, argv[8]->arg);
/* construct option chain */
@@ -3663,15 +3709,20 @@ DEFUN (debug_rfapi_query_vn_un_l2o,
DEFUN (debug_rfapi_query_done_vn_un,
debug_rfapi_query_vn_un_done_cmd,
- "debug rfapi-dev query done vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) target (A.B.C.D|X:X::X:X)",
+ "debug rfapi-dev query done vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> target <A.B.C.D|X:X::X:X>",
DEBUG_STR
DEBUG_RFAPI_STR
"rfapi_query_done\n"
+ "rfapi_query_done\n"
"indicate vn addr follows\n"
- "virtual network interface address\n"
+ "virtual network interface IPv4 address\n"
+ "virtual network interface IPv6 address\n"
"indicate xt addr follows\n"
- "underlay network interface address\n"
- "indicate prefix follows\n" "prefix\n")
+ "underlay network interface IPv4 address\n"
+ "underlay network interface IPv6 address\n"
+ "indicate target follows\n"
+ "Target IPv4 address\n"
+ "Target IPv6 address\n")
{
struct rfapi_ip_addr vn;
struct rfapi_ip_addr un;
@@ -3682,28 +3733,28 @@ DEFUN (debug_rfapi_query_done_vn_un,
/*
* Get VN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[0], &vn)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[5]->arg, &vn)))
return rc;
/*
* Get UN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[1], &un)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[7]->arg, &un)))
return rc;
/*
* Get target addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[2], &target)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[9]->arg, &target)))
return rc;
if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
{
vty_out (vty, "can't locate handle matching vn=%s, un=%s%s",
- argv[0], argv[1], VTY_NEWLINE);
+ argv[5]->arg, argv[7]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3807,14 +3858,17 @@ DEFUN (debug_rfapi_show_import,
DEFUN (debug_rfapi_show_import_vn_un,
debug_rfapi_show_import_vn_un_cmd,
- "debug rfapi-dev show import vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X)",
+ "debug rfapi-dev show import vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
DEBUG_STR
DEBUG_RFAPI_STR
SHOW_STR
"import\n"
"indicate vn addr follows\n"
- "virtual network interface address\n"
- "indicate xt addr follows\n" "underlay network interface address\n")
+ "virtual network interface IPv4 address\n"
+ "virtual network interface IPv6 address\n"
+ "indicate xt addr follows\n"
+ "underlay network interface IPv4 address\n"
+ "underlay network interface IPv6 address\n")
{
struct rfapi_ip_addr vn;
struct rfapi_ip_addr un;
@@ -3825,21 +3879,21 @@ DEFUN (debug_rfapi_show_import_vn_un,
/*
* Get VN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[0], &vn)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[5]->arg, &vn)))
return rc;
/*
* Get UN addr
*/
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[1], &un)))
+ if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[7]->arg, &un)))
return rc;
if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
{
vty_out (vty, "can't locate handle matching vn=%s, un=%s%s",
- argv[0], argv[1], VTY_NEWLINE);
+ argv[5]->arg, argv[7]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3859,7 +3913,7 @@ DEFUN (debug_rfapi_show_import_vn_un,
DEFUN (debug_rfapi_response_omit_self,
debug_rfapi_response_omit_self_cmd,
- "debug rfapi-dev response-omit-self (on|off)",
+ "debug rfapi-dev response-omit-self <on|off>",
DEBUG_STR
DEBUG_RFAPI_STR
"Omit self in RFP responses\n"
@@ -3878,7 +3932,7 @@ DEFUN (debug_rfapi_response_omit_self,
return CMD_WARNING;
}
- if (!strcmp (argv[0], "on"))
+ if (!strcmp (argv[3]->arg, "on"))
SET_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP);
else
UNSET_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP);
diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c
index 4c415504fa..68292c26b1 100644
--- a/bgpd/rfapi/rfapi_ap.c
+++ b/bgpd/rfapi/rfapi_ap.c
@@ -35,13 +35,13 @@
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_attr.h"
-#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
#include "bgpd/rfapi/rfapi.h"
#include "bgpd/rfapi/rfapi_backend.h"
#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_advertise.h"
@@ -169,7 +169,7 @@ void
rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
{
struct rfapi_adb *adb;
- void *cursor;
+ void *cursor = NULL;
int rc;
for (rc =
diff --git a/bgpd/rfapi/rfapi_backend.h b/bgpd/rfapi/rfapi_backend.h
index 788ec73751..9e5b0dc5cb 100644
--- a/bgpd/rfapi/rfapi_backend.h
+++ b/bgpd/rfapi/rfapi_backend.h
@@ -36,15 +36,6 @@ extern void rfapi_delete (struct bgp *);
struct rfapi *bgp_rfapi_new (struct bgp *bgp);
void bgp_rfapi_destroy (struct bgp *bgp, struct rfapi *h);
-struct rfapi_import_table *rfapiImportTableRefAdd (struct bgp *bgp,
- struct ecommunity
- *rt_import_list);
-
-void
-rfapiImportTableRefDelByIt (struct bgp *bgp,
- struct rfapi_import_table *it_target);
-
-
extern void
rfapiProcessUpdate (struct peer *peer,
void *rfd,
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index adb54fd0e1..9ae3311e15 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -113,7 +113,7 @@ rfapiDebugBacktrace (void)
for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; ++i)
{
- vnc_zlog_debug_verbose ("backtrace[%2lu]: %s", i, syms[i]);
+ vnc_zlog_debug_verbose ("backtrace[%2zu]: %s", i, syms[i]);
}
free (syms);
@@ -4096,7 +4096,6 @@ rfapiBgpInfoFilteredImportFunction (safi_t safi)
switch (safi)
{
case SAFI_MPLS_VPN:
- case BGP_SAFI_VPN:
return rfapiBgpInfoFilteredImportVPN;
case SAFI_ENCAP:
@@ -4213,7 +4212,7 @@ rfapiProcessUpdate (
label);
}
- if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPN)
+ if (safi == SAFI_MPLS_VPN)
{
vnc_direct_bgp_rh_add_route (bgp, afi, p, peer, attr);
}
@@ -4342,7 +4341,7 @@ rfapiProcessWithdraw (
}
/* TBD the deletion should happen after the lifetime expires */
- if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPN)
+ if (safi == SAFI_MPLS_VPN)
vnc_direct_bgp_rh_del_route (bgp, afi, p, peer);
if (safi == SAFI_MPLS_VPN)
@@ -4658,7 +4657,8 @@ bgp_rfapi_destroy (struct bgp *bgp, struct rfapi *h)
}
struct rfapi_import_table *
-rfapiImportTableRefAdd (struct bgp *bgp, struct ecommunity *rt_import_list)
+rfapiImportTableRefAdd (struct bgp *bgp, struct ecommunity *rt_import_list,
+ struct rfapi_nve_group_cfg *rfg)
{
struct rfapi *h;
struct rfapi_import_table *it;
@@ -4684,6 +4684,7 @@ rfapiImportTableRefAdd (struct bgp *bgp, struct ecommunity *rt_import_list)
h->imports = it;
it->rt_import_list = ecommunity_dup (rt_import_list);
+ it->rfg = rfg;
it->monitor_exterior_orphans =
skiplist_new (0, NULL, (void (*)(void *)) prefix_free);
@@ -4957,6 +4958,7 @@ rfapiDeleteRemotePrefixesIt (
* un if set, tunnel must match this prefix
* vn if set, nexthop prefix must match this prefix
* p if set, prefix must match this prefix
+ * it if set, only look in this import table
*
* output
* pARcount number of active routes deleted
@@ -4972,6 +4974,7 @@ rfapiDeleteRemotePrefixes (
struct prefix *un,
struct prefix *vn,
struct prefix *p,
+ struct rfapi_import_table *arg_it,
int delete_active,
int delete_holddown,
uint32_t *pARcount,
@@ -5009,7 +5012,11 @@ rfapiDeleteRemotePrefixes (
* for the afi/safi combination
*/
- for (it = h->imports; it; it = it->next)
+ if (arg_it)
+ it = arg_it;
+ else
+ it = h->imports;
+ for (; it; )
{
vnc_zlog_debug_verbose
@@ -5030,6 +5037,11 @@ rfapiDeleteRemotePrefixes (
&deleted_holddown_nve_count,
uniq_active_nves,
uniq_holddown_nves);
+
+ if (arg_it)
+ it = NULL;
+ else
+ it = it->next;
}
/*
diff --git a/bgpd/rfapi/rfapi_import.h b/bgpd/rfapi/rfapi_import.h
index 3cf55462a1..3ba76539dd 100644
--- a/bgpd/rfapi/rfapi_import.h
+++ b/bgpd/rfapi/rfapi_import.h
@@ -38,6 +38,7 @@
struct rfapi_import_table
{
struct rfapi_import_table *next;
+ struct rfapi_nve_group_cfg *rfg;
struct ecommunity *rt_import_list; /* copied from nve grp */
int refcount; /* nve grps and nves */
uint32_t l2_logical_net_id; /* L2 only: EVPN Eth Seg Id */
@@ -90,6 +91,11 @@ rfapiShowImportTable (
struct route_table *rt,
int isvpn);
+extern struct rfapi_import_table *
+rfapiImportTableRefAdd (
+ struct bgp *bgp,
+ struct ecommunity *rt_import_list,
+ struct rfapi_nve_group_cfg *rfg);
extern void
rfapiImportTableRefDelByIt (
@@ -223,6 +229,7 @@ extern int rfapiEcommunityGetEthernetTag (
* un if set, tunnel must match this prefix
* vn if set, nexthop prefix must match this prefix
* p if set, prefix must match this prefix
+ * it if set, only look in this import table
*
* output
* pARcount number of active routes deleted
@@ -238,6 +245,7 @@ rfapiDeleteRemotePrefixes (
struct prefix *un,
struct prefix *vn,
struct prefix *p,
+ struct rfapi_import_table *it,
int delete_active,
int delete_holddown,
uint32_t *pARcount, /* active routes */
diff --git a/bgpd/rfapi/rfapi_private.h b/bgpd/rfapi/rfapi_private.h
index 00f90e35fc..8ac2966bfe 100644
--- a/bgpd/rfapi/rfapi_private.h
+++ b/bgpd/rfapi/rfapi_private.h
@@ -31,6 +31,7 @@
#include "lib/workqueue.h"
#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_route.h"
#include "rfapi.h"
@@ -135,6 +136,7 @@ struct rfapi_descriptor
#define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_ETHER 0x00000004
#define RFAPI_HD_FLAG_PROVISIONAL 0x00000008
#define RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY 0x00000010
+#define RFAPI_HD_FLAG_IS_VRF 0x00000012
};
#define RFAPI_QUEUED_FLAG(afi) ( \
@@ -433,4 +435,17 @@ DECLARE_MTYPE(RFAPI_L2ADDR_OPT)
DECLARE_MTYPE(RFAPI_AP)
DECLARE_MTYPE(RFAPI_MONITOR_ETH)
+
+/*
+ * Caller must supply an already-allocated rfd with the "caller"
+ * fields already set (vn_addr, un_addr, callback, cookie)
+ * The advertised_prefixes[] array elements should be NULL to
+ * have this function set them to newly-allocated radix trees.
+ */
+extern int
+rfapi_init_and_open(
+ struct bgp *bgp,
+ struct rfapi_descriptor *rfd,
+ struct rfapi_nve_group_cfg *rfg);
+
#endif /* _QUAGGA_BGP_RFAPI_PRIVATE_H */
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c
index 3a4a159215..8e5d47415f 100644
--- a/bgpd/rfapi/rfapi_rib.c
+++ b/bgpd/rfapi/rfapi_rib.c
@@ -514,9 +514,13 @@ rfapi_info_cmp (struct rfapi_info *a, struct rfapi_info *b)
void
rfapiRibClear (struct rfapi_descriptor *rfd)
{
- struct bgp *bgp = bgp_get_default ();
+ struct bgp *bgp;
afi_t afi;
+ if (rfd->bgp)
+ bgp = rfd->bgp;
+ else
+ bgp = bgp_get_default ();
#if DEBUG_L2_EXTRA
vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd);
#endif
diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c
index 0a5ee9428d..521c2319b2 100644
--- a/bgpd/rfapi/rfapi_vty.c
+++ b/bgpd/rfapi/rfapi_vty.c
@@ -35,6 +35,7 @@
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_route.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
@@ -56,6 +57,7 @@
#include "bgpd/rfapi/vnc_debug.h"
#define DEBUG_L2_EXTRA 0
+#define DEBUG_SHOW_EXTRA 0
#define VNC_SHOW_STR "VNC information\n"
@@ -1447,17 +1449,24 @@ rfapiShowRemoteRegistrationsIt (
if (pLni)
{
- fp (out, "%s[%s] L2VPN Network 0x%x (%u) RT={%s}%s",
- HVTY_NEWLINE, type, *pLni, (*pLni & 0xfff), s,
- HVTY_NEWLINE);
+ fp (out, "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
+ HVTY_NEWLINE, type, *pLni, (*pLni & 0xfff), s);
}
else
{
- fp (out, "%s[%s] Prefix RT={%s}%s",
- HVTY_NEWLINE, type, s, HVTY_NEWLINE);
+ fp (out, "%s[%s] Prefix RT={%s}",
+ HVTY_NEWLINE, type, s);
}
XFREE (MTYPE_ECOMMUNITY_STR, s);
+ if (it->rfg && it->rfg->name)
+ {
+ fp (out, " %s \"%s\"",
+ (it->rfg->type == RFAPI_GROUP_CFG_VRF ?
+ "VRF" : "NVE group"),
+ it->rfg->name);
+ }
+ fp (out, "%s", HVTY_NEWLINE);
if (show_expiring)
{
#if RFAPI_REGISTRATIONS_REPORT_AGE
@@ -1513,6 +1522,9 @@ rfapiShowRemoteRegistrationsIt (
fp (out, "Displayed %d out of %d %s%s",
printed, total, type, HVTY_NEWLINE);
+#if DEBUG_SHOW_EXTRA
+ fp(out, "IT table above: it=%p%s", it, HVTY_NEWLINE);
+#endif
}
return printed;
}
@@ -2179,16 +2191,23 @@ rfapiAddDeleteLocalRfpPrefix (
static int
register_add (
struct vty *vty,
- const char *arg_prefix,
- const char *arg_vn,
- const char *arg_un,
- const char *arg_cost, /* optional */
- const char *arg_lifetime, /* optional */
- const char *arg_macaddr, /* optional */
- const char *arg_vni, /* mac present=>mandatory Virtual Network ID */
+ struct cmd_token *carg_prefix,
+ struct cmd_token *carg_vn,
+ struct cmd_token *carg_un,
+ struct cmd_token *carg_cost, /* optional */
+ struct cmd_token *carg_lifetime, /* optional */
+ struct cmd_token *carg_macaddr, /* optional */
+ struct cmd_token *carg_vni, /* mac present=>mandatory Virtual Network ID */
int argc,
- const char **argv)
+ struct cmd_token **argv)
{
+ const char *arg_prefix = carg_prefix->arg;
+ const char *arg_vn = carg_vn->arg;
+ const char *arg_un = carg_un->arg;
+ const char *arg_cost = carg_cost ? carg_cost->arg : NULL;
+ const char *arg_lifetime = carg_lifetime ? carg_lifetime->arg : NULL;
+ const char *arg_macaddr = carg_macaddr ? carg_macaddr->arg : NULL;
+ const char *arg_vni = carg_vni ? carg_vni->arg : NULL;
struct rfapi_ip_addr vn_address;
struct rfapi_ip_addr un_address;
struct prefix pfx;
@@ -2229,7 +2248,7 @@ register_add (
for (; argc; --argc, ++argv)
{
- if (!strcmp (*argv, "local-next-hop"))
+ if (!strcmp (argv[0]->arg, "local-next-hop"))
{
if (arg_lnh)
{
@@ -2244,9 +2263,9 @@ register_add (
return CMD_WARNING;
}
++argv, --argc;
- arg_lnh = *argv;
+ arg_lnh = argv[0]->arg;
}
- if (!strcmp (*argv, "local-cost"))
+ if (!strcmp (argv[0]->arg, "local-cost"))
{
if (arg_lnh_cost)
{
@@ -2261,7 +2280,7 @@ register_add (
return CMD_WARNING;
}
++argv, --argc;
- arg_lnh_cost = *argv;
+ arg_lnh_cost = argv[0]->arg;
}
}
@@ -2533,11 +2552,11 @@ register_add (
}
/************************************************************************
- * Add prefix With .LNH_OPTIONS
+ * Add prefix With LNH_OPTIONS...
************************************************************************/
DEFUN (add_vnc_prefix_cost_life_lnh,
add_vnc_prefix_cost_life_lnh_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> lifetime <1-4294967295> .LNH_OPTIONS",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295) LNH_OPTIONS...",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2556,14 +2575,14 @@ DEFUN (add_vnc_prefix_cost_life_lnh,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], argv[3], argv[4],
+ return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11],
/* mac vni */
- NULL, NULL, argc, argv);
+ NULL, NULL, argc - 12, argv + 12);
}
DEFUN (add_vnc_prefix_life_cost_lnh,
add_vnc_prefix_life_cost_lnh_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295> cost <0-255> .LNH_OPTIONS",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255) LNH_OPTIONS...",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2582,14 +2601,14 @@ DEFUN (add_vnc_prefix_life_cost_lnh,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], argv[4], argv[3],
+ return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9],
/* mac vni */
- NULL, NULL, argc, argv);
+ NULL, NULL, argc - 12, argv + 12);
}
DEFUN (add_vnc_prefix_cost_lnh,
add_vnc_prefix_cost_lnh_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> .LNH_OPTIONS",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) LNH_OPTIONS...",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2606,14 +2625,14 @@ DEFUN (add_vnc_prefix_cost_lnh,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], argv[3], NULL,
+ return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL,
/* mac vni */
- NULL, NULL, argc, argv);
+ NULL, NULL, argc - 10, argv + 10);
}
DEFUN (add_vnc_prefix_life_lnh,
add_vnc_prefix_life_lnh_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295> .LNH_OPTIONS",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) LNH_OPTIONS...",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2630,14 +2649,14 @@ DEFUN (add_vnc_prefix_life_lnh,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], NULL, argv[3],
+ return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9],
/* mac vni */
- NULL, NULL, argc, argv);
+ NULL, NULL, argc - 10, argv + 10);
}
DEFUN (add_vnc_prefix_lnh,
add_vnc_prefix_lnh_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) .LNH_OPTIONS",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> LNH_OPTIONS...",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2652,17 +2671,17 @@ DEFUN (add_vnc_prefix_lnh,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], NULL, NULL,
+ return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL,
/* mac vni */
- NULL, NULL, argc, argv);
+ NULL, NULL, argc - 8, argv + 8);
}
/************************************************************************
- * Add prefix Without .LNH_OPTIONS
+ * Add prefix Without LNH_OPTIONS...
************************************************************************/
DEFUN (add_vnc_prefix_cost_life,
add_vnc_prefix_cost_life_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> lifetime <1-4294967295>",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2681,14 +2700,14 @@ DEFUN (add_vnc_prefix_cost_life,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], argv[3], argv[4],
+ return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11],
/* mac vni */
NULL, NULL, 0, NULL);
}
DEFUN (add_vnc_prefix_life_cost,
add_vnc_prefix_life_cost_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295> cost <0-255>",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255)",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2707,14 +2726,14 @@ DEFUN (add_vnc_prefix_life_cost,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], argv[4], argv[3],
+ return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9],
/* mac vni */
NULL, NULL, 0, NULL);
}
DEFUN (add_vnc_prefix_cost,
add_vnc_prefix_cost_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255>",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2731,14 +2750,14 @@ DEFUN (add_vnc_prefix_cost,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], argv[3], NULL,
+ return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL,
/* mac vni */
NULL, NULL, 0, NULL);
}
DEFUN (add_vnc_prefix_life,
add_vnc_prefix_life_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295>",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2755,14 +2774,14 @@ DEFUN (add_vnc_prefix_life,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], NULL, argv[3],
+ return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9],
/* mac vni */
NULL, NULL, 0, NULL);
}
DEFUN (add_vnc_prefix,
add_vnc_prefix_cmd,
- "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X)",
+ "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
"Add registration\n"
"VNC Information\n"
"Add/modify prefix related information\n"
@@ -2777,7 +2796,7 @@ DEFUN (add_vnc_prefix,
"[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[0], argv[1], argv[2], NULL, NULL,
+ return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL,
/* mac vni */
NULL, NULL, 0, NULL);
}
@@ -2787,7 +2806,7 @@ DEFUN (add_vnc_prefix,
************************************************************************/
DEFUN (add_vnc_mac_vni_prefix_cost_life,
add_vnc_mac_vni_prefix_cost_life_cmd,
- "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) cost <0-255> lifetime <1-4294967295>",
+ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255) lifetime (1-4294967295)",
"Add registration\n"
"VNC Information\n"
"Add/modify mac address information\n"
@@ -2809,15 +2828,15 @@ DEFUN (add_vnc_mac_vni_prefix_cost_life,
"Lifetime value in seconds\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[4], argv[2], argv[3], argv[5], argv[6],
+ return register_add (vty, argv[11], argv[7], argv[9], argv[13], argv[15],
/* mac vni */
- argv[0], argv[1], 0, NULL);
+ argv[3], argv[5], 0, NULL);
}
DEFUN (add_vnc_mac_vni_prefix_life,
add_vnc_mac_vni_prefix_life_cmd,
- "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) lifetime <1-4294967295>",
+ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime (1-4294967295)",
"Add registration\n"
"VNC Information\n"
"Add/modify mac address information\n"
@@ -2837,14 +2856,14 @@ DEFUN (add_vnc_mac_vni_prefix_life,
"Lifetime value in seconds\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[4], argv[2], argv[3], NULL, argv[5],
+ return register_add (vty, argv[11], argv[7], argv[9], NULL, argv[13],
/* mac vni */
- argv[0], argv[1], 0, NULL);
+ argv[3], argv[5], 0, NULL);
}
DEFUN (add_vnc_mac_vni_prefix_cost,
add_vnc_mac_vni_prefix_cost_cmd,
- "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) cost <0-255>",
+ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255)",
"Add registration\n"
"VNC Information\n"
"Add/modify mac address information\n"
@@ -2863,14 +2882,14 @@ DEFUN (add_vnc_mac_vni_prefix_cost,
"Administrative cost [default: 255]\n" "Administrative cost\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[4], argv[2], argv[3], argv[5], NULL,
+ return register_add (vty, argv[11], argv[7], argv[9], argv[13], NULL,
/* mac vni */
- argv[0], argv[1], 0, NULL);
+ argv[3], argv[5], 0, NULL);
}
DEFUN (add_vnc_mac_vni_prefix,
add_vnc_mac_vni_prefix_cmd,
- "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M)",
+ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>",
"Add registration\n"
"VNC Information\n"
"Add/modify mac address information\n"
@@ -2887,14 +2906,14 @@ DEFUN (add_vnc_mac_vni_prefix,
"IPv4 prefix\n" "IPv6 prefix\n")
{
/* pfx vn un cost life */
- return register_add (vty, argv[4], argv[2], argv[3], NULL, NULL,
+ return register_add (vty, argv[11], argv[7], argv[9], NULL, NULL,
/* mac vni */
- argv[0], argv[1], 0, NULL);
+ argv[3], argv[5], 0, NULL);
}
DEFUN (add_vnc_mac_vni_cost_life,
add_vnc_mac_vni_cost_life_cmd,
- "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> lifetime <1-4294967295>",
+ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
"Add registration\n"
"VNC Information\n"
"Add/modify mac address information\n"
@@ -2913,15 +2932,15 @@ DEFUN (add_vnc_mac_vni_cost_life,
"Lifetime value in seconds\n")
{
/* pfx vn un cost life */
- return register_add (vty, NULL, argv[2], argv[3], argv[4], argv[5],
+ return register_add (vty, NULL, argv[7], argv[9], argv[11], argv[13],
/* mac vni */
- argv[0], argv[1], 0, NULL);
+ argv[3], argv[5], 0, NULL);
}
DEFUN (add_vnc_mac_vni_cost,
add_vnc_mac_vni_cost_cmd,
- "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255>",
+ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
"Add registration\n"
"VNC Information\n"
"Add/modify mac address information\n"
@@ -2937,15 +2956,15 @@ DEFUN (add_vnc_mac_vni_cost,
"Administrative cost [default: 255]\n" "Administrative cost\n")
{
/* pfx vn un cost life */
- return register_add (vty, NULL, argv[2], argv[3], argv[4], NULL,
+ return register_add (vty, NULL, argv[7], argv[9], argv[11], NULL,
/* mac vni */
- argv[0], argv[1], 0, NULL);
+ argv[3], argv[5], 0, NULL);
}
DEFUN (add_vnc_mac_vni_life,
add_vnc_mac_vni_life_cmd,
- "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295>",
+ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
"Add registration\n"
"VNC Information\n"
"Add/modify mac address information\n"
@@ -2962,15 +2981,15 @@ DEFUN (add_vnc_mac_vni_life,
"Lifetime value in seconds\n")
{
/* pfx vn un cost life */
- return register_add (vty, NULL, argv[2], argv[3], NULL, argv[4],
+ return register_add (vty, NULL, argv[7], argv[9], NULL, argv[11],
/* mac vni */
- argv[0], argv[1], 0, NULL);
+ argv[3], argv[5], 0, NULL);
}
DEFUN (add_vnc_mac_vni,
add_vnc_mac_vni_cmd,
- "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X)",
+ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
"Add registration\n"
"VNC Information\n"
"Add/modify mac address information\n"
@@ -2984,9 +3003,9 @@ DEFUN (add_vnc_mac_vni,
"UN IPv4 interface address\n" "UN IPv6 interface address\n")
{
/* pfx vn un cost life */
- return register_add (vty, NULL, argv[2], argv[3], NULL, NULL,
+ return register_add (vty, NULL, argv[7], argv[9], NULL, NULL,
/* mac vni */
- argv[0], argv[1], 0, NULL);
+ argv[3], argv[5], 0, NULL);
}
/************************************************************************
@@ -2998,9 +3017,12 @@ struct rfapi_local_reg_delete_arg
/*
* match parameters
*/
+ struct bgp *bgp;
struct rfapi_ip_addr un_address; /* AF==0: wildcard */
struct rfapi_ip_addr vn_address; /* AF==0: wildcard */
struct prefix prefix; /* AF==0: wildcard */
+ struct prefix_rd rd; /* plen!=64: wildcard */
+ struct rfapi_nve_group_cfg *rfg; /* NULL: wildcard */
struct rfapi_l2address_option_match l2o;
@@ -3100,17 +3122,26 @@ nve_addr_cmp (void *k1, void *k2)
static int
parse_deleter_args (
- struct vty *vty,
- const char *arg_prefix,
- const char *arg_vn,
- const char *arg_un,
- const char *arg_l2addr,
- const char *arg_vni,
- struct rfapi_local_reg_delete_arg *rcdarg)
+ struct vty *vty,
+ struct bgp *bgp,
+ const char *arg_prefix,
+ const char *arg_vn,
+ const char *arg_un,
+ const char *arg_l2addr,
+ const char *arg_vni,
+ const char *arg_rd,
+ struct rfapi_nve_group_cfg *arg_rfg,
+ struct rfapi_local_reg_delete_arg *rcdarg)
{
int rc = CMD_WARNING;
- memset (rcdarg, 0, sizeof (struct rfapi_local_reg_delete_arg));
+ memset (rcdarg, 0, sizeof (struct rfapi_local_reg_delete_arg));
+
+ rcdarg->vty = vty;
+ if (bgp == NULL)
+ bgp = bgp_get_default();
+ rcdarg->bgp = bgp;
+ rcdarg->rfg = arg_rfg; /* may be NULL */
if (arg_vn && strcmp (arg_vn, "*"))
{
@@ -3156,7 +3187,41 @@ parse_deleter_args (
rcdarg->l2o.flags |= RFAPI_L2O_LNI;
}
}
- return 0;
+ if (arg_rd)
+ {
+ if (!str2prefix_rd (arg_rd, &rcdarg->rd))
+ {
+ vty_out (vty, "Malformed RD \"%s\"%s",
+ arg_rd, VTY_NEWLINE);
+ return rc;
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+static int
+parse_deleter_tokens (
+ struct vty *vty,
+ struct bgp *bgp,
+ struct cmd_token *carg_prefix,
+ struct cmd_token *carg_vn,
+ struct cmd_token *carg_un,
+ struct cmd_token *carg_l2addr,
+ struct cmd_token *carg_vni,
+ struct cmd_token *carg_rd,
+ struct rfapi_nve_group_cfg *arg_rfg,
+ struct rfapi_local_reg_delete_arg *rcdarg)
+{
+ const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL;
+ const char *arg_vn = carg_vn ? carg_vn->arg : NULL;
+ const char *arg_un = carg_un ? carg_un->arg : NULL;
+ const char *arg_l2addr = carg_l2addr ? carg_l2addr->arg : NULL;
+ const char *arg_vni = carg_vni ? carg_vni->arg : NULL;
+ const char *arg_rd = carg_rd ? carg_rd->arg : NULL;
+ return parse_deleter_args (vty, bgp,arg_prefix, arg_vn, arg_un,
+ arg_l2addr, arg_vni, arg_rd,
+ arg_rfg, rcdarg);
}
static void
@@ -3260,51 +3325,37 @@ clear_vnc_responses (struct rfapi_local_reg_delete_arg *cda)
* TBD need to count deleted prefixes and nves?
*
* ENXIO BGP or VNC not configured
- */
+ */
static int
-rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
+rfapiDeleteLocalPrefixesByRFD (struct rfapi_local_reg_delete_arg *cda,
+ struct rfapi_descriptor *rfd)
{
- struct rfapi_ip_addr *pUn; /* NULL = wildcard */
- struct rfapi_ip_addr *pVn; /* NULL = wildcard */
- struct prefix *pPrefix; /* NULL = wildcard */
+ struct rfapi_ip_addr *pUn; /* NULL = wildcard */
+ struct rfapi_ip_addr *pVn; /* NULL = wildcard */
+ struct prefix *pPrefix; /* NULL = wildcard */
+ struct prefix_rd *pPrd; /* NULL = wildcard */
- struct rfapi *h;
- struct listnode *node;
- struct rfapi_descriptor *rfd;
struct rfapi_ip_prefix rprefix;
- struct bgp *bgp_default = bgp_get_default ();
struct rfapi_next_hop_entry *head = NULL;
struct rfapi_next_hop_entry *tail = NULL;
- struct rfapi_cfg *rfapi_cfg;
#if DEBUG_L2_EXTRA
- vnc_zlog_debug_verbose ("%s: entry", __func__);
+ vnc_zlog_debug_verbose ("%s: entry", __func__);
#endif
- if (!bgp_default)
- return ENXIO;
-
- pUn = (cda->un_address.addr_family ? &cda->un_address : NULL);
- pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL);
- pPrefix = (cda->prefix.family ? &cda->prefix : NULL);
-
- h = bgp_default->rfapi;
- rfapi_cfg = bgp_default->rfapi_cfg;
-
- if (!h || !rfapi_cfg)
- return ENXIO;
+ pUn = (cda->un_address.addr_family ? &cda->un_address : NULL);
+ pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL);
+ pPrefix = (cda->prefix.family ? &cda->prefix : NULL);
+ pPrd = (cda->rd.prefixlen == 64 ? &cda->rd : NULL);
if (pPrefix)
{
rfapiQprefix2Rprefix (pPrefix, &rprefix);
}
-#if DEBUG_L2_EXTRA
- vnc_zlog_debug_verbose ("%s: starting descriptor loop", __func__);
-#endif
-
- for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
+ do /* to preserve old code structure */
{
+ struct rfapi *h=cda->bgp->rfapi;;
struct rfapi_adb *adb;
int rc;
int deleted_from_this_nve;
@@ -3373,6 +3424,17 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
continue;
}
}
+ if (pPrd)
+ {
+ if (memcmp(pPrd->val, adb->u.s.prd.val, 8) != 0)
+ {
+#if DEBUG_L2_EXTRA
+ vnc_zlog_debug_verbose ("%s: adb=%p, RD doesn't match, skipping",
+ __func__, adb);
+#endif
+ continue;
+ }
+ }
if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR))
{
if (memcmp
@@ -3411,47 +3473,43 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb))
{
-
- struct rfapi_vn_option vn1;
- struct rfapi_vn_option vn2;
- struct rfapi_vn_option *pVn;
int this_advertisement_prefix_count;
+ struct rfapi_vn_option optary[3];
+ struct rfapi_vn_option *opt = NULL;
+ int cur_opt = 0;
this_advertisement_prefix_count = 1;
rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp);
+ memset (optary, 0, sizeof (optary));
+
/* if mac addr present in advert, make l2o vn option */
if (adb->u.s.prefix_eth.family == AF_ETHERNET)
{
- memset (&vn1, 0, sizeof (vn1));
- memset (&vn2, 0, sizeof (vn2));
-
- vn1.type = RFAPI_VN_OPTION_TYPE_L2ADDR;
- vn1.v.l2addr.macaddr = adb->u.s.prefix_eth.u.prefix_eth;
-
- /*
- * use saved RD value instead of trying to invert
- * complex L2-style RD computation in rfapi_register()
- */
- vn2.type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
- vn2.v.internal_rd = adb->u.s.prd;
-
- vn1.next = &vn2;
-
- pVn = &vn1;
+ if (opt != NULL)
+ opt->next = &optary[cur_opt];
+ opt = &optary[cur_opt++];
+ opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
+ opt->v.l2addr.macaddr = adb->u.s.prefix_eth.u.prefix_eth;
++this_advertisement_prefix_count;
}
- else
- {
- pVn = NULL;
- }
+ /*
+ * use saved RD value instead of trying to invert
+ * complex RD computation in rfapi_register()
+ */
+ if (opt != NULL)
+ opt->next = &optary[cur_opt];
+ opt = &optary[cur_opt++];
+ opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
+ opt->v.internal_rd = adb->u.s.prd;
#if DEBUG_L2_EXTRA
vnc_zlog_debug_verbose ("%s: ipN killing reg from adb %p ", __func__, adb);
#endif
- rc = rfapi_register (rfd, &rp, 0, NULL, pVn, RFAPI_REGISTER_KILL);
+ rc = rfapi_register (rfd, &rp, 0, NULL,
+ (cur_opt ? optary : NULL), RFAPI_REGISTER_KILL);
if (!rc)
{
cda->pfx_count += this_advertisement_prefix_count;
@@ -3577,11 +3635,44 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
skiplist_insert (cda->nves, hap, hap);
}
}
- }
+ } while (0); /* to preserve old code structure */
return 0;
}
+static int
+rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
+{
+ int rc = 0;
+
+ if (cda->rfg)
+ {
+ if (cda->rfg->rfd) /* if not open, nothing to delete */
+ rc = rfapiDeleteLocalPrefixesByRFD (cda, cda->rfg->rfd);
+ }
+ else
+ {
+ struct bgp *bgp = cda->bgp;
+ struct rfapi *h;
+ struct rfapi_cfg *rfapi_cfg;
+
+ struct listnode *node;
+ struct rfapi_descriptor *rfd;
+ if (!bgp)
+ return ENXIO;
+ h = bgp->rfapi;
+ rfapi_cfg = bgp->rfapi_cfg;
+ if (!h || !rfapi_cfg)
+ return ENXIO;
+ vnc_zlog_debug_verbose ("%s: starting descriptor loop", __func__);
+ for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
+ {
+ rc = rfapiDeleteLocalPrefixesByRFD (cda, rfd);
+ }
+ }
+ return rc;
+}
+
/*
* clear_vnc_prefix
*
@@ -3597,6 +3688,8 @@ clear_vnc_prefix (struct rfapi_local_reg_delete_arg *cda)
struct prefix *pVN = NULL;
struct prefix *pPrefix = NULL;
+ struct rfapi_import_table *it = NULL;
+
/*
* Delete matching remote prefixes in holddown
*/
@@ -3614,7 +3707,11 @@ clear_vnc_prefix (struct rfapi_local_reg_delete_arg *cda)
{
pPrefix = &cda->prefix;
}
- rfapiDeleteRemotePrefixes (pUN, pVN, pPrefix,
+ if (cda->rfg)
+ {
+ it = cda->rfg->rfapi_import_table;
+ }
+ rfapiDeleteRemotePrefixes (pUN, pVN, pPrefix, it,
0, 1, &cda->remote_active_pfx_count,
&cda->remote_active_nve_count,
&cda->remote_holddown_pfx_count,
@@ -3691,13 +3788,15 @@ DEFUN (clear_vnc_nve_all,
clear_vnc_nve_all_cmd,
"clear vnc nve *",
"clear\n"
- "VNC Information\n" "Clear per NVE information\n" "For all NVEs\n")
+ "VNC Information\n"
+ "Clear per NVE information\n"
+ "For all NVEs\n")
{
struct rfapi_local_reg_delete_arg cda;
int rc;
- if ((rc = parse_deleter_args (vty, NULL, NULL, NULL, NULL, NULL, &cda)))
+ if ((rc = parse_deleter_args (vty, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
@@ -3713,21 +3812,24 @@ DEFUN (clear_vnc_nve_all,
DEFUN (clear_vnc_nve_vn_un,
clear_vnc_nve_vn_un_cmd,
- "clear vnc nve vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X)",
+ "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear prefix registration information\n"
"VN address of NVE\n"
+ "For all NVEs\n"
"VN IPv4 interface address\n"
"VN IPv6 interface address\n"
"UN address of NVE\n"
- "UN IPv4 interface address\n" "UN IPv6 interface address\n")
+ "For all UN addresses\n"
+ "UN IPv4 interface address\n"
+ "UN IPv6 interface address\n")
{
struct rfapi_local_reg_delete_arg cda;
int rc;
if ((rc =
- parse_deleter_args (vty, NULL, argv[0], argv[1], NULL, NULL, &cda)))
+ parse_deleter_tokens (vty, NULL, NULL, argv[4], argv[6], NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
@@ -3743,21 +3845,24 @@ DEFUN (clear_vnc_nve_vn_un,
DEFUN (clear_vnc_nve_un_vn,
clear_vnc_nve_un_vn_cmd,
- "clear vnc nve un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X)",
+ "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear prefix registration information\n"
"UN address of NVE\n"
+ "For all un NVEs\n"
"UN IPv4 interface address\n"
"UN IPv6 interface address\n"
"VN address of NVE\n"
- "VN IPv4 interface address\n" "VN IPv6 interface address\n")
+ "For all vn NVEs\n"
+ "VN IPv4 interface address\n"
+ "VN IPv6 interface address\n")
{
struct rfapi_local_reg_delete_arg cda;
int rc;
if ((rc =
- parse_deleter_args (vty, NULL, argv[1], argv[0], NULL, NULL, &cda)))
+ parse_deleter_tokens (vty, NULL, NULL, argv[6], argv[4], NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
@@ -3773,17 +3878,19 @@ DEFUN (clear_vnc_nve_un_vn,
DEFUN (clear_vnc_nve_vn,
clear_vnc_nve_vn_cmd,
- "clear vnc nve vn (*|A.B.C.D|X:X::X:X)",
+ "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear prefix registration information\n"
"VN address of NVE\n"
- "VN IPv4 interface address\n" "VN IPv6 interface address\n")
+ "All addresses\n"
+ "VN IPv4 interface address\n"
+ "VN IPv6 interface address\n")
{
struct rfapi_local_reg_delete_arg cda;
int rc;
- if ((rc = parse_deleter_args (vty, NULL, argv[0], NULL, NULL, NULL, &cda)))
+ if ((rc = parse_deleter_tokens (vty, NULL, NULL, argv[4], NULL, NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
@@ -3798,17 +3905,19 @@ DEFUN (clear_vnc_nve_vn,
DEFUN (clear_vnc_nve_un,
clear_vnc_nve_un_cmd,
- "clear vnc nve un (*|A.B.C.D|X:X::X:X)",
+ "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear prefix registration information\n"
"UN address of NVE\n"
- "UN IPv4 interface address\n" "UN IPv6 interface address\n")
+ "All un nves\n"
+ "UN IPv4 interface address\n"
+ "UN IPv6 interface address\n")
{
struct rfapi_local_reg_delete_arg cda;
int rc;
- if ((rc = parse_deleter_args (vty, NULL, NULL, argv[0], NULL, NULL, &cda)))
+ if ((rc = parse_deleter_tokens (vty, NULL, NULL, NULL, argv[6], NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
@@ -3831,7 +3940,7 @@ DEFUN (clear_vnc_nve_un,
*/
DEFUN (clear_vnc_prefix_vn_un,
clear_vnc_prefix_vn_un_cmd,
- "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X)",
+ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear prefix registration information\n"
@@ -3851,7 +3960,7 @@ DEFUN (clear_vnc_prefix_vn_un,
int rc;
if ((rc =
- parse_deleter_args (vty, argv[0], argv[1], argv[2], NULL, NULL, &cda)))
+ parse_deleter_tokens (vty, NULL, argv[3], argv[5], argv[7], NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -3861,7 +3970,7 @@ DEFUN (clear_vnc_prefix_vn_un,
DEFUN (clear_vnc_prefix_un_vn,
clear_vnc_prefix_un_vn_cmd,
- "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X)",
+ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear prefix registration information\n"
@@ -3881,7 +3990,7 @@ DEFUN (clear_vnc_prefix_un_vn,
int rc;
if ((rc =
- parse_deleter_args (vty, argv[0], argv[2], argv[1], NULL, NULL, &cda)))
+ parse_deleter_tokens (vty, NULL, argv[3], argv[7], argv[5], NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -3891,7 +4000,7 @@ DEFUN (clear_vnc_prefix_un_vn,
DEFUN (clear_vnc_prefix_un,
clear_vnc_prefix_un_cmd,
- "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) un (*|A.B.C.D|X:X::X:X)",
+ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear prefix registration information\n"
@@ -3907,7 +4016,7 @@ DEFUN (clear_vnc_prefix_un,
int rc;
if ((rc =
- parse_deleter_args (vty, argv[0], NULL, argv[1], NULL, NULL, &cda)))
+ parse_deleter_tokens (vty, NULL, argv[3], NULL, argv[5], NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -3917,7 +4026,7 @@ DEFUN (clear_vnc_prefix_un,
DEFUN (clear_vnc_prefix_vn,
clear_vnc_prefix_vn_cmd,
- "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) vn (*|A.B.C.D|X:X::X:X)",
+ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear prefix registration information\n"
@@ -3933,7 +4042,7 @@ DEFUN (clear_vnc_prefix_vn,
int rc;
if ((rc =
- parse_deleter_args (vty, argv[0], argv[1], NULL, NULL, NULL, &cda)))
+ parse_deleter_tokens (vty, NULL, argv[3], argv[5], NULL, NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -3943,7 +4052,7 @@ DEFUN (clear_vnc_prefix_vn,
DEFUN (clear_vnc_prefix_all,
clear_vnc_prefix_all_cmd,
- "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) *",
+ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
"clear\n"
"VNC Information\n"
"Clear prefix registration information\n"
@@ -3955,7 +4064,7 @@ DEFUN (clear_vnc_prefix_all,
struct rfapi_local_reg_delete_arg cda;
int rc;
- if ((rc = parse_deleter_args (vty, argv[0], NULL, NULL, NULL, NULL, &cda)))
+ if ((rc = parse_deleter_tokens (vty, NULL, argv[3], NULL, NULL, NULL, NULL, NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -3973,7 +4082,7 @@ DEFUN (clear_vnc_prefix_all,
*/
DEFUN (clear_vnc_mac_vn_un,
clear_vnc_mac_vn_un_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X)",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -3997,8 +4106,8 @@ DEFUN (clear_vnc_mac_vn_un,
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, NULL, argv[2], argv[3], argv[0], argv[1],
- &cda)))
+ parse_deleter_tokens (vty, NULL, NULL, argv[7], argv[9], argv[3], argv[5],
+ NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4008,7 +4117,7 @@ DEFUN (clear_vnc_mac_vn_un,
DEFUN (clear_vnc_mac_un_vn,
clear_vnc_mac_un_vn_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X)",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -4031,8 +4140,8 @@ DEFUN (clear_vnc_mac_un_vn,
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, NULL, argv[3], argv[2], argv[0], argv[1],
- &cda)))
+ parse_deleter_tokens (vty, NULL, NULL, argv[9], argv[7], argv[3], argv[5],
+ NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4042,7 +4151,7 @@ DEFUN (clear_vnc_mac_un_vn,
DEFUN (clear_vnc_mac_un,
clear_vnc_mac_un_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X)",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -4061,7 +4170,7 @@ DEFUN (clear_vnc_mac_un,
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, NULL, NULL, argv[2], argv[0], argv[1], &cda)))
+ parse_deleter_tokens (vty, NULL, NULL, NULL, argv[7], argv[3], argv[5], NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4071,7 +4180,7 @@ DEFUN (clear_vnc_mac_un,
DEFUN (clear_vnc_mac_vn,
clear_vnc_mac_vn_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X)",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -4090,7 +4199,7 @@ DEFUN (clear_vnc_mac_vn,
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, NULL, argv[2], NULL, argv[0], argv[1], &cda)))
+ parse_deleter_tokens (vty, NULL, NULL, argv[7], NULL, argv[3], argv[5], NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4100,7 +4209,7 @@ DEFUN (clear_vnc_mac_vn,
DEFUN (clear_vnc_mac_all,
clear_vnc_mac_all_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) *",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -4116,7 +4225,7 @@ DEFUN (clear_vnc_mac_all,
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, NULL, NULL, NULL, argv[0], argv[1], &cda)))
+ parse_deleter_tokens (vty, NULL, NULL, NULL, NULL, argv[3], argv[5], NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4130,7 +4239,7 @@ DEFUN (clear_vnc_mac_all,
DEFUN (clear_vnc_mac_vn_un_prefix,
clear_vnc_mac_vn_un_prefix_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M)",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -4139,7 +4248,6 @@ DEFUN (clear_vnc_mac_vn_un_prefix,
"VNI keyword\n"
"Any virtual network identifier\n"
"Virtual network identifier\n"
- "Virtual network identifier\n"
"VN address of NVE\n"
"All VN addresses\n"
"VN IPv4 interface address\n"
@@ -4158,8 +4266,8 @@ DEFUN (clear_vnc_mac_vn_un_prefix,
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, argv[4], argv[2], argv[3], argv[0], argv[1],
- &cda)))
+ parse_deleter_tokens (vty, NULL, argv[11], argv[7], argv[9], argv[3], argv[5],
+ NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4169,7 +4277,7 @@ DEFUN (clear_vnc_mac_vn_un_prefix,
DEFUN (clear_vnc_mac_un_vn_prefix,
clear_vnc_mac_un_vn_prefix_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M) prefix (*|A.B.C.D/M|X:X::X:X/M)",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M> prefix <*|A.B.C.D/M|X:X::X:X/M>",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -4185,15 +4293,23 @@ DEFUN (clear_vnc_mac_un_vn_prefix,
"VN address of NVE\n"
"All VN addresses\n"
"VN IPv4 interface address\n"
- "VN IPv6 interface address\n")
+ "VN IPv6 interface address\n"
+ "Clear prefix registration information\n"
+ "All prefixes\n"
+ "IPv4 prefix\n"
+ "IPv6 prefix\n"
+ "Clear prefix registration information\n"
+ "All prefixes\n"
+ "IPv4 prefix\n"
+ "IPv6 prefix\n")
{
struct rfapi_local_reg_delete_arg cda;
int rc;
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, argv[4], argv[3], argv[2], argv[0], argv[1],
- &cda)))
+ parse_deleter_tokens (vty, NULL, argv[11], argv[9], argv[7], argv[3], argv[5],
+ NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4203,7 +4319,7 @@ DEFUN (clear_vnc_mac_un_vn_prefix,
DEFUN (clear_vnc_mac_un_prefix,
clear_vnc_mac_un_prefix_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M)",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -4215,15 +4331,19 @@ DEFUN (clear_vnc_mac_un_prefix,
"UN address of NVE\n"
"All UN addresses\n"
"UN IPv4 interface address\n"
- "UN IPv6 interface address\n")
+ "UN IPv6 interface address\n"
+ "Clear prefix registration information\n"
+ "All prefixes\n"
+ "IPv4 Prefix\n"
+ "IPv6 Prefix\n")
{
struct rfapi_local_reg_delete_arg cda;
int rc;
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, argv[3], NULL, argv[2], argv[0], argv[1],
- &cda)))
+ parse_deleter_tokens (vty, NULL, argv[9], NULL, argv[7], argv[3], argv[5],
+ NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4233,7 +4353,7 @@ DEFUN (clear_vnc_mac_un_prefix,
DEFUN (clear_vnc_mac_vn_prefix,
clear_vnc_mac_vn_prefix_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M)",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -4245,15 +4365,19 @@ DEFUN (clear_vnc_mac_vn_prefix,
"UN address of NVE\n"
"All VN addresses\n"
"VN IPv4 interface address\n"
- "VN IPv6 interface address\n")
+ "VN IPv6 interface address\n"
+ "Clear prefix registration information\n"
+ "All prefixes\n"
+ "IPv4 Prefix\n"
+ "IPv6 Prefix\n")
{
struct rfapi_local_reg_delete_arg cda;
int rc;
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, argv[3], argv[2], NULL, argv[0], argv[1],
- &cda)))
+ parse_deleter_tokens (vty, NULL, argv[9], argv[7], NULL, argv[3], argv[5],
+ NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4263,7 +4387,7 @@ DEFUN (clear_vnc_mac_vn_prefix,
DEFUN (clear_vnc_mac_all_prefix,
clear_vnc_mac_all_prefix_cmd,
- "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) prefix (*|A.B.C.D/M|X:X::X:X/M)",
+ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> prefix <*|A.B.C.D/M|X:X::X:X/M>",
"clear\n"
"VNC Information\n"
"Clear mac registration information\n"
@@ -4282,7 +4406,7 @@ DEFUN (clear_vnc_mac_all_prefix,
/* pfx vn un L2 VNI */
if ((rc =
- parse_deleter_args (vty, argv[2], NULL, NULL, argv[0], argv[1], &cda)))
+ parse_deleter_tokens (vty, NULL, argv[7], NULL, NULL, argv[3], argv[5], NULL, NULL, &cda)))
return rc;
cda.vty = vty;
clear_vnc_prefix (&cda);
@@ -4547,7 +4671,7 @@ DEFUN (vnc_show_nves,
DEFUN (vnc_show_nves_ptct,
vnc_show_nves_ptct_cmd,
- "show vnc nves (vn|un) (A.B.C.D|X:X::X:X)",
+ "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
SHOW_STR
VNC_SHOW_STR
"List known NVEs\n"
@@ -4561,18 +4685,18 @@ DEFUN (vnc_show_nves_ptct,
if (!check_and_display_is_vnc_running (vty))
return CMD_SUCCESS;
- if (!str2prefix (argv[1], &pfx))
+ if (!str2prefix (argv[4]->arg, &pfx))
{
- vty_out (vty, "Malformed address \"%s\"%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "Malformed address \"%s\"%s", argv[4]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
if (pfx.family != AF_INET && pfx.family != AF_INET6)
{
- vty_out (vty, "Invalid address \"%s\"%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "Invalid address \"%s\"%s", argv[4]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
- if (*(argv[0]) == 'u')
+ if (argv[3]->arg[0] == 'u')
{
rfapi_show_nves (vty, NULL, &pfx);
}
@@ -4629,21 +4753,22 @@ rfapi_show_registrations (
DEFUN (vnc_show_registrations_pfx,
vnc_show_registrations_pfx_cmd,
- "show vnc registrations ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
+ "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
SHOW_STR
VNC_SHOW_STR
"List active prefix registrations\n"
- "Limit output to a particular prefix or address\n"
- "Limit output to a particular prefix or address\n")
+ "Limit output to a particular IPv4 prefix\n"
+ "Limit output to a particular IPv6 prefix\n"
+ "Limit output to a particular IPv6 address\n")
{
struct prefix p;
struct prefix *p_addr = NULL;
- if (argc == 1)
+ if (argc > 3)
{
- if (!str2prefix (argv[0], &p))
+ if (!str2prefix (argv[3]->arg, &p))
{
- vty_out (vty, "Invalid prefix: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Invalid prefix: %s%s", argv[3]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
else
@@ -4656,15 +4781,9 @@ DEFUN (vnc_show_registrations_pfx,
return CMD_SUCCESS;
}
-ALIAS (vnc_show_registrations_pfx,
- vnc_show_registrations_cmd,
- "show vnc registrations",
- SHOW_STR
- VNC_SHOW_STR
- "List active prefix registrations\n")
- DEFUN (vnc_show_registrations_some_pfx,
+DEFUN (vnc_show_registrations_some_pfx,
vnc_show_registrations_some_pfx_cmd,
- "show vnc registrations (all|holddown|imported|local|remote) ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
+ "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
SHOW_STR
VNC_SHOW_STR
"List active prefix registrations\n"
@@ -4674,6 +4793,7 @@ ALIAS (vnc_show_registrations_pfx,
"show only local registrations\n"
"show only remote registrations\n"
"Limit output to a particular prefix or address\n"
+ "Limit output to a particular prefix or address\n"
"Limit output to a particular prefix or address\n")
{
struct prefix p;
@@ -4684,11 +4804,11 @@ ALIAS (vnc_show_registrations_pfx,
int show_holddown = 0;
int show_imported = 0;
- if (argc == 2)
+ if (argc > 4)
{
- if (!str2prefix (argv[1], &p))
+ if (!str2prefix (argv[4]->arg, &p))
{
- vty_out (vty, "Invalid prefix: %s%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "Invalid prefix: %s%s", argv[4]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
else
@@ -4696,7 +4816,7 @@ ALIAS (vnc_show_registrations_pfx,
p_addr = &p;
}
}
- switch (*argv[0])
+ switch (argv[3]->arg[0])
{
case 'a':
show_local = 1;
@@ -4728,35 +4848,24 @@ ALIAS (vnc_show_registrations_pfx,
return CMD_SUCCESS;
}
-ALIAS (vnc_show_registrations_some_pfx,
- vnc_show_registrations_some_cmd,
- "show vnc registrations (all|holddown|imported|local|remote)",
+DEFUN (vnc_show_responses_pfx,
+ vnc_show_responses_pfx_cmd,
+ "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
SHOW_STR
VNC_SHOW_STR
- "List active prefix registrations\n"
- "show all registrations\n"
- "show only registrations in holddown\n"
- "show only imported prefixes\n"
- "show only local registrations\n"
- "show only remote registrations\n")
-
-DEFUN (vnc_show_responses_pfx,
- vnc_show_responses_pfx_cmd,
- "show vnc responses ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
- SHOW_STR
- VNC_SHOW_STR
- "List recent query responses\n"
- "Limit output to a particular prefix or address\n"
- "Limit output to a particular prefix or address\n")
+ "List recent query responses\n"
+ "Limit output to a particular IPv4 prefix\n"
+ "Limit output to a particular IPv6 prefix\n"
+ "Limit output to a particular IPv6 address\n" )
{
struct prefix p;
struct prefix *p_addr = NULL;
- if (argc == 1)
+ if (argc > 3)
{
- if (!str2prefix (argv[0], &p))
+ if (!str2prefix (argv[3]->arg, &p))
{
- vty_out (vty, "Invalid prefix: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Invalid prefix: %s%s", argv[3]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
else
@@ -4774,23 +4883,17 @@ DEFUN (vnc_show_responses_pfx,
return CMD_SUCCESS;
}
-ALIAS (vnc_show_responses_pfx,
- vnc_show_responses_cmd,
- "show vnc responses",
+DEFUN (vnc_show_responses_some_pfx,
+ vnc_show_responses_some_pfx_cmd,
+ "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
SHOW_STR
VNC_SHOW_STR
- "List recent query responses\n")
-
-DEFUN (vnc_show_responses_some_pfx,
- vnc_show_responses_some_pfx_cmd,
- "show vnc responses (active|removed) ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
- SHOW_STR
- VNC_SHOW_STR
- "List recent query responses\n"
- "show only active query responses\n"
- "show only removed query responses\n"
- "Limit output to a particular prefix or address\n"
- "Limit output to a particular prefix or address\n")
+ "List recent query responses\n"
+ "show only active query responses\n"
+ "show only removed query responses\n"
+ "Limit output to a particular IPv4 prefix\n"
+ "Limit output to a particular IPv6 prefix\n"
+ "Limit output to a particular IPV6 address\n")
{
struct prefix p;
struct prefix *p_addr = NULL;
@@ -4801,11 +4904,11 @@ DEFUN (vnc_show_responses_some_pfx,
if (!check_and_display_is_vnc_running (vty))
return CMD_SUCCESS;
- if (argc == 2)
+ if (argc > 4)
{
- if (!str2prefix (argv[1], &p))
+ if (!str2prefix (argv[4]->arg, &p))
{
- vty_out (vty, "Invalid prefix: %s%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "Invalid prefix: %s%s", argv[4]->arg, VTY_NEWLINE);
return CMD_SUCCESS;
}
else
@@ -4814,7 +4917,7 @@ DEFUN (vnc_show_responses_some_pfx,
}
}
- switch (*argv[0])
+ switch (argv[3]->arg[0])
{
case 'a':
show_active = 1;
@@ -4837,32 +4940,24 @@ DEFUN (vnc_show_responses_some_pfx,
return CMD_SUCCESS;
}
-ALIAS (vnc_show_responses_some_pfx,
- vnc_show_responses_some_cmd,
- "show vnc responses (active|removed)",
- SHOW_STR
- VNC_SHOW_STR
- "List recent query responses\n"
- "show only active query responses\n"
- "show only removed query responses\n")
-
DEFUN (show_vnc_queries_pfx,
show_vnc_queries_pfx_cmd,
- "show vnc queries ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
+ "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
SHOW_STR
VNC_SHOW_STR
"List active queries\n"
"Limit output to a particular IPv4 prefix or address\n"
- "Limit output to a particular IPv6 prefix or address\n")
+ "Limit output to a particular IPv6 prefix\n"
+ "Limit output to a particualr IPV6 address\n")
{
struct prefix pfx;
struct prefix *p = NULL;
- if (argc == 1)
+ if (argc > 3)
{
- if (!str2prefix (argv[0], &pfx))
+ if (!str2prefix (argv[3]->arg, &pfx))
{
- vty_out (vty, "Invalid prefix: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Invalid prefix: %s%s", argv[3]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
p = &pfx;
@@ -4873,13 +4968,6 @@ DEFUN (show_vnc_queries_pfx,
return rfapiShowVncQueries (vty, p);
}
-ALIAS (show_vnc_queries_pfx,
- show_vnc_queries_cmd,
- "show vnc queries",
- SHOW_STR
- VNC_SHOW_STR
- "List active queries\n")
-
DEFUN (vnc_clear_counters,
vnc_clear_counters_cmd,
"clear vnc counters",
@@ -4926,6 +5014,361 @@ notcfg:
return CMD_WARNING;
}
+/************************************************************************
+ * Add prefix with vrf
+ *
+ * add [vrf <vrf-name>] prefix <prefix>
+ * [rd <value>] [label <value>] [local-preference <0-4294967295>]
+ ************************************************************************/
+static int
+vnc_add_vrf_prefix (struct vty *vty,
+ const char *arg_vrf,
+ const char *arg_prefix,
+ const char *arg_rd, /* optional */
+ const char *arg_label, /* optional */
+ const char *arg_pref) /* optional */
+{
+ struct bgp *bgp;
+ struct rfapi_nve_group_cfg *rfg;
+ struct prefix pfx;
+ struct rfapi_ip_prefix rpfx;
+ uint32_t pref = 0;
+ struct rfapi_vn_option optary[3];
+ struct rfapi_vn_option *opt = NULL;
+ int cur_opt = 0;
+
+ bgp = bgp_get_default (); /* assume main instance for now */
+ if (!bgp)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (!bgp->rfapi || !bgp->rfapi_cfg)
+ {
+ vty_out (vty, "VRF support not configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ rfg = bgp_rfapi_cfg_match_byname (bgp, arg_vrf, RFAPI_GROUP_CFG_VRF);
+ /* arg checks */
+ if (!rfg)
+ {
+ vty_out (vty, "VRF \"%s\" appears not to be configured.%s",
+ arg_vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (!rfg->rt_export_list || !rfg->rfapi_import_table)
+ {
+ vty_out (vty, "VRF \"%s\" is missing RT import/export RT configuration.%s",
+ arg_vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (!rfg->rd.family && !arg_rd)
+ {
+ vty_out (vty, "VRF \"%s\" isn't configured with an RD, so RD must be provided.%s",
+ arg_vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (rfg->label > MPLS_LABEL_MAX && !arg_label)
+ {
+ vty_out (vty, "VRF \"%s\" isn't configured with a default labels, so a label must be provided.%s",
+ arg_vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (!str2prefix (arg_prefix, &pfx))
+ {
+ vty_out (vty, "Malformed prefix \"%s\"%s",
+ arg_prefix, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ rfapiQprefix2Rprefix (&pfx, &rpfx);
+ memset (optary, 0, sizeof (optary));
+ if (arg_rd)
+ {
+ if (opt != NULL)
+ opt->next = &optary[cur_opt];
+ opt = &optary[cur_opt++];
+ opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
+ if (!str2prefix_rd (arg_rd, &opt->v.internal_rd))
+ {
+ vty_out (vty, "Malformed RD \"%s\"%s",
+ arg_rd, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ if (rfg->label <= MPLS_LABEL_MAX || arg_label)
+ {
+ struct rfapi_l2address_option *l2o;
+ if (opt != NULL)
+ opt->next = &optary[cur_opt];
+ opt = &optary[cur_opt++];
+ opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
+ l2o = &opt->v.l2addr;
+ if (arg_label)
+ {
+ int32_t label;
+ VTY_GET_INTEGER_RANGE ("Label value", label, arg_label, 0, MPLS_LABEL_MAX);
+ l2o->label = label;
+ }
+ else
+ l2o->label = rfg->label;
+ }
+ if (arg_pref)
+ {
+ char *endptr = NULL;
+ pref = strtoul (arg_pref, &endptr, 10);
+ if (*endptr != '\0')
+ {
+ vty_out (vty, "%% Invalid local-preference value \"%s\"%s", arg_pref, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ rpfx.cost = 255 - (pref & 255) ;
+ if (rfg->rfd == NULL) /* need new rfapi_handle */
+ {
+ /* based on rfapi_open */
+ struct rfapi_descriptor *rfd;
+ rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor));
+ rfd->bgp = bgp;
+ rfg->rfd = rfd;
+ /* leave most fields empty as will get from (dynamic) config when needed */
+ rfd->default_tunneltype_option.type = BGP_ENCAP_TYPE_MPLS;
+ rfd->cookie = rfg;
+ if (rfg->vn_prefix.family &&
+ !CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF))
+ {
+ rfapiQprefix2Raddr(&rfg->vn_prefix, &rfd->vn_addr);
+ }
+ else
+ {
+ memset(&rfd->vn_addr, 0, sizeof(struct rfapi_ip_addr));
+ rfd->vn_addr.addr_family = AF_INET;
+ rfd->vn_addr.addr.v4 = bgp->router_id;
+ }
+ rfd->un_addr = rfd->vn_addr; /* sigh, need something in UN for lookups */
+ vnc_zlog_debug_verbose ("%s: Opening RFD for VRF %s",
+ __func__, rfg->name);
+ rfapi_init_and_open(bgp, rfd, rfg);
+ }
+
+ if (!rfapi_register (rfg->rfd, &rpfx, RFAPI_INFINITE_LIFETIME, NULL,
+ (cur_opt ? optary : NULL), RFAPI_REGISTER_ADD))
+ {
+ struct rfapi_next_hop_entry *head = NULL;
+ struct rfapi_next_hop_entry *tail = NULL;
+ struct rfapi_vn_option *vn_opt_new;
+
+ vnc_zlog_debug_verbose ("%s: rfapi_register succeeded", __func__);
+
+ if (bgp->rfapi->rfp_methods.local_cb)
+ {
+ struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfg->rfd;
+ vn_opt_new = rfapi_vn_options_dup (opt);
+
+ rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx,
+ 1, RFAPI_INFINITE_LIFETIME,
+ vn_opt_new, &head, &tail);
+ if (head)
+ {
+ bgp->rfapi->flags |= RFAPI_INCALLBACK;
+ (*bgp->rfapi->rfp_methods.local_cb) (head, r->cookie);
+ bgp->rfapi->flags &= ~RFAPI_INCALLBACK;
+ }
+ head = tail = NULL;
+ }
+ vnc_zlog_debug_verbose ("%s completed, count=%d/%d", __func__,
+ rfg->rfapi_import_table->local_count[AFI_IP],
+ rfg->rfapi_import_table->local_count[AFI_IP6]);
+ return CMD_SUCCESS;
+ }
+
+ vnc_zlog_debug_verbose ("%s: rfapi_register failed", __func__);
+ vty_out (vty, "Add failed.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+}
+
+DEFUN (add_vrf_prefix_rd_label_pref,
+ add_vrf_prefix_rd_label_pref_cmd,
+ "add vrf NAME prefix <A.B.C.D/M|X:X::X:X/M> [{rd ASN:nn_or_IP-address|label (0-1048575)|preference (0-4294967295)}]",
+ "Add\n"
+ "To a VRF\n"
+ "VRF name\n"
+ "Add/modify prefix related information\n"
+ "IPv4 prefix\n"
+ "IPv6 prefix\n"
+ "Override configured VRF Route Distinguisher\n"
+ "<as-number>:<number> or <ip-address>:<number>\n"
+ "Override configured VRF label\n"
+ "Label Value <0-1048575>\n"
+ "Set advertised local preference\n"
+ "local preference (higher=more preferred)\n")
+{
+ char *arg_vrf = argv[2]->arg;
+ char *arg_prefix = argv[4]->arg;
+ char *arg_rd = NULL; /* optional */
+ char *arg_label = NULL; /* optional */
+ char *arg_pref = NULL; /* optional */
+ int pargc = 5;
+ argc--; /* don't parse argument */
+ while (pargc < argc)
+ {
+ switch (argv[pargc++]->arg[0])
+ {
+ case 'r':
+ arg_rd = argv[pargc]->arg;
+ break;
+ case 'l':
+ arg_label = argv[pargc]->arg;
+ break;
+ case 'p':
+ arg_pref = argv[pargc]->arg;
+ break;
+ default:
+ break;
+ }
+ pargc ++;
+ }
+
+ return vnc_add_vrf_prefix (vty, arg_vrf, arg_prefix, arg_rd, arg_label, arg_pref);
+}
+
+/************************************************************************
+ * del prefix with vrf
+ *
+ * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
+ ************************************************************************/
+static int
+rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg)
+{
+ int count = 0;
+ afi_t afi = AFI_MAX;
+ while (afi-- > 0)
+ {
+ count += rfg->rfapi_import_table->local_count[afi];
+ }
+ return count;
+}
+
+static void
+clear_vnc_vrf_closer (struct rfapi_nve_group_cfg *rfg)
+{
+ struct rfapi_descriptor *rfd = rfg->rfd;
+ afi_t afi;
+
+ if (rfd == NULL)
+ return;
+ /* check if IT is empty */
+ for (afi = 0;
+ afi < AFI_MAX && rfg->rfapi_import_table->local_count[afi] == 0;
+ afi++);
+
+ if (afi == AFI_MAX)
+ {
+ vnc_zlog_debug_verbose ("%s: closing RFD for VRF %s",
+ __func__, rfg->name);
+ rfg->rfd = NULL;
+ rfapi_close(rfd);
+ }
+ else
+ {
+ vnc_zlog_debug_verbose ("%s: VRF %s afi=%d count=%d",
+ __func__, rfg->name, afi,
+ rfg->rfapi_import_table->local_count[afi]);
+ }
+}
+
+static int
+vnc_clear_vrf (struct vty *vty,
+ struct bgp *bgp,
+ const char *arg_vrf,
+ const char *arg_prefix, /* NULL = all */
+ const char *arg_rd) /* optional */
+{
+ struct rfapi_nve_group_cfg *rfg;
+ struct rfapi_local_reg_delete_arg cda;
+ int rc;
+ int start_count;
+
+ if (bgp == NULL)
+ bgp = bgp_get_default (); /* assume main instance for now */
+ if (!bgp)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (!bgp->rfapi || !bgp->rfapi_cfg)
+ {
+ vty_out (vty, "VRF support not configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ rfg = bgp_rfapi_cfg_match_byname (bgp, arg_vrf, RFAPI_GROUP_CFG_VRF);
+ /* arg checks */
+ if (!rfg)
+ {
+ vty_out (vty, "VRF \"%s\" appears not to be configured.%s",
+ arg_vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ rc = parse_deleter_args (vty, bgp, arg_prefix, NULL, NULL, NULL, NULL,
+ arg_rd, rfg, &cda);
+ if (rc != CMD_SUCCESS) /* parse error */
+ return rc;
+
+ start_count = rfapi_cfg_group_it_count(rfg);
+ clear_vnc_prefix (&cda);
+ clear_vnc_vrf_closer (rfg);
+ vty_out (vty, "Cleared %u out of %d prefixes.%s",
+ cda.pfx_count, start_count, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+DEFUN (clear_vrf_prefix_rd,
+ clear_vrf_prefix_rd_cmd,
+ "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:nn_or_IP-address]",
+ "Clear stored data\n"
+ "From a VRF\n"
+ "VRF name\n"
+ "Prefix related information\n"
+ "IPv4 prefix\n"
+ "IPv6 prefix\n"
+ "Specific VRF Route Distinguisher\n"
+ "<as-number>:<number> or <ip-address>:<number>\n")
+{
+ char *arg_vrf = argv[2]->arg;
+ char *arg_prefix = NULL; /* optional */
+ char *arg_rd = NULL; /* optional */
+ int pargc = 3;
+ argc--; /* don't check parameter */
+ while (pargc < argc)
+ {
+ switch (argv[pargc++]->arg[0])
+ {
+ case 'r':
+ arg_rd = argv[pargc]->arg;
+ break;
+ case 'p':
+ arg_prefix = argv[pargc]->arg;
+ break;
+ default:
+ break;
+ }
+ pargc ++;
+ }
+ return vnc_clear_vrf (vty, NULL, arg_vrf, arg_prefix, arg_rd);
+}
+
+DEFUN (clear_vrf_all,
+ clear_vrf_all_cmd,
+ "clear vrf NAME all",
+ "Clear stored data\n"
+ "From a VRF\n"
+ "VRF name\n"
+ "All prefixes\n")
+{
+ char *arg_vrf = argv[2]->arg;
+ return vnc_clear_vrf (vty, NULL, arg_vrf, NULL, NULL);
+}
+
void rfapi_vty_init ()
{
install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd);
@@ -4949,6 +5392,8 @@ void rfapi_vty_init ()
install_element (ENABLE_NODE, &add_vnc_mac_vni_life_cmd);
install_element (ENABLE_NODE, &add_vnc_mac_vni_cmd);
+ install_element (ENABLE_NODE, &add_vrf_prefix_rd_label_pref_cmd);
+
install_element (ENABLE_NODE, &clear_vnc_nve_all_cmd);
install_element (ENABLE_NODE, &clear_vnc_nve_vn_un_cmd);
install_element (ENABLE_NODE, &clear_vnc_nve_un_vn_cmd);
@@ -4973,24 +5418,18 @@ void rfapi_vty_init ()
install_element (ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd);
install_element (ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd);
+ install_element (ENABLE_NODE, &clear_vrf_prefix_rd_cmd);
+ install_element (ENABLE_NODE, &clear_vrf_all_cmd);
+
install_element (ENABLE_NODE, &vnc_clear_counters_cmd);
install_element (VIEW_NODE, &vnc_show_summary_cmd);
install_element (VIEW_NODE, &vnc_show_nves_cmd);
install_element (VIEW_NODE, &vnc_show_nves_ptct_cmd);
- install_element (VIEW_NODE, &vnc_show_registrations_cmd);
install_element (VIEW_NODE, &vnc_show_registrations_pfx_cmd);
-
- install_element (VIEW_NODE, &vnc_show_registrations_some_cmd);
install_element (VIEW_NODE, &vnc_show_registrations_some_pfx_cmd);
-
- install_element (VIEW_NODE, &vnc_show_responses_cmd);
install_element (VIEW_NODE, &vnc_show_responses_pfx_cmd);
-
- install_element (VIEW_NODE, &vnc_show_responses_some_cmd);
install_element (VIEW_NODE, &vnc_show_responses_some_pfx_cmd);
-
- install_element (VIEW_NODE, &show_vnc_queries_cmd);
install_element (VIEW_NODE, &show_vnc_queries_pfx_cmd);
}
diff --git a/bgpd/rfapi/vnc_debug.c b/bgpd/rfapi/vnc_debug.c
index 4d91f38dcb..b5ff5bbc88 100644
--- a/bgpd/rfapi/vnc_debug.c
+++ b/bgpd/rfapi/vnc_debug.c
@@ -35,19 +35,19 @@ unsigned long conf_vnc_debug;
unsigned long term_vnc_debug;
struct vnc_debug {
- unsigned long bit;
- const char *name;
+ unsigned long bit;
+ const char *name;
};
struct vnc_debug vncdebug[] =
{
- {VNC_DEBUG_RFAPI_QUERY, "rfapi-query"},
- {VNC_DEBUG_IMPORT_BI_ATTACH, "import-bi-attach"},
- {VNC_DEBUG_IMPORT_DEL_REMOTE, "import-del-remote"},
- {VNC_DEBUG_EXPORT_BGP_GETCE, "export-bgp-getce"},
- {VNC_DEBUG_EXPORT_BGP_DIRECT_ADD, "export-bgp-direct-add"},
- {VNC_DEBUG_IMPORT_BGP_ADD_ROUTE, "import-bgp-add-route"},
- {VNC_DEBUG_VERBOSE, "verbose"},
+ {VNC_DEBUG_RFAPI_QUERY, "rfapi-query"},
+ {VNC_DEBUG_IMPORT_BI_ATTACH, "import-bi-attach"},
+ {VNC_DEBUG_IMPORT_DEL_REMOTE, "import-del-remote"},
+ {VNC_DEBUG_EXPORT_BGP_GETCE, "export-bgp-getce"},
+ {VNC_DEBUG_EXPORT_BGP_DIRECT_ADD, "export-bgp-direct-add"},
+ {VNC_DEBUG_IMPORT_BGP_ADD_ROUTE, "import-bgp-add-route"},
+ {VNC_DEBUG_VERBOSE, "verbose"},
};
#define VNC_STR "VNC information\n"
@@ -57,7 +57,7 @@ struct vnc_debug vncdebug[] =
***********************************************************************/
DEFUN (debug_bgp_vnc,
debug_bgp_vnc_cmd,
- "debug bgp vnc (rfapi-query|import-bi-attach|import-del-remote|verbose)",
+ "debug bgp vnc <rfapi-query|import-bi-attach|import-del-remote|verbose>",
DEBUG_STR
BGP_STR
VNC_STR
@@ -70,7 +70,7 @@ DEFUN (debug_bgp_vnc,
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
{
- if (!strcmp(argv[0], vncdebug[i].name))
+ if (!strcmp(argv[3]->arg, vncdebug[i].name))
{
if (vty->node == CONFIG_NODE)
{
@@ -86,15 +86,16 @@ DEFUN (debug_bgp_vnc,
return CMD_SUCCESS;
}
}
- vty_out (vty, "Unknown debug flag: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Unknown debug flag: %s%s", argv[3]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
DEFUN (no_debug_bgp_vnc,
no_debug_bgp_vnc_cmd,
- "no debug bgp vnc (rfapi-query|import-bi-attach|import-del-remote|verbose)",
+ "<no debug|undebug> bgp vnc <rfapi-query|import-bi-attach|import-del-remote|verbose>",
NO_STR
DEBUG_STR
+ "Undebug\n"
BGP_STR
VNC_STR
"rfapi query handling\n"
@@ -104,9 +105,11 @@ DEFUN (no_debug_bgp_vnc,
{
size_t i;
+ if (!strcmp(argv[0]->arg, "no"))
+ argc--, argv++;
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
{
- if (!strcmp(argv[0], vncdebug[i].name))
+ if (!strcmp(argv[3]->arg, vncdebug[i].name))
{
if (vty->node == CONFIG_NODE)
{
@@ -122,21 +125,10 @@ DEFUN (no_debug_bgp_vnc,
return CMD_SUCCESS;
}
}
- vty_out (vty, "Unknown debug flag: %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Unknown debug flag: %s%s", argv[3]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
-ALIAS (no_debug_bgp_vnc,
- undebug_bgp_vnc_cmd,
- "undebug bgp vnc (rfapi-query|import-bi-attach|import-del-remote|verbose)",
- UNDEBUG_STR
- BGP_STR
- VNC_STR
- "rfapi query handling\n"
- "import BI atachment\n"
- "import delete remote routes\n"
- "verbose logging\n")
-
/***********************************************************************
* no debug bgp vnc all
@@ -144,9 +136,10 @@ ALIAS (no_debug_bgp_vnc,
DEFUN (no_debug_bgp_vnc_all,
no_debug_bgp_vnc_all_cmd,
- "no debug all bgp vnc",
+ "<no debug|undebug> all bgp vnc",
NO_STR
DEBUG_STR
+ "Undebug command\n"
"Disable all VNC debugging\n"
BGP_STR
VNC_STR)
@@ -157,14 +150,6 @@ DEFUN (no_debug_bgp_vnc_all,
return CMD_SUCCESS;
}
-ALIAS (no_debug_bgp_vnc_all,
- undebug_bgp_vnc_all_cmd,
- "undebug all bgp vnc",
- UNDEBUG_STR
- "Disable all VNC debugging\n"
- BGP_STR
- VNC_STR)
-
/***********************************************************************
* show/save
***********************************************************************/
@@ -226,8 +211,6 @@ vnc_debug_init (void)
install_element (ENABLE_NODE, &debug_bgp_vnc_cmd);
install_element (CONFIG_NODE, &debug_bgp_vnc_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_vnc_cmd);
- install_element (ENABLE_NODE, &undebug_bgp_vnc_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_vnc_all_cmd);
- install_element (ENABLE_NODE, &undebug_bgp_vnc_all_cmd);
}
diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c
index d5ca965465..10246758f3 100644
--- a/bgpd/rfapi/vnc_import_bgp.c
+++ b/bgpd/rfapi/vnc_import_bgp.c
@@ -37,6 +37,7 @@
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_route.h"
#include "bgpd/bgp_mplsvpn.h" /* for RD_TYPE_IP */
#include "bgpd/rfapi/vnc_export_bgp.h"
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index 608bc6d3c7..23b6e9dbb4 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -433,7 +433,7 @@ vnc_zebra_read_ipv6 (
struct stream *s;
struct zapi_ipv6 api;
struct in6_addr nexthop;
- struct prefix_ipv6 p;
+ struct prefix_ipv6 p, src_p;
s = zclient->ibuf;
memset (&nexthop, 0, sizeof (struct in6_addr));
@@ -449,6 +449,18 @@ vnc_zebra_read_ipv6 (
p.prefixlen = stream_getc (s);
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
+ {
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ }
+
+ if (src_p.prefixlen)
+ /* we completely ignore srcdest routes for now. */
+ return 0;
+
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
@@ -534,6 +546,7 @@ vnc_zebra_route_msg (
api.nexthop_num = nhp_count;
api.nexthop = nhp_ary;
api.ifindex_num = 0;
+ api.instance = 0;
if (BGP_DEBUG (zebra, ZEBRA))
{
@@ -568,6 +581,7 @@ vnc_zebra_route_msg (
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
api.ifindex_num = 1;
api.ifindex = &ifindex;
+ api.instance = 0;
if (BGP_DEBUG (zebra, ZEBRA))
{
@@ -582,7 +596,7 @@ vnc_zebra_route_msg (
zapi_ipv6_route ((add ? ZEBRA_IPV6_NEXTHOP_ADD :
ZEBRA_IPV6_NEXTHOP_DELETE), zclient_vnc,
- (struct prefix_ipv6 *) p, &api);
+ (struct prefix_ipv6 *) p, NULL, &api);
}
else
{
diff --git a/bgpd/rfp-example/librfp/rfp_example.c b/bgpd/rfp-example/librfp/rfp_example.c
index e8b546ddf4..d4100c096f 100644
--- a/bgpd/rfp-example/librfp/rfp_example.c
+++ b/bgpd/rfp-example/librfp/rfp_example.c
@@ -41,14 +41,16 @@ struct rfp_instance_t global_rfi; /* dynamically allocate in full implemen
DEFUN (rfp_example_config_value,
rfp_example_config_value_cmd,
"rfp example-config-value VALUE",
- RFP_SHOW_STR "Example value to be configured\n")
+ RFP_SHOW_STR
+ "Example value to be configured\n"
+ "Value to display")
{
uint32_t value = 0;
struct rfp_instance_t *rfi = NULL;
- rfi = rfapi_get_rfp_start_val (vty->index); /* index=bgp for BGP_NODE */
+ rfi = rfapi_get_rfp_start_val (VTY_GET_CONTEXT (bgp)); /* BGP_NODE */
assert (rfi != NULL);
- VTY_GET_INTEGER ("Example value", value, argv[0]);
+ VTY_GET_INTEGER ("Example value", value, argv[2]->arg);
if (rfi)
rfi->config_var = value;
return CMD_SUCCESS;
diff --git a/configure.ac b/configure.ac
index cd88e30c78..1436b2fc7c 100755
--- a/configure.ac
+++ b/configure.ac
@@ -7,7 +7,7 @@
##
AC_PREREQ(2.60)
-AC_INIT(frr, 2.0-rc1, [https://github.com/freerangerouting/frr/issues])
+AC_INIT(frr, 2.1-dev, [https://github.com/freerangerouting/frr/issues])
PACKAGE_URL="https://freerangerouting.org/"
PACKAGE_FULLNAME="FreeRangeRouting"
AC_SUBST(PACKAGE_FULLNAME)
@@ -27,12 +27,13 @@ AC_CANONICAL_TARGET()
# Disable portability warnings -- our automake code (in particular
# common.am) uses some constructs specific to gmake.
-AM_INIT_AUTOMAKE([1.6 -Wno-portability])
+AM_INIT_AUTOMAKE([1.12 -Wno-portability])
m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])])
AM_SILENT_RULES([yes])
AC_CONFIG_HEADERS(config.h)
AC_PATH_PROG(PERL, perl)
+PKG_PROG_PKG_CONFIG
dnl default is to match previous behavior
exampledir=${sysconfdir}
@@ -282,6 +283,8 @@ AC_ARG_ENABLE(rr-semantics,
AS_HELP_STRING([--disable-rr-semantics], [disable the v6 Route Replace semantics]))
AC_ARG_ENABLE([protobuf],
AS_HELP_STRING([--enable-protobuf], [Enable experimental protobuf support]))
+AC_ARG_ENABLE([oldvpn_commands],
+ AS_HELP_STRING([--enable-old-vpn-commands], [Keep old vpn commands]))
AC_CHECK_HEADERS(json-c/json.h)
AC_CHECK_LIB(json-c, json_object_get, LIBS="$LIBS -ljson-c")
@@ -387,6 +390,13 @@ if test "$enable_protobuf" = "yes"; then
fi
fi
+#
+# Logic for old vpn commans support.
+#
+if test "$enable_old_vpn_commands" = "yes"; then
+ AC_DEFINE(KEEP_OLD_VPN_COMMANDS,, [Define for compiling with old vpn commands])
+fi
+
# Fail if the user explicity enabled protobuf support and we couldn't
# find the compiler or libraries.
if test "x$have_protobuf" = "xno" && test "x$enable_protobuf" = "xyes"; then
@@ -780,7 +790,6 @@ AC_CHECK_HEADER([math.h],
[AC_CHECK_LIB([m], [pow],
[LIBM="-lm"
LIBS="$LIBS $LIBM"
- AC_DEFINE(HAVE_LIBM,, Have libm)
AC_CHECK_FUNCS(pow,[],[LIBM=""])
])
])
@@ -1098,9 +1107,6 @@ dnl ----------
AC_MSG_ERROR([Failed to detect IPv6 stack])
fi
-dnl this is unconditial, for compatibility
-AC_DEFINE(HAVE_IPV6,1,IPv6)
-
dnl ------------------
dnl IPv6 header checks
dnl ------------------
@@ -1163,11 +1169,19 @@ else
fi
AM_CONDITIONAL(OSPFD, test "x$OSPFD" = "xospfd")
-if test "${enable_ldpd}" = "yes";then
+if test "${enable_ldpd}" = "no";then
+ LDPD=""
+else
+ AX_PROG_PERL_MODULES(XML::LibXML, , [
+ if test -f "${srcdir}/ldpd/ldp_vty_cmds.c"; then
+ AC_MSG_WARN([XML::LibXML perl module not found, using pregenerated ldp_vty_cmds.c])
+ else
+ AC_MSG_ERROR([XML::LibXML perl module not found and pregenerated ldp_vty_cmds.c missing])
+ fi
+ ])
+
LDPD="ldpd"
AC_DEFINE(HAVE_LDPD, 1, ldpd)
-else
- LDPD=""
fi
AM_CONDITIONAL(LDPD, test "x$LDPD" = "xldpd")
@@ -1416,6 +1430,69 @@ AC_CHECK_DECL(CLOCK_MONOTONIC,
AC_DEFINE(HAVE_CLOCK_MONOTONIC,, Have monotonic clock)
], [AC_MSG_RESULT(no)], [FRR_INCLUDES])
+dnl --------------------------------------
+dnl checking for flex and bison
+dnl --------------------------------------
+
+AM_PROG_LEX
+AC_MSG_CHECKING(version of flex)
+quagga_ac_flex_version="$(eval $LEX -V | grep flex | head -n 1)"
+quagga_ac_flex_version="${quagga_ac_flex_version##* }"
+AC_MSG_RESULT([$quagga_ac_flex_version])
+AX_COMPARE_VERSION([$quagga_ac_flex_version], [lt], [2.5.20], [
+ LEX="$SHELL $missing_dir/missing flex"
+ if test -f "${srcdir}/lib/command_lex.c" -a -f "${srcdir}/lib/command_lex.h"; then
+ AC_MSG_WARN([using pregenerated flex output files])
+ else
+ AC_MSG_ERROR([flex failure and pregenerated files not included (probably a git build)])
+ fi
+ AC_SUBST([LEX_OUTPUT_ROOT], [lex.yy])
+ AC_SUBST([LEXLIB], [''])
+])
+
+AC_PROG_YACC
+dnl thanks GNU bison for this b*llshit...
+AC_MSG_CHECKING(version of bison)
+quagga_ac_bison_version="$(eval $YACC -V | grep bison | head -n 1)"
+quagga_ac_bison_version="${quagga_ac_bison_version##* }"
+quagga_ac_bison_missing="false"
+case "x${quagga_ac_bison_version}" in
+ x2.7*)
+ BISON_OPENBRACE='"'
+ BISON_CLOSEBRACE='"'
+ BISON_VERBOSE=''
+ AC_MSG_RESULT([$quagga_ac_bison_version - 2.7 or older])
+ ;;
+ x2.*|x1.*)
+ AC_MSG_RESULT([$quagga_ac_bison_version])
+ AC_MSG_WARN([installed bison is too old. Please install GNU bison 2.7.x or newer.])
+ quagga_ac_bison_missing="true"
+ ;;
+ x)
+ AC_MSG_RESULT([none])
+ AC_MSG_WARN([could not determine bison version. Please install GNU bison 2.7.x or newer.])
+ quagga_ac_bison_missing="true"
+ ;;
+ *)
+ BISON_OPENBRACE='{'
+ BISON_CLOSEBRACE='}'
+ BISON_VERBOSE='-Dparse.error=verbose'
+ AC_MSG_RESULT([$quagga_ac_bison_version - 3.0 or newer])
+ ;;
+esac
+AC_SUBST(BISON_OPENBRACE)
+AC_SUBST(BISON_CLOSEBRACE)
+AC_SUBST(BISON_VERBOSE)
+
+if $quagga_ac_bison_missing; then
+ YACC="$SHELL $missing_dir/missing bison -y"
+ if test -f "${srcdir}/lib/command_parse.c" -a -f "${srcdir}/lib/command_parse.h"; then
+ AC_MSG_WARN([using pregenerated bison output files])
+ else
+ AC_MSG_ERROR([bison failure and pregenerated files not included (probably a git build)])
+ fi
+fi
+
dnl -------------------
dnl capabilities checks
dnl -------------------
@@ -1497,18 +1574,6 @@ dnl ----------
CONFDATE=`date '+%Y%m%d'`
AC_SUBST(CONFDATE)
-dnl -------
-dnl DejaGNU
-dnl -------
-if test x"$DEJAGNU" = x
-then
- DEJAGNU="\$(top_srcdir)/tests/global-conf.exp"
-fi
-RUNTESTDEFAULTFLAGS="-x --tool \$\$tool"
-
-AC_SUBST(DEJAGNU)
-AC_SUBST(RUNTESTDEFAULTFLAGS)
-
dnl ------------------------------
dnl set paths for state directory
dnl ------------------------------
@@ -1610,8 +1675,6 @@ AC_CONFIG_FILES([Makefile lib/Makefile qpb/Makefile zebra/Makefile ripd/Makefile
ospf6d/Makefile ldpd/Makefile isisd/Makefile vtysh/Makefile
doc/Makefile ospfclient/Makefile tests/Makefile m4/Makefile
pimd/Makefile
- tests/bgpd.tests/Makefile
- tests/libfrr.tests/Makefile
redhat/Makefile
tools/Makefile
cumulus/Makefile
diff --git a/cumulus/start-stop-daemon.c b/cumulus/start-stop-daemon.c
index 4d447d9051..c123f87e92 100644
--- a/cumulus/start-stop-daemon.c
+++ b/cumulus/start-stop-daemon.c
@@ -51,7 +51,7 @@
#include <grp.h>
#include <sys/ioctl.h>
#include <sys/types.h>
-#include <sys/termios.h>
+#include <termios.h>
#include <fcntl.h>
#include <limits.h>
#include <assert.h>
@@ -223,6 +223,7 @@ clear(struct pid_list **list)
*list = NULL;
}
+#ifdef linux
static const char *
next_dirname(const char *s)
{
@@ -242,7 +243,6 @@ next_dirname(const char *s)
return cur;
}
-#ifdef linux
static void
add_namespace(const char *path)
{
diff --git a/debian/changelog b/debian/changelog
index e4635baa5d..8302af4b4c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-frr (2.0) Released; urgency=medium
+frr (2.1) Released; urgency=medium
* Switchover to FRR
diff --git a/debian/control b/debian/control
index 578795d998..ac9298425f 100644
--- a/debian/control
+++ b/debian/control
@@ -3,7 +3,7 @@ Section: net
Priority: optional
Maintainer: Christian Hammers <ch@debian.org>
Uploaders: Florian Weimer <fw@debian.org>
-Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, po-debconf, autotools-dev, hardening-wrapper, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson0, libjson0-dev, dh-systemd, libsystemd-dev, python-ipaddr
+Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, po-debconf, autotools-dev, hardening-wrapper, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson0, libjson0-dev, dh-systemd, libsystemd-dev, python-ipaddr, bison, flex
Standards-Version: 3.9.6
Homepage: http://www.frr.net/
XS-Testsuite: autopkgtest
diff --git a/doc/main.texi b/doc/main.texi
index 2e50457628..dfe02e1b5d 100644
--- a/doc/main.texi
+++ b/doc/main.texi
@@ -239,6 +239,16 @@ Routing entry for 10.0.0.0/8
These behave similarly to their ipv4 counterparts.
@end deffn
+@deffn Command {ipv6 route @var{network} from @var{srcprefix} @var{gateway}} {}
+@deffnx Command {ipv6 route @var{network} from @var{srcprefix} @var{gateway} @var{distance}} {}
+Install a static source-specific route. These routes are currently supported
+on Linux operating systems only, and perform AND matching on packet's
+destination and source addresses in the kernel's forwarding path. Note that
+destination longest-prefix match is "more important" than source LPM, e.g.
+@command{"2001:db8:1::/64 from 2001:db8::/48"} will win over
+@command{"2001:db8::/48 from 2001:db8:1::/64"} if both match.
+@end deffn
+
@deffn Command {table @var{tableno}} {}
Select the primary kernel routing table to be used. This only works
diff --git a/isisd/Makefile.am b/isisd/Makefile.am
index 334107a2a0..c97385f87a 100644
--- a/isisd/Makefile.am
+++ b/isisd/Makefile.am
@@ -1,7 +1,6 @@
## Process this file with automake to produce Makefile.in.
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \
- -DVTY_DEPRECATE_INDEX
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
LIBS = @LIBS@
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index 7f8e8deccc..f550924874 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -145,10 +145,8 @@ isis_delete_adj (void *arg)
list_delete (adj->area_addrs);
if (adj->ipv4_addrs)
list_delete (adj->ipv4_addrs);
-#ifdef HAVE_IPV6
if (adj->ipv6_addrs)
list_delete (adj->ipv6_addrs);
-#endif
XFREE (MTYPE_ISIS_ADJACENCY, adj);
return;
@@ -301,10 +299,8 @@ isis_adj_print (struct isis_adjacency *adj)
struct isis_dynhn *dyn;
struct listnode *node;
struct in_addr *ipv4_addr;
-#ifdef HAVE_IPV6
struct in6_addr *ipv6_addr;
u_char ip6[INET6_ADDRSTRLEN];
-#endif /* HAVE_IPV6 */
if (!adj)
return;
@@ -323,7 +319,6 @@ isis_adj_print (struct isis_adjacency *adj)
zlog_debug ("%s", inet_ntoa (*ipv4_addr));
}
-#ifdef HAVE_IPV6
if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
{
zlog_debug ("IPv6 Address(es):");
@@ -333,7 +328,6 @@ isis_adj_print (struct isis_adjacency *adj)
zlog_debug ("%s", ip6);
}
}
-#endif /* HAVE_IPV6 */
zlog_debug ("Speaks: %s", nlpid2string (&adj->nlpids));
return;
@@ -363,10 +357,8 @@ isis_adj_expire (struct thread *thread)
void
isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty, char detail)
{
-#ifdef HAVE_IPV6
struct in6_addr *ipv6_addr;
u_char ip6[INET6_ADDRSTRLEN];
-#endif /* HAVE_IPV6 */
struct in_addr *ip_addr;
time_t now;
struct isis_dynhn *dyn;
@@ -457,7 +449,6 @@ isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty, char detail)
for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr))
vty_out (vty, " %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);
}
-#ifdef HAVE_IPV6
if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
{
vty_out (vty, " IPv6 Address(es):%s", VTY_NEWLINE);
@@ -467,7 +458,6 @@ isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty, char detail)
vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
}
}
-#endif /* HAVE_IPV6 */
vty_out (vty, "%s", VTY_NEWLINE);
}
return;
diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h
index 99d0c493ba..8539b03d6b 100644
--- a/isisd/isis_adjacency.h
+++ b/isisd/isis_adjacency.h
@@ -85,10 +85,8 @@ struct isis_adjacency
struct nlpids nlpids; /* protocols spoken ... */
struct list *ipv4_addrs;
struct in_addr router_address;
-#ifdef HAVE_IPV6
struct list *ipv6_addrs;
struct in6_addr router_address6;
-#endif /* HAVE_IPV6 */
u_char prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS */
int circuit_t; /* from hello PDU hdr */
int level; /* level (1 or 2) */
diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c
index 8775e12a24..3a5eaf5585 100644
--- a/isisd/isis_bpf.c
+++ b/isisd/isis_bpf.c
@@ -78,7 +78,10 @@ open_bpf_dev (struct isis_circuit *circuit)
int i = 0, fd;
char bpfdev[128];
struct ifreq ifr;
- u_int blen, immediate, seesent;
+ u_int blen, immediate;
+#ifdef BIOCSSEESENT
+ u_int seesent;
+#endif
struct timeval timeout;
struct bpf_program bpf_prog;
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 0ea6c3d453..b138b8950c 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -284,10 +284,8 @@ isis_circuit_del_addr (struct isis_circuit *circuit,
struct prefix_ipv4 *ipv4, *ip = NULL;
struct listnode *node;
char buf[PREFIX2STR_BUFFER];
-#ifdef HAVE_IPV6
struct prefix_ipv6 *ipv6, *ip6 = NULL;
int found = 0;
-#endif /* HAVE_IPV6 */
if (connected->address->family == AF_INET)
{
@@ -321,7 +319,6 @@ isis_circuit_del_addr (struct isis_circuit *circuit,
prefix_ipv4_free (ipv4);
}
-#ifdef HAVE_IPV6
if (connected->address->family == AF_INET6)
{
ipv6 = prefix_ipv6_new ();
@@ -379,7 +376,6 @@ isis_circuit_del_addr (struct isis_circuit *circuit,
prefix_ipv6_free (ipv6);
}
-#endif /* HAVE_IPV6 */
return;
}
@@ -467,10 +463,8 @@ isis_circuit_if_add (struct isis_circuit *circuit, struct interface *ifp)
}
circuit->ip_addrs = list_new ();
-#ifdef HAVE_IPV6
circuit->ipv6_link = list_new ();
circuit->ipv6_non_link = list_new ();
-#endif /* HAVE_IPV6 */
for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, conn))
isis_circuit_add_addr (circuit, conn);
@@ -497,7 +491,6 @@ isis_circuit_if_del (struct isis_circuit *circuit, struct interface *ifp)
circuit->ip_addrs = NULL;
}
-#ifdef HAVE_IPV6
if (circuit->ipv6_link)
{
assert (listcount(circuit->ipv6_link) == 0);
@@ -511,7 +504,6 @@ isis_circuit_if_del (struct isis_circuit *circuit, struct interface *ifp)
list_delete (circuit->ipv6_non_link);
circuit->ipv6_non_link = NULL;
}
-#endif /* HAVE_IPV6 */
circuit->circ_type = CIRCUIT_T_UNKNOWN;
circuit->circuit_id = 0;
@@ -857,13 +849,11 @@ circuit_update_nlpids (struct isis_circuit *circuit)
circuit->nlpids.nlpids[0] = NLPID_IP;
circuit->nlpids.count++;
}
-#ifdef HAVE_IPV6
if (circuit->ipv6_router)
{
circuit->nlpids.nlpids[circuit->nlpids.count] = NLPID_IPV6;
circuit->nlpids.count++;
}
-#endif /* HAVE_IPV6 */
return;
}
@@ -1045,14 +1035,12 @@ isis_interface_config_write (struct vty *vty)
vty_out (vty, " isis network point-to-point%s", VTY_NEWLINE);
write++;
}
-#ifdef HAVE_IPV6
if (circuit->ipv6_router)
{
vty_out (vty, " ipv6 router isis %s%s", area->area_tag,
VTY_NEWLINE);
write++;
}
-#endif /* HAVE_IPV6 */
/* ISIS - circuit type */
if (circuit->is_type == IS_LEVEL_1)
@@ -1424,12 +1412,7 @@ isis_circuit_init ()
/* Install interface node */
install_node (&interface_node, isis_interface_config_write);
- install_element (CONFIG_NODE, &interface_cmd);
- install_element (CONFIG_NODE, &no_interface_cmd);
-
- install_default (INTERFACE_NODE);
- install_element (INTERFACE_NODE, &interface_desc_cmd);
- install_element (INTERFACE_NODE, &no_interface_desc_cmd);
+ if_cmd_init ();
isis_vty_init ();
}
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index 035e558c0a..bb0dc0f983 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -124,11 +124,9 @@ struct isis_circuit
int ip_router; /* Route IP ? */
int is_passive; /* Is Passive ? */
struct list *ip_addrs; /* our IP addresses */
-#ifdef HAVE_IPV6
int ipv6_router; /* Route IPv6 ? */
struct list *ipv6_link; /* our link local IPv6 addresses */
struct list *ipv6_non_link; /* our non-link local IPv6 addresses */
-#endif /* HAVE_IPV6 */
u_int16_t upadjcount[2];
#define ISIS_CIRCUIT_FLAPPED_AFTER_SPF 0x01
u_char flags;
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index c13bcc5d8a..da24a7f0d3 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -156,9 +156,7 @@ lsp_destroy (struct isis_lsp *lsp)
}
isis_spf_schedule (lsp->area, lsp->level);
-#ifdef HAVE_IPV6
isis_spf_schedule6 (lsp->area, lsp->level);
-#endif
if (lsp->pdu)
stream_free (lsp->pdu);
@@ -427,9 +425,7 @@ lsp_inc_seqnum (struct isis_lsp *lsp, u_int32_t seq_num)
ntohs (lsp->lsp_header->pdu_len) - 12, 12);
isis_spf_schedule (lsp->area, lsp->level);
-#ifdef HAVE_IPV6
isis_spf_schedule6 (lsp->area, lsp->level);
-#endif
return;
}
@@ -510,10 +506,8 @@ lsp_update_data (struct isis_lsp *lsp, struct stream *stream,
expected |= TLVFLAG_IPV4_ADDR;
expected |= TLVFLAG_IPV4_INT_REACHABILITY;
expected |= TLVFLAG_IPV4_EXT_REACHABILITY;
-#ifdef HAVE_IPV6
expected |= TLVFLAG_IPV6_ADDR;
expected |= TLVFLAG_IPV6_REACHABILITY;
-#endif /* HAVE_IPV6 */
retval = parse_tlvs (area->area_tag, STREAM_DATA (lsp->pdu) +
ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN,
@@ -646,9 +640,7 @@ lsp_insert (struct isis_lsp *lsp, dict_t * lspdb)
if (lsp->lsp_header->seq_num != 0)
{
isis_spf_schedule (lsp->area, lsp->level);
-#ifdef HAVE_IPV6
isis_spf_schedule6 (lsp->area, lsp->level);
-#endif
}
}
@@ -848,11 +840,9 @@ lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost)
struct ipv4_reachability *ipv4_reach;
struct in_addr *ipv4_addr;
struct te_ipv4_reachability *te_ipv4_reach;
-#ifdef HAVE_IPV6
struct ipv6_reachability *ipv6_reach;
struct in6_addr in6;
u_char buff[BUFSIZ];
-#endif
u_char LSPid[255];
u_char hostname[255];
u_char ipv4_reach_prefix[20];
@@ -961,7 +951,6 @@ lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost)
}
/* IPv6 tlv */
-#ifdef HAVE_IPV6
if (lsp->tlv_data.ipv6_reachs)
for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv6_reachs, lnode, ipv6_reach))
{
@@ -979,7 +968,6 @@ lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost)
ntohl (ipv6_reach->metric),
buff, ipv6_reach->prefix_len, VTY_NEWLINE);
}
-#endif
/* TE IS neighbor tlv */
if (lsp->tlv_data.te_is_neighs)
@@ -1356,10 +1344,8 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
struct ipv4_reachability *ipreach;
struct te_ipv4_reachability *te_ipreach;
struct isis_adjacency *nei;
-#ifdef HAVE_IPV6
struct prefix_ipv6 *ipv6, ip6prefix;
struct ipv6_reachability *ip6reach;
-#endif /* HAVE_IPV6 */
struct tlvs tlv_data;
struct isis_lsp *lsp0 = lsp;
struct in_addr *routerid;
@@ -1399,11 +1385,7 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
tlv_add_area_addrs (lsp->tlv_data.area_addrs, lsp->pdu);
/* Protocols Supported */
- if (area->ip_circuits > 0
-#ifdef HAVE_IPV6
- || area->ipv6_circuits > 0
-#endif /* HAVE_IPV6 */
- )
+ if (area->ip_circuits > 0 || area->ipv6_circuits > 0)
{
lsp->tlv_data.nlpids = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct nlpids));
lsp->tlv_data.nlpids->count = 0;
@@ -1413,7 +1395,6 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
lsp->tlv_data.nlpids->count++;
lsp->tlv_data.nlpids->nlpids[0] = NLPID_IP;
}
-#ifdef HAVE_IPV6
if (area->ipv6_circuits > 0)
{
lsp_debug("ISIS (%s): Found IPv6 circuit, adding IPv6 to NLPIDs", area->area_tag);
@@ -1421,7 +1402,6 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
lsp->tlv_data.nlpids->nlpids[lsp->tlv_data.nlpids->count - 1] =
NLPID_IPV6;
}
-#endif /* HAVE_IPV6 */
tlv_add_nlpid (lsp->tlv_data.nlpids, lsp->pdu);
}
@@ -1568,7 +1548,6 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
}
}
-#ifdef HAVE_IPV6
/*
* Add IPv6 reachability of this circuit
*/
@@ -1606,7 +1585,6 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
listnode_add (tlv_data.ipv6_reachs, ip6reach);
}
}
-#endif /* HAVE_IPV6 */
switch (circuit->circ_type)
{
@@ -1807,7 +1785,6 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
lsp0, area, level);
}
-#ifdef HAVE_IPV6
while (tlv_data.ipv6_reachs && listcount (tlv_data.ipv6_reachs))
{
if (lsp->tlv_data.ipv6_reachs == NULL)
@@ -1820,7 +1797,6 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
lsp0, area, level);
}
-#endif /* HAVE_IPV6 */
while (tlv_data.is_neighs && listcount (tlv_data.is_neighs))
{
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index 96e459a797..e111a17dee 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -357,7 +357,6 @@ tlvs_to_adj_ipv4_addrs (struct tlvs *tlvs, struct isis_adjacency *adj)
}
}
-#ifdef HAVE_IPV6
static void
tlvs_to_adj_ipv6_addrs (struct tlvs *tlvs, struct isis_adjacency *adj)
{
@@ -381,7 +380,6 @@ tlvs_to_adj_ipv6_addrs (struct tlvs *tlvs, struct isis_adjacency *adj)
}
}
-#endif /* HAVE_IPV6 */
/*
* RECEIVE SIDE
@@ -527,12 +525,6 @@ process_p2p_hello (struct isis_circuit *circuit)
zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap "
"in P2P IIH from %s\n", circuit->interface->name);
}
-#ifndef HAVE_IPV6
- else /* !(found & TLVFLAG_IPV4_ADDR) */
- zlog_warn ("ISIS-Adj: no IPv4 in P2P IIH from %s "
- "(this isisd has no IPv6)\n", circuit->interface->name);
-
-#else
if (found & TLVFLAG_IPV6_ADDR)
{
/* TBA: check that we have a linklocal ourselves? */
@@ -553,7 +545,6 @@ process_p2p_hello (struct isis_circuit *circuit)
if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR)))
zlog_warn ("ISIS-Adj: neither IPv4 nor IPv6 addr in P2P IIH from %s\n",
circuit->interface->name);
-#endif
if (!v6_usable && !v4_usable)
{
@@ -639,10 +630,8 @@ process_p2p_hello (struct isis_circuit *circuit)
set_circuitparams_rmt_ipaddr (circuit->mtc, *ip_addr);
}
-#ifdef HAVE_IPV6
if (found & TLVFLAG_IPV6_ADDR)
tlvs_to_adj_ipv6_addrs (&tlvs, adj);
-#endif /* HAVE_IPV6 */
/* lets take care of the expiry */
THREAD_TIMER_OFF (adj->t_expire);
@@ -1125,12 +1114,6 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap "
"in LAN IIH from %s\n", circuit->interface->name);
}
-#ifndef HAVE_IPV6
- else /* !(found & TLVFLAG_IPV4_ADDR) */
- zlog_warn ("ISIS-Adj: no IPv4 in LAN IIH from %s "
- "(this isisd has no IPv6)\n", circuit->interface->name);
-
-#else
if (found & TLVFLAG_IPV6_ADDR)
{
/* TBA: check that we have a linklocal ourselves? */
@@ -1151,7 +1134,6 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR)))
zlog_warn ("ISIS-Adj: neither IPv4 nor IPv6 addr in LAN IIH from %s\n",
circuit->interface->name);
-#endif
if (!v6_usable && !v4_usable)
{
@@ -1236,10 +1218,8 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
if (found & TLVFLAG_IPV4_ADDR)
tlvs_to_adj_ipv4_addrs (&tlvs, adj);
-#ifdef HAVE_IPV6
if (found & TLVFLAG_IPV6_ADDR)
tlvs_to_adj_ipv6_addrs (&tlvs, adj);
-#endif /* HAVE_IPV6 */
adj->circuit_t = hdr.circuit_t;
@@ -2357,13 +2337,11 @@ send_hello (struct isis_circuit *circuit, int level)
if (tlv_add_ip_addrs (circuit->ip_addrs, circuit->snd_stream))
return ISIS_WARNING;
-#ifdef HAVE_IPV6
/* IPv6 Interface Address TLV */
if (circuit->ipv6_router && circuit->ipv6_link &&
listcount (circuit->ipv6_link) > 0)
if (tlv_add_ipv6_addrs (circuit->ipv6_link, circuit->snd_stream))
return ISIS_WARNING;
-#endif /* HAVE_IPV6 */
if (circuit->pad_hellos)
if (tlv_add_padding (circuit->snd_stream))
diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c
index 8282591a49..bdf90aaa1e 100644
--- a/isisd/isis_redist.c
+++ b/isisd/isis_redist.c
@@ -540,8 +540,7 @@ isis_redist_area_finish(struct isis_area *area)
DEFUN (isis_redistribute,
isis_redistribute_cmd,
- "redistribute (ipv4|ipv6) " FRR_REDIST_STR_ISISD
- " (level-1|level-2) {metric <0-16777215>|route-map WORD}",
+ "redistribute " FRR_REDIST_STR_ISISD " <level-1|level-2> [<metric (0-16777215)|route-map WORD>]",
REDIST_STR
"Redistribute IPv4 routes\n"
"Redistribute IPv6 routes\n"
@@ -553,18 +552,19 @@ DEFUN (isis_redistribute,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ int idx_afi = 1;
+ int idx_protocol = 2;
+ int idx_level = 3;
+ int idx_metric_rmap = 4;
VTY_DECLVAR_CONTEXT (isis_area, area);
int family;
int afi;
int type;
int level;
unsigned long metric;
- const char *routemap;
+ const char *routemap = NULL;
- if (argc < 5)
- return CMD_WARNING;
-
- family = str2family(argv[0]);
+ family = str2family(argv[idx_afi]->text);
if (family < 0)
return CMD_WARNING;
@@ -572,13 +572,13 @@ DEFUN (isis_redistribute,
if (!afi)
return CMD_WARNING;
- type = proto_redistnum(afi, argv[1]);
- if (type < 0 || type == ZEBRA_ROUTE_ISIS)
+ type = proto_redistnum(afi, argv[idx_protocol]->text);
+ if (type < 0)
return CMD_WARNING;
- if (!strcmp("level-1", argv[2]))
+ if (!strcmp("level-1", argv[idx_level]->arg))
level = 1;
- else if (!strcmp("level-2", argv[2]))
+ else if (!strcmp("level-2", argv[idx_level]->arg))
level = 2;
else
return CMD_WARNING;
@@ -589,28 +589,28 @@ DEFUN (isis_redistribute,
return CMD_WARNING;
}
- if (argv[3])
+ if (strmatch(argv[idx_metric_rmap]->text, "metric"))
{
char *endp;
- metric = strtoul(argv[3], &endp, 10);
- if (argv[3][0] == '\0' || *endp != '\0')
+ metric = strtoul(argv[idx_metric_rmap + 1]->arg, &endp, 10);
+ routemap = NULL;
+
+ if (argv[idx_metric_rmap]->arg[0] == '\0' || *endp != '\0')
return CMD_WARNING;
}
else
{
+ routemap = argv[idx_metric_rmap + 1]->arg;
metric = 0xffffffff;
}
- routemap = argv[4];
-
isis_redist_set(area, level, family, type, metric, routemap, 0);
return 0;
}
DEFUN (no_isis_redistribute,
no_isis_redistribute_cmd,
- "no redistribute (ipv4|ipv6) " FRR_REDIST_STR_ISISD
- " (level-1|level-2)",
+ "no redistribute " FRR_REDIST_STR_ISISD " <level-1|level-2>",
NO_STR
REDIST_STR
"Redistribute IPv4 routes\n"
@@ -619,16 +619,16 @@ DEFUN (no_isis_redistribute,
"Redistribute into level-1\n"
"Redistribute into level-2\n")
{
+ int idx_afi = 2;
+ int idx_protocol = 3;
+ int idx_level = 4;
VTY_DECLVAR_CONTEXT (isis_area, area);
int type;
int level;
int family;
int afi;
- if (argc < 3)
- return CMD_WARNING;
-
- family = str2family(argv[0]);
+ family = str2family(argv[idx_afi]->arg);
if (family < 0)
return CMD_WARNING;
@@ -636,16 +636,11 @@ DEFUN (no_isis_redistribute,
if (!afi)
return CMD_WARNING;
- type = proto_redistnum(afi, argv[1]);
- if (type < 0 || type == ZEBRA_ROUTE_ISIS)
+ type = proto_redistnum(afi, argv[idx_protocol]->text);
+ if (type < 0)
return CMD_WARNING;
- if (!strcmp("level-1", argv[2]))
- level = 1;
- else if (!strcmp("level-2", argv[2]))
- level = 2;
- else
- return CMD_WARNING;
+ level = strmatch ("level-1", argv[idx_level]->text) ? 1 : 2;
isis_redist_unset(area, level, family, type);
return 0;
@@ -653,8 +648,7 @@ DEFUN (no_isis_redistribute,
DEFUN (isis_default_originate,
isis_default_originate_cmd,
- "default-information originate (ipv4|ipv6) (level-1|level-2) "
- "{always|metric <0-16777215>|route-map WORD}",
+ "default-information originate <ipv4|ipv6> <level-1|level-2> [<always|metric (0-16777215)|route-map WORD>]",
"Control distribution of default information\n"
"Distribute a default route\n"
"Distribute default route for IPv4\n"
@@ -667,26 +661,21 @@ DEFUN (isis_default_originate,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ int idx_afi = 2;
+ int idx_level = 3;
+ int idx_metric_rmap = 4;
VTY_DECLVAR_CONTEXT (isis_area, area);
int family;
- int originate_type;
+ int originate_type = DEFAULT_ORIGINATE;
int level;
- unsigned long metric;
- const char *routemap;
-
- if (argc < 5)
- return CMD_WARNING;
+ unsigned long metric = 0xffffffff;
+ const char *routemap = NULL;
- family = str2family(argv[0]);
+ family = str2family(argv[idx_afi]->text);
if (family < 0)
return CMD_WARNING;
- if (!strcmp("level-1", argv[1]))
- level = 1;
- else if (!strcmp("level-2", argv[1]))
- level = 2;
- else
- return CMD_WARNING;
+ level = strmatch ("level-1", argv[idx_level]->text) ? 1 : 2;
if ((area->is_type & level) != level)
{
@@ -694,10 +683,15 @@ DEFUN (isis_default_originate,
return CMD_WARNING;
}
- if (argv[2] && *argv[2] != '\0')
- originate_type = DEFAULT_ORIGINATE_ALWAYS;
- else
- originate_type = DEFAULT_ORIGINATE;
+ if (argc > 4)
+ {
+ if (strmatch (argv[idx_metric_rmap]->text, "always"))
+ originate_type = DEFAULT_ORIGINATE_ALWAYS;
+ else if (strmatch(argv[idx_metric_rmap]->text, "metric"))
+ metric = strtoul(argv[idx_metric_rmap + 1]->arg, NULL, 10);
+ else
+ routemap = argv[idx_metric_rmap + 1]->arg;
+ }
if (family == AF_INET6 && originate_type != DEFAULT_ORIGINATE_ALWAYS)
{
@@ -705,27 +699,13 @@ DEFUN (isis_default_originate,
vty_out(vty, "so use with care or use default-originate always.%s", VTY_NEWLINE);
}
- if (argv[3])
- {
- char *endp;
- metric = strtoul(argv[3], &endp, 10);
- if (argv[3][0] == '\0' || *endp != '\0')
- return CMD_WARNING;
- }
- else
- {
- metric = 0xffffffff;
- }
-
- routemap = argv[4];
-
isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap, originate_type);
return 0;
}
DEFUN (no_isis_default_originate,
no_isis_default_originate_cmd,
- "no default-information originate (ipv4|ipv6) (level-1|level-2)",
+ "no default-information originate <ipv4|ipv6> <level-1|level-2>",
NO_STR
"Control distribution of default information\n"
"Distribute a default route\n"
@@ -734,20 +714,19 @@ DEFUN (no_isis_default_originate,
"Distribute default route into level-1\n"
"Distribute default route into level-2\n")
{
+ int idx_afi = 3;
+ int idx_level = 4;
VTY_DECLVAR_CONTEXT (isis_area, area);
int family;
int level;
- if (argc < 2)
- return CMD_WARNING;
-
- family = str2family(argv[0]);
+ family = str2family(argv[idx_afi]->text);
if (family < 0)
return CMD_WARNING;
- if (!strcmp("level-1", argv[1]))
+ if (strmatch ("level-1", argv[idx_level]->text))
level = 1;
- else if (!strcmp("level-2", argv[1]))
+ else if (strmatch ("level-2", argv[idx_level]->text))
level = 2;
else
return CMD_WARNING;
diff --git a/isisd/isis_route.c b/isisd/isis_route.c
index cc3ecba0d3..b2b858feb7 100644
--- a/isisd/isis_route.c
+++ b/isisd/isis_route.c
@@ -128,7 +128,6 @@ nexthops_print (struct list *nhs)
}
#endif /* EXTREME_DEBUG */
-#ifdef HAVE_IPV6
static struct isis_nexthop6 *
isis_nexthop6_new (struct in6_addr *ip6, ifindex_t ifindex)
{
@@ -217,7 +216,6 @@ nexthops6_print (struct list *nhs6)
nexthop6_print (nh6);
}
#endif /* EXTREME_DEBUG */
-#endif /* HAVE_IPV6 */
static void
adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj)
@@ -242,7 +240,6 @@ adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj)
}
}
-#ifdef HAVE_IPV6
static void
adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj)
{
@@ -265,7 +262,6 @@ adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj)
}
}
}
-#endif /* HAVE_IPV6 */
static struct isis_route_info *
isis_route_info_new (struct prefix *prefix, uint32_t cost, uint32_t depth,
@@ -291,7 +287,6 @@ isis_route_info_new (struct prefix *prefix, uint32_t cost, uint32_t depth,
adjinfo2nexthop (rinfo->nexthops, adj);
}
}
-#ifdef HAVE_IPV6
if (prefix->family == AF_INET6)
{
rinfo->nexthops6 = list_new ();
@@ -307,8 +302,6 @@ isis_route_info_new (struct prefix *prefix, uint32_t cost, uint32_t depth,
}
}
-#endif /* HAVE_IPV6 */
-
rinfo->cost = cost;
rinfo->depth = depth;
@@ -324,13 +317,11 @@ isis_route_info_delete (struct isis_route_info *route_info)
list_delete (route_info->nexthops);
}
-#ifdef HAVE_IPV6
if (route_info->nexthops6)
{
route_info->nexthops6->del = (void (*)(void *)) isis_nexthop6_delete;
list_delete (route_info->nexthops6);
}
-#endif /* HAVE_IPV6 */
XFREE (MTYPE_ISIS_ROUTE_INFO, route_info);
}
@@ -353,9 +344,7 @@ isis_route_info_same (struct isis_route_info *new,
{
struct listnode *node;
struct isis_nexthop *nexthop;
-#ifdef HAVE_IPV6
struct isis_nexthop6 *nexthop6;
-#endif /* HAVE_IPV6 */
if (!CHECK_FLAG (old->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
return 0;
@@ -378,7 +367,6 @@ isis_route_info_same (struct isis_route_info *new,
== 0)
return 0;
}
-#ifdef HAVE_IPV6
else if (family == AF_INET6)
{
for (ALL_LIST_ELEMENTS_RO (new->nexthops6, node, nexthop6))
@@ -391,7 +379,6 @@ isis_route_info_same (struct isis_route_info *new,
nexthop6->ifindex) == 0)
return 0;
}
-#endif /* HAVE_IPV6 */
return 1;
}
@@ -414,10 +401,8 @@ isis_route_create (struct prefix *prefix, u_int32_t cost, u_int32_t depth,
if (family == AF_INET)
route_node = route_node_get (area->route_table[level - 1], prefix);
-#ifdef HAVE_IPV6
else if (family == AF_INET6)
route_node = route_node_get (area->route_table6[level - 1], prefix);
-#endif /* HAVE_IPV6 */
else
{
isis_route_info_delete (rinfo_new);
@@ -547,7 +532,6 @@ isis_route_validate_table (struct isis_area *area, struct route_table *table)
drnode->info = NULL;
}
-#ifdef HAVE_IPV6
if (rnode->p.family == AF_INET6)
{
drnode = route_node_get (area->route_table6[0], &rnode->p);
@@ -557,7 +541,6 @@ isis_route_validate_table (struct isis_area *area, struct route_table *table)
if (drnode->info == rnode->info)
drnode->info = NULL;
}
-#endif
isis_route_delete (&rnode->p, table);
}
@@ -585,10 +568,8 @@ isis_route_validate_merge (struct isis_area *area, int family)
if (family == AF_INET)
table = area->route_table[0];
-#ifdef HAVE_IPV6
else if (family == AF_INET6)
table = area->route_table6[0];
-#endif
for (rnode = route_top (table); rnode; rnode = route_next (rnode))
{
@@ -600,10 +581,8 @@ isis_route_validate_merge (struct isis_area *area, int family)
if (family == AF_INET)
table = area->route_table[1];
-#ifdef HAVE_IPV6
else if (family == AF_INET6)
table = area->route_table6[1];
-#endif
for (rnode = route_top (table); rnode; rnode = route_next (rnode))
{
@@ -634,14 +613,12 @@ isis_route_validate (struct isis_area *area)
else
isis_route_validate_merge (area, AF_INET);
-#ifdef HAVE_IPV6
if (area->is_type == IS_LEVEL_1)
isis_route_validate_table (area, area->route_table6[0]);
else if (area->is_type == IS_LEVEL_2)
isis_route_validate_table (area, area->route_table6[1]);
else
isis_route_validate_merge (area, AF_INET6);
-#endif
if (!area->circuit_list) {
return;
diff --git a/isisd/isis_route.h b/isisd/isis_route.h
index 0d2379cbe8..de23070aa8 100644
--- a/isisd/isis_route.h
+++ b/isisd/isis_route.h
@@ -25,7 +25,6 @@
#ifndef _ZEBRA_ISIS_ROUTE_H
#define _ZEBRA_ISIS_ROUTE_H
-#ifdef HAVE_IPV6
struct isis_nexthop6
{
ifindex_t ifindex;
@@ -33,7 +32,6 @@ struct isis_nexthop6
struct in6_addr router_address6;
unsigned int lock;
};
-#endif /* HAVE_IPV6 */
struct isis_nexthop
{
@@ -52,9 +50,7 @@ struct isis_route_info
u_int32_t cost;
u_int32_t depth;
struct list *nexthops;
-#ifdef HAVE_IPV6
struct list *nexthops6;
-#endif /* HAVE_IPV6 */
};
struct isis_route_info *isis_route_create (struct prefix *prefix,
diff --git a/isisd/isis_routemap.c b/isisd/isis_routemap.c
index 070965b2df..61f3315f08 100644
--- a/isisd/isis_routemap.c
+++ b/isisd/isis_routemap.c
@@ -250,314 +250,29 @@ static struct route_map_rule_cmd route_set_metric_cmd =
route_set_metric_free
};
-/* ------------------------------------------------------------*/
-
-static int
-isis_route_match_add(struct vty *vty,
- const char *command, const char *arg)
-{
- VTY_DECLVAR_CONTEXT (route_map_index, index);
- int ret;
-
- ret = route_map_add_match (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
-static int
-isis_route_match_delete(struct vty *vty,
- const char *command, const char *arg)
-{
- VTY_DECLVAR_CONTEXT (route_map_index, index);
- int ret;
-
- ret = route_map_delete_match (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
-static int
-isis_route_set_add(struct vty *vty,
- const char *command, const char *arg)
-{
- VTY_DECLVAR_CONTEXT (route_map_index, index);
- int ret;
-
- ret = route_map_add_set(index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- return CMD_SUCCESS;
-}
-
-static int
-isis_route_set_delete (struct vty *vty,
- const char *command, const char *arg)
-{
- VTY_DECLVAR_CONTEXT (route_map_index, index);
- int ret;
-
- ret = route_map_delete_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- return CMD_SUCCESS;
-}
-
-/* ------------------------------------------------------------*/
-
-DEFUN (match_ip_address,
- match_ip_address_cmd,
- "match ip address (<1-199>|<1300-2699>|WORD)",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-{
- return isis_route_match_add(vty, "ip address", argv[0]);
-}
-
-DEFUN (no_match_ip_address,
- no_match_ip_address_val_cmd,
- "no match ip address (<1-199>|<1300-2699>|WORD)",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-{
- if (argc == 0)
- return isis_route_match_delete(vty, "ip address", NULL);
- return isis_route_match_delete(vty, "ip address", argv[0]);
-}
-
-ALIAS (no_match_ip_address,
- no_match_ip_address_cmd,
- "no match ip address",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n")
-
-/* ------------------------------------------------------------*/
-
-DEFUN (match_ip_address_prefix_list,
- match_ip_address_prefix_list_cmd,
- "match ip address prefix-list WORD",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return isis_route_match_add(vty, "ip address prefix-list", argv[0]);
-}
-
-DEFUN (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_cmd,
- "no match ip address prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n")
-{
- if (argc == 0)
- return isis_route_match_delete (vty, "ip address prefix-list", NULL);
- return isis_route_match_delete (vty, "ip address prefix-list", argv[0]);
-}
-
-ALIAS (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_val_cmd,
- "no match ip address prefix-list WORD",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-
-/* ------------------------------------------------------------*/
-
-DEFUN (match_ipv6_address,
- match_ipv6_address_cmd,
- "match ipv6 address WORD",
- MATCH_STR
- IPV6_STR
- "Match IPv6 address of route\n"
- "IPv6 access-list name\n")
-{
- return isis_route_match_add(vty, "ipv6 address", argv[0]);
-}
-
-DEFUN (no_match_ipv6_address,
- no_match_ipv6_address_val_cmd,
- "no match ipv6 address WORD",
- NO_STR
- MATCH_STR
- IPV6_STR
- "Match IPv6 address of route\n"
- "IPv6 access-list name\n")
-{
- if (argc == 0)
- return isis_route_match_delete(vty, "ipv6 address", NULL);
- return isis_route_match_delete(vty, "ipv6 address", argv[0]);
-}
-
-ALIAS (no_match_ipv6_address,
- no_match_ipv6_address_cmd,
- "no match ipv6 address",
- NO_STR
- MATCH_STR
- IPV6_STR
- "Match IPv6 address of route\n")
-
-/* ------------------------------------------------------------*/
-
-DEFUN (match_ipv6_address_prefix_list,
- match_ipv6_address_prefix_list_cmd,
- "match ipv6 address prefix-list WORD",
- MATCH_STR
- IPV6_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return isis_route_match_add(vty, "ipv6 address prefix-list", argv[0]);
-}
-
-DEFUN (no_match_ipv6_address_prefix_list,
- no_match_ipv6_address_prefix_list_cmd,
- "no match ipv6 address prefix-list",
- NO_STR
- MATCH_STR
- IPV6_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n")
+void
+isis_route_map_init(void)
{
- if (argc == 0)
- return isis_route_match_delete (vty, "ipv6 address prefix-list", NULL);
- return isis_route_match_delete (vty, "ipv6 address prefix-list", argv[0]);
-}
+ route_map_init();
-ALIAS (no_match_ipv6_address_prefix_list,
- no_match_ipv6_address_prefix_list_val_cmd,
- "no match ipv6 address prefix-list WORD",
- NO_STR
- MATCH_STR
- IPV6_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
+ route_map_match_ip_address_hook (generic_match_add);
+ route_map_no_match_ip_address_hook (generic_match_delete);
-/* ------------------------------------------------------------*/
+ route_map_match_ip_address_prefix_list_hook (generic_match_add);
+ route_map_no_match_ip_address_prefix_list_hook (generic_match_delete);
-/* set metric already exists e.g. in the ospf routemap. vtysh doesn't cope well with different
- * commands at the same node, therefore add set metric with the same 32-bit range as ospf and
- * verify that the input is a valid isis metric */
-DEFUN (set_metric,
- set_metric_cmd,
- "set metric <0-4294967295>",
- SET_STR
- "Metric vale for destination routing protocol\n"
- "Metric value\n")
-{
- return isis_route_set_add(vty, "metric", argv[0]);
-}
+ route_map_match_ipv6_address_hook (generic_match_add);
+ route_map_no_match_ipv6_address_hook (generic_match_delete);
-DEFUN (no_set_metric,
- no_set_metric_val_cmd,
- "no set metric <0-4294967295>",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n"
- "Metric value\n")
-{
- if (argc == 0)
- return isis_route_set_delete(vty, "metric", NULL);
- return isis_route_set_delete(vty, "metric", argv[0]);
-}
+ route_map_match_ipv6_address_prefix_list_hook (generic_match_add);
+ route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete);
-ALIAS (no_set_metric,
- no_set_metric_cmd,
- "no set metric",
- NO_STR
- SET_STR
- "Metric vale for destination routing protocol\n");
-
-void
-isis_route_map_init(void)
-{
- route_map_init();
+ route_map_set_metric_hook (generic_set_add);
+ route_map_no_set_metric_hook (generic_set_delete);
route_map_install_match(&route_match_ip_address_cmd);
- install_element(RMAP_NODE, &match_ip_address_cmd);
- install_element(RMAP_NODE, &no_match_ip_address_val_cmd);
- install_element(RMAP_NODE, &no_match_ip_address_cmd);
-
route_map_install_match(&route_match_ip_address_prefix_list_cmd);
- install_element(RMAP_NODE, &match_ip_address_prefix_list_cmd);
- install_element(RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
- install_element(RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
-
route_map_install_match(&route_match_ipv6_address_cmd);
- install_element(RMAP_NODE, &match_ipv6_address_cmd);
- install_element(RMAP_NODE, &no_match_ipv6_address_val_cmd);
- install_element(RMAP_NODE, &no_match_ipv6_address_cmd);
-
route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
- install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
- install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_val_cmd);
- install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
-
route_map_install_set(&route_set_metric_cmd);
- install_element(RMAP_NODE, &set_metric_cmd);
- install_element(RMAP_NODE, &no_set_metric_val_cmd);
- install_element(RMAP_NODE, &no_set_metric_cmd);
}
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 041f2ed3f6..c1fb062e55 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -139,14 +139,12 @@ vtype2string (enum vertextype vtype)
case VTYPE_IPREACH_TE:
return "IP TE";
break;
-#ifdef HAVE_IPV6
case VTYPE_IP6REACH_INTERNAL:
return "IP6 internal";
break;
case VTYPE_IP6REACH_EXTERNAL:
return "IP6 external";
break;
-#endif /* HAVE_IPV6 */
default:
return "UNKNOWN";
}
@@ -170,10 +168,8 @@ vid2string (struct isis_vertex *vertex, char * buff, int size)
case VTYPE_IPREACH_INTERNAL:
case VTYPE_IPREACH_EXTERNAL:
case VTYPE_IPREACH_TE:
-#ifdef HAVE_IPV6
case VTYPE_IP6REACH_INTERNAL:
case VTYPE_IP6REACH_EXTERNAL:
-#endif /* HAVE_IPV6 */
prefix2str ((struct prefix *) &vertex->N.prefix, buff, size);
break;
default:
@@ -205,10 +201,8 @@ isis_vertex_new (void *id, enum vertextype vtype)
case VTYPE_IPREACH_INTERNAL:
case VTYPE_IPREACH_EXTERNAL:
case VTYPE_IPREACH_TE:
-#ifdef HAVE_IPV6
case VTYPE_IP6REACH_INTERNAL:
case VTYPE_IP6REACH_EXTERNAL:
-#endif /* HAVE_IPV6 */
memcpy (&vertex->N.prefix, (struct prefix *) id,
sizeof (struct prefix));
break;
@@ -314,20 +308,16 @@ spftree_area_init (struct isis_area *area)
{
if (area->spftree[0] == NULL)
area->spftree[0] = isis_spftree_new (area);
-#ifdef HAVE_IPV6
if (area->spftree6[0] == NULL)
area->spftree6[0] = isis_spftree_new (area);
-#endif
}
if (area->is_type & IS_LEVEL_2)
{
if (area->spftree[1] == NULL)
area->spftree[1] = isis_spftree_new (area);
-#ifdef HAVE_IPV6
if (area->spftree6[1] == NULL)
area->spftree6[1] = isis_spftree_new (area);
-#endif
}
return;
@@ -343,13 +333,11 @@ spftree_area_del (struct isis_area *area)
isis_spftree_del (area->spftree[0]);
area->spftree[0] = NULL;
}
-#ifdef HAVE_IPV6
if (area->spftree6[0])
{
isis_spftree_del (area->spftree6[0]);
area->spftree6[0] = NULL;
}
-#endif
}
if (area->is_type & IS_LEVEL_2)
@@ -359,13 +347,11 @@ spftree_area_del (struct isis_area *area)
isis_spftree_del (area->spftree[1]);
area->spftree[1] = NULL;
}
-#ifdef HAVE_IPV6
if (area->spftree6[1] != NULL)
{
isis_spftree_del (area->spftree6[1]);
area->spftree6[1] = NULL;
}
-#endif
}
return;
@@ -378,20 +364,16 @@ spftree_area_adj_del (struct isis_area *area, struct isis_adjacency *adj)
{
if (area->spftree[0] != NULL)
isis_spftree_adj_del (area->spftree[0], adj);
-#ifdef HAVE_IPV6
if (area->spftree6[0] != NULL)
isis_spftree_adj_del (area->spftree6[0], adj);
-#endif
}
if (area->is_type & IS_LEVEL_2)
{
if (area->spftree[1] != NULL)
isis_spftree_adj_del (area->spftree[1], adj);
-#ifdef HAVE_IPV6
if (area->spftree6[1] != NULL)
isis_spftree_adj_del (area->spftree6[1], adj);
-#endif
}
return;
@@ -475,10 +457,8 @@ isis_find_vertex (struct list *list, void *id, enum vertextype vtype)
case VTYPE_IPREACH_INTERNAL:
case VTYPE_IPREACH_EXTERNAL:
case VTYPE_IPREACH_TE:
-#ifdef HAVE_IPV6
case VTYPE_IP6REACH_INTERNAL:
case VTYPE_IP6REACH_EXTERNAL:
-#endif /* HAVE_IPV6 */
p1 = (struct prefix *) id;
p2 = (struct prefix *) &vertex->N.id;
if (p1->family == p2->family && p1->prefixlen == p2->prefixlen &&
@@ -718,9 +698,7 @@ isis_spf_process_lsp (struct isis_spftree *spftree, struct isis_lsp *lsp,
struct te_ipv4_reachability *te_ipv4_reach;
enum vertextype vtype;
struct prefix prefix;
-#ifdef HAVE_IPV6
struct ipv6_reachability *ip6reach;
-#endif /* HAVE_IPV6 */
static const u_char null_sysid[ISIS_SYS_ID_LEN];
if (!speaks (lsp->tlv_data.nlpids, family))
@@ -820,7 +798,6 @@ lspfragloop:
family, parent);
}
}
-#ifdef HAVE_IPV6
if (family == AF_INET6 && lsp->tlv_data.ipv6_reachs)
{
prefix.family = AF_INET6;
@@ -839,7 +816,6 @@ lspfragloop:
family, parent);
}
}
-#endif /* HAVE_IPV6 */
if (fragnode == NULL)
fragnode = listhead (lsp->lspu.frags);
@@ -939,9 +915,7 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
int retval = ISIS_OK;
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
static u_char null_lsp_id[ISIS_SYS_ID_LEN + 2];
-#ifdef HAVE_IPV6
struct prefix_ipv6 *ipv6;
-#endif /* HAVE_IPV6 */
for (ALL_LIST_ELEMENTS_RO (spftree->area->circuit_list, cnode, circuit))
{
@@ -951,10 +925,8 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
continue;
if (family == AF_INET && !circuit->ip_router)
continue;
-#ifdef HAVE_IPV6
if (family == AF_INET6 && !circuit->ipv6_router)
continue;
-#endif /* HAVE_IPV6 */
/*
* Add IP(v6) addresses of this circuit
*/
@@ -970,7 +942,6 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
NULL, 0, family, parent);
}
}
-#ifdef HAVE_IPV6
if (family == AF_INET6)
{
prefix.family = AF_INET6;
@@ -983,7 +954,6 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
&prefix, NULL, 0, family, parent);
}
}
-#endif /* HAVE_IPV6 */
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
{
/*
@@ -1179,26 +1149,22 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
unsigned long long start_time, end_time;
/* Get time that can't roll backwards. */
- quagga_gettime(QUAGGA_CLK_MONOTONIC, &time_now);
+ monotime(&time_now);
start_time = time_now.tv_sec;
start_time = (start_time * 1000000) + time_now.tv_usec;
if (family == AF_INET)
spftree = area->spftree[level - 1];
-#ifdef HAVE_IPV6
else if (family == AF_INET6)
spftree = area->spftree6[level - 1];
-#endif
assert (spftree);
assert (sysid);
/* Make all routes in current route table inactive. */
if (family == AF_INET)
table = area->route_table[level - 1];
-#ifdef HAVE_IPV6
else if (family == AF_INET6)
table = area->route_table6[level - 1];
-#endif
isis_route_invalidate_table (area, table);
@@ -1277,7 +1243,7 @@ out:
spftree->pending = 0;
spftree->runcount++;
spftree->last_run_timestamp = time (NULL);
- quagga_gettime(QUAGGA_CLK_MONOTONIC, &time_now);
+ monotime(&time_now);
end_time = time_now.tv_sec;
end_time = (end_time * 1000000) + time_now.tv_usec;
spftree->last_run_duration = end_time - start_time;
@@ -1382,7 +1348,6 @@ isis_spf_schedule (struct isis_area *area, int level)
return ISIS_OK;
}
-#ifdef HAVE_IPV6
static int
isis_run_spf6_l1 (struct thread *thread)
{
@@ -1479,7 +1444,6 @@ isis_spf_schedule6 (struct isis_area *area, int level)
return retval;
}
-#endif
static void
isis_print_paths (struct vty *vty, struct list *paths, u_char *root_sysid)
@@ -1569,7 +1533,6 @@ DEFUN (show_isis_topology,
isis_print_paths (vty, area->spftree[level]->paths, isis->sysid);
vty_out (vty, "%s", VTY_NEWLINE);
}
-#ifdef HAVE_IPV6
if (area->ipv6_circuits > 0 && area->spftree6[level]
&& area->spftree6[level]->paths->count > 0)
{
@@ -1579,7 +1542,6 @@ DEFUN (show_isis_topology,
isis_print_paths (vty, area->spftree6[level]->paths, isis->sysid);
vty_out (vty, "%s", VTY_NEWLINE);
}
-#endif /* HAVE_IPV6 */
}
vty_out (vty, "%s", VTY_NEWLINE);
@@ -1615,7 +1577,6 @@ DEFUN (show_isis_topology_l1,
isis_print_paths (vty, area->spftree[0]->paths, isis->sysid);
vty_out (vty, "%s", VTY_NEWLINE);
}
-#ifdef HAVE_IPV6
if (area->ipv6_circuits > 0 && area->spftree6[0]
&& area->spftree6[0]->paths->count > 0)
{
@@ -1624,7 +1585,6 @@ DEFUN (show_isis_topology_l1,
isis_print_paths (vty, area->spftree6[0]->paths, isis->sysid);
vty_out (vty, "%s", VTY_NEWLINE);
}
-#endif /* HAVE_IPV6 */
vty_out (vty, "%s", VTY_NEWLINE);
}
@@ -1658,7 +1618,6 @@ DEFUN (show_isis_topology_l2,
isis_print_paths (vty, area->spftree[1]->paths, isis->sysid);
vty_out (vty, "%s", VTY_NEWLINE);
}
-#ifdef HAVE_IPV6
if (area->ipv6_circuits > 0 && area->spftree6[1]
&& area->spftree6[1]->paths->count > 0)
{
@@ -1667,7 +1626,6 @@ DEFUN (show_isis_topology_l2,
isis_print_paths (vty, area->spftree6[1]->paths, isis->sysid);
vty_out (vty, "%s", VTY_NEWLINE);
}
-#endif /* HAVE_IPV6 */
vty_out (vty, "%s", VTY_NEWLINE);
}
diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h
index aa543b705d..0e42cac81f 100644
--- a/isisd/isis_spf.h
+++ b/isisd/isis_spf.h
@@ -33,12 +33,9 @@ enum vertextype
VTYPE_ES,
VTYPE_IPREACH_INTERNAL,
VTYPE_IPREACH_EXTERNAL,
- VTYPE_IPREACH_TE
-#ifdef HAVE_IPV6
- ,
+ VTYPE_IPREACH_TE,
VTYPE_IP6REACH_INTERNAL,
VTYPE_IP6REACH_EXTERNAL
-#endif /* HAVE_IPV6 */
};
/*
@@ -83,7 +80,5 @@ void spftree_area_adj_del (struct isis_area *area,
struct isis_adjacency *adj);
int isis_spf_schedule (struct isis_area *area, int level);
void isis_spf_cmds_init (void);
-#ifdef HAVE_IPV6
int isis_spf_schedule6 (struct isis_area *area, int level);
-#endif
#endif /* _ZEBRA_ISIS_SPF_H */
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index ecbb63c92b..34cd8397f4 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -591,7 +591,7 @@ isis_link_params_update (struct isis_circuit *circuit, struct interface *ifp)
else
SUBTLV_TYPE(mtc->unrsv_bw) = 0;
- if (IS_PARAM_SET(ifp->link_params, LP_TE))
+ if (IS_PARAM_SET(ifp->link_params, LP_TE_METRIC))
set_circuitparams_te_metric(mtc, ifp->link_params->te_metric);
else
SUBTLV_TYPE(mtc->te_metric) = 0;
@@ -1160,11 +1160,12 @@ DEFUN (isis_mpls_te_router_addr,
"Stable IP address of the advertising router\n"
"MPLS-TE router address in IPv4 address format\n")
{
+ int idx_ipv4 = 2;
struct in_addr value;
struct listnode *node;
struct isis_area *area;
- if (! inet_aton (argv[0], &value))
+ if (! inet_aton (argv[idx_ipv4]->arg, &value))
{
vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -1187,7 +1188,7 @@ DEFUN (isis_mpls_te_router_addr,
DEFUN (isis_mpls_te_inter_as,
isis_mpls_te_inter_as_cmd,
- "mpls-te inter-as (level-1|level-1-2|level-2-only)",
+ "mpls-te inter-as <level-1|level-1-2|level-2-only>",
MPLS_TE_STR
"Configure MPLS-TE Inter-AS support\n"
"AREA native mode self originate INTER-AS LSP with L1 only flooding scope)\n"
@@ -1314,11 +1315,12 @@ DEFUN (show_isis_mpls_te_interface,
"Interface information\n"
"Interface name\n")
{
+ int idx_interface = 4;
struct interface *ifp;
struct listnode *node;
/* Show All Interfaces. */
- if (argc == 0)
+ if (argc == 4)
{
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
show_mpls_te_sub (vty, ifp);
@@ -1326,7 +1328,7 @@ DEFUN (show_isis_mpls_te_interface,
/* Interface name is specified. */
else
{
- if ((ifp = if_lookup_by_name (argv[0])) == NULL)
+ if ((ifp = if_lookup_by_name (argv[idx_interface]->arg)) == NULL)
vty_out (vty, "No such interface name%s", VTY_NEWLINE);
else
show_mpls_te_sub (vty, ifp);
diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c
index b19a181a3f..4192fff9a8 100644
--- a/isisd/isis_tlv.c
+++ b/isisd/isis_tlv.c
@@ -81,12 +81,10 @@ free_tlvs (struct tlvs *tlvs)
list_delete (tlvs->ipv4_ext_reachs);
if (tlvs->te_ipv4_reachs)
list_delete (tlvs->te_ipv4_reachs);
-#ifdef HAVE_IPV6
if (tlvs->ipv6_addrs)
list_delete (tlvs->ipv6_addrs);
if (tlvs->ipv6_reachs)
list_delete (tlvs->ipv6_reachs);
-#endif /* HAVE_IPV6 */
memset (tlvs, 0, sizeof (struct tlvs));
@@ -111,11 +109,9 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
struct in_addr *ipv4_addr;
struct ipv4_reachability *ipv4_reach;
struct te_ipv4_reachability *te_ipv4_reach;
-#ifdef HAVE_IPV6
struct in6_addr *ipv6_addr;
struct ipv6_reachability *ipv6_reach;
int prefix_octets;
-#endif /* HAVE_IPV6 */
int value_len, retval = ISIS_OK;
u_char *start = stream, *pnt = stream, *endpnt;
@@ -646,7 +642,6 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
pnt = endpnt;
break;
-#ifdef HAVE_IPV6
case IPV6_ADDR:
/* +-------+-------+-------+-------+-------+-------+-------+-------+
* + IP version 6 address + 16
@@ -737,7 +732,6 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
pnt = endpnt;
break;
-#endif /* HAVE_IPV6 */
case WAY3_HELLO:
/* +---------------------------------------------------------------+
@@ -1139,7 +1133,6 @@ tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, struct stream *stream)
return add_tlv (TE_IPV4_REACHABILITY, pos - value, value, stream);
}
-#ifdef HAVE_IPV6
int
tlv_add_ipv6_addrs (struct list *ipv6_addrs, struct stream *stream)
{
@@ -1196,7 +1189,6 @@ tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream)
return add_tlv (IPV6_REACHABILITY, pos - value, value, stream);
}
-#endif /* HAVE_IPV6 */
int
tlv_add_padding (struct stream *stream)
diff --git a/isisd/isis_tlv.h b/isisd/isis_tlv.h
index 27ded7a0e8..f899b9e9db 100644
--- a/isisd/isis_tlv.h
+++ b/isisd/isis_tlv.h
@@ -231,7 +231,6 @@ struct idrp_info
u_char *value;
};
-#ifdef HAVE_IPV6
struct ipv6_reachability
{
u_int32_t metric;
@@ -250,7 +249,6 @@ struct ipv6_reachability
#define DISTRIBUTION_EXTERNAL 0x40
#define CTRL_INFO_SUBTLVS 0x20
-#endif /* HAVE_IPV6 */
/*
* Pointer to each tlv type, filled by parse_tlvs()
@@ -272,10 +270,8 @@ struct tlvs
struct list *ipv4_int_reachs;
struct list *ipv4_ext_reachs;
struct list *te_ipv4_reachs;
-#ifdef HAVE_IPV6
struct list *ipv6_addrs;
struct list *ipv6_reachs;
-#endif
struct isis_passwd auth_info;
};
@@ -330,10 +326,8 @@ int tlv_add_lsp_entries (struct list *lsps, struct stream *stream);
int tlv_add_ipv4_int_reachs (struct list *ipv4_reachs, struct stream *stream);
int tlv_add_ipv4_ext_reachs (struct list *ipv4_reachs, struct stream *stream);
int tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, struct stream *stream);
-#ifdef HAVE_IPV6
int tlv_add_ipv6_addrs (struct list *ipv6_addrs, struct stream *stream);
int tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream);
-#endif /* HAVE_IPV6 */
int tlv_add_padding (struct stream *stream);
diff --git a/isisd/isis_vty.c b/isisd/isis_vty.c
index 12ef682c17..848c56a6ac 100644
--- a/isisd/isis_vty.c
+++ b/isisd/isis_vty.c
@@ -54,17 +54,19 @@ isis_circuit_lookup (struct vty *vty)
DEFUN (ip_router_isis,
ip_router_isis_cmd,
- "(ip|ipv6) router isis WORD",
+ "ip router isis WORD",
"Interface Internet Protocol config commands\n"
"IP router interface commands\n"
"IS-IS Routing for IP\n"
"Routing process tag\n")
{
+ int idx_afi = 0;
+ int idx_word = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct isis_circuit *circuit;
struct isis_area *area;
- const char *af = argv[0];
- const char *area_tag = argv[1];
+ const char *af = argv[idx_afi]->arg;
+ const char *area_tag = argv[idx_word]->arg;
/* Prevent more than one area per circuit */
circuit = circuit_scan_by_ifp (ifp);
@@ -102,26 +104,40 @@ DEFUN (ip_router_isis,
return CMD_SUCCESS;
}
+DEFUN (ip6_router_isis,
+ ip6_router_isis_cmd,
+ "ipv6 router isis WORD",
+ "Interface Internet Protocol config commands\n"
+ "IP router interface commands\n"
+ "IS-IS Routing for IP\n"
+ "Routing process tag\n")
+{
+ return ip_router_isis (self, vty, argc, argv);
+}
+
DEFUN (no_ip_router_isis,
no_ip_router_isis_cmd,
- "no (ip|ipv6) router isis WORD",
+ "no <ip|ipv6> router isis WORD",
NO_STR
"Interface Internet Protocol config commands\n"
"IP router interface commands\n"
+ "IP router interface commands\n"
"IS-IS Routing for IP\n"
"Routing process tag\n")
{
+ int idx_afi = 1;
+ int idx_word = 4;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct isis_area *area;
struct isis_circuit *circuit;
- const char *af = argv[0];
- const char *area_tag = argv[1];
+ const char *af = argv[idx_afi]->arg;
+ const char *area_tag = argv[idx_word]->arg;
area = isis_area_lookup (area_tag);
if (!area)
{
vty_out (vty, "Can't find ISIS instance %s%s",
- argv[0], VTY_NEWLINE);
+ argv[idx_afi]->arg, VTY_NEWLINE);
return CMD_ERR_NO_MATCH;
}
@@ -181,19 +197,20 @@ DEFUN (no_isis_passive,
DEFUN (isis_circuit_type,
isis_circuit_type_cmd,
- "isis circuit-type (level-1|level-1-2|level-2-only)",
+ "isis circuit-type <level-1|level-1-2|level-2-only>",
"IS-IS commands\n"
"Configure circuit type for interface\n"
"Level-1 only adjacencies are formed\n"
"Level-1-2 adjacencies are formed\n"
"Level-2 only adjacencies are formed\n")
{
+ int idx_level = 2;
int is_type;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- is_type = string2circuit_t (argv[0]);
+ is_type = string2circuit_t (argv[idx_level]->arg);
if (!is_type)
{
vty_out (vty, "Unknown circuit-type %s", VTY_NEWLINE);
@@ -215,7 +232,7 @@ DEFUN (isis_circuit_type,
DEFUN (no_isis_circuit_type,
no_isis_circuit_type_cmd,
- "no isis circuit-type (level-1|level-1-2|level-2-only)",
+ "no isis circuit-type <level-1|level-1-2|level-2-only>",
NO_STR
"IS-IS commands\n"
"Configure circuit type for interface\n"
@@ -287,22 +304,24 @@ DEFUN (no_isis_network,
DEFUN (isis_passwd,
isis_passwd_cmd,
- "isis password (md5|clear) WORD",
+ "isis password <md5|clear> WORD",
"IS-IS commands\n"
"Configure the authentication password for a circuit\n"
"HMAC-MD5 authentication\n"
"Cleartext password\n"
"Circuit password\n")
{
+ int idx_encryption = 2;
+ int idx_word = 3;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
int rv;
if (!circuit)
return CMD_ERR_NO_MATCH;
- if (argv[0][0] == 'm')
- rv = isis_circuit_passwd_hmac_md5_set(circuit, argv[1]);
+ if (argv[idx_encryption]->arg[0] == 'm')
+ rv = isis_circuit_passwd_hmac_md5_set(circuit, argv[idx_word]->arg);
else
- rv = isis_circuit_passwd_cleartext_set(circuit, argv[1]);
+ rv = isis_circuit_passwd_cleartext_set(circuit, argv[idx_word]->arg);
if (rv)
{
vty_out (vty, "Too long circuit password (>254)%s", VTY_NEWLINE);
@@ -314,10 +333,13 @@ DEFUN (isis_passwd,
DEFUN (no_isis_passwd,
no_isis_passwd_cmd,
- "no isis password",
+ "no isis password [<md5|clear> WORD]",
NO_STR
"IS-IS commands\n"
- "Configure the authentication password for a circuit\n")
+ "Configure the authentication password for a circuit\n"
+ "HMAC-MD5 authentication\n"
+ "Cleartext password\n"
+ "Circuit password\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
@@ -328,29 +350,21 @@ DEFUN (no_isis_passwd,
return CMD_SUCCESS;
}
-ALIAS (no_isis_passwd,
- no_isis_passwd_arg_cmd,
- "no isis password (md5|clear) WORD",
- NO_STR
- "IS-IS commands\n"
- "Configure the authentication password for a circuit\n"
- "HMAC-MD5 authentication\n"
- "Cleartext password\n"
- "Circuit password\n")
DEFUN (isis_priority,
isis_priority_cmd,
- "isis priority <0-127>",
+ "isis priority (0-127)",
"IS-IS commands\n"
"Set priority for Designated Router election\n"
"Priority value\n")
{
+ int idx_number = 2;
int prio;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- prio = atoi (argv[0]);
+ prio = atoi (argv[idx_number]->arg);
if (prio < MIN_PRIORITY || prio > MAX_PRIORITY)
{
vty_out (vty, "Invalid priority %d - should be <0-127>%s",
@@ -366,10 +380,11 @@ DEFUN (isis_priority,
DEFUN (no_isis_priority,
no_isis_priority_cmd,
- "no isis priority",
+ "no isis priority [(0-127)]",
NO_STR
"IS-IS commands\n"
- "Set priority for Designated Router election\n")
+ "Set priority for Designated Router election\n"
+ "Priority value\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
@@ -381,28 +396,22 @@ DEFUN (no_isis_priority,
return CMD_SUCCESS;
}
-ALIAS (no_isis_priority,
- no_isis_priority_arg_cmd,
- "no isis priority <0-127>",
- NO_STR
- "IS-IS commands\n"
- "Set priority for Designated Router election\n"
- "Priority value\n")
DEFUN (isis_priority_l1,
isis_priority_l1_cmd,
- "isis priority <0-127> level-1",
+ "isis priority (0-127) level-1",
"IS-IS commands\n"
"Set priority for Designated Router election\n"
"Priority value\n"
"Specify priority for level-1 routing\n")
{
+ int idx_number = 2;
int prio;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- prio = atoi (argv[0]);
+ prio = atoi (argv[idx_number]->arg);
if (prio < MIN_PRIORITY || prio > MAX_PRIORITY)
{
vty_out (vty, "Invalid priority %d - should be <0-127>%s",
@@ -417,10 +426,11 @@ DEFUN (isis_priority_l1,
DEFUN (no_isis_priority_l1,
no_isis_priority_l1_cmd,
- "no isis priority level-1",
+ "no isis priority [(0-127)] level-1",
NO_STR
"IS-IS commands\n"
"Set priority for Designated Router election\n"
+ "Priority value\n"
"Specify priority for level-1 routing\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -432,29 +442,22 @@ DEFUN (no_isis_priority_l1,
return CMD_SUCCESS;
}
-ALIAS (no_isis_priority_l1,
- no_isis_priority_l1_arg_cmd,
- "no isis priority <0-127> level-1",
- NO_STR
- "IS-IS commands\n"
- "Set priority for Designated Router election\n"
- "Priority value\n"
- "Specify priority for level-1 routing\n")
DEFUN (isis_priority_l2,
isis_priority_l2_cmd,
- "isis priority <0-127> level-2",
+ "isis priority (0-127) level-2",
"IS-IS commands\n"
"Set priority for Designated Router election\n"
"Priority value\n"
"Specify priority for level-2 routing\n")
{
+ int idx_number = 2;
int prio;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- prio = atoi (argv[0]);
+ prio = atoi (argv[idx_number]->arg);
if (prio < MIN_PRIORITY || prio > MAX_PRIORITY)
{
vty_out (vty, "Invalid priority %d - should be <0-127>%s",
@@ -469,10 +472,11 @@ DEFUN (isis_priority_l2,
DEFUN (no_isis_priority_l2,
no_isis_priority_l2_cmd,
- "no isis priority level-2",
+ "no isis priority [(0-127)] level-2",
NO_STR
"IS-IS commands\n"
"Set priority for Designated Router election\n"
+ "Priority value\n"
"Specify priority for level-2 routing\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -484,29 +488,22 @@ DEFUN (no_isis_priority_l2,
return CMD_SUCCESS;
}
-ALIAS (no_isis_priority_l2,
- no_isis_priority_l2_arg_cmd,
- "no isis priority <0-127> level-2",
- NO_STR
- "IS-IS commands\n"
- "Set priority for Designated Router election\n"
- "Priority value\n"
- "Specify priority for level-2 routing\n")
/* Metric command */
DEFUN (isis_metric,
isis_metric_cmd,
- "isis metric <0-16777215>",
+ "isis metric (0-16777215)",
"IS-IS commands\n"
"Set default metric for circuit\n"
"Default metric value\n")
{
+ int idx_number = 2;
int met;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- met = atoi (argv[0]);
+ met = atoi (argv[idx_number]->arg);
/* RFC3787 section 5.1 */
if (circuit->area && circuit->area->oldmetric == 1 &&
@@ -533,12 +530,14 @@ DEFUN (isis_metric,
return CMD_SUCCESS;
}
+
DEFUN (no_isis_metric,
no_isis_metric_cmd,
- "no isis metric",
+ "no isis metric [(0-16777215)]",
NO_STR
"IS-IS commands\n"
- "Set default metric for circuit\n")
+ "Set default metric for circuit\n"
+ "Default metric value\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
@@ -549,28 +548,22 @@ DEFUN (no_isis_metric,
return CMD_SUCCESS;
}
-ALIAS (no_isis_metric,
- no_isis_metric_arg_cmd,
- "no isis metric <0-16777215>",
- NO_STR
- "IS-IS commands\n"
- "Set default metric for circuit\n"
- "Default metric value\n")
DEFUN (isis_metric_l1,
isis_metric_l1_cmd,
- "isis metric <0-16777215> level-1",
+ "isis metric (0-16777215) level-1",
"IS-IS commands\n"
"Set default metric for circuit\n"
"Default metric value\n"
"Specify metric for level-1 routing\n")
{
+ int idx_number = 2;
int met;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- met = atoi (argv[0]);
+ met = atoi (argv[idx_number]->arg);
/* RFC3787 section 5.1 */
if (circuit->area && circuit->area->oldmetric == 1 &&
@@ -596,12 +589,14 @@ DEFUN (isis_metric_l1,
return CMD_SUCCESS;
}
+
DEFUN (no_isis_metric_l1,
no_isis_metric_l1_cmd,
- "no isis metric level-1",
+ "no isis metric [(0-16777215)] level-1",
NO_STR
"IS-IS commands\n"
"Set default metric for circuit\n"
+ "Default metric value\n"
"Specify metric for level-1 routing\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -612,29 +607,22 @@ DEFUN (no_isis_metric_l1,
return CMD_SUCCESS;
}
-ALIAS (no_isis_metric_l1,
- no_isis_metric_l1_arg_cmd,
- "no isis metric <0-16777215> level-1",
- NO_STR
- "IS-IS commands\n"
- "Set default metric for circuit\n"
- "Default metric value\n"
- "Specify metric for level-1 routing\n")
DEFUN (isis_metric_l2,
isis_metric_l2_cmd,
- "isis metric <0-16777215> level-2",
+ "isis metric (0-16777215) level-2",
"IS-IS commands\n"
"Set default metric for circuit\n"
"Default metric value\n"
"Specify metric for level-2 routing\n")
{
+ int idx_number = 2;
int met;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- met = atoi (argv[0]);
+ met = atoi (argv[idx_number]->arg);
/* RFC3787 section 5.1 */
if (circuit->area && circuit->area->oldmetric == 1 &&
@@ -660,12 +648,14 @@ DEFUN (isis_metric_l2,
return CMD_SUCCESS;
}
+
DEFUN (no_isis_metric_l2,
no_isis_metric_l2_cmd,
- "no isis metric level-2",
+ "no isis metric [(0-16777215)] level-2",
NO_STR
"IS-IS commands\n"
"Set default metric for circuit\n"
+ "Default metric value\n"
"Specify metric for level-2 routing\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -676,30 +666,23 @@ DEFUN (no_isis_metric_l2,
return CMD_SUCCESS;
}
-ALIAS (no_isis_metric_l2,
- no_isis_metric_l2_arg_cmd,
- "no isis metric <0-16777215> level-2",
- NO_STR
- "IS-IS commands\n"
- "Set default metric for circuit\n"
- "Default metric value\n"
- "Specify metric for level-2 routing\n")
/* end of metrics */
DEFUN (isis_hello_interval,
isis_hello_interval_cmd,
- "isis hello-interval <1-600>",
+ "isis hello-interval (1-600)",
"IS-IS commands\n"
"Set Hello interval\n"
"Hello interval value\n"
"Holdtime 1 seconds, interval depends on multiplier\n")
{
+ int idx_number = 2;
int interval;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- interval = atoi (argv[0]);
+ interval = atoi (argv[idx_number]->arg);
if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL)
{
vty_out (vty, "Invalid hello-interval %d - should be <1-600>%s",
@@ -713,12 +696,14 @@ DEFUN (isis_hello_interval,
return CMD_SUCCESS;
}
+
DEFUN (no_isis_hello_interval,
no_isis_hello_interval_cmd,
- "no isis hello-interval",
+ "no isis hello-interval [(1-600)]",
NO_STR
"IS-IS commands\n"
- "Set Hello interval\n")
+ "Set Hello interval\n"
+ "Holdtime 1 second, interval depends on multiplier\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
@@ -730,30 +715,23 @@ DEFUN (no_isis_hello_interval,
return CMD_SUCCESS;
}
-ALIAS (no_isis_hello_interval,
- no_isis_hello_interval_arg_cmd,
- "no isis hello-interval <1-600>",
- NO_STR
- "IS-IS commands\n"
- "Set Hello interval\n"
- "Hello interval value\n"
- "Holdtime 1 second, interval depends on multiplier\n")
DEFUN (isis_hello_interval_l1,
isis_hello_interval_l1_cmd,
- "isis hello-interval <1-600> level-1",
+ "isis hello-interval (1-600) level-1",
"IS-IS commands\n"
"Set Hello interval\n"
"Hello interval value\n"
"Holdtime 1 second, interval depends on multiplier\n"
"Specify hello-interval for level-1 IIHs\n")
{
+ int idx_number = 2;
long interval;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- interval = atoi (argv[0]);
+ interval = atoi (argv[idx_number]->arg);
if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL)
{
vty_out (vty, "Invalid hello-interval %ld - should be <1-600>%s",
@@ -766,12 +744,14 @@ DEFUN (isis_hello_interval_l1,
return CMD_SUCCESS;
}
+
DEFUN (no_isis_hello_interval_l1,
no_isis_hello_interval_l1_cmd,
- "no isis hello-interval level-1",
+ "no isis hello-interval [(1-600)] level-1",
NO_STR
"IS-IS commands\n"
"Set Hello interval\n"
+ "Holdtime 1 second, interval depends on multiplier\n"
"Specify hello-interval for level-1 IIHs\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -783,31 +763,23 @@ DEFUN (no_isis_hello_interval_l1,
return CMD_SUCCESS;
}
-ALIAS (no_isis_hello_interval_l1,
- no_isis_hello_interval_l1_arg_cmd,
- "no isis hello-interval <1-600> level-1",
- NO_STR
- "IS-IS commands\n"
- "Set Hello interval\n"
- "Hello interval value\n"
- "Holdtime 1 second, interval depends on multiplier\n"
- "Specify hello-interval for level-1 IIHs\n")
DEFUN (isis_hello_interval_l2,
isis_hello_interval_l2_cmd,
- "isis hello-interval <1-600> level-2",
+ "isis hello-interval (1-600) level-2",
"IS-IS commands\n"
"Set Hello interval\n"
"Hello interval value\n"
"Holdtime 1 second, interval depends on multiplier\n"
"Specify hello-interval for level-2 IIHs\n")
{
+ int idx_number = 2;
long interval;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- interval = atoi (argv[0]);
+ interval = atoi (argv[idx_number]->arg);
if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL)
{
vty_out (vty, "Invalid hello-interval %ld - should be <1-600>%s",
@@ -820,12 +792,14 @@ DEFUN (isis_hello_interval_l2,
return CMD_SUCCESS;
}
+
DEFUN (no_isis_hello_interval_l2,
no_isis_hello_interval_l2_cmd,
- "no isis hello-interval level-2",
+ "no isis hello-interval [(1-600)] level-2",
NO_STR
"IS-IS commands\n"
"Set Hello interval\n"
+ "Holdtime 1 second, interval depends on multiplier\n"
"Specify hello-interval for level-2 IIHs\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -837,29 +811,21 @@ DEFUN (no_isis_hello_interval_l2,
return CMD_SUCCESS;
}
-ALIAS (no_isis_hello_interval_l2,
- no_isis_hello_interval_l2_arg_cmd,
- "no isis hello-interval <1-600> level-2",
- NO_STR
- "IS-IS commands\n"
- "Set Hello interval\n"
- "Hello interval value\n"
- "Holdtime 1 second, interval depends on multiplier\n"
- "Specify hello-interval for level-2 IIHs\n")
DEFUN (isis_hello_multiplier,
isis_hello_multiplier_cmd,
- "isis hello-multiplier <2-100>",
+ "isis hello-multiplier (2-100)",
"IS-IS commands\n"
"Set multiplier for Hello holding time\n"
"Hello multiplier value\n")
{
+ int idx_number = 2;
int mult;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- mult = atoi (argv[0]);
+ mult = atoi (argv[idx_number]->arg);
if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER)
{
vty_out (vty, "Invalid hello-multiplier %d - should be <2-100>%s",
@@ -873,12 +839,14 @@ DEFUN (isis_hello_multiplier,
return CMD_SUCCESS;
}
+
DEFUN (no_isis_hello_multiplier,
no_isis_hello_multiplier_cmd,
- "no isis hello-multiplier",
+ "no isis hello-multiplier [(2-100)]",
NO_STR
"IS-IS commands\n"
- "Set multiplier for Hello holding time\n")
+ "Set multiplier for Hello holding time\n"
+ "Hello multiplier value\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
@@ -890,28 +858,22 @@ DEFUN (no_isis_hello_multiplier,
return CMD_SUCCESS;
}
-ALIAS (no_isis_hello_multiplier,
- no_isis_hello_multiplier_arg_cmd,
- "no isis hello-multiplier <2-100>",
- NO_STR
- "IS-IS commands\n"
- "Set multiplier for Hello holding time\n"
- "Hello multiplier value\n")
DEFUN (isis_hello_multiplier_l1,
isis_hello_multiplier_l1_cmd,
- "isis hello-multiplier <2-100> level-1",
+ "isis hello-multiplier (2-100) level-1",
"IS-IS commands\n"
"Set multiplier for Hello holding time\n"
"Hello multiplier value\n"
"Specify hello multiplier for level-1 IIHs\n")
{
+ int idx_number = 2;
int mult;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- mult = atoi (argv[0]);
+ mult = atoi (argv[idx_number]->arg);
if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER)
{
vty_out (vty, "Invalid hello-multiplier %d - should be <2-100>%s",
@@ -924,12 +886,14 @@ DEFUN (isis_hello_multiplier_l1,
return CMD_SUCCESS;
}
+
DEFUN (no_isis_hello_multiplier_l1,
no_isis_hello_multiplier_l1_cmd,
- "no isis hello-multiplier level-1",
+ "no isis hello-multiplier [(2-100)] level-1",
NO_STR
"IS-IS commands\n"
"Set multiplier for Hello holding time\n"
+ "Hello multiplier value\n"
"Specify hello multiplier for level-1 IIHs\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -941,29 +905,22 @@ DEFUN (no_isis_hello_multiplier_l1,
return CMD_SUCCESS;
}
-ALIAS (no_isis_hello_multiplier_l1,
- no_isis_hello_multiplier_l1_arg_cmd,
- "no isis hello-multiplier <2-100> level-1",
- NO_STR
- "IS-IS commands\n"
- "Set multiplier for Hello holding time\n"
- "Hello multiplier value\n"
- "Specify hello multiplier for level-1 IIHs\n")
DEFUN (isis_hello_multiplier_l2,
isis_hello_multiplier_l2_cmd,
- "isis hello-multiplier <2-100> level-2",
+ "isis hello-multiplier (2-100) level-2",
"IS-IS commands\n"
"Set multiplier for Hello holding time\n"
"Hello multiplier value\n"
"Specify hello multiplier for level-2 IIHs\n")
{
+ int idx_number = 2;
int mult;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- mult = atoi (argv[0]);
+ mult = atoi (argv[idx_number]->arg);
if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER)
{
vty_out (vty, "Invalid hello-multiplier %d - should be <2-100>%s",
@@ -976,12 +933,14 @@ DEFUN (isis_hello_multiplier_l2,
return CMD_SUCCESS;
}
+
DEFUN (no_isis_hello_multiplier_l2,
no_isis_hello_multiplier_l2_cmd,
- "no isis hello-multiplier level-2",
+ "no isis hello-multiplier [(2-100)] level-2",
NO_STR
"IS-IS commands\n"
"Set multiplier for Hello holding time\n"
+ "Hello multiplier value\n"
"Specify hello multiplier for level-2 IIHs\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -993,14 +952,6 @@ DEFUN (no_isis_hello_multiplier_l2,
return CMD_SUCCESS;
}
-ALIAS (no_isis_hello_multiplier_l2,
- no_isis_hello_multiplier_l2_arg_cmd,
- "no isis hello-multiplier <2-100> level-2",
- NO_STR
- "IS-IS commands\n"
- "Set multiplier for Hello holding time\n"
- "Hello multiplier value\n"
- "Specify hello multiplier for level-2 IIHs\n")
DEFUN (isis_hello_padding,
isis_hello_padding_cmd,
@@ -1039,17 +990,18 @@ DEFUN (no_isis_hello_padding,
DEFUN (csnp_interval,
csnp_interval_cmd,
- "isis csnp-interval <1-600>",
+ "isis csnp-interval (1-600)",
"IS-IS commands\n"
"Set CSNP interval in seconds\n"
"CSNP interval value\n")
{
+ int idx_number = 2;
unsigned long interval;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- interval = atol (argv[0]);
+ interval = atol (argv[idx_number]->arg);
if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL)
{
vty_out (vty, "Invalid csnp-interval %lu - should be <1-600>%s",
@@ -1063,12 +1015,14 @@ DEFUN (csnp_interval,
return CMD_SUCCESS;
}
+
DEFUN (no_csnp_interval,
no_csnp_interval_cmd,
- "no isis csnp-interval",
+ "no isis csnp-interval [(1-600)]",
NO_STR
"IS-IS commands\n"
- "Set CSNP interval in seconds\n")
+ "Set CSNP interval in seconds\n"
+ "CSNP interval value\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
@@ -1080,28 +1034,22 @@ DEFUN (no_csnp_interval,
return CMD_SUCCESS;
}
-ALIAS (no_csnp_interval,
- no_csnp_interval_arg_cmd,
- "no isis csnp-interval <1-600>",
- NO_STR
- "IS-IS commands\n"
- "Set CSNP interval in seconds\n"
- "CSNP interval value\n")
DEFUN (csnp_interval_l1,
csnp_interval_l1_cmd,
- "isis csnp-interval <1-600> level-1",
+ "isis csnp-interval (1-600) level-1",
"IS-IS commands\n"
"Set CSNP interval in seconds\n"
"CSNP interval value\n"
"Specify interval for level-1 CSNPs\n")
{
+ int idx_number = 2;
unsigned long interval;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- interval = atol (argv[0]);
+ interval = atol (argv[idx_number]->arg);
if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL)
{
vty_out (vty, "Invalid csnp-interval %lu - should be <1-600>%s",
@@ -1114,12 +1062,14 @@ DEFUN (csnp_interval_l1,
return CMD_SUCCESS;
}
+
DEFUN (no_csnp_interval_l1,
no_csnp_interval_l1_cmd,
- "no isis csnp-interval level-1",
+ "no isis csnp-interval [(1-600)] level-1",
NO_STR
"IS-IS commands\n"
"Set CSNP interval in seconds\n"
+ "CSNP interval value\n"
"Specify interval for level-1 CSNPs\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -1131,29 +1081,22 @@ DEFUN (no_csnp_interval_l1,
return CMD_SUCCESS;
}
-ALIAS (no_csnp_interval_l1,
- no_csnp_interval_l1_arg_cmd,
- "no isis csnp-interval <1-600> level-1",
- NO_STR
- "IS-IS commands\n"
- "Set CSNP interval in seconds\n"
- "CSNP interval value\n"
- "Specify interval for level-1 CSNPs\n")
DEFUN (csnp_interval_l2,
csnp_interval_l2_cmd,
- "isis csnp-interval <1-600> level-2",
+ "isis csnp-interval (1-600) level-2",
"IS-IS commands\n"
"Set CSNP interval in seconds\n"
"CSNP interval value\n"
"Specify interval for level-2 CSNPs\n")
{
+ int idx_number = 2;
unsigned long interval;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- interval = atol (argv[0]);
+ interval = atol (argv[idx_number]->arg);
if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL)
{
vty_out (vty, "Invalid csnp-interval %lu - should be <1-600>%s",
@@ -1166,12 +1109,14 @@ DEFUN (csnp_interval_l2,
return CMD_SUCCESS;
}
+
DEFUN (no_csnp_interval_l2,
no_csnp_interval_l2_cmd,
- "no isis csnp-interval level-2",
+ "no isis csnp-interval [(1-600)] level-2",
NO_STR
"IS-IS commands\n"
"Set CSNP interval in seconds\n"
+ "CSNP interval value\n"
"Specify interval for level-2 CSNPs\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -1183,28 +1128,21 @@ DEFUN (no_csnp_interval_l2,
return CMD_SUCCESS;
}
-ALIAS (no_csnp_interval_l2,
- no_csnp_interval_l2_arg_cmd,
- "no isis csnp-interval <1-600> level-2",
- NO_STR
- "IS-IS commands\n"
- "Set CSNP interval in seconds\n"
- "CSNP interval value\n"
- "Specify interval for level-2 CSNPs\n")
DEFUN (psnp_interval,
psnp_interval_cmd,
- "isis psnp-interval <1-120>",
+ "isis psnp-interval (1-120)",
"IS-IS commands\n"
"Set PSNP interval in seconds\n"
"PSNP interval value\n")
{
+ int idx_number = 2;
unsigned long interval;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- interval = atol (argv[0]);
+ interval = atol (argv[idx_number]->arg);
if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL)
{
vty_out (vty, "Invalid psnp-interval %lu - should be <1-120>%s",
@@ -1218,12 +1156,14 @@ DEFUN (psnp_interval,
return CMD_SUCCESS;
}
+
DEFUN (no_psnp_interval,
no_psnp_interval_cmd,
- "no isis psnp-interval",
+ "no isis psnp-interval [(1-120)]",
NO_STR
"IS-IS commands\n"
- "Set PSNP interval in seconds\n")
+ "Set PSNP interval in seconds\n"
+ "PSNP interval value\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
@@ -1235,28 +1175,22 @@ DEFUN (no_psnp_interval,
return CMD_SUCCESS;
}
-ALIAS (no_psnp_interval,
- no_psnp_interval_arg_cmd,
- "no isis psnp-interval <1-120>",
- NO_STR
- "IS-IS commands\n"
- "Set PSNP interval in seconds\n"
- "PSNP interval value\n")
DEFUN (psnp_interval_l1,
psnp_interval_l1_cmd,
- "isis psnp-interval <1-120> level-1",
+ "isis psnp-interval (1-120) level-1",
"IS-IS commands\n"
"Set PSNP interval in seconds\n"
"PSNP interval value\n"
"Specify interval for level-1 PSNPs\n")
{
+ int idx_number = 2;
unsigned long interval;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- interval = atol (argv[0]);
+ interval = atol (argv[idx_number]->arg);
if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL)
{
vty_out (vty, "Invalid psnp-interval %lu - should be <1-120>%s",
@@ -1269,12 +1203,14 @@ DEFUN (psnp_interval_l1,
return CMD_SUCCESS;
}
+
DEFUN (no_psnp_interval_l1,
no_psnp_interval_l1_cmd,
- "no isis psnp-interval level-1",
+ "no isis psnp-interval [(1-120)] level-1",
NO_STR
"IS-IS commands\n"
"Set PSNP interval in seconds\n"
+ "PSNP interval value\n"
"Specify interval for level-1 PSNPs\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -1286,29 +1222,22 @@ DEFUN (no_psnp_interval_l1,
return CMD_SUCCESS;
}
-ALIAS (no_psnp_interval_l1,
- no_psnp_interval_l1_arg_cmd,
- "no isis psnp-interval <1-120> level-1",
- NO_STR
- "IS-IS commands\n"
- "Set PSNP interval in seconds\n"
- "PSNP interval value\n"
- "Specify interval for level-1 PSNPs\n")
DEFUN (psnp_interval_l2,
psnp_interval_l2_cmd,
- "isis psnp-interval <1-120> level-2",
+ "isis psnp-interval (1-120) level-2",
"IS-IS commands\n"
"Set PSNP interval in seconds\n"
"PSNP interval value\n"
"Specify interval for level-2 PSNPs\n")
{
+ int idx_number = 2;
unsigned long interval;
struct isis_circuit *circuit = isis_circuit_lookup (vty);
if (!circuit)
return CMD_ERR_NO_MATCH;
- interval = atol (argv[0]);
+ interval = atol (argv[idx_number]->arg);
if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL)
{
vty_out (vty, "Invalid psnp-interval %lu - should be <1-120>%s",
@@ -1321,12 +1250,14 @@ DEFUN (psnp_interval_l2,
return CMD_SUCCESS;
}
+
DEFUN (no_psnp_interval_l2,
no_psnp_interval_l2_cmd,
- "no isis psnp-interval level-2",
+ "no isis psnp-interval [(1-120)] level-2",
NO_STR
"IS-IS commands\n"
"Set PSNP interval in seconds\n"
+ "PSNP interval value\n"
"Specify interval for level-2 PSNPs\n")
{
struct isis_circuit *circuit = isis_circuit_lookup (vty);
@@ -1338,14 +1269,6 @@ DEFUN (no_psnp_interval_l2,
return CMD_SUCCESS;
}
-ALIAS (no_psnp_interval_l2,
- no_psnp_interval_l2_arg_cmd,
- "no isis psnp-interval <1-120> level-2",
- NO_STR
- "IS-IS commands\n"
- "Set PSNP interval in seconds\n"
- "PSNP interval value\n"
- "Specify interval for level-2 PSNPs\n")
static int
validate_metric_style_narrow (struct vty *vty, struct isis_area *area)
@@ -1387,16 +1310,17 @@ validate_metric_style_narrow (struct vty *vty, struct isis_area *area)
DEFUN (metric_style,
metric_style_cmd,
- "metric-style (narrow|transition|wide)",
+ "metric-style <narrow|transition|wide>",
"Use old-style (ISO 10589) or new-style packet formats\n"
"Use old style of TLVs with narrow metric\n"
"Send and accept both styles of TLVs during transition\n"
"Use new style of TLVs to carry wider metric\n")
{
+ int idx_metric_style = 1;
VTY_DECLVAR_CONTEXT (isis_area, area);
int ret;
- if (strncmp (argv[0], "w", 1) == 0)
+ if (strncmp (argv[idx_metric_style]->arg, "w", 1) == 0)
{
isis_area_metricstyle_set(area, false, true);
return CMD_SUCCESS;
@@ -1406,9 +1330,9 @@ DEFUN (metric_style,
if (ret != CMD_SUCCESS)
return ret;
- if (strncmp (argv[0], "t", 1) == 0)
+ if (strncmp (argv[idx_metric_style]->arg, "t", 1) == 0)
isis_area_metricstyle_set(area, true, true);
- else if (strncmp (argv[0], "n", 1) == 0)
+ else if (strncmp (argv[idx_metric_style]->arg, "n", 1) == 0)
isis_area_metricstyle_set(area, true, false);
return CMD_SUCCESS;
@@ -1471,6 +1395,7 @@ DEFUN (set_attached_bit,
DEFUN (no_set_attached_bit,
no_set_attached_bit_cmd,
"no set-attached-bit",
+ NO_STR
"Reset attached bit\n")
{
VTY_DECLVAR_CONTEXT (isis_area, area);
@@ -1529,45 +1454,43 @@ static int area_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu)
DEFUN (area_lsp_mtu,
area_lsp_mtu_cmd,
- "lsp-mtu <128-4352>",
+ "lsp-mtu (128-4352)",
"Configure the maximum size of generated LSPs\n"
"Maximum size of generated LSPs\n")
{
+ int idx_number = 1;
unsigned int lsp_mtu;
- VTY_GET_INTEGER_RANGE("lsp-mtu", lsp_mtu, argv[0], 128, 4352);
+ VTY_GET_INTEGER_RANGE("lsp-mtu", lsp_mtu, argv[idx_number]->arg, 128, 4352);
return area_lsp_mtu_set(vty, lsp_mtu);
}
+
DEFUN (no_area_lsp_mtu,
no_area_lsp_mtu_cmd,
- "no lsp-mtu",
+ "no lsp-mtu [(128-4352)]",
NO_STR
- "Configure the maximum size of generated LSPs\n")
+ "Configure the maximum size of generated LSPs\n"
+ "Maximum size of generated LSPs\n")
{
return area_lsp_mtu_set(vty, DEFAULT_LSP_MTU);
}
-ALIAS (no_area_lsp_mtu,
- no_area_lsp_mtu_arg_cmd,
- "no lsp-mtu <128-4352>",
- NO_STR
- "Configure the maximum size of generated LSPs\n"
- "Maximum size of generated LSPs\n");
DEFUN (is_type,
is_type_cmd,
- "is-type (level-1|level-1-2|level-2-only)",
+ "is-type <level-1|level-1-2|level-2-only>",
"IS Level for this routing process (OSI only)\n"
"Act as a station router only\n"
"Act as both a station router and an area router\n"
"Act as an area router only\n")
{
+ int idx_level = 1;
VTY_DECLVAR_CONTEXT (isis_area, area);
int type;
- type = string2circuit_t (argv[0]);
+ type = string2circuit_t (argv[idx_level]->arg);
if (!type)
{
vty_out (vty, "Unknown IS level %s", VTY_NEWLINE);
@@ -1581,7 +1504,7 @@ DEFUN (is_type,
DEFUN (no_is_type,
no_is_type_cmd,
- "no is-type (level-1|level-1-2|level-2-only)",
+ "no is-type <level-1|level-1-2|level-2-only>",
NO_STR
"IS Level for this routing process (OSI only)\n"
"Act as a station router only\n"
@@ -1638,142 +1561,79 @@ set_lsp_gen_interval (struct vty *vty, struct isis_area *area,
DEFUN (lsp_gen_interval,
lsp_gen_interval_cmd,
- "lsp-gen-interval <1-120>",
- "Minimum interval between regenerating same LSP\n"
- "Minimum interval in seconds\n")
-{
- VTY_DECLVAR_CONTEXT (isis_area, area);
- uint16_t interval;
- int level;
-
- interval = atoi (argv[0]);
- level = IS_LEVEL_1 | IS_LEVEL_2;
- return set_lsp_gen_interval (vty, area, interval, level);
-}
-
-DEFUN (no_lsp_gen_interval,
- no_lsp_gen_interval_cmd,
- "no lsp-gen-interval",
- NO_STR
- "Minimum interval between regenerating same LSP\n")
-{
- VTY_DECLVAR_CONTEXT (isis_area, area);
- uint16_t interval;
- int level;
-
- interval = DEFAULT_MIN_LSP_GEN_INTERVAL;
- level = IS_LEVEL_1 | IS_LEVEL_2;
- return set_lsp_gen_interval (vty, area, interval, level);
-}
-
-ALIAS (no_lsp_gen_interval,
- no_lsp_gen_interval_arg_cmd,
- "no lsp-gen-interval <1-120>",
- NO_STR
- "Minimum interval between regenerating same LSP\n"
- "Minimum interval in seconds\n")
-
-DEFUN (lsp_gen_interval_l1,
- lsp_gen_interval_l1_cmd,
- "lsp-gen-interval level-1 <1-120>",
+ "lsp-gen-interval [<level-1|level-2>] (1-120)",
"Minimum interval between regenerating same LSP\n"
"Set interval for level 1 only\n"
+ "Set interval for level 2 only\n"
"Minimum interval in seconds\n")
{
+ int idx = 0;
VTY_DECLVAR_CONTEXT (isis_area, area);
uint16_t interval;
int level;
- interval = atoi (argv[0]);
- level = IS_LEVEL_1;
- return set_lsp_gen_interval (vty, area, interval, level);
-}
+ level = 0;
+ level |= argv_find (argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0;
+ level |= argv_find (argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0;
+ if (!level)
+ level = IS_LEVEL_1 | IS_LEVEL_2;
-DEFUN (no_lsp_gen_interval_l1,
- no_lsp_gen_interval_l1_cmd,
- "no lsp-gen-interval level-1",
- NO_STR
- "Minimum interval between regenerating same LSP\n"
- "Set interval for level 1 only\n")
-{
- VTY_DECLVAR_CONTEXT (isis_area, area);
- uint16_t interval;
- int level;
+ argv_find (argv, argc, "(1-120)", &idx);
- interval = DEFAULT_MIN_LSP_GEN_INTERVAL;
- level = IS_LEVEL_1;
+ interval = atoi (argv[idx]->arg);
return set_lsp_gen_interval (vty, area, interval, level);
}
-ALIAS (no_lsp_gen_interval_l1,
- no_lsp_gen_interval_l1_arg_cmd,
- "no lsp-gen-interval level-1 <1-120>",
+DEFUN (no_lsp_gen_interval,
+ no_lsp_gen_interval_cmd,
+ "no lsp-gen-interval [<level-1|level-2>] [(1-120)]",
NO_STR
"Minimum interval between regenerating same LSP\n"
"Set interval for level 1 only\n"
- "Minimum interval in seconds\n")
-
-DEFUN (lsp_gen_interval_l2,
- lsp_gen_interval_l2_cmd,
- "lsp-gen-interval level-2 <1-120>",
- "Minimum interval between regenerating same LSP\n"
"Set interval for level 2 only\n"
"Minimum interval in seconds\n")
{
+ int idx = 0;
VTY_DECLVAR_CONTEXT (isis_area, area);
uint16_t interval;
int level;
- interval = atoi (argv[0]);
- level = IS_LEVEL_2;
- return set_lsp_gen_interval (vty, area, interval, level);
-}
-
-DEFUN (no_lsp_gen_interval_l2,
- no_lsp_gen_interval_l2_cmd,
- "no lsp-gen-interval level-2",
- NO_STR
- "Minimum interval between regenerating same LSP\n"
- "Set interval for level 2 only\n")
-{
- VTY_DECLVAR_CONTEXT (isis_area, area);
- uint16_t interval;
- int level;
+ level = 0;
+ level |= argv_find (argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0;
+ level |= argv_find (argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0;
+ if (!level)
+ level = IS_LEVEL_1 | IS_LEVEL_2;
interval = DEFAULT_MIN_LSP_GEN_INTERVAL;
- level = IS_LEVEL_2;
return set_lsp_gen_interval (vty, area, interval, level);
}
-ALIAS (no_lsp_gen_interval_l2,
- no_lsp_gen_interval_l2_arg_cmd,
- "no lsp-gen-interval level-2 <1-120>",
- NO_STR
- "Minimum interval between regenerating same LSP\n"
- "Set interval for level 2 only\n"
- "Minimum interval in seconds\n")
-
DEFUN (spf_interval,
spf_interval_cmd,
- "spf-interval <1-120>",
+ "spf-interval (1-120)",
"Minimum interval between SPF calculations\n"
"Minimum interval between consecutive SPFs in seconds\n")
{
+ int idx_number = 1;
VTY_DECLVAR_CONTEXT (isis_area, area);
u_int16_t interval;
- interval = atoi (argv[0]);
+ interval = atoi (argv[idx_number]->arg);
area->min_spf_interval[0] = interval;
area->min_spf_interval[1] = interval;
return CMD_SUCCESS;
}
+
DEFUN (no_spf_interval,
no_spf_interval_cmd,
- "no spf-interval",
+ "no spf-interval [[<level-1|level-2>] (1-120)]",
NO_STR
- "Minimum interval between SPF calculations\n")
+ "Minimum interval between SPF calculations\n"
+ "Set interval for level 1 only\n"
+ "Set interval for level 2 only\n"
+ "Minimum interval between consecutive SPFs in seconds\n")
{
VTY_DECLVAR_CONTEXT (isis_area, area);
@@ -1783,24 +1643,19 @@ DEFUN (no_spf_interval,
return CMD_SUCCESS;
}
-ALIAS (no_spf_interval,
- no_spf_interval_arg_cmd,
- "no spf-interval <1-120>",
- NO_STR
- "Minimum interval between SPF calculations\n"
- "Minimum interval between consecutive SPFs in seconds\n")
DEFUN (spf_interval_l1,
spf_interval_l1_cmd,
- "spf-interval level-1 <1-120>",
+ "spf-interval level-1 (1-120)",
"Minimum interval between SPF calculations\n"
"Set interval for level 1 only\n"
"Minimum interval between consecutive SPFs in seconds\n")
{
+ int idx_number = 2;
VTY_DECLVAR_CONTEXT (isis_area, area);
u_int16_t interval;
- interval = atoi (argv[0]);
+ interval = atoi (argv[idx_number]->arg);
area->min_spf_interval[0] = interval;
return CMD_SUCCESS;
@@ -1820,25 +1675,19 @@ DEFUN (no_spf_interval_l1,
return CMD_SUCCESS;
}
-ALIAS (no_spf_interval,
- no_spf_interval_l1_arg_cmd,
- "no spf-interval level-1 <1-120>",
- NO_STR
- "Minimum interval between SPF calculations\n"
- "Set interval for level 1 only\n"
- "Minimum interval between consecutive SPFs in seconds\n")
DEFUN (spf_interval_l2,
spf_interval_l2_cmd,
- "spf-interval level-2 <1-120>",
+ "spf-interval level-2 (1-120)",
"Minimum interval between SPF calculations\n"
"Set interval for level 2 only\n"
"Minimum interval between consecutive SPFs in seconds\n")
{
+ int idx_number = 2;
VTY_DECLVAR_CONTEXT (isis_area, area);
u_int16_t interval;
- interval = atoi (argv[0]);
+ interval = atoi (argv[idx_number]->arg);
area->min_spf_interval[1] = interval;
return CMD_SUCCESS;
@@ -1858,13 +1707,6 @@ DEFUN (no_spf_interval_l2,
return CMD_SUCCESS;
}
-ALIAS (no_spf_interval,
- no_spf_interval_l2_arg_cmd,
- "no spf-interval level-2 <1-120>",
- NO_STR
- "Minimum interval between SPF calculations\n"
- "Set interval for level 2 only\n"
- "Minimum interval between consecutive SPFs in seconds\n")
static int
area_max_lsp_lifetime_set(struct vty *vty, int level,
@@ -1914,79 +1756,46 @@ area_max_lsp_lifetime_set(struct vty *vty, int level,
DEFUN (max_lsp_lifetime,
max_lsp_lifetime_cmd,
- "max-lsp-lifetime <350-65535>",
+ "max-lsp-lifetime [<level-1|level-2>] (350-65535)",
"Maximum LSP lifetime\n"
+ "Maximum LSP lifetime for Level 1 only\n"
+ "Maximum LSP lifetime for Level 2 only\n"
"LSP lifetime in seconds\n")
{
- return area_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, atoi(argv[0]));
-}
+ int idx = 0;
+ unsigned int level = IS_LEVEL_1_AND_2;
-DEFUN (no_max_lsp_lifetime,
- no_max_lsp_lifetime_cmd,
- "no max-lsp-lifetime",
- NO_STR
- "LSP lifetime in seconds\n")
-{
- return area_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2,
- DEFAULT_LSP_LIFETIME);
-}
+ if (argv_find (argv, argc, "level-1", &idx))
+ level = IS_LEVEL_1;
+ else if (argv_find (argv, argc, "level-2", &idx))
+ level = IS_LEVEL_2;
-ALIAS (no_max_lsp_lifetime,
- no_max_lsp_lifetime_arg_cmd,
- "no max-lsp-lifetime <350-65535>",
- NO_STR
- "Maximum LSP lifetime\n"
- "LSP lifetime in seconds\n")
+ argv_find (argv, argc, "(350-65535)", &idx);
+ int lifetime = atoi(argv[idx]->arg);
-DEFUN (max_lsp_lifetime_l1,
- max_lsp_lifetime_l1_cmd,
- "max-lsp-lifetime level-1 <350-65535>",
- "Maximum LSP lifetime for Level 1 only\n"
- "LSP lifetime for Level 1 only in seconds\n")
-{
- return area_max_lsp_lifetime_set(vty, IS_LEVEL_1, atoi(argv[0]));
+ return area_max_lsp_lifetime_set(vty, level, lifetime);
}
-DEFUN (no_max_lsp_lifetime_l1,
- no_max_lsp_lifetime_l1_cmd,
- "no max-lsp-lifetime level-1",
- NO_STR
- "LSP lifetime for Level 1 only in seconds\n")
-{
- return area_max_lsp_lifetime_set(vty, IS_LEVEL_1, DEFAULT_LSP_LIFETIME);
-}
-ALIAS (no_max_lsp_lifetime_l1,
- no_max_lsp_lifetime_l1_arg_cmd,
- "no max-lsp-lifetime level-1 <350-65535>",
+DEFUN (no_max_lsp_lifetime,
+ no_max_lsp_lifetime_cmd,
+ "no max-lsp-lifetime [<level-1|level-2>] [(350-65535)]",
NO_STR
+ "Maximum LSP lifetime\n"
"Maximum LSP lifetime for Level 1 only\n"
- "LSP lifetime for Level 1 only in seconds\n")
-
-DEFUN (max_lsp_lifetime_l2,
- max_lsp_lifetime_l2_cmd,
- "max-lsp-lifetime level-2 <350-65535>",
"Maximum LSP lifetime for Level 2 only\n"
- "LSP lifetime for Level 2 only in seconds\n")
+ "LSP lifetime in seconds\n")
{
- return area_max_lsp_lifetime_set(vty, IS_LEVEL_2, atoi(argv[0]));
-}
+ int idx = 0;
+ unsigned int level = IS_LEVEL_1_AND_2;
-DEFUN (no_max_lsp_lifetime_l2,
- no_max_lsp_lifetime_l2_cmd,
- "no max-lsp-lifetime level-2",
- NO_STR
- "LSP lifetime for Level 2 only in seconds\n")
-{
- return area_max_lsp_lifetime_set(vty, IS_LEVEL_2, DEFAULT_LSP_LIFETIME);
-}
+ if (argv_find (argv, argc, "level-1", &idx))
+ level = IS_LEVEL_1;
+ else if (argv_find (argv, argc, "level-2", &idx))
+ level = IS_LEVEL_2;
-ALIAS (no_max_lsp_lifetime_l2,
- no_max_lsp_lifetime_l2_arg_cmd,
- "no max-lsp-lifetime level-2 <350-65535>",
- NO_STR
- "Maximum LSP lifetime for Level 2 only\n"
- "LSP lifetime for Level 2 only in seconds\n")
+ return area_max_lsp_lifetime_set(vty, level, DEFAULT_LSP_LIFETIME);
+}
static int
area_lsp_refresh_interval_set(struct vty *vty, int level, uint16_t interval)
@@ -2028,81 +1837,44 @@ area_lsp_refresh_interval_set(struct vty *vty, int level, uint16_t interval)
DEFUN (lsp_refresh_interval,
lsp_refresh_interval_cmd,
- "lsp-refresh-interval <1-65235>",
+ "lsp-refresh-interval [<level-1|level-2>] (1-65235)",
"LSP refresh interval\n"
+ "LSP refresh interval for Level 1 only\n"
+ "LSP refresh interval for Level 2 only\n"
"LSP refresh interval in seconds\n")
{
- return area_lsp_refresh_interval_set(vty, IS_LEVEL_1_AND_2, atoi(argv[0]));
+ int idx = 0;
+ unsigned int level = IS_LEVEL_1_AND_2;
+ unsigned int interval = 0;
+
+ if (argv_find (argv, argc, "level-1", &idx))
+ level = IS_LEVEL_1;
+ else if (argv_find (argv, argc, "level-2", &idx))
+ level = IS_LEVEL_2;
+
+ interval = atoi(argv[argc-1]->arg);
+ return area_lsp_refresh_interval_set(vty, level, interval);
}
DEFUN (no_lsp_refresh_interval,
no_lsp_refresh_interval_cmd,
- "no lsp-refresh-interval",
- NO_STR
- "LSP refresh interval in seconds\n")
-{
- return area_lsp_refresh_interval_set(vty, IS_LEVEL_1_AND_2,
- DEFAULT_MAX_LSP_GEN_INTERVAL);
-}
-
-ALIAS (no_lsp_refresh_interval,
- no_lsp_refresh_interval_arg_cmd,
- "no lsp-refresh-interval <1-65235>",
+ "no lsp-refresh-interval [<level-1|level-2>] [(1-65235)]",
NO_STR
"LSP refresh interval\n"
- "LSP refresh interval in seconds\n")
-
-DEFUN (lsp_refresh_interval_l1,
- lsp_refresh_interval_l1_cmd,
- "lsp-refresh-interval level-1 <1-65235>",
"LSP refresh interval for Level 1 only\n"
- "LSP refresh interval for Level 1 only in seconds\n")
-{
- return area_lsp_refresh_interval_set(vty, IS_LEVEL_1, atoi(argv[0]));
-}
-
-DEFUN (no_lsp_refresh_interval_l1,
- no_lsp_refresh_interval_l1_cmd,
- "no lsp-refresh-interval level-1",
- NO_STR
- "LSP refresh interval for Level 1 only in seconds\n")
-{
- return area_lsp_refresh_interval_set(vty, IS_LEVEL_1,
- DEFAULT_MAX_LSP_GEN_INTERVAL);
-}
-
-ALIAS (no_lsp_refresh_interval_l1,
- no_lsp_refresh_interval_l1_arg_cmd,
- "no lsp-refresh-interval level-1 <1-65235>",
- NO_STR
- "LSP refresh interval for Level 1 only\n"
- "LSP refresh interval for Level 1 only in seconds\n")
-
-DEFUN (lsp_refresh_interval_l2,
- lsp_refresh_interval_l2_cmd,
- "lsp-refresh-interval level-2 <1-65235>",
"LSP refresh interval for Level 2 only\n"
- "LSP refresh interval for Level 2 only in seconds\n")
+ "LSP refresh interval in seconds\n")
{
- return area_lsp_refresh_interval_set(vty, IS_LEVEL_2, atoi(argv[0]));
-}
+ int idx = 0;
+ unsigned int level = IS_LEVEL_1_AND_2;
-DEFUN (no_lsp_refresh_interval_l2,
- no_lsp_refresh_interval_l2_cmd,
- "no lsp-refresh-interval level-2",
- NO_STR
- "LSP refresh interval for Level 2 only in seconds\n")
-{
- return area_lsp_refresh_interval_set(vty, IS_LEVEL_2,
- DEFAULT_MAX_LSP_GEN_INTERVAL);
-}
+ if (argv_find (argv, argc, "level-1", &idx))
+ level = IS_LEVEL_1;
+ else if (argv_find (argv, argc, "level-2", &idx))
+ level = IS_LEVEL_2;
-ALIAS (no_lsp_refresh_interval_l2,
- no_lsp_refresh_interval_l2_arg_cmd,
- "no lsp-refresh-interval level-2 <1-65235>",
- NO_STR
- "LSP refresh interval for Level 2 only\n"
- "LSP refresh interval for Level 2 only in seconds\n")
+ return area_lsp_refresh_interval_set(vty, level, DEFAULT_MAX_LSP_GEN_INTERVAL);
+}
static int
area_passwd_set(struct vty *vty, int level,
@@ -2122,32 +1894,38 @@ area_passwd_set(struct vty *vty, int level,
return CMD_SUCCESS;
}
+
DEFUN (area_passwd_md5,
area_passwd_md5_cmd,
- "(area-password|domain-password) md5 WORD",
+ "area-password md5 WORD [authenticate snp <send-only|validate>]",
"Configure the authentication password for an area\n"
- "Set the authentication password for a routing domain\n"
"Authentication type\n"
- "Level-wide password\n")
+ "Level-wide password\n"
+ "Authentication\n"
+ "SNP PDUs\n"
+ "Send but do not check PDUs on receiving\n"
+ "Send and check PDUs on receiving\n")
{
+ int idx_password = 0;
+ int idx_word = 2;
+ int idx_type = 5;
u_char snp_auth = 0;
- int level = (argv[0][0] == 'd') ? IS_LEVEL_2 : IS_LEVEL_1;
+ int level = strmatch(argv[idx_password]->text, "domain-password") ? IS_LEVEL_2 : IS_LEVEL_1;
- if (argc > 2)
+ if (argc > 3)
{
snp_auth = SNP_AUTH_SEND;
- if (strncmp(argv[2], "v", 1) == 0)
+ if (strmatch(argv[idx_type]->text, "validate"))
snp_auth |= SNP_AUTH_RECV;
}
return area_passwd_set(vty, level, isis_area_passwd_hmac_md5_set,
- argv[1], snp_auth);
+ argv[idx_word]->arg, snp_auth);
}
-ALIAS (area_passwd_md5,
- area_passwd_md5_snpauth_cmd,
- "(area-password|domain-password) md5 WORD authenticate snp (send-only|validate)",
- "Configure the authentication password for an area\n"
+DEFUN (domain_passwd_md5,
+ domain_passwd_md5_cmd,
+ "domain-password md5 WORD [authenticate snp <send-only|validate>]",
"Set the authentication password for a routing domain\n"
"Authentication type\n"
"Level-wide password\n"
@@ -2155,33 +1933,41 @@ ALIAS (area_passwd_md5,
"SNP PDUs\n"
"Send but do not check PDUs on receiving\n"
"Send and check PDUs on receiving\n")
+{
+ return area_passwd_md5 (self, vty, argc, argv);
+}
DEFUN (area_passwd_clear,
area_passwd_clear_cmd,
- "(area-password|domain-password) clear WORD",
+ "area-password clear WORD [authenticate snp <send-only|validate>]",
"Configure the authentication password for an area\n"
- "Set the authentication password for a routing domain\n"
"Authentication type\n"
- "Area password\n")
+ "Area password\n"
+ "Authentication\n"
+ "SNP PDUs\n"
+ "Send but do not check PDUs on receiving\n"
+ "Send and check PDUs on receiving\n")
{
+ int idx_password = 0;
+ int idx_word = 2;
+ int idx_type = 5;
u_char snp_auth = 0;
- int level = (argv[0][0] == 'd') ? IS_LEVEL_2 : IS_LEVEL_1;
+ int level = strmatch(argv[idx_password]->text, "domain-password") ? IS_LEVEL_2 : IS_LEVEL_1;
- if (argc > 2)
+ if (argc > 3)
{
snp_auth = SNP_AUTH_SEND;
- if (strncmp(argv[2], "v", 1) == 0)
+ if (strmatch (argv[idx_type]->text, "validate"))
snp_auth |= SNP_AUTH_RECV;
}
return area_passwd_set(vty, level, isis_area_passwd_cleartext_set,
- argv[1], snp_auth);
+ argv[idx_word]->arg, snp_auth);
}
-ALIAS (area_passwd_clear,
- area_passwd_clear_snpauth_cmd,
- "(area-password|domain-password) clear WORD authenticate snp (send-only|validate)",
- "Configure the authentication password for an area\n"
+DEFUN (domain_passwd_clear,
+ domain_passwd_clear_cmd,
+ "domain-password clear WORD [authenticate snp <send-only|validate>]",
"Set the authentication password for a routing domain\n"
"Authentication type\n"
"Area password\n"
@@ -2189,16 +1975,20 @@ ALIAS (area_passwd_clear,
"SNP PDUs\n"
"Send but do not check PDUs on receiving\n"
"Send and check PDUs on receiving\n")
+{
+ return area_passwd_clear (self, vty, argc, argv);
+}
DEFUN (no_area_passwd,
no_area_passwd_cmd,
- "no (area-password|domain-password)",
+ "no <area-password|domain-password>",
NO_STR
"Configure the authentication password for an area\n"
"Set the authentication password for a routing domain\n")
{
+ int idx_password = 1;
+ int level = strmatch (argv[idx_password]->text, "domain-password") ? IS_LEVEL_2 : IS_LEVEL_1;
VTY_DECLVAR_CONTEXT (isis_area, area);
- int level = (argv[0][0] == 'd') ? IS_LEVEL_2 : IS_LEVEL_1;
return isis_area_passwd_unset (area, level);
}
@@ -2207,6 +1997,7 @@ void
isis_vty_init (void)
{
install_element (INTERFACE_NODE, &ip_router_isis_cmd);
+ install_element (INTERFACE_NODE, &ip6_router_isis_cmd);
install_element (INTERFACE_NODE, &no_ip_router_isis_cmd);
install_element (INTERFACE_NODE, &isis_passive_cmd);
@@ -2220,70 +2011,51 @@ isis_vty_init (void)
install_element (INTERFACE_NODE, &isis_passwd_cmd);
install_element (INTERFACE_NODE, &no_isis_passwd_cmd);
- install_element (INTERFACE_NODE, &no_isis_passwd_arg_cmd);
install_element (INTERFACE_NODE, &isis_priority_cmd);
install_element (INTERFACE_NODE, &no_isis_priority_cmd);
- install_element (INTERFACE_NODE, &no_isis_priority_arg_cmd);
install_element (INTERFACE_NODE, &isis_priority_l1_cmd);
install_element (INTERFACE_NODE, &no_isis_priority_l1_cmd);
- install_element (INTERFACE_NODE, &no_isis_priority_l1_arg_cmd);
install_element (INTERFACE_NODE, &isis_priority_l2_cmd);
install_element (INTERFACE_NODE, &no_isis_priority_l2_cmd);
- install_element (INTERFACE_NODE, &no_isis_priority_l2_arg_cmd);
install_element (INTERFACE_NODE, &isis_metric_cmd);
install_element (INTERFACE_NODE, &no_isis_metric_cmd);
- install_element (INTERFACE_NODE, &no_isis_metric_arg_cmd);
install_element (INTERFACE_NODE, &isis_metric_l1_cmd);
install_element (INTERFACE_NODE, &no_isis_metric_l1_cmd);
- install_element (INTERFACE_NODE, &no_isis_metric_l1_arg_cmd);
install_element (INTERFACE_NODE, &isis_metric_l2_cmd);
install_element (INTERFACE_NODE, &no_isis_metric_l2_cmd);
- install_element (INTERFACE_NODE, &no_isis_metric_l2_arg_cmd);
install_element (INTERFACE_NODE, &isis_hello_interval_cmd);
install_element (INTERFACE_NODE, &no_isis_hello_interval_cmd);
- install_element (INTERFACE_NODE, &no_isis_hello_interval_arg_cmd);
install_element (INTERFACE_NODE, &isis_hello_interval_l1_cmd);
install_element (INTERFACE_NODE, &no_isis_hello_interval_l1_cmd);
- install_element (INTERFACE_NODE, &no_isis_hello_interval_l1_arg_cmd);
install_element (INTERFACE_NODE, &isis_hello_interval_l2_cmd);
install_element (INTERFACE_NODE, &no_isis_hello_interval_l2_cmd);
- install_element (INTERFACE_NODE, &no_isis_hello_interval_l2_arg_cmd);
install_element (INTERFACE_NODE, &isis_hello_multiplier_cmd);
install_element (INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
- install_element (INTERFACE_NODE, &no_isis_hello_multiplier_arg_cmd);
install_element (INTERFACE_NODE, &isis_hello_multiplier_l1_cmd);
install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l1_cmd);
- install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l1_arg_cmd);
install_element (INTERFACE_NODE, &isis_hello_multiplier_l2_cmd);
install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l2_cmd);
- install_element (INTERFACE_NODE, &no_isis_hello_multiplier_l2_arg_cmd);
install_element (INTERFACE_NODE, &isis_hello_padding_cmd);
install_element (INTERFACE_NODE, &no_isis_hello_padding_cmd);
install_element (INTERFACE_NODE, &csnp_interval_cmd);
install_element (INTERFACE_NODE, &no_csnp_interval_cmd);
- install_element (INTERFACE_NODE, &no_csnp_interval_arg_cmd);
install_element (INTERFACE_NODE, &csnp_interval_l1_cmd);
install_element (INTERFACE_NODE, &no_csnp_interval_l1_cmd);
- install_element (INTERFACE_NODE, &no_csnp_interval_l1_arg_cmd);
install_element (INTERFACE_NODE, &csnp_interval_l2_cmd);
install_element (INTERFACE_NODE, &no_csnp_interval_l2_cmd);
- install_element (INTERFACE_NODE, &no_csnp_interval_l2_arg_cmd);
install_element (INTERFACE_NODE, &psnp_interval_cmd);
install_element (INTERFACE_NODE, &no_psnp_interval_cmd);
- install_element (INTERFACE_NODE, &no_psnp_interval_arg_cmd);
install_element (INTERFACE_NODE, &psnp_interval_l1_cmd);
install_element (INTERFACE_NODE, &no_psnp_interval_l1_cmd);
- install_element (INTERFACE_NODE, &no_psnp_interval_l1_arg_cmd);
install_element (INTERFACE_NODE, &psnp_interval_l2_cmd);
install_element (INTERFACE_NODE, &no_psnp_interval_l2_cmd);
- install_element (INTERFACE_NODE, &no_psnp_interval_l2_arg_cmd);
install_element (ISIS_NODE, &metric_style_cmd);
install_element (ISIS_NODE, &no_metric_style_cmd);
@@ -2299,54 +2071,29 @@ isis_vty_init (void)
install_element (ISIS_NODE, &area_lsp_mtu_cmd);
install_element (ISIS_NODE, &no_area_lsp_mtu_cmd);
- install_element (ISIS_NODE, &no_area_lsp_mtu_arg_cmd);
install_element (ISIS_NODE, &is_type_cmd);
install_element (ISIS_NODE, &no_is_type_cmd);
install_element (ISIS_NODE, &lsp_gen_interval_cmd);
install_element (ISIS_NODE, &no_lsp_gen_interval_cmd);
- install_element (ISIS_NODE, &no_lsp_gen_interval_arg_cmd);
- install_element (ISIS_NODE, &lsp_gen_interval_l1_cmd);
- install_element (ISIS_NODE, &no_lsp_gen_interval_l1_cmd);
- install_element (ISIS_NODE, &no_lsp_gen_interval_l1_arg_cmd);
- install_element (ISIS_NODE, &lsp_gen_interval_l2_cmd);
- install_element (ISIS_NODE, &no_lsp_gen_interval_l2_cmd);
- install_element (ISIS_NODE, &no_lsp_gen_interval_l2_arg_cmd);
install_element (ISIS_NODE, &spf_interval_cmd);
install_element (ISIS_NODE, &no_spf_interval_cmd);
- install_element (ISIS_NODE, &no_spf_interval_arg_cmd);
install_element (ISIS_NODE, &spf_interval_l1_cmd);
install_element (ISIS_NODE, &no_spf_interval_l1_cmd);
- install_element (ISIS_NODE, &no_spf_interval_l1_arg_cmd);
install_element (ISIS_NODE, &spf_interval_l2_cmd);
install_element (ISIS_NODE, &no_spf_interval_l2_cmd);
- install_element (ISIS_NODE, &no_spf_interval_l2_arg_cmd);
install_element (ISIS_NODE, &max_lsp_lifetime_cmd);
install_element (ISIS_NODE, &no_max_lsp_lifetime_cmd);
- install_element (ISIS_NODE, &no_max_lsp_lifetime_arg_cmd);
- install_element (ISIS_NODE, &max_lsp_lifetime_l1_cmd);
- install_element (ISIS_NODE, &no_max_lsp_lifetime_l1_cmd);
- install_element (ISIS_NODE, &no_max_lsp_lifetime_l1_arg_cmd);
- install_element (ISIS_NODE, &max_lsp_lifetime_l2_cmd);
- install_element (ISIS_NODE, &no_max_lsp_lifetime_l2_cmd);
- install_element (ISIS_NODE, &no_max_lsp_lifetime_l2_arg_cmd);
install_element (ISIS_NODE, &lsp_refresh_interval_cmd);
install_element (ISIS_NODE, &no_lsp_refresh_interval_cmd);
- install_element (ISIS_NODE, &no_lsp_refresh_interval_arg_cmd);
- install_element (ISIS_NODE, &lsp_refresh_interval_l1_cmd);
- install_element (ISIS_NODE, &no_lsp_refresh_interval_l1_cmd);
- install_element (ISIS_NODE, &no_lsp_refresh_interval_l1_arg_cmd);
- install_element (ISIS_NODE, &lsp_refresh_interval_l2_cmd);
- install_element (ISIS_NODE, &no_lsp_refresh_interval_l2_cmd);
- install_element (ISIS_NODE, &no_lsp_refresh_interval_l2_arg_cmd);
install_element (ISIS_NODE, &area_passwd_md5_cmd);
- install_element (ISIS_NODE, &area_passwd_md5_snpauth_cmd);
install_element (ISIS_NODE, &area_passwd_clear_cmd);
- install_element (ISIS_NODE, &area_passwd_clear_snpauth_cmd);
+ install_element (ISIS_NODE, &domain_passwd_md5_cmd);
+ install_element (ISIS_NODE, &domain_passwd_clear_cmd);
install_element (ISIS_NODE, &no_area_passwd_cmd);
}
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 646c5fa88e..e7bd99c3e8 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -187,10 +187,8 @@ isis_zebra_if_address_add (int command, struct zclient *zclient,
#ifdef EXTREME_DEBUG
if (p->family == AF_INET)
zlog_debug ("connected IP address %s", buf);
-#ifdef HAVE_IPV6
if (p->family == AF_INET6)
zlog_debug ("connected IPv6 address %s", buf);
-#endif /* HAVE_IPV6 */
#endif /* EXTREME_DEBUG */
if (if_is_operative (c->ifp))
isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
@@ -223,10 +221,8 @@ isis_zebra_if_address_del (int command, struct zclient *client,
if (p->family == AF_INET)
zlog_debug ("disconnected IP address %s", buf);
-#ifdef HAVE_IPV6
if (p->family == AF_INET6)
zlog_debug ("disconnected IPv6 address %s", buf);
-#endif /* HAVE_IPV6 */
#endif /* EXTREME_DEBUG */
if (if_is_operative (ifp))
@@ -352,7 +348,6 @@ isis_zebra_route_del_ipv4 (struct prefix *prefix,
return;
}
-#ifdef HAVE_IPV6
static void
isis_zebra_route_add_ipv6 (struct prefix *prefix,
struct isis_route_info *route_info)
@@ -429,7 +424,7 @@ isis_zebra_route_add_ipv6 (struct prefix *prefix,
prefix6.family = AF_INET6;
prefix6.prefixlen = prefix->prefixlen;
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
- zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
+ zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, NULL, &api);
SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
}
@@ -510,7 +505,7 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
prefix6.family = AF_INET6;
prefix6.prefixlen = prefix->prefixlen;
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
- zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
+ zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, NULL, &api);
UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
}
@@ -518,8 +513,6 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
XFREE (MTYPE_ISIS_TMP, ifindex_list);
}
-#endif /* HAVE_IPV6 */
-
void
isis_zebra_route_update (struct prefix *prefix,
struct isis_route_info *route_info)
@@ -535,19 +528,15 @@ isis_zebra_route_update (struct prefix *prefix,
{
if (prefix->family == AF_INET)
isis_zebra_route_add_ipv4 (prefix, route_info);
-#ifdef HAVE_IPV6
else if (prefix->family == AF_INET6)
isis_zebra_route_add_ipv6 (prefix, route_info);
-#endif /* HAVE_IPV6 */
}
else
{
if (prefix->family == AF_INET)
isis_zebra_route_del_ipv4 (prefix, route_info);
-#ifdef HAVE_IPV6
else if (prefix->family == AF_INET6)
isis_zebra_route_del_ipv6 (prefix, route_info);
-#endif /* HAVE_IPV6 */
}
return;
}
@@ -709,10 +698,8 @@ isis_zebra_init (struct thread_master *master)
zclient->interface_link_params = isis_zebra_link_params;
zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4;
zclient->redistribute_route_ipv4_del = isis_zebra_read_ipv4;
-#ifdef HAVE_IPV6
zclient->redistribute_route_ipv6_add = isis_zebra_read_ipv6;
zclient->redistribute_route_ipv6_del = isis_zebra_read_ipv6;
-#endif /* HAVE_IPV6 */
return;
}
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 61a5ad0d66..9bef250883 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -89,9 +89,7 @@ isis_new (unsigned long process_id)
isis->init_circ_list = list_new ();
isis->uptime = time (NULL);
isis->nexthops = list_new ();
-#ifdef HAVE_IPV6
isis->nexthops6 = list_new ();
-#endif /* HAVE_IPV6 */
dyn_cache_init ();
/*
* uncomment the next line for full debugs
@@ -124,17 +122,13 @@ isis_area_create (const char *area_tag)
{
area->lspdb[0] = lsp_db_init ();
area->route_table[0] = route_table_init ();
-#ifdef HAVE_IPV6
area->route_table6[0] = route_table_init ();
-#endif /* HAVE_IPV6 */
}
if (area->is_type & IS_LEVEL_2)
{
area->lspdb[1] = lsp_db_init ();
area->route_table[1] = route_table_init ();
-#ifdef HAVE_IPV6
area->route_table6[1] = route_table_init ();
-#endif /* HAVE_IPV6 */
}
spftree_area_init (area);
@@ -231,9 +225,7 @@ isis_area_destroy (struct vty *vty, const char *area_tag)
for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
{
circuit->ip_router = 0;
-#ifdef HAVE_IPV6
circuit->ipv6_router = 0;
-#endif
isis_csm_state_change (ISIS_DISABLE, circuit, area);
}
list_delete (area->circuit_list);
@@ -267,7 +259,6 @@ isis_area_destroy (struct vty *vty, const char *area_tag)
route_table_finish (area->route_table[1]);
area->route_table[1] = NULL;
}
-#ifdef HAVE_IPV6
if (area->route_table6[0])
{
route_table_finish (area->route_table6[0]);
@@ -278,7 +269,6 @@ isis_area_destroy (struct vty *vty, const char *area_tag)
route_table_finish (area->route_table6[1]);
area->route_table6[1] = NULL;
}
-#endif /* HAVE_IPV6 */
isis_redist_area_finish(area);
@@ -320,12 +310,6 @@ area_net_title (struct vty *vty, const char *net_title)
u_char buff[255];
- if (!area)
- {
- vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
- return CMD_ERR_NO_MATCH;
- }
-
/* We check that we are not over the maximal number of addresses */
if (listcount (area->area_addrs) >= isis->max_area_addrs)
{
@@ -420,12 +404,6 @@ area_clear_net_title (struct vty *vty, const char *net_title)
struct listnode *node;
u_char buff[255];
- if (!area)
- {
- vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
- return CMD_ERR_NO_MATCH;
- }
-
addr.addr_len = dotformat2buff (buff, net_title);
if (addr.addr_len < 8 || addr.addr_len > 20)
{
@@ -529,7 +507,8 @@ DEFUN (show_isis_interface_arg,
"ISIS interface\n"
"ISIS interface name\n")
{
- return show_isis_interface_common (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
+ int idx_word = 3;
+ return show_isis_interface_common (vty, argv[idx_word]->arg, ISIS_UI_LEVEL_DETAIL);
}
/*
@@ -703,7 +682,8 @@ DEFUN (show_isis_neighbor_arg,
"ISIS neighbor adjacencies\n"
"System id\n")
{
- return show_isis_neighbor_common (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
+ int idx_word = 3;
+ return show_isis_neighbor_common (vty, argv[idx_word]->arg, ISIS_UI_LEVEL_DETAIL);
}
DEFUN (clear_isis_neighbor,
@@ -724,7 +704,8 @@ DEFUN (clear_isis_neighbor_arg,
"ISIS neighbor adjacencies\n"
"System id\n")
{
- return clear_isis_neighbor_common (vty, argv[0]);
+ int idx_word = 3;
+ return clear_isis_neighbor_common (vty, argv[idx_word]->arg);
}
/*
@@ -895,6 +876,7 @@ DEFUN (debug_isis_adj,
DEFUN (no_debug_isis_adj,
no_debug_isis_adj_cmd,
"no debug isis adj-packets",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS Adjacency related packets\n")
@@ -921,6 +903,7 @@ DEFUN (debug_isis_csum,
DEFUN (no_debug_isis_csum,
no_debug_isis_csum_cmd,
"no debug isis checksum-errors",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS LSP checksum errors\n")
@@ -947,6 +930,7 @@ DEFUN (debug_isis_lupd,
DEFUN (no_debug_isis_lupd,
no_debug_isis_lupd_cmd,
"no debug isis local-updates",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS local update packets\n")
@@ -973,6 +957,7 @@ DEFUN (debug_isis_err,
DEFUN (no_debug_isis_err,
no_debug_isis_err_cmd,
"no debug isis protocol-errors",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS LSP protocol errors\n")
@@ -999,6 +984,7 @@ DEFUN (debug_isis_snp,
DEFUN (no_debug_isis_snp,
no_debug_isis_snp_cmd,
"no debug isis snp-packets",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS CSNP/PSNP packets\n")
@@ -1025,6 +1011,7 @@ DEFUN (debug_isis_upd,
DEFUN (no_debug_isis_upd,
no_debug_isis_upd_cmd,
"no debug isis update-packets",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS Update related packets\n")
@@ -1051,6 +1038,7 @@ DEFUN (debug_isis_spfevents,
DEFUN (no_debug_isis_spfevents,
no_debug_isis_spfevents_cmd,
"no debug isis spf-events",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS Shortest Path First Events\n")
@@ -1077,6 +1065,7 @@ DEFUN (debug_isis_spfstats,
DEFUN (no_debug_isis_spfstats,
no_debug_isis_spfstats_cmd,
"no debug isis spf-statistics",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS SPF Timing and Statistic Data\n")
@@ -1103,6 +1092,7 @@ DEFUN (debug_isis_spftrigg,
DEFUN (no_debug_isis_spftrigg,
no_debug_isis_spftrigg_cmd,
"no debug isis spf-triggers",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS SPF triggering events\n")
@@ -1129,6 +1119,7 @@ DEFUN (debug_isis_rtevents,
DEFUN (no_debug_isis_rtevents,
no_debug_isis_rtevents_cmd,
"no debug isis route-events",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS Route related events\n")
@@ -1155,6 +1146,7 @@ DEFUN (debug_isis_events,
DEFUN (no_debug_isis_events,
no_debug_isis_events_cmd,
"no debug isis events",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS Events\n")
@@ -1181,6 +1173,7 @@ DEFUN (debug_isis_packet_dump,
DEFUN (no_debug_isis_packet_dump,
no_debug_isis_packet_dump_cmd,
"no debug isis packet-dump",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS packet dump\n")
@@ -1207,6 +1200,7 @@ DEFUN (debug_isis_lsp_gen,
DEFUN (no_debug_isis_lsp_gen,
no_debug_isis_lsp_gen_cmd,
"no debug isis lsp-gen",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS generation of own LSPs\n")
@@ -1233,6 +1227,7 @@ DEFUN (debug_isis_lsp_sched,
DEFUN (no_debug_isis_lsp_sched,
no_debug_isis_lsp_sched_cmd,
"no debug isis lsp-sched",
+ NO_STR
UNDEBUG_STR
"IS-IS information\n"
"IS-IS scheduling of LSP generation\n")
@@ -1350,7 +1345,6 @@ DEFUN (show_isis_summary,
vty_out (vty, " run count : %d%s",
spftree->runcount, VTY_NEWLINE);
-#ifdef HAVE_IPV6
spftree = area->spftree6[level - 1];
if (spftree->pending)
vty_out (vty, " IPv6 SPF: (pending)%s", VTY_NEWLINE);
@@ -1369,7 +1363,6 @@ DEFUN (show_isis_summary,
vty_out (vty, " run count : %d%s",
spftree->runcount, VTY_NEWLINE);
-#endif
}
}
vty_out (vty, "%s", VTY_NEWLINE);
@@ -1508,59 +1501,19 @@ show_isis_database (struct vty *vty, const char *argv, int ui_level)
return CMD_SUCCESS;
}
-DEFUN (show_database_brief,
+DEFUN (show_database,
show_database_cmd,
- "show isis database",
- SHOW_STR
- "IS-IS information\n"
- "IS-IS link state database\n")
-{
- return show_isis_database (vty, NULL, ISIS_UI_LEVEL_BRIEF);
-}
-
-DEFUN (show_database_lsp_brief,
- show_database_arg_cmd,
- "show isis database WORD",
- SHOW_STR
- "IS-IS information\n"
- "IS-IS link state database\n"
- "LSP ID\n")
-{
- return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_BRIEF);
-}
-
-DEFUN (show_database_lsp_detail,
- show_database_arg_detail_cmd,
- "show isis database WORD detail",
- SHOW_STR
- "IS-IS information\n"
- "IS-IS link state database\n"
- "LSP ID\n"
- "Detailed information\n")
-{
- return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
-}
-
-DEFUN (show_database_detail,
- show_database_detail_cmd,
- "show isis database detail",
- SHOW_STR
- "IS-IS information\n"
- "IS-IS link state database\n")
-{
- return show_isis_database (vty, NULL, ISIS_UI_LEVEL_DETAIL);
-}
-
-DEFUN (show_database_detail_lsp,
- show_database_detail_arg_cmd,
- "show isis database detail WORD",
+ "show isis database [detail] [WORD]",
SHOW_STR
"IS-IS information\n"
"IS-IS link state database\n"
"Detailed information\n"
"LSP ID\n")
{
- return show_isis_database (vty, argv[0], ISIS_UI_LEVEL_DETAIL);
+ int idx = 0;
+ int uilevel = argv_find (argv, argc, "detail", &idx) ? ISIS_UI_LEVEL_DETAIL : ISIS_UI_LEVEL_BRIEF;
+ char *id = argv_find (argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
+ return show_isis_database (vty, id, uilevel);
}
/*
@@ -1573,7 +1526,8 @@ DEFUN (router_isis,
"ISO IS-IS\n"
"ISO Routing area tag")
{
- return isis_area_get (vty, argv[0]);
+ int idx_word = 2;
+ return isis_area_get (vty, argv[idx_word]->arg);
}
/*
@@ -1584,7 +1538,8 @@ DEFUN (no_router_isis,
"no router isis WORD",
"no\n" ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag")
{
- return isis_area_destroy (vty, argv[0]);
+ int idx_word = 3;
+ return isis_area_destroy (vty, argv[idx_word]->arg);
}
/*
@@ -1596,7 +1551,8 @@ DEFUN (net,
"A Network Entity Title for this process (OSI only)\n"
"XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
{
- return area_net_title (vty, argv[0]);
+ int idx_word = 1;
+ return area_net_title (vty, argv[idx_word]->arg);
}
/*
@@ -1609,7 +1565,8 @@ DEFUN (no_net,
"A Network Entity Title for this process (OSI only)\n"
"XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
{
- return area_clear_net_title (vty, argv[0]);
+ int idx_word = 2;
+ return area_clear_net_title (vty, argv[idx_word]->arg);
}
void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu)
@@ -1689,25 +1646,21 @@ area_resign_level (struct isis_area *area, int level)
isis_spftree_del (area->spftree[level - 1]);
area->spftree[level - 1] = NULL;
}
-#ifdef HAVE_IPV6
if (area->spftree6[level - 1])
{
isis_spftree_del (area->spftree6[level - 1]);
area->spftree6[level - 1] = NULL;
}
-#endif
if (area->route_table[level - 1])
{
route_table_finish (area->route_table[level - 1]);
area->route_table[level - 1] = NULL;
}
-#ifdef HAVE_IPV6
if (area->route_table6[level - 1])
{
route_table_finish (area->route_table6[level - 1]);
area->route_table6[level - 1] = NULL;
}
-#endif /* HAVE_IPV6 */
sched_debug("ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.",
area->area_tag, level);
@@ -1738,10 +1691,8 @@ isis_area_is_type_set(struct isis_area *area, int is_type)
area->lspdb[1] = lsp_db_init ();
if (area->route_table[1] == NULL)
area->route_table[1] = route_table_init ();
-#ifdef HAVE_IPV6
if (area->route_table6[1] == NULL)
area->route_table6[1] = route_table_init ();
-#endif /* HAVE_IPV6 */
break;
case IS_LEVEL_1_AND_2:
@@ -1759,10 +1710,8 @@ isis_area_is_type_set(struct isis_area *area, int is_type)
area->lspdb[0] = lsp_db_init ();
if (area->route_table[0] == NULL)
area->route_table[0] = route_table_init ();
-#ifdef HAVE_IPV6
if (area->route_table6[0] == NULL)
area->route_table6[0] = route_table_init ();
-#endif /* HAVE_IPV6 */
break;
default:
@@ -1876,6 +1825,7 @@ DEFUN (log_adj_changes,
DEFUN (no_log_adj_changes,
no_log_adj_changes_cmd,
"no log-adjacency-changes",
+ NO_STR
"Stop logging changes in adjacency state\n")
{
VTY_DECLVAR_CONTEXT (isis_area, area);
@@ -2159,10 +2109,6 @@ isis_init ()
install_element (VIEW_NODE, &show_hostname_cmd);
install_element (VIEW_NODE, &show_database_cmd);
- install_element (VIEW_NODE, &show_database_arg_cmd);
- install_element (VIEW_NODE, &show_database_arg_detail_cmd);
- install_element (VIEW_NODE, &show_database_detail_cmd);
- install_element (VIEW_NODE, &show_database_detail_arg_cmd);
install_element (ENABLE_NODE, &show_debugging_isis_cmd);
diff --git a/isisd/isisd.h b/isisd/isisd.h
index f7dc0efe25..efbfafc5fb 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -48,9 +48,7 @@ struct isis
struct list *area_list; /* list of IS-IS areas */
struct list *init_circ_list;
struct list *nexthops; /* IPv4 next hops from this IS */
-#ifdef HAVE_IPV6
struct list *nexthops6; /* IPv6 next hops from this IS */
-#endif /* HAVE_IPV6 */
u_char max_area_addrs; /* maximumAreaAdresses */
struct area_addr *man_area_addrs; /* manualAreaAddresses */
u_int32_t debugs; /* bitmap for debug */
@@ -71,10 +69,8 @@ struct isis_area
dict_t *lspdb[ISIS_LEVELS]; /* link-state dbs */
struct isis_spftree *spftree[ISIS_LEVELS]; /* The v4 SPTs */
struct route_table *route_table[ISIS_LEVELS]; /* IPv4 routes */
-#ifdef HAVE_IPV6
struct isis_spftree *spftree6[ISIS_LEVELS]; /* The v6 SPTs */
struct route_table *route_table6[ISIS_LEVELS]; /* IPv6 routes */
-#endif
#define DEFAULT_LSP_MTU 1497
unsigned int lsp_mtu; /* Size of LSPs to generate */
struct list *circuit_list; /* IS-IS circuits */
@@ -124,9 +120,7 @@ struct isis_area
int ip_circuits;
/* logging adjacency changes? */
u_char log_adj_changes;
-#ifdef HAVE_IPV6
int ipv6_circuits;
-#endif /* HAVE_IPV6 */
/* Counters */
u_int32_t circuit_state_changes;
struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT]
diff --git a/ldpd/.gitignore b/ldpd/.gitignore
index be90d42119..e4ee82587a 100644
--- a/ldpd/.gitignore
+++ b/ldpd/.gitignore
@@ -15,4 +15,4 @@ TAGS
.arch-ids
*~
*.loT
-
+ldp_vty_cmds.c
diff --git a/ldpd/Makefile.am b/ldpd/Makefile.am
index bf3147d579..42e54138aa 100644
--- a/ldpd/Makefile.am
+++ b/ldpd/Makefile.am
@@ -1,15 +1,18 @@
## Process this file with automake to produce Makefile.in.
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \
- -DVTY_DEPRECATE_INDEX
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
+EXTRA_DIST=
AM_CFLAGS = $(WERROR)
noinst_LIBRARIES = libldp.a
sbin_PROGRAMS = ldpd
+BUILT_SOURCES = ldp_vty_cmds.c
+EXTRA_DIST += ldp_vty.xml
+
libldp_a_SOURCES = \
accept.c address.c adjacency.c control.c hello.c init.c interface.c \
keepalive.c l2vpn.c labelmapping.c lde.c lde_lib.c ldpd.c \
@@ -20,6 +23,9 @@ libldp_a_SOURCES = \
noinst_HEADERS = \
control.h lde.h ldpd.h ldpe.h ldp.h log.h ldp_debug.h ldp_vty.h
+ldp_vty_cmds.c: $(srcdir)/ldp_vty.xml $(srcdir)/../tools/xml2cli.pl
+ @PERL@ $(srcdir)/../tools/xml2cli.pl $(srcdir)/ldp_vty.xml > $@
+
ldpd_SOURCES = ldpd.c
ldpd_LDADD = libldp.a ../lib/libfrr.la @LIBCAP@
diff --git a/ldpd/adjacency.c b/ldpd/adjacency.c
index 3607ee96b3..2e7b43296a 100644
--- a/ldpd/adjacency.c
+++ b/ldpd/adjacency.c
@@ -25,12 +25,55 @@
#include "ldpe.h"
#include "log.h"
+static __inline int adj_compare(struct adj *, struct adj *);
static int adj_itimer(struct thread *);
-static void tnbr_del(struct tnbr *);
+static __inline int tnbr_compare(struct tnbr *, struct tnbr *);
+static void tnbr_del(struct ldpd_conf *, struct tnbr *);
static int tnbr_hello_timer(struct thread *);
static void tnbr_start_hello_timer(struct tnbr *);
static void tnbr_stop_hello_timer(struct tnbr *);
+RB_GENERATE(global_adj_head, adj, global_entry, adj_compare)
+RB_GENERATE(nbr_adj_head, adj, nbr_entry, adj_compare)
+RB_GENERATE(ia_adj_head, adj, ia_entry, adj_compare)
+RB_GENERATE(tnbr_head, tnbr, entry, tnbr_compare)
+
+static __inline int
+adj_compare(struct adj *a, struct adj *b)
+{
+ if (a->source.type < b->source.type)
+ return (-1);
+ if (a->source.type > b->source.type)
+ return (1);
+
+ switch (a->source.type) {
+ case HELLO_LINK:
+ if (strcmp(a->source.link.ia->iface->name,
+ b->source.link.ia->iface->name) < 0)
+ return (-1);
+ if (strcmp(a->source.link.ia->iface->name,
+ b->source.link.ia->iface->name) > 0)
+ return (1);
+ if (a->source.link.ia->af < b->source.link.ia->af)
+ return (-1);
+ if (a->source.link.ia->af > b->source.link.ia->af)
+ return (1);
+ return (ldp_addrcmp(a->source.link.ia->af,
+ &a->source.link.src_addr, &b->source.link.src_addr));
+ case HELLO_TARGETED:
+ if (a->source.target->af < b->source.target->af)
+ return (-1);
+ if (a->source.target->af > b->source.target->af)
+ return (1);
+ return (ldp_addrcmp(a->source.target->af,
+ &a->source.target->addr, &b->source.target->addr));
+ default:
+ fatalx("adj_get_af: unknown hello type");
+ }
+
+ return (0);
+}
+
struct adj *
adj_new(struct in_addr lsr_id, struct hello_source *source,
union ldpd_addr *addr)
@@ -48,11 +91,11 @@ adj_new(struct in_addr lsr_id, struct hello_source *source,
adj->source = *source;
adj->trans_addr = *addr;
- LIST_INSERT_HEAD(&global.adj_list, adj, global_entry);
+ RB_INSERT(global_adj_head, &global.adj_tree, adj);
switch (source->type) {
case HELLO_LINK:
- LIST_INSERT_HEAD(&source->link.ia->adj_list, adj, ia_entry);
+ RB_INSERT(ia_adj_head, &source->link.ia->adj_tree, adj);
break;
case HELLO_TARGETED:
source->target->adj = adj;
@@ -70,12 +113,12 @@ adj_del_single(struct adj *adj)
adj_stop_itimer(adj);
- LIST_REMOVE(adj, global_entry);
+ RB_REMOVE(global_adj_head, &global.adj_tree, adj);
if (adj->nbr)
- LIST_REMOVE(adj, nbr_entry);
+ RB_REMOVE(nbr_adj_head, &adj->nbr->adj_tree, adj);
switch (adj->source.type) {
case HELLO_LINK:
- LIST_REMOVE(adj, ia_entry);
+ RB_REMOVE(ia_adj_head, &adj->source.link.ia->adj_tree, adj);
break;
case HELLO_TARGETED:
adj->source.target->adj = NULL;
@@ -99,7 +142,7 @@ adj_del(struct adj *adj, uint32_t notif_status)
* then delete it.
*/
if (nbr && nbr_adj_count(nbr, nbr->af) == 0) {
- LIST_FOREACH_SAFE(adj, &nbr->adj_list, nbr_entry, atmp)
+ RB_FOREACH_SAFE(adj, nbr_adj_head, &nbr->adj_tree, atmp)
adj_del_single(adj);
session_shutdown(nbr, notif_status, 0, 0);
nbr_del(nbr);
@@ -109,27 +152,9 @@ adj_del(struct adj *adj, uint32_t notif_status)
struct adj *
adj_find(struct hello_source *source)
{
- struct adj *adj;
-
- LIST_FOREACH(adj, &global.adj_list, global_entry) {
- if (adj->source.type != source->type)
- continue;
-
- switch (source->type) {
- case HELLO_LINK:
- if (ldp_addrcmp(source->link.ia->af,
- &adj->source.link.src_addr,
- &source->link.src_addr) == 0)
- return (adj);
- break;
- case HELLO_TARGETED:
- if (adj->source.target == source->target)
- return (adj);
- break;
- }
- }
-
- return (NULL);
+ struct adj adj;
+ adj.source = *source;
+ return (RB_FIND(global_adj_head, &global.adj_tree, &adj));
}
int
@@ -161,7 +186,7 @@ adj_itimer(struct thread *thread)
if (!(adj->source.target->flags & F_TNBR_CONFIGURED) &&
adj->source.target->pw_count == 0) {
/* remove dynamic targeted neighbor */
- tnbr_del(adj->source.target);
+ tnbr_del(leconf, adj->source.target);
return (0);
}
adj->source.target->adj = NULL;
@@ -188,6 +213,17 @@ adj_stop_itimer(struct adj *adj)
/* targeted neighbors */
+static __inline int
+tnbr_compare(struct tnbr *a, struct tnbr *b)
+{
+ if (a->af < b->af)
+ return (-1);
+ if (a->af > b->af)
+ return (1);
+
+ return (ldp_addrcmp(a->af, &a->addr, &b->addr));
+}
+
struct tnbr *
tnbr_new(int af, union ldpd_addr *addr)
{
@@ -204,34 +240,30 @@ tnbr_new(int af, union ldpd_addr *addr)
}
static void
-tnbr_del(struct tnbr *tnbr)
+tnbr_del(struct ldpd_conf *xconf, struct tnbr *tnbr)
{
tnbr_stop_hello_timer(tnbr);
if (tnbr->adj)
adj_del(tnbr->adj, S_SHUTDOWN);
- LIST_REMOVE(tnbr, entry);
+ RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
free(tnbr);
}
struct tnbr *
tnbr_find(struct ldpd_conf *xconf, int af, union ldpd_addr *addr)
{
- struct tnbr *tnbr;
-
- LIST_FOREACH(tnbr, &xconf->tnbr_list, entry)
- if (af == tnbr->af &&
- ldp_addrcmp(af, addr, &tnbr->addr) == 0)
- return (tnbr);
-
- return (NULL);
+ struct tnbr tnbr;
+ tnbr.af = af;
+ tnbr.addr = *addr;
+ return (RB_FIND(tnbr_head, &xconf->tnbr_tree, &tnbr));
}
struct tnbr *
-tnbr_check(struct tnbr *tnbr)
+tnbr_check(struct ldpd_conf *xconf, struct tnbr *tnbr)
{
if (!(tnbr->flags & (F_TNBR_CONFIGURED|F_TNBR_DYNAMIC)) &&
tnbr->pw_count == 0) {
- tnbr_del(tnbr);
+ tnbr_del(xconf, tnbr);
return (NULL);
}
@@ -276,7 +308,7 @@ tnbr_update_all(int af)
struct tnbr *tnbr;
/* update targeted neighbors */
- LIST_FOREACH(tnbr, &leconf->tnbr_list, entry)
+ RB_FOREACH(tnbr, tnbr_head, &leconf->tnbr_tree)
if (tnbr->af == af || af == AF_UNSPEC)
tnbr_update(tnbr);
}
diff --git a/ldpd/hello.c b/ldpd/hello.c
index 755b25aa85..e7935899b7 100644
--- a/ldpd/hello.c
+++ b/ldpd/hello.c
@@ -261,19 +261,25 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
if (tnbr && (tnbr->flags & F_TNBR_DYNAMIC) &&
!((flags & F_HELLO_REQ_TARG))) {
tnbr->flags &= ~F_TNBR_DYNAMIC;
- tnbr = tnbr_check(tnbr);
+ tnbr = tnbr_check(leconf, tnbr);
}
if (!tnbr) {
- if (!((flags & F_HELLO_REQ_TARG) &&
- ((ldp_af_conf_get(leconf, af))->flags &
- F_LDPD_AF_THELLO_ACCEPT)))
+ struct ldpd_af_conf *af_conf;
+
+ if (!(flags & F_HELLO_REQ_TARG))
+ return;
+ af_conf = ldp_af_conf_get(leconf, af);
+ if (!(af_conf->flags & F_LDPD_AF_THELLO_ACCEPT))
+ return;
+ if (ldpe_acl_check(af_conf->acl_thello_accept_from, af,
+ src, (af == AF_INET) ? 32 : 128) != FILTER_PERMIT)
return;
tnbr = tnbr_new(af, src);
tnbr->flags |= F_TNBR_DYNAMIC;
tnbr_update(tnbr);
- LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
+ RB_INSERT(tnbr_head, &leconf->tnbr_tree, tnbr);
}
source.type = HELLO_TARGETED;
@@ -364,7 +370,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
adj = adj_new(lsr_id, &source, &trans_addr);
if (nbr) {
adj->nbr = nbr;
- LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry);
+ RB_INSERT(nbr_adj_head, &nbr->adj_tree, adj);
}
}
diff --git a/ldpd/interface.c b/ldpd/interface.c
index b6472fe5e8..8fea91b878 100644
--- a/ldpd/interface.c
+++ b/ldpd/interface.c
@@ -26,6 +26,7 @@
#include "sockopt.h"
+static __inline int iface_compare(struct iface *, struct iface *);
static struct if_addr *if_addr_new(struct kaddr *);
static struct if_addr *if_addr_lookup(struct if_addr_head *, struct kaddr *);
static int if_start(struct iface *, int);
@@ -39,6 +40,14 @@ static int if_leave_ipv4_group(struct iface *, struct in_addr *);
static int if_join_ipv6_group(struct iface *, struct in6_addr *);
static int if_leave_ipv6_group(struct iface *, struct in6_addr *);
+RB_GENERATE(iface_head, iface, entry, iface_compare)
+
+static __inline int
+iface_compare(struct iface *a, struct iface *b)
+{
+ return (strcmp(a->name, b->name));
+}
+
struct iface *
if_new(struct kif *kif)
{
@@ -57,30 +66,18 @@ if_new(struct kif *kif)
iface->ipv4.iface = iface;
iface->ipv4.enabled = 0;
iface->ipv4.state = IF_STA_DOWN;
- LIST_INIT(&iface->ipv4.adj_list);
+ RB_INIT(&iface->ipv4.adj_tree);
/* ipv6 */
iface->ipv6.af = AF_INET6;
iface->ipv6.iface = iface;
iface->ipv6.enabled = 0;
iface->ipv6.state = IF_STA_DOWN;
- LIST_INIT(&iface->ipv6.adj_list);
+ RB_INIT(&iface->ipv6.adj_tree);
return (iface);
}
-struct iface *
-if_lookup(struct ldpd_conf *xconf, unsigned short ifindex)
-{
- struct iface *iface;
-
- LIST_FOREACH(iface, &xconf->iface_list, entry)
- if (iface->ifindex == ifindex)
- return (iface);
-
- return (NULL);
-}
-
void
if_exit(struct iface *iface)
{
@@ -100,17 +97,25 @@ if_exit(struct iface *iface)
}
struct iface *
-if_lookup_name(struct ldpd_conf *xconf, const char *ifname)
+if_lookup(struct ldpd_conf *xconf, unsigned short ifindex)
{
struct iface *iface;
- LIST_FOREACH(iface, &xconf->iface_list, entry)
- if (strcmp(iface->name, ifname) == 0)
+ RB_FOREACH(iface, iface_head, &xconf->iface_tree)
+ if (iface->ifindex == ifindex)
return (iface);
return (NULL);
}
+struct iface *
+if_lookup_name(struct ldpd_conf *xconf, const char *ifname)
+{
+ struct iface iface;
+ strlcpy(iface.name, ifname, sizeof(iface.name));
+ return (RB_FIND(iface_head, &xconf->iface_tree, &iface));
+}
+
void
if_update_info(struct iface *iface, struct kif *kif)
{
@@ -288,7 +293,7 @@ if_reset(struct iface *iface, int af)
ia = iface_af_get(iface, af);
if_stop_hello_timer(ia);
- while ((adj = LIST_FIRST(&ia->adj_list)) != NULL)
+ while ((adj = RB_ROOT(&ia->adj_tree)) != NULL)
adj_del(adj, S_SHUTDOWN);
/* try to cleanup */
@@ -380,7 +385,7 @@ if_update_all(int af)
{
struct iface *iface;
- LIST_FOREACH(iface, &leconf->iface_list, entry)
+ RB_FOREACH(iface, iface_head, &leconf->iface_tree)
if_update(iface, af);
}
@@ -460,7 +465,7 @@ if_to_ctl(struct iface_af *ia)
ictl.uptime = 0;
ictl.adj_cnt = 0;
- LIST_FOREACH(adj, &ia->adj_list, ia_entry)
+ RB_FOREACH(adj, ia_adj_head, &ia->adj_tree)
ictl.adj_cnt++;
return (&ictl);
diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c
index db382e484f..792608d425 100644
--- a/ldpd/l2vpn.c
+++ b/ldpd/l2vpn.c
@@ -26,7 +26,20 @@
#include "lde.h"
#include "log.h"
-static void l2vpn_pw_fec(struct l2vpn_pw *, struct fec *);
+static void l2vpn_pw_fec(struct l2vpn_pw *, struct fec *);
+static __inline int l2vpn_compare(struct l2vpn *, struct l2vpn *);
+static __inline int l2vpn_if_compare(struct l2vpn_if *, struct l2vpn_if *);
+static __inline int l2vpn_pw_compare(struct l2vpn_pw *, struct l2vpn_pw *);
+
+RB_GENERATE(l2vpn_head, l2vpn, entry, l2vpn_compare)
+RB_GENERATE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare)
+RB_GENERATE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare)
+
+static __inline int
+l2vpn_compare(struct l2vpn *a, struct l2vpn *b)
+{
+ return (strcmp(a->name, b->name));
+}
struct l2vpn *
l2vpn_new(const char *name)
@@ -42,9 +55,9 @@ l2vpn_new(const char *name)
l2vpn->mtu = DEFAULT_L2VPN_MTU;
l2vpn->pw_type = DEFAULT_PW_TYPE;
- LIST_INIT(&l2vpn->if_list);
- LIST_INIT(&l2vpn->pw_list);
- LIST_INIT(&l2vpn->pw_inactive_list);
+ RB_INIT(&l2vpn->if_tree);
+ RB_INIT(&l2vpn->pw_tree);
+ RB_INIT(&l2vpn->pw_inactive_tree);
return (l2vpn);
}
@@ -52,13 +65,9 @@ l2vpn_new(const char *name)
struct l2vpn *
l2vpn_find(struct ldpd_conf *xconf, const char *name)
{
- struct l2vpn *l2vpn;
-
- LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry)
- if (strcmp(l2vpn->name, name) == 0)
- return (l2vpn);
-
- return (NULL);
+ struct l2vpn l2vpn;
+ strlcpy(l2vpn.name, name, sizeof(l2vpn.name));
+ return (RB_FIND(l2vpn_head, &xconf->l2vpn_tree, &l2vpn));
}
void
@@ -67,16 +76,16 @@ l2vpn_del(struct l2vpn *l2vpn)
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
- while ((lif = LIST_FIRST(&l2vpn->if_list)) != NULL) {
- LIST_REMOVE(lif, entry);
+ while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
+ RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
}
- while ((pw = LIST_FIRST(&l2vpn->pw_list)) != NULL) {
- LIST_REMOVE(pw, entry);
+ while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw);
}
- while ((pw = LIST_FIRST(&l2vpn->pw_inactive_list)) != NULL) {
- LIST_REMOVE(pw, entry);
+ while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw);
}
@@ -88,7 +97,7 @@ l2vpn_init(struct l2vpn *l2vpn)
{
struct l2vpn_pw *pw;
- LIST_FOREACH(pw, &l2vpn->pw_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
l2vpn_pw_init(pw);
}
@@ -97,10 +106,16 @@ l2vpn_exit(struct l2vpn *l2vpn)
{
struct l2vpn_pw *pw;
- LIST_FOREACH(pw, &l2vpn->pw_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
l2vpn_pw_exit(pw);
}
+static __inline int
+l2vpn_if_compare(struct l2vpn_if *a, struct l2vpn_if *b)
+{
+ return (strcmp(a->ifname, b->ifname));
+}
+
struct l2vpn_if *
l2vpn_if_new(struct l2vpn *l2vpn, struct kif *kif)
{
@@ -122,7 +137,7 @@ l2vpn_if_find(struct l2vpn *l2vpn, unsigned int ifindex)
{
struct l2vpn_if *lif;
- LIST_FOREACH(lif, &l2vpn->if_list, entry)
+ RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
if (lif->ifindex == ifindex)
return (lif);
@@ -132,15 +147,16 @@ l2vpn_if_find(struct l2vpn *l2vpn, unsigned int ifindex)
struct l2vpn_if *
l2vpn_if_find_name(struct l2vpn *l2vpn, const char *ifname)
{
- struct l2vpn_if *lif;
-
- LIST_FOREACH(lif, &l2vpn->if_list, entry)
- if (strcmp(lif->ifname, ifname) == 0)
- return (lif);
-
- return (NULL);
+ struct l2vpn_if lif;
+ strlcpy(lif.ifname, ifname, sizeof(lif.ifname));
+ return (RB_FIND(l2vpn_if_head, &l2vpn->if_tree, &lif));
}
+static __inline int
+l2vpn_pw_compare(struct l2vpn_pw *a, struct l2vpn_pw *b)
+{
+ return (strcmp(a->ifname, b->ifname));
+}
struct l2vpn_pw *
l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif)
@@ -162,10 +178,10 @@ l2vpn_pw_find(struct l2vpn *l2vpn, unsigned int ifindex)
{
struct l2vpn_pw *pw;
- LIST_FOREACH(pw, &l2vpn->pw_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
if (pw->ifindex == ifindex)
return (pw);
- LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
if (pw->ifindex == ifindex)
return (pw);
@@ -176,15 +192,13 @@ struct l2vpn_pw *
l2vpn_pw_find_name(struct l2vpn *l2vpn, const char *ifname)
{
struct l2vpn_pw *pw;
+ struct l2vpn_pw s;
- LIST_FOREACH(pw, &l2vpn->pw_list, entry)
- if (strcmp(pw->ifname, ifname) == 0)
- return (pw);
- LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
- if (strcmp(pw->ifname, ifname) == 0)
- return (pw);
-
- return (NULL);
+ strlcpy(s.ifname, ifname, sizeof(s.ifname));
+ pw = RB_FIND(l2vpn_pw_head, &l2vpn->pw_tree, &s);
+ if (pw)
+ return (pw);
+ return (RB_FIND(l2vpn_pw_head, &l2vpn->pw_inactive_tree, &s));
}
void
@@ -195,8 +209,9 @@ l2vpn_pw_init(struct l2vpn_pw *pw)
l2vpn_pw_reset(pw);
l2vpn_pw_fec(pw, &fec);
- lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0,
+ lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0,
0, (void *)pw);
+ lde_kernel_update(&fec);
}
void
@@ -205,7 +220,8 @@ l2vpn_pw_exit(struct l2vpn_pw *pw)
struct fec fec;
l2vpn_pw_fec(pw, &fec);
- lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0);
+ lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0);
+ lde_kernel_update(&fec);
}
static void
@@ -374,7 +390,7 @@ l2vpn_recv_pw_status(struct lde_nbr *ln, struct notify_msg *nm)
if (pw == NULL)
return;
- fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0);
+ fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0, 0);
if (fnh == NULL)
return;
@@ -399,8 +415,8 @@ l2vpn_sync_pws(int af, union ldpd_addr *addr)
struct fec_node *fn;
struct fec_nh *fnh;
- LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry) {
- LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
+ RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree) {
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
if (af != pw->af || ldp_addrcmp(af, &pw->addr, addr))
continue;
@@ -409,7 +425,7 @@ l2vpn_sync_pws(int af, union ldpd_addr *addr)
if (fn == NULL)
continue;
fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)
- &pw->lsr_id, 0);
+ &pw->lsr_id, 0, 0);
if (fnh == NULL)
continue;
@@ -428,8 +444,8 @@ l2vpn_pw_ctl(pid_t pid)
struct l2vpn_pw *pw;
static struct ctl_pw pwctl;
- LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry)
- LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
+ RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
memset(&pwctl, 0, sizeof(pwctl));
strlcpy(pwctl.l2vpn_name, pw->l2vpn->name,
sizeof(pwctl.l2vpn_name));
@@ -459,7 +475,7 @@ l2vpn_binding_ctl(pid_t pid)
fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL &&
- LIST_EMPTY(&fn->downstream))
+ RB_EMPTY(&fn->downstream))
continue;
memset(&pwctl, 0, sizeof(pwctl));
@@ -477,7 +493,7 @@ l2vpn_binding_ctl(pid_t pid)
} else
pwctl.local_label = NO_LABEL;
- LIST_FOREACH(me, &fn->downstream, entry)
+ RB_FOREACH(me, lde_map_head, &fn->downstream)
if (f->u.pwid.lsr_id.s_addr == me->nexthop->id.s_addr)
break;
@@ -508,7 +524,7 @@ ldpe_l2vpn_init(struct l2vpn *l2vpn)
{
struct l2vpn_pw *pw;
- LIST_FOREACH(pw, &l2vpn->pw_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
ldpe_l2vpn_pw_init(pw);
}
@@ -517,7 +533,7 @@ ldpe_l2vpn_exit(struct l2vpn *l2vpn)
{
struct l2vpn_pw *pw;
- LIST_FOREACH(pw, &l2vpn->pw_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
ldpe_l2vpn_pw_exit(pw);
}
@@ -530,7 +546,7 @@ ldpe_l2vpn_pw_init(struct l2vpn_pw *pw)
if (tnbr == NULL) {
tnbr = tnbr_new(pw->af, &pw->addr);
tnbr_update(tnbr);
- LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
+ RB_INSERT(tnbr_head, &leconf->tnbr_tree, tnbr);
}
tnbr->pw_count++;
@@ -544,6 +560,6 @@ ldpe_l2vpn_pw_exit(struct l2vpn_pw *pw)
tnbr = tnbr_find(leconf, pw->af, &pw->addr);
if (tnbr) {
tnbr->pw_count--;
- tnbr_check(tnbr);
+ tnbr_check(leconf, tnbr);
}
}
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 29c9590908..1323ba3d02 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -45,18 +45,20 @@ static struct lde_nbr *lde_nbr_find(uint32_t);
static void lde_nbr_clear(void);
static void lde_nbr_addr_update(struct lde_nbr *,
struct lde_addr *, int);
+static __inline int lde_map_compare(struct lde_map *, struct lde_map *);
static void lde_map_free(void *);
static int lde_address_add(struct lde_nbr *, struct lde_addr *);
static int lde_address_del(struct lde_nbr *, struct lde_addr *);
static void lde_address_list_free(struct lde_nbr *);
RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
+RB_GENERATE(lde_map_head, lde_map, entry, lde_map_compare)
struct ldpd_conf *ldeconf;
struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs);
static struct imsgev *iev_ldpe;
-static struct imsgev *iev_main;
+static struct imsgev *iev_main, *iev_main_sync;
/* Master of threads. */
struct thread_master *master;
@@ -131,15 +133,18 @@ lde(const char *user, const char *group)
/* setup signal handler */
signal_init(master, array_size(lde_signals), lde_signals);
- /* setup pipe and event handler to the parent process */
- if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
+ /* setup pipes and event handlers to the parent process */
+ if ((iev_main = calloc(1, sizeof(struct imsgev))) == NULL)
fatal(NULL);
- imsg_init(&iev_main->ibuf, 3);
+ imsg_init(&iev_main->ibuf, LDPD_FD_ASYNC);
iev_main->handler_read = lde_dispatch_parent;
iev_main->ev_read = thread_add_read(master, iev_main->handler_read,
iev_main, iev_main->ibuf.fd);
iev_main->handler_write = ldp_write_handler;
- iev_main->ev_write = NULL;
+
+ if ((iev_main_sync = calloc(1, sizeof(struct imsgev))) == NULL)
+ fatal(NULL);
+ imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
/* start the LIB garbage collector */
lde_gc_start_timer();
@@ -160,6 +165,8 @@ lde_shutdown(void)
close(iev_ldpe->ibuf.fd);
msgbuf_clear(&iev_main->ibuf.w);
close(iev_main->ibuf.fd);
+ msgbuf_clear(&iev_main_sync->ibuf.w);
+ close(iev_main_sync->ibuf.fd);
lde_gc_stop_timer();
lde_nbr_clear();
@@ -169,6 +176,7 @@ lde_shutdown(void)
free(iev_ldpe);
free(iev_main);
+ free(iev_main_sync);
log_info("label decision engine exiting");
exit(0);
@@ -406,8 +414,7 @@ lde_dispatch_parent(struct thread *thread)
switch (imsg.hdr.type) {
case IMSG_NETWORK_ADD:
- case IMSG_NETWORK_ADD_END:
- case IMSG_NETWORK_DEL:
+ case IMSG_NETWORK_UPDATE:
if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) {
log_warnx("%s: wrong imsg len", __func__);
break;
@@ -432,14 +439,11 @@ lde_dispatch_parent(struct thread *thread)
switch (imsg.hdr.type) {
case IMSG_NETWORK_ADD:
lde_kernel_insert(&fec, kr.af, &kr.nexthop,
- kr.priority, kr.flags & F_CONNECTED, NULL);
+ kr.ifindex, kr.priority,
+ kr.flags & F_CONNECTED, NULL);
break;
- case IMSG_NETWORK_ADD_END:
- lde_kernel_reevaluate(&fec);
- break;
- case IMSG_NETWORK_DEL:
- lde_kernel_remove(&fec, kr.af, &kr.nexthop,
- kr.priority);
+ case IMSG_NETWORK_UPDATE:
+ lde_kernel_update(&fec);
break;
}
break;
@@ -470,10 +474,10 @@ lde_dispatch_parent(struct thread *thread)
fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
- LIST_INIT(&nconf->iface_list);
- LIST_INIT(&nconf->tnbr_list);
- LIST_INIT(&nconf->nbrp_list);
- LIST_INIT(&nconf->l2vpn_list);
+ RB_INIT(&nconf->iface_tree);
+ RB_INIT(&nconf->tnbr_tree);
+ RB_INIT(&nconf->nbrp_tree);
+ RB_INIT(&nconf->l2vpn_tree);
break;
case IMSG_RECONF_IFACE:
if ((niface = malloc(sizeof(struct iface))) == NULL)
@@ -481,37 +485,37 @@ lde_dispatch_parent(struct thread *thread)
memcpy(niface, imsg.data, sizeof(struct iface));
LIST_INIT(&niface->addr_list);
- LIST_INIT(&niface->ipv4.adj_list);
- LIST_INIT(&niface->ipv6.adj_list);
+ RB_INIT(&niface->ipv4.adj_tree);
+ RB_INIT(&niface->ipv6.adj_tree);
niface->ipv4.iface = niface;
niface->ipv6.iface = niface;
- LIST_INSERT_HEAD(&nconf->iface_list, niface, entry);
+ RB_INSERT(iface_head, &nconf->iface_tree, niface);
break;
case IMSG_RECONF_TNBR:
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
fatal(NULL);
memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
- LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry);
+ RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
break;
case IMSG_RECONF_NBRP:
if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
fatal(NULL);
memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
- LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry);
+ RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
break;
case IMSG_RECONF_L2VPN:
if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
fatal(NULL);
memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
- LIST_INIT(&nl2vpn->if_list);
- LIST_INIT(&nl2vpn->pw_list);
- LIST_INIT(&nl2vpn->pw_inactive_list);
+ RB_INIT(&nl2vpn->if_tree);
+ RB_INIT(&nl2vpn->pw_tree);
+ RB_INIT(&nl2vpn->pw_inactive_tree);
- LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry);
+ RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
break;
case IMSG_RECONF_L2VPN_IF:
if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
@@ -519,7 +523,7 @@ lde_dispatch_parent(struct thread *thread)
memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
nlif->l2vpn = nl2vpn;
- LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry);
+ RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
break;
case IMSG_RECONF_L2VPN_PW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@@ -527,7 +531,7 @@ lde_dispatch_parent(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn;
- LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry);
+ RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
break;
case IMSG_RECONF_L2VPN_IPW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@@ -535,7 +539,7 @@ lde_dispatch_parent(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn;
- LIST_INSERT_HEAD(&nl2vpn->pw_inactive_list, npw, entry);
+ RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
break;
case IMSG_RECONF_END:
merge_config(ldeconf, nconf);
@@ -568,10 +572,79 @@ lde_dispatch_parent(struct thread *thread)
return (0);
}
+int
+lde_acl_check(char *acl_name, int af, union ldpd_addr *addr, uint8_t prefixlen)
+{
+ return ldp_acl_request(iev_main_sync, acl_name, af, addr, prefixlen);
+}
+
uint32_t
-lde_assign_label(void)
+lde_update_label(struct fec_node *fn)
{
- static uint32_t label = MPLS_LABEL_RESERVED_MAX;
+ static uint32_t label = MPLS_LABEL_RESERVED_MAX;
+ struct fec_nh *fnh;
+ int connected = 0;
+
+ LIST_FOREACH(fnh, &fn->nexthops, entry) {
+ if (fnh->flags & F_FEC_NH_CONNECTED) {
+ connected = 1;
+ break;
+ }
+ }
+
+ /* should we allocate a label for this fec? */
+ switch (fn->fec.type) {
+ case FEC_TYPE_IPV4:
+ if ((ldeconf->ipv4.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
+ fn->fec.u.ipv4.prefixlen != 32)
+ return (NO_LABEL);
+ if (lde_acl_check(ldeconf->ipv4.acl_label_allocate_for,
+ AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
+ fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
+ return (NO_LABEL);
+ break;
+ case FEC_TYPE_IPV6:
+ if ((ldeconf->ipv6.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
+ fn->fec.u.ipv6.prefixlen != 128)
+ return (NO_LABEL);
+ if (lde_acl_check(ldeconf->ipv6.acl_label_allocate_for,
+ AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
+ fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
+ return (NO_LABEL);
+ break;
+ default:
+ break;
+ }
+
+ if (connected) {
+ /* choose implicit or explicit-null depending on configuration */
+ switch (fn->fec.type) {
+ case FEC_TYPE_IPV4:
+ if (!(ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL))
+ return (MPLS_LABEL_IMPLNULL);
+ if (lde_acl_check(ldeconf->ipv4.acl_label_expnull_for,
+ AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
+ fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
+ return (MPLS_LABEL_IMPLNULL);
+ return (MPLS_LABEL_IPV4NULL);
+ case FEC_TYPE_IPV6:
+ if (!(ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL))
+ return (MPLS_LABEL_IMPLNULL);
+ if (lde_acl_check(ldeconf->ipv6.acl_label_expnull_for,
+ AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
+ fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
+ return (MPLS_LABEL_IMPLNULL);
+ return (MPLS_LABEL_IPV6NULL);
+ default:
+ fatalx("lde_update_label: unexpected fec type");
+ break;
+ }
+ }
+
+ /* preserve current label if there's no need to update it */
+ if (fn->local_label != NO_LABEL &&
+ fn->local_label > MPLS_LABEL_RESERVED_MAX)
+ return (fn->local_label);
/*
* TODO: request label to zebra or define a range of labels for ldpd.
@@ -595,6 +668,7 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.prefix.v4 = fn->fec.u.ipv4.prefix;
kr.prefixlen = fn->fec.u.ipv4.prefixlen;
kr.nexthop.v4 = fnh->nexthop.v4;
+ kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority;
@@ -612,6 +686,7 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.prefix.v6 = fn->fec.u.ipv6.prefix;
kr.prefixlen = fn->fec.u.ipv6.prefixlen;
kr.nexthop.v6 = fnh->nexthop.v6;
+ kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority;
@@ -660,6 +735,7 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.prefix.v4 = fn->fec.u.ipv4.prefix;
kr.prefixlen = fn->fec.u.ipv4.prefixlen;
kr.nexthop.v4 = fnh->nexthop.v4;
+ kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority;
@@ -677,6 +753,7 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.prefix.v6 = fn->fec.u.ipv6.prefix;
kr.prefixlen = fn->fec.u.ipv6.prefixlen;
kr.nexthop.v6 = fnh->nexthop.v6;
+ kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority;
@@ -788,10 +865,24 @@ lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
case FEC_TYPE_IPV4:
if (!ln->v4_enabled)
return;
+ if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_to,
+ AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
+ return;
+ if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_for,
+ AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
+ fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
+ return;
break;
case FEC_TYPE_IPV6:
if (!ln->v6_enabled)
return;
+ if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_to,
+ AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
+ return;
+ if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_for,
+ AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
+ fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
+ return;
break;
case FEC_TYPE_PWID:
pw = (struct l2vpn_pw *) fn->data;
@@ -1136,6 +1227,13 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
}
}
+static __inline int
+lde_map_compare(struct lde_map *a, struct lde_map *b)
+{
+ return (ldp_addrcmp(AF_INET, (union ldpd_addr *)&a->nexthop->id,
+ (union ldpd_addr *)&b->nexthop->id));
+}
+
struct lde_map *
lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
{
@@ -1149,13 +1247,15 @@ lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
me->nexthop = ln;
if (sent) {
- LIST_INSERT_HEAD(&fn->upstream, me, entry);
+ RB_INSERT(lde_map_head, &fn->upstream, me);
+ me->head = &fn->upstream;
if (fec_insert(&ln->sent_map, &me->fec))
log_warnx("failed to add %s to sent map",
log_fec(&me->fec));
/* XXX on failure more cleanup is needed */
} else {
- LIST_INSERT_HEAD(&fn->downstream, me, entry);
+ RB_INSERT(lde_map_head, &fn->downstream, me);
+ me->head = &fn->downstream;
if (fec_insert(&ln->recv_map, &me->fec))
log_warnx("failed to add %s to recv map",
log_fec(&me->fec));
@@ -1180,7 +1280,7 @@ lde_map_free(void *ptr)
{
struct lde_map *map = ptr;
- LIST_REMOVE(map, entry);
+ RB_REMOVE(lde_map_head, map->head, map);
free(map);
}
@@ -1244,52 +1344,50 @@ lde_wdraw_del(struct lde_nbr *ln, struct lde_wdraw *lw)
}
void
-lde_change_egress_label(int af, int was_implicit)
+lde_change_egress_label(int af)
{
struct lde_nbr *ln;
struct fec *f;
struct fec_node *fn;
+ /* explicitly withdraw all null labels */
RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
- /* explicit withdraw */
- if (was_implicit)
- lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IMPLNULL,
+ lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IMPLNULL, NULL);
+ if (ln->v4_enabled)
+ lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IPV4NULL,
NULL);
- else {
- if (ln->v4_enabled)
- lde_send_labelwithdraw(ln, NULL,
- MPLS_LABEL_IPV4NULL, NULL);
- if (ln->v6_enabled)
- lde_send_labelwithdraw(ln, NULL,
- MPLS_LABEL_IPV6NULL, NULL);
- }
-
- /* advertise new label of connected prefixes */
- RB_FOREACH(f, fec_tree, &ft) {
- fn = (struct fec_node *)f;
- if (fn->local_label > MPLS_LABEL_RESERVED_MAX)
- continue;
+ if (ln->v6_enabled)
+ lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IPV6NULL,
+ NULL);
+ }
- switch (af) {
- case AF_INET:
- if (fn->fec.type != FEC_TYPE_IPV4)
- continue;
- break;
- case AF_INET6:
- if (fn->fec.type != FEC_TYPE_IPV6)
- continue;
- break;
- default:
- fatalx("lde_change_egress_label: unknown af");
- }
+ /* update label of connected routes */
+ RB_FOREACH(f, fec_tree, &ft) {
+ fn = (struct fec_node *)f;
+ if (fn->local_label > MPLS_LABEL_RESERVED_MAX)
+ continue;
- fn->local_label = egress_label(fn->fec.type);
- lde_send_labelmapping(ln, fn, 0);
+ switch (af) {
+ case AF_INET:
+ if (fn->fec.type != FEC_TYPE_IPV4)
+ continue;
+ break;
+ case AF_INET6:
+ if (fn->fec.type != FEC_TYPE_IPV6)
+ continue;
+ break;
+ default:
+ fatalx("lde_change_egress_label: unknown af");
}
+ fn->local_label = lde_update_label(fn);
+ if (fn->local_label != NO_LABEL)
+ RB_FOREACH(ln, nbr_tree, &lde_nbrs)
+ lde_send_labelmapping(ln, fn, 0);
+ }
+ RB_FOREACH(ln, nbr_tree, &lde_nbrs)
lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
NULL, 0);
- }
}
static int
diff --git a/ldpd/lde.h b/ldpd/lde.h
index cf8f2129af..e0e9873d5c 100644
--- a/ldpd/lde.h
+++ b/ldpd/lde.h
@@ -23,6 +23,7 @@
#include "openbsd-queue.h"
#include "openbsd-tree.h"
+#include "if.h"
enum fec_type {
FEC_TYPE_IPV4,
@@ -61,10 +62,13 @@ struct lde_req {
/* mapping entries */
struct lde_map {
struct fec fec;
- LIST_ENTRY(lde_map) entry;
+ struct lde_map_head *head; /* fec_node's upstream/downstream */
+ RB_ENTRY(lde_map) entry;
struct lde_nbr *nexthop;
struct map map;
};
+RB_HEAD(lde_map_head, lde_map);
+RB_PROTOTYPE(lde_map_head, lde_map, entry, lde_map_cmp);
/* withdraw entries */
struct lde_wdraw {
@@ -100,18 +104,20 @@ struct fec_nh {
LIST_ENTRY(fec_nh) entry;
int af;
union ldpd_addr nexthop;
+ ifindex_t ifindex;
uint32_t remote_label;
uint8_t priority;
uint8_t flags;
};
#define F_FEC_NH_NEW 0x01
+#define F_FEC_NH_CONNECTED 0x02
struct fec_node {
struct fec fec;
LIST_HEAD(, fec_nh) nexthops; /* fib nexthops */
- LIST_HEAD(, lde_map) downstream; /* recv mappings */
- LIST_HEAD(, lde_map) upstream; /* sent mappings */
+ struct lde_map_head downstream; /* recv mappings */
+ struct lde_map_head upstream; /* sent mappings */
uint32_t local_label;
void *data; /* fec specific data */
@@ -128,7 +134,8 @@ extern struct thread *gc_timer;
void lde(const char *, const char *);
int lde_imsg_compose_parent(int, pid_t, void *, uint16_t);
int lde_imsg_compose_ldpe(int, uint32_t, pid_t, void *, uint16_t);
-uint32_t lde_assign_label(void);
+int lde_acl_check(char *, int, union ldpd_addr *, uint8_t);
+uint32_t lde_update_label(struct fec_node *);
void lde_send_change_klabel(struct fec_node *, struct fec_nh *);
void lde_send_delete_klabel(struct fec_node *, struct fec_nh *);
void lde_fec2map(struct fec *, struct map *);
@@ -149,7 +156,7 @@ struct lde_req *lde_req_add(struct lde_nbr *, struct fec *, int);
void lde_req_del(struct lde_nbr *, struct lde_req *, int);
struct lde_wdraw *lde_wdraw_add(struct lde_nbr *, struct fec_node *);
void lde_wdraw_del(struct lde_nbr *, struct lde_wdraw *);
-void lde_change_egress_label(int, int);
+void lde_change_egress_label(int);
struct lde_addr *lde_address_find(struct lde_nbr *, int,
union ldpd_addr *);
@@ -163,13 +170,12 @@ void rt_dump(pid_t);
void fec_snap(struct lde_nbr *);
void fec_tree_clear(void);
struct fec_nh *fec_nh_find(struct fec_node *, int, union ldpd_addr *,
- uint8_t);
-uint32_t egress_label(enum fec_type);
+ ifindex_t, uint8_t);
void lde_kernel_insert(struct fec *, int, union ldpd_addr *,
- uint8_t, int, void *);
+ ifindex_t, uint8_t, int, void *);
void lde_kernel_remove(struct fec *, int, union ldpd_addr *,
- uint8_t);
-void lde_kernel_reevaluate(struct fec *);
+ ifindex_t, uint8_t);
+void lde_kernel_update(struct fec *);
void lde_check_mapping(struct map *, struct lde_nbr *);
void lde_check_request(struct map *, struct lde_nbr *);
void lde_check_release(struct map *, struct lde_nbr *);
diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c
index 43e5f92f2f..234d373fbb 100644
--- a/ldpd/lde_lib.c
+++ b/ldpd/lde_lib.c
@@ -31,7 +31,7 @@ static int lde_nbr_is_nexthop(struct fec_node *,
static void fec_free(void *);
static struct fec_node *fec_add(struct fec *fec);
static struct fec_nh *fec_nh_add(struct fec_node *, int, union ldpd_addr *,
- uint8_t priority);
+ ifindex_t, uint8_t);
static void fec_nh_del(struct fec_nh *);
RB_GENERATE(fec_tree, fec, entry, fec_compare)
@@ -159,7 +159,7 @@ rt_dump(pid_t pid)
RB_FOREACH(f, fec_tree, &ft) {
fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL &&
- LIST_EMPTY(&fn->downstream))
+ RB_EMPTY(&fn->downstream))
continue;
rtctl.first = 1;
@@ -179,7 +179,7 @@ rt_dump(pid_t pid)
}
rtctl.local_label = fn->local_label;
- LIST_FOREACH(me, &fn->downstream, entry) {
+ RB_FOREACH(me, lde_map_head, &fn->downstream) {
rtctl.in_use = lde_nbr_is_nexthop(fn, me->nexthop);
rtctl.nexthop = me->nexthop->id;
rtctl.remote_label = me->map.label;
@@ -188,7 +188,7 @@ rt_dump(pid_t pid)
&rtctl, sizeof(rtctl));
rtctl.first = 0;
}
- if (LIST_EMPTY(&fn->downstream)) {
+ if (RB_EMPTY(&fn->downstream)) {
rtctl.in_use = 0;
rtctl.nexthop.s_addr = INADDR_ANY;
rtctl.remote_label = NO_LABEL;
@@ -224,10 +224,10 @@ fec_free(void *arg)
while ((fnh = LIST_FIRST(&fn->nexthops)))
fec_nh_del(fnh);
- if (!LIST_EMPTY(&fn->downstream))
+ if (!RB_EMPTY(&fn->downstream))
log_warnx("%s: fec %s downstream list not empty", __func__,
log_fec(&fn->fec));
- if (!LIST_EMPTY(&fn->upstream))
+ if (!RB_EMPTY(&fn->upstream))
log_warnx("%s: fec %s upstream list not empty", __func__,
log_fec(&fn->fec));
@@ -251,8 +251,8 @@ fec_add(struct fec *fec)
fn->fec = *fec;
fn->local_label = NO_LABEL;
- LIST_INIT(&fn->upstream);
- LIST_INIT(&fn->downstream);
+ RB_INIT(&fn->upstream);
+ RB_INIT(&fn->downstream);
LIST_INIT(&fn->nexthops);
if (fec_insert(&ft, &fn->fec))
@@ -264,13 +264,14 @@ fec_add(struct fec *fec)
struct fec_nh *
fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
- uint8_t priority)
+ ifindex_t ifindex, uint8_t priority)
{
struct fec_nh *fnh;
LIST_FOREACH(fnh, &fn->nexthops, entry)
if (fnh->af == af &&
ldp_addrcmp(af, &fnh->nexthop, nexthop) == 0 &&
+ fnh->ifindex == ifindex &&
fnh->priority == priority)
return (fnh);
@@ -279,7 +280,7 @@ fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
static struct fec_nh *
fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
- uint8_t priority)
+ ifindex_t ifindex, uint8_t priority)
{
struct fec_nh *fnh;
@@ -289,6 +290,7 @@ fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
fnh->af = af;
fnh->nexthop = *nexthop;
+ fnh->ifindex = ifindex;
fnh->remote_label = NO_LABEL;
fnh->priority = priority;
LIST_INSERT_HEAD(&fn->nexthops, fnh, entry);
@@ -303,87 +305,30 @@ fec_nh_del(struct fec_nh *fnh)
free(fnh);
}
-uint32_t
-egress_label(enum fec_type fec_type)
-{
- switch (fec_type) {
- case FEC_TYPE_IPV4:
- if (ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL)
- return (MPLS_LABEL_IPV4NULL);
- break;
- case FEC_TYPE_IPV6:
- if (ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL)
- return (MPLS_LABEL_IPV6NULL);
- break;
- default:
- fatalx("egress_label: unexpected fec type");
- }
-
- return (MPLS_LABEL_IMPLNULL);
-}
-
void
lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
- uint8_t priority, int connected, void *data)
+ ifindex_t ifindex, uint8_t priority, int connected, void *data)
{
struct fec_node *fn;
struct fec_nh *fnh;
- struct lde_map *me;
- struct lde_nbr *ln;
fn = (struct fec_node *)fec_find(&ft, fec);
if (fn == NULL)
fn = fec_add(fec);
- fnh = fec_nh_find(fn, af, nexthop, priority);
- if (fnh != NULL) {
- lde_send_change_klabel(fn, fnh);
- fnh->flags |= F_FEC_NH_NEW;
- return;
- }
-
- if (fn->fec.type == FEC_TYPE_PWID)
+ if (data)
fn->data = data;
- if (fn->local_label == NO_LABEL) {
- if (connected)
- fn->local_label = egress_label(fn->fec.type);
- else
- fn->local_label = lde_assign_label();
-
- /* FEC.1: perform lsr label distribution procedure */
- RB_FOREACH(ln, nbr_tree, &lde_nbrs)
- lde_send_labelmapping(ln, fn, 1);
- }
-
- fnh = fec_nh_add(fn, af, nexthop, priority);
+ fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
+ if (fnh == NULL)
+ fnh = fec_nh_add(fn, af, nexthop, ifindex, priority);
fnh->flags |= F_FEC_NH_NEW;
- lde_send_change_klabel(fn, fnh);
-
- switch (fn->fec.type) {
- case FEC_TYPE_IPV4:
- case FEC_TYPE_IPV6:
- ln = lde_nbr_find_by_addr(af, &fnh->nexthop);
- break;
- case FEC_TYPE_PWID:
- ln = lde_nbr_find_by_lsrid(fn->fec.u.pwid.lsr_id);
- break;
- default:
- ln = NULL;
- break;
- }
-
- if (ln) {
- /* FEC.2 */
- me = (struct lde_map *)fec_find(&ln->recv_map, &fn->fec);
- if (me)
- /* FEC.5 */
- lde_check_mapping(&me->map, ln);
- }
+ if (connected)
+ fnh->flags |= F_FEC_NH_CONNECTED;
}
void
lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
- uint8_t priority)
+ ifindex_t ifindex, uint8_t priority)
{
struct fec_node *fn;
struct fec_nh *fnh;
@@ -392,19 +337,13 @@ lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
if (fn == NULL)
/* route lost */
return;
- fnh = fec_nh_find(fn, af, nexthop, priority);
+ fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
if (fnh == NULL)
/* route lost */
return;
lde_send_delete_klabel(fn, fnh);
fec_nh_del(fnh);
- if (LIST_EMPTY(&fn->nexthops)) {
- lde_send_labelwithdraw_all(fn, NO_LABEL);
- fn->local_label = NO_LABEL;
- if (fn->fec.type == FEC_TYPE_PWID)
- fn->data = NULL;
- }
}
/*
@@ -414,10 +353,12 @@ lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
* them (if any), withdraw the associated labels from zebra.
*/
void
-lde_kernel_reevaluate(struct fec *fec)
+lde_kernel_update(struct fec *fec)
{
struct fec_node *fn;
struct fec_nh *fnh, *safe;
+ struct lde_nbr *ln;
+ struct lde_map *me;
fn = (struct fec_node *)fec_find(&ft, fec);
if (fn == NULL)
@@ -426,9 +367,53 @@ lde_kernel_reevaluate(struct fec *fec)
LIST_FOREACH_SAFE(fnh, &fn->nexthops, entry, safe) {
if (fnh->flags & F_FEC_NH_NEW)
fnh->flags &= ~F_FEC_NH_NEW;
- else
- lde_kernel_remove(fec, fnh->af, &fnh->nexthop,
- fnh->priority);
+ else {
+ lde_send_delete_klabel(fn, fnh);
+ fec_nh_del(fnh);
+ }
+ }
+
+ if (LIST_EMPTY(&fn->nexthops)) {
+ lde_send_labelwithdraw_all(fn, NO_LABEL);
+ fn->local_label = NO_LABEL;
+ fn->data = NULL;
+ } else {
+ uint32_t previous_label;
+
+ previous_label = fn->local_label;
+ fn->local_label = lde_update_label(fn);
+
+ if (fn->local_label != NO_LABEL &&
+ fn->local_label != previous_label) {
+ /* FEC.1: perform lsr label distribution procedure */
+ RB_FOREACH(ln, nbr_tree, &lde_nbrs)
+ lde_send_labelmapping(ln, fn, 1);
+ }
+ }
+
+ LIST_FOREACH(fnh, &fn->nexthops, entry) {
+ lde_send_change_klabel(fn, fnh);
+
+ switch (fn->fec.type) {
+ case FEC_TYPE_IPV4:
+ case FEC_TYPE_IPV6:
+ ln = lde_nbr_find_by_addr(fnh->af, &fnh->nexthop);
+ break;
+ case FEC_TYPE_PWID:
+ ln = lde_nbr_find_by_lsrid(fn->fec.u.pwid.lsr_id);
+ break;
+ default:
+ ln = NULL;
+ break;
+ }
+
+ if (ln) {
+ /* FEC.2 */
+ me = (struct lde_map *)fec_find(&ln->recv_map, &fn->fec);
+ if (me)
+ /* FEC.5 */
+ lde_check_mapping(&me->map, ln);
+ }
}
}
@@ -444,6 +429,30 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln)
int msgsource = 0;
lde_map2fec(map, ln->id, &fec);
+
+ switch (fec.type) {
+ case FEC_TYPE_IPV4:
+ if (lde_acl_check(ldeconf->ipv4.acl_label_accept_from,
+ AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
+ return;
+ if (lde_acl_check(ldeconf->ipv4.acl_label_accept_for,
+ AF_INET, (union ldpd_addr *)&fec.u.ipv4.prefix,
+ fec.u.ipv4.prefixlen) != FILTER_PERMIT)
+ return;
+ break;
+ case FEC_TYPE_IPV6:
+ if (lde_acl_check(ldeconf->ipv6.acl_label_accept_from,
+ AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
+ return;
+ if (lde_acl_check(ldeconf->ipv6.acl_label_accept_for,
+ AF_INET6, (union ldpd_addr *)&fec.u.ipv6.prefix,
+ fec.u.ipv6.prefixlen) != FILTER_PERMIT)
+ return;
+ break;
+ default:
+ break;
+ }
+
fn = (struct fec_node *)fec_find(&ft, &fec);
if (fn == NULL)
fn = fec_add(&fec);
@@ -772,8 +781,8 @@ lde_gc_timer(struct thread *thread)
fn = (struct fec_node *) fec;
if (!LIST_EMPTY(&fn->nexthops) ||
- !LIST_EMPTY(&fn->downstream) ||
- !LIST_EMPTY(&fn->upstream))
+ !RB_EMPTY(&fn->downstream) ||
+ !RB_EMPTY(&fn->upstream))
continue;
fec_remove(&ft, &fn->fec);
diff --git a/ldpd/ldp_debug.c b/ldpd/ldp_debug.c
index 15dd06a0f3..86b679d8aa 100644
--- a/ldpd/ldp_debug.c
+++ b/ldpd/ldp_debug.c
@@ -74,7 +74,7 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
DEBUG_OFF(event, EVENT);
else
DEBUG_ON(event, EVENT);
- } else if (strcmp(type_str, "messages") == 0) {
+ } else if (strcmp(type_str, "messages") == 0) {
all = (vty_get_arg_value(args, "all")) ? 1 : 0;
dir_str = vty_get_arg_value(args, "dir");
if (dir_str == NULL)
@@ -99,7 +99,7 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
DEBUG_ON(msg, MSG_SEND_ALL);
}
}
- } else if (strcmp(type_str, "zebra") == 0) {
+ } else if (strcmp(type_str, "zebra") == 0) {
if (disable)
DEBUG_OFF(zebra, ZEBRA);
else
diff --git a/ldpd/ldp_vty.h b/ldpd/ldp_vty.h
index 735554badf..b0dc291434 100644
--- a/ldpd/ldp_vty.h
+++ b/ldpd/ldp_vty.h
@@ -47,7 +47,10 @@ int ldp_vty_session_holdtime(struct vty *, struct vty_arg *[]);
int ldp_vty_interface(struct vty *, struct vty_arg *[]);
int ldp_vty_trans_addr(struct vty *, struct vty_arg *[]);
int ldp_vty_neighbor_targeted(struct vty *, struct vty_arg *[]);
-int ldp_vty_explicit_null(struct vty *, struct vty_arg *[]);
+int ldp_vty_label_advertise(struct vty *, struct vty_arg *[]);
+int ldp_vty_label_allocate(struct vty *, struct vty_arg *[]);
+int ldp_vty_label_expnull(struct vty *, struct vty_arg *[]);
+int ldp_vty_label_accept(struct vty *, struct vty_arg *[]);
int ldp_vty_ttl_security(struct vty *, struct vty_arg *[]);
int ldp_vty_router_id(struct vty *, struct vty_arg *[]);
int ldp_vty_ds_cisco_interop(struct vty *, struct vty_arg *[]);
diff --git a/ldpd/ldp_vty.xml b/ldpd/ldp_vty.xml
index ee5c6e4df2..966b634c27 100644
--- a/ldpd/ldp_vty.xml
+++ b/ldpd/ldp_vty.xml
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<file init="ldp_vty_init" cmdprefix="ldp" header="ldp_vty.h">
+<file init="ldp_vty_init" cmdprefix="ldp" header="ldpd/ldp_vty.h">
<!-- address-family -->
<options name="address-family">
<option name="ipv4" help="IPv4 Address Family"/>
@@ -30,7 +30,48 @@
<option name="sent" help="Sent messages"/>
</options>
+ <!-- ACL -->
+ <options name="acl">
+ <option input="acl_range" help="IP access-list number"/>
+ <option input="acl_expanded_range" help="IP access-list number (expanded range)"/>
+ <option input="word" help="IP access-list name"/>
+ </options>
+
<!-- shared subtrees -->
+ <subtree name="label_local_acls">
+ <option name="to" help="IP Access-list specifying controls on LDP Peers">
+ <select options="acl" arg="to_acl" function="inherited">
+ <option name="for" help="IP access-list for destination prefixes">
+ <select options="acl" arg="for_acl" function="inherited"/>
+ </option>
+ </select>
+ </option>
+ <option name="for" help="IP access-list for destination prefixes">
+ <select options="acl" arg="for_acl" function="inherited">
+ <option name="to" help="IP Access-list specifying controls on LDP Peers">
+ <select options="acl" arg="to_acl" function="inherited"/>
+ </option>
+ </select>
+ </option>
+ </subtree>
+
+ <subtree name="label_remote_acls">
+ <option name="from" help="Neighbor from whom to accept label advertisement">
+ <select options="acl" arg="from_acl" function="inherited">
+ <option name="for" help="IP access-list for destination prefixes">
+ <select options="acl" arg="for_acl" function="inherited"/>
+ </option>
+ </select>
+ </option>
+ <option name="for" help="IP access-list for destination prefixes">
+ <select options="acl" arg="for_acl" function="inherited">
+ <option name="from" help="Neighbor from whom to accept label advertisement">
+ <select options="acl" arg="from_acl" function="inherited"/>
+ </option>
+ </select>
+ </option>
+ </subtree>
+
<subtree name="discovery_link">
<option name="discovery" help="Configure discovery parameters">
<option name="hello" arg="hello_type" help="LDP Link Hellos">
@@ -70,13 +111,33 @@
<include subtree="discovery_targeted"/>
<option name="discovery" help="Configure discovery parameters">
<option name="targeted-hello" arg="hello_type" help="LDP Targeted Hellos">
- <option name="accept" help="Accept and respond to targeted hellos" function="ldp_vty_targeted_hello_accept"/>
+ <option name="accept" help="Accept and respond to targeted hellos" function="ldp_vty_targeted_hello_accept">
+ <option name="from" help="Access list to specify acceptable targeted hello source">
+ <select options="acl" arg="from_acl" function="inherited"/>
+ </option>
+ </option>
</option>
</option>
<option name="label" help="Configure label control and policies">
<option name="local" help="Configure local label control and policies">
- <option name="advertise" help="Configure outbound label advertisement control">
- <option name="explicit-null" help="Configure explicit-null advertisement" function="ldp_vty_explicit_null"/>
+ <option name="advertise" help="Configure outbound label advertisement control" function="ldp_vty_label_advertise">
+ <include subtree="label_local_acls"/>
+ <option name="explicit-null" help="Configure explicit-null advertisement" function="ldp_vty_label_expnull">
+ <option name="for" help="IP access-list for destination prefixes">
+ <select options="acl" arg="for_acl" function="inherited"/>
+ </option>
+ </option>
+ </option>
+ <option name="allocate" help="Configure label allocation control">
+ <option name="for" help="IP access-list">
+ <select options="acl" arg="for_acl" function="ldp_vty_label_allocate"/>
+ </option>
+ <option name="host-routes" arg="host-routes" help="allocate local label for host routes only" function="ldp_vty_label_allocate"/>
+ </option>
+ </option>
+ <option name="remote" help="Configure remote/peer label control and policies">
+ <option name="accept" help="Configure inbound label acceptance control" function="ldp_vty_label_accept">
+ <include subtree="label_remote_acls"/>
</option>
</option>
</option>
@@ -272,15 +333,23 @@
<!-- exec mode commands -->
<subtree name="ldp_show_af">
- <option name="binding" help="Label Information Base (LIB) information" function="ldp_vty_show_binding"/>
- <option name="discovery" help="Discovery Hello Information" function="ldp_vty_show_discovery"/>
- <option name="interface" help="interface information" function="ldp_vty_show_interface"/>
+ <option name="binding" help="Label Information Base (LIB) information">
+ <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_binding"/>
+ </option>
+ <option name="discovery" help="Discovery Hello Information">
+ <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_discovery"/>
+ </option>
+ <option name="interface" help="interface information">
+ <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_interface"/>
+ </option>
</subtree>
<tree name="ldp_exec">
<option name="show" help="Show running system information">
<option name="mpls" help="MPLS information">
<option name="ldp" help="Label Distribution Protocol">
- <option name="neighbor" help="Neighbor information" function="ldp_vty_show_neighbor"/>
+ <option name="neighbor" help="Neighbor information">
+ <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_neighbor"/>
+ </option>
<include subtree="ldp_show_af"/>
<select options="address-family" arg="address-family">
<include subtree="ldp_show_af"/>
@@ -289,8 +358,12 @@
</option>
<option name="l2vpn" help="Show information about Layer2 VPN">
<option name="atom" help="Show Any Transport over MPLS information">
- <option name="binding" help="Show AToM label binding information" function="ldp_vty_show_atom_binding"/>
- <option name="vc" help="Show AToM virtual circuit information" function="ldp_vty_show_atom_vc"/>
+ <option name="binding" help="Show AToM label binding information">
+ <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_atom_binding"/>
+ </option>
+ <option name="vc" help="Show AToM virtual circuit information">
+ <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_atom_vc"/>
+ </option>
</option>
</option>
<option name="debugging" help="Debugging functions">
diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c
deleted file mode 100644
index b55c7fc8a9..0000000000
--- a/ldpd/ldp_vty_cmds.c
+++ /dev/null
@@ -1,1726 +0,0 @@
-/* Auto-generated from ldp_vty.xml. */
-/* Do not edit! */
-
-#include <zebra.h>
-
-#include "command.h"
-#include "vty.h"
-#include "ldp_vty.h"
-
-DEFUN (ldp_mpls_ldp,
- ldp_mpls_ldp_cmd,
- "mpls ldp",
- "Global MPLS configuration subcommands\n"
- "Label Distribution Protocol\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_mpls_ldp (vty, args);
-}
-
-DEFUN (ldp_l2vpn_word_type_vpls,
- ldp_l2vpn_word_type_vpls_cmd,
- "l2vpn WORD type vpls",
- "Configure l2vpn commands\n"
- "L2VPN name\n"
- "L2VPN type\n"
- "Virtual Private LAN Service\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "name", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn (vty, args);
-}
-
-DEFUN (ldp_no_mpls_ldp,
- ldp_no_mpls_ldp_cmd,
- "no mpls ldp",
- "Negate a command or set its defaults\n"
- "Global MPLS configuration subcommands\n"
- "Label Distribution Protocol\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- NULL
- };
- return ldp_vty_mpls_ldp (vty, args);
-}
-
-DEFUN (ldp_no_l2vpn_word_type_vpls,
- ldp_no_l2vpn_word_type_vpls_cmd,
- "no l2vpn WORD type vpls",
- "Negate a command or set its defaults\n"
- "Configure l2vpn commands\n"
- "L2VPN name\n"
- "L2VPN type\n"
- "Virtual Private LAN Service\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "name", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn (vty, args);
-}
-
-DEFUN (ldp_address_family_ipv4,
- ldp_address_family_ipv4_cmd,
- "address-family ipv4",
- "Configure Address Family and its parameters\n"
- "IPv4\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "address-family", .value = "ipv4" },
- NULL
- };
- return ldp_vty_address_family (vty, args);
-}
-
-DEFUN (ldp_address_family_ipv6,
- ldp_address_family_ipv6_cmd,
- "address-family ipv6",
- "Configure Address Family and its parameters\n"
- "IPv6\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "address-family", .value = "ipv6" },
- NULL
- };
- return ldp_vty_address_family (vty, args);
-}
-
-DEFUN (ldp_discovery_hello_holdtime_disc_time,
- ldp_discovery_hello_holdtime_disc_time_cmd,
- "discovery hello holdtime <1-65535>",
- "Configure discovery parameters\n"
- "LDP Link Hellos\n"
- "Hello holdtime\n"
- "Time (seconds) - 65535 implies infinite\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "hello_type", .value = "hello" },
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_disc_holdtime (vty, args);
-}
-
-DEFUN (ldp_discovery_hello_interval_disc_time,
- ldp_discovery_hello_interval_disc_time_cmd,
- "discovery hello interval <1-65535>",
- "Configure discovery parameters\n"
- "LDP Link Hellos\n"
- "Hello interval\n"
- "Time (seconds)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "hello_type", .value = "hello" },
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_disc_interval (vty, args);
-}
-
-DEFUN (ldp_discovery_targeted_hello_holdtime_disc_time,
- ldp_discovery_targeted_hello_holdtime_disc_time_cmd,
- "discovery targeted-hello holdtime <1-65535>",
- "Configure discovery parameters\n"
- "LDP Targeted Hellos\n"
- "Targeted hello holdtime\n"
- "Time (seconds) - 65535 implies infinite\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_disc_holdtime (vty, args);
-}
-
-DEFUN (ldp_discovery_targeted_hello_interval_disc_time,
- ldp_discovery_targeted_hello_interval_disc_time_cmd,
- "discovery targeted-hello interval <1-65535>",
- "Configure discovery parameters\n"
- "LDP Targeted Hellos\n"
- "Targeted hello interval\n"
- "Time (seconds)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_disc_interval (vty, args);
-}
-
-DEFUN (ldp_dual_stack_transport_connection_prefer_ipv4,
- ldp_dual_stack_transport_connection_prefer_ipv4_cmd,
- "dual-stack transport-connection prefer ipv4",
- "Configure dual stack parameters\n"
- "Configure TCP transport parameters\n"
- "Configure prefered address family for TCP transport connection with neighbor\n"
- "IPv4\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_trans_pref_ipv4 (vty, args);
-}
-
-DEFUN (ldp_dual_stack_cisco_interop,
- ldp_dual_stack_cisco_interop_cmd,
- "dual-stack cisco-interop",
- "Configure dual stack parameters\n"
- "Use Cisco non-compliant format to send and interpret the Dual-Stack capability TLV\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_ds_cisco_interop (vty, args);
-}
-
-DEFUN (ldp_neighbor_ipv4_password_word,
- ldp_neighbor_ipv4_password_word_cmd,
- "neighbor A.B.C.D password WORD",
- "Configure neighbor parameters\n"
- "LDP Id of neighbor\n"
- "Configure password for MD5 authentication\n"
- "The password\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
- &(struct vty_arg) { .name = "password", .value = argv[1] },
- NULL
- };
- return ldp_vty_neighbor_password (vty, args);
-}
-
-DEFUN (ldp_neighbor_ipv4_session_holdtime_session_time,
- ldp_neighbor_ipv4_session_holdtime_session_time_cmd,
- "neighbor A.B.C.D session holdtime <15-65535>",
- "Configure neighbor parameters\n"
- "LDP Id of neighbor\n"
- "Configure session parameters\n"
- "Configure session holdtime\n"
- "Time (seconds)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
- &(struct vty_arg) { .name = "seconds", .value = argv[1] },
- NULL
- };
- return ldp_vty_session_holdtime (vty, args);
-}
-
-DEFUN (ldp_neighbor_ipv4_ttl_security_disable,
- ldp_neighbor_ipv4_ttl_security_disable_cmd,
- "neighbor A.B.C.D ttl-security disable",
- "Configure neighbor parameters\n"
- "LDP Id of neighbor\n"
- "LDP ttl security check\n"
- "Disable ttl security\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
- NULL
- };
- return ldp_vty_neighbor_ttl_security (vty, args);
-}
-
-DEFUN (ldp_neighbor_ipv4_ttl_security_hops_hops,
- ldp_neighbor_ipv4_ttl_security_hops_hops_cmd,
- "neighbor A.B.C.D ttl-security hops <1-254>",
- "Configure neighbor parameters\n"
- "LDP Id of neighbor\n"
- "LDP ttl security check\n"
- "IP hops\n"
- "maximum number of hops\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
- &(struct vty_arg) { .name = "hops", .value = argv[1] },
- NULL
- };
- return ldp_vty_neighbor_ttl_security (vty, args);
-}
-
-DEFUN (ldp_router_id_ipv4,
- ldp_router_id_ipv4_cmd,
- "router-id A.B.C.D",
- "Configure router Id\n"
- "LSR Id (in form of an IPv4 address)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_router_id (vty, args);
-}
-
-DEFUN (ldp_no_address_family_ipv4,
- ldp_no_address_family_ipv4_cmd,
- "no address-family ipv4",
- "Negate a command or set its defaults\n"
- "Configure Address Family and its parameters\n"
- "IPv4\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "address-family", .value = "ipv4" },
- NULL
- };
- return ldp_vty_address_family (vty, args);
-}
-
-DEFUN (ldp_no_address_family_ipv6,
- ldp_no_address_family_ipv6_cmd,
- "no address-family ipv6",
- "Negate a command or set its defaults\n"
- "Configure Address Family and its parameters\n"
- "IPv6\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "address-family", .value = "ipv6" },
- NULL
- };
- return ldp_vty_address_family (vty, args);
-}
-
-DEFUN (ldp_no_discovery_hello_holdtime_disc_time,
- ldp_no_discovery_hello_holdtime_disc_time_cmd,
- "no discovery hello holdtime <1-65535>",
- "Negate a command or set its defaults\n"
- "Configure discovery parameters\n"
- "LDP Link Hellos\n"
- "Hello holdtime\n"
- "Time (seconds) - 65535 implies infinite\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "hello_type", .value = "hello" },
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_disc_holdtime (vty, args);
-}
-
-DEFUN (ldp_no_discovery_hello_interval_disc_time,
- ldp_no_discovery_hello_interval_disc_time_cmd,
- "no discovery hello interval <1-65535>",
- "Negate a command or set its defaults\n"
- "Configure discovery parameters\n"
- "LDP Link Hellos\n"
- "Hello interval\n"
- "Time (seconds)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "hello_type", .value = "hello" },
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_disc_interval (vty, args);
-}
-
-DEFUN (ldp_no_discovery_targeted_hello_holdtime_disc_time,
- ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd,
- "no discovery targeted-hello holdtime <1-65535>",
- "Negate a command or set its defaults\n"
- "Configure discovery parameters\n"
- "LDP Targeted Hellos\n"
- "Targeted hello holdtime\n"
- "Time (seconds) - 65535 implies infinite\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_disc_holdtime (vty, args);
-}
-
-DEFUN (ldp_no_discovery_targeted_hello_interval_disc_time,
- ldp_no_discovery_targeted_hello_interval_disc_time_cmd,
- "no discovery targeted-hello interval <1-65535>",
- "Negate a command or set its defaults\n"
- "Configure discovery parameters\n"
- "LDP Targeted Hellos\n"
- "Targeted hello interval\n"
- "Time (seconds)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_disc_interval (vty, args);
-}
-
-DEFUN (ldp_no_dual_stack_transport_connection_prefer_ipv4,
- ldp_no_dual_stack_transport_connection_prefer_ipv4_cmd,
- "no dual-stack transport-connection prefer ipv4",
- "Negate a command or set its defaults\n"
- "Configure dual stack parameters\n"
- "Configure TCP transport parameters\n"
- "Configure prefered address family for TCP transport connection with neighbor\n"
- "IPv4\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- NULL
- };
- return ldp_vty_trans_pref_ipv4 (vty, args);
-}
-
-DEFUN (ldp_no_dual_stack_cisco_interop,
- ldp_no_dual_stack_cisco_interop_cmd,
- "no dual-stack cisco-interop",
- "Negate a command or set its defaults\n"
- "Configure dual stack parameters\n"
- "Use Cisco non-compliant format to send and interpret the Dual-Stack capability TLV\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- NULL
- };
- return ldp_vty_ds_cisco_interop (vty, args);
-}
-
-DEFUN (ldp_no_neighbor_ipv4_password_word,
- ldp_no_neighbor_ipv4_password_word_cmd,
- "no neighbor A.B.C.D password WORD",
- "Negate a command or set its defaults\n"
- "Configure neighbor parameters\n"
- "LDP Id of neighbor\n"
- "Configure password for MD5 authentication\n"
- "The password\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
- &(struct vty_arg) { .name = "password", .value = argv[1] },
- NULL
- };
- return ldp_vty_neighbor_password (vty, args);
-}
-
-DEFUN (ldp_no_neighbor_ipv4_session_holdtime_session_time,
- ldp_no_neighbor_ipv4_session_holdtime_session_time_cmd,
- "no neighbor A.B.C.D session holdtime <15-65535>",
- "Negate a command or set its defaults\n"
- "Configure neighbor parameters\n"
- "LDP Id of neighbor\n"
- "Configure session parameters\n"
- "Configure session holdtime\n"
- "Time (seconds)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
- &(struct vty_arg) { .name = "seconds", .value = argv[1] },
- NULL
- };
- return ldp_vty_session_holdtime (vty, args);
-}
-
-DEFUN (ldp_no_neighbor_ipv4_ttl_security_disable,
- ldp_no_neighbor_ipv4_ttl_security_disable_cmd,
- "no neighbor A.B.C.D ttl-security disable",
- "Negate a command or set its defaults\n"
- "Configure neighbor parameters\n"
- "LDP Id of neighbor\n"
- "LDP ttl security check\n"
- "Disable ttl security\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
- NULL
- };
- return ldp_vty_neighbor_ttl_security (vty, args);
-}
-
-DEFUN (ldp_no_neighbor_ipv4_ttl_security_hops_hops,
- ldp_no_neighbor_ipv4_ttl_security_hops_hops_cmd,
- "no neighbor A.B.C.D ttl-security hops <1-254>",
- "Negate a command or set its defaults\n"
- "Configure neighbor parameters\n"
- "LDP Id of neighbor\n"
- "LDP ttl security check\n"
- "IP hops\n"
- "maximum number of hops\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
- &(struct vty_arg) { .name = "hops", .value = argv[1] },
- NULL
- };
- return ldp_vty_neighbor_ttl_security (vty, args);
-}
-
-DEFUN (ldp_no_router_id_ipv4,
- ldp_no_router_id_ipv4_cmd,
- "no router-id A.B.C.D",
- "Negate a command or set its defaults\n"
- "Configure router Id\n"
- "LSR Id (in form of an IPv4 address)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_router_id (vty, args);
-}
-
-DEFUN (ldp_discovery_targeted_hello_accept,
- ldp_discovery_targeted_hello_accept_cmd,
- "discovery targeted-hello accept",
- "Configure discovery parameters\n"
- "LDP Targeted Hellos\n"
- "Accept and respond to targeted hellos\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
- NULL
- };
- return ldp_vty_targeted_hello_accept (vty, args);
-}
-
-DEFUN (ldp_label_local_advertise_explicit_null,
- ldp_label_local_advertise_explicit_null_cmd,
- "label local advertise explicit-null",
- "Configure label control and policies\n"
- "Configure local label control and policies\n"
- "Configure outbound label advertisement control\n"
- "Configure explicit-null advertisement\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_explicit_null (vty, args);
-}
-
-DEFUN (ldp_ttl_security_disable,
- ldp_ttl_security_disable_cmd,
- "ttl-security disable",
- "LDP ttl security check\n"
- "Disable ttl security\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_ttl_security (vty, args);
-}
-
-DEFUN (ldp_session_holdtime_session_time,
- ldp_session_holdtime_session_time_cmd,
- "session holdtime <15-65535>",
- "Configure session parameters\n"
- "Configure session holdtime\n"
- "Time (seconds)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_session_holdtime (vty, args);
-}
-
-DEFUN (ldp_interface_ifname,
- ldp_interface_ifname_cmd,
- "interface IFNAME",
- "Enable LDP on an interface and enter interface submode\n"
- "Interface's name\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "ifname", .value = argv[0] },
- NULL
- };
- return ldp_vty_interface (vty, args);
-}
-
-DEFUN (ldp_discovery_transport_address_ipv4,
- ldp_discovery_transport_address_ipv4_cmd,
- "discovery transport-address A.B.C.D",
- "Configure discovery parameters\n"
- "Specify transport address for TCP connection\n"
- "IP address to be used as transport address\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_trans_addr (vty, args);
-}
-
-DEFUN (ldp_neighbor_ipv4_targeted,
- ldp_neighbor_ipv4_targeted_cmd,
- "neighbor A.B.C.D targeted",
- "Configure neighbor parameters\n"
- "IP address of neighbor\n"
- "Establish targeted session\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_neighbor_targeted (vty, args);
-}
-
-DEFUN (ldp_no_discovery_targeted_hello_accept,
- ldp_no_discovery_targeted_hello_accept_cmd,
- "no discovery targeted-hello accept",
- "Negate a command or set its defaults\n"
- "Configure discovery parameters\n"
- "LDP Targeted Hellos\n"
- "Accept and respond to targeted hellos\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
- NULL
- };
- return ldp_vty_targeted_hello_accept (vty, args);
-}
-
-DEFUN (ldp_no_label_local_advertise_explicit_null,
- ldp_no_label_local_advertise_explicit_null_cmd,
- "no label local advertise explicit-null",
- "Negate a command or set its defaults\n"
- "Configure label control and policies\n"
- "Configure local label control and policies\n"
- "Configure outbound label advertisement control\n"
- "Configure explicit-null advertisement\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- NULL
- };
- return ldp_vty_explicit_null (vty, args);
-}
-
-DEFUN (ldp_no_ttl_security_disable,
- ldp_no_ttl_security_disable_cmd,
- "no ttl-security disable",
- "Negate a command or set its defaults\n"
- "LDP ttl security check\n"
- "Disable ttl security\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- NULL
- };
- return ldp_vty_ttl_security (vty, args);
-}
-
-DEFUN (ldp_no_session_holdtime_session_time,
- ldp_no_session_holdtime_session_time_cmd,
- "no session holdtime <15-65535>",
- "Negate a command or set its defaults\n"
- "Configure session parameters\n"
- "Configure session holdtime\n"
- "Time (seconds)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "seconds", .value = argv[0] },
- NULL
- };
- return ldp_vty_session_holdtime (vty, args);
-}
-
-DEFUN (ldp_no_interface_ifname,
- ldp_no_interface_ifname_cmd,
- "no interface IFNAME",
- "Negate a command or set its defaults\n"
- "Enable LDP on an interface and enter interface submode\n"
- "Interface's name\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "ifname", .value = argv[0] },
- NULL
- };
- return ldp_vty_interface (vty, args);
-}
-
-DEFUN (ldp_no_discovery_transport_address_ipv4,
- ldp_no_discovery_transport_address_ipv4_cmd,
- "no discovery transport-address A.B.C.D",
- "Negate a command or set its defaults\n"
- "Configure discovery parameters\n"
- "Specify transport address for TCP connection\n"
- "IP address to be used as transport address\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_trans_addr (vty, args);
-}
-
-DEFUN (ldp_no_neighbor_ipv4_targeted,
- ldp_no_neighbor_ipv4_targeted_cmd,
- "no neighbor A.B.C.D targeted",
- "Negate a command or set its defaults\n"
- "Configure neighbor parameters\n"
- "IP address of neighbor\n"
- "Establish targeted session\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_neighbor_targeted (vty, args);
-}
-
-DEFUN (ldp_discovery_transport_address_ipv6,
- ldp_discovery_transport_address_ipv6_cmd,
- "discovery transport-address X:X::X:X",
- "Configure discovery parameters\n"
- "Specify transport address for TCP connection\n"
- "IPv6 address to be used as transport address\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_trans_addr (vty, args);
-}
-
-DEFUN (ldp_neighbor_ipv6_targeted,
- ldp_neighbor_ipv6_targeted_cmd,
- "neighbor X:X::X:X targeted",
- "Configure neighbor parameters\n"
- "IPv6 address of neighbor\n"
- "Establish targeted session\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_neighbor_targeted (vty, args);
-}
-
-DEFUN (ldp_no_discovery_transport_address_ipv6,
- ldp_no_discovery_transport_address_ipv6_cmd,
- "no discovery transport-address X:X::X:X",
- "Negate a command or set its defaults\n"
- "Configure discovery parameters\n"
- "Specify transport address for TCP connection\n"
- "IPv6 address to be used as transport address\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_trans_addr (vty, args);
-}
-
-DEFUN (ldp_no_neighbor_ipv6_targeted,
- ldp_no_neighbor_ipv6_targeted_cmd,
- "no neighbor X:X::X:X targeted",
- "Negate a command or set its defaults\n"
- "Configure neighbor parameters\n"
- "IPv6 address of neighbor\n"
- "Establish targeted session\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_neighbor_targeted (vty, args);
-}
-
-DEFUN (ldp_bridge_ifname,
- ldp_bridge_ifname_cmd,
- "bridge IFNAME",
- "Bridge interface\n"
- "Interface's name\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "ifname", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_bridge (vty, args);
-}
-
-DEFUN (ldp_mtu_mtu,
- ldp_mtu_mtu_cmd,
- "mtu <1500-9180>",
- "set Maximum Transmission Unit\n"
- "Maximum Transmission Unit value\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "mtu", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_mtu (vty, args);
-}
-
-DEFUN (ldp_member_interface_ifname,
- ldp_member_interface_ifname_cmd,
- "member interface IFNAME",
- "L2VPN member configuration\n"
- "Local interface\n"
- "Interface's name\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "ifname", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_interface (vty, args);
-}
-
-DEFUN (ldp_member_pseudowire_ifname,
- ldp_member_pseudowire_ifname_cmd,
- "member pseudowire IFNAME",
- "L2VPN member configuration\n"
- "Pseudowire interface\n"
- "Interface's name\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "ifname", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pseudowire (vty, args);
-}
-
-DEFUN (ldp_vc_type_pwtype,
- ldp_vc_type_pwtype_cmd,
- "vc type (ethernet|ethernet-tagged)",
- "Virtual Circuit options\n"
- "Virtual Circuit type to use\n"
- "Ethernet (type 5)\n"
- "Ethernet-tagged (type 4)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "type", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pwtype (vty, args);
-}
-
-DEFUN (ldp_no_bridge_ifname,
- ldp_no_bridge_ifname_cmd,
- "no bridge IFNAME",
- "Negate a command or set its defaults\n"
- "Bridge interface\n"
- "Interface's name\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "ifname", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_bridge (vty, args);
-}
-
-DEFUN (ldp_no_mtu_mtu,
- ldp_no_mtu_mtu_cmd,
- "no mtu <1500-9180>",
- "Negate a command or set its defaults\n"
- "set Maximum Transmission Unit\n"
- "Maximum Transmission Unit value\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "mtu", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_mtu (vty, args);
-}
-
-DEFUN (ldp_no_member_interface_ifname,
- ldp_no_member_interface_ifname_cmd,
- "no member interface IFNAME",
- "Negate a command or set its defaults\n"
- "L2VPN member configuration\n"
- "Local interface\n"
- "Interface's name\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "ifname", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_interface (vty, args);
-}
-
-DEFUN (ldp_no_member_pseudowire_ifname,
- ldp_no_member_pseudowire_ifname_cmd,
- "no member pseudowire IFNAME",
- "Negate a command or set its defaults\n"
- "L2VPN member configuration\n"
- "Pseudowire interface\n"
- "Interface's name\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "ifname", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pseudowire (vty, args);
-}
-
-DEFUN (ldp_no_vc_type_pwtype,
- ldp_no_vc_type_pwtype_cmd,
- "no vc type (ethernet|ethernet-tagged)",
- "Negate a command or set its defaults\n"
- "Virtual Circuit options\n"
- "Virtual Circuit type to use\n"
- "Ethernet (type 5)\n"
- "Ethernet-tagged (type 4)\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "type", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pwtype (vty, args);
-}
-
-DEFUN (ldp_control_word_cword,
- ldp_control_word_cword_cmd,
- "control-word (exclude|include)",
- "Control-word options\n"
- "Exclude control-word in pseudowire packets\n"
- "Include control-word in pseudowire packets\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "preference", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pw_cword (vty, args);
-}
-
-DEFUN (ldp_neighbor_address_addr,
- ldp_neighbor_address_addr_cmd,
- "neighbor address (A.B.C.D|X:X::X:X)",
- "Remote endpoint configuration\n"
- "Specify the IPv4 or IPv6 address of the remote endpoint\n"
- "IPv4 address\n"
- "IPv6 address\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pw_nbr_addr (vty, args);
-}
-
-DEFUN (ldp_neighbor_lsr_id_ipv4,
- ldp_neighbor_lsr_id_ipv4_cmd,
- "neighbor lsr-id A.B.C.D",
- "Remote endpoint configuration\n"
- "Specify the LSR-ID of the remote endpoint\n"
- "IPv4 address\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "lsr-id", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pw_nbr_id (vty, args);
-}
-
-DEFUN (ldp_pw_id_pwid,
- ldp_pw_id_pwid_cmd,
- "pw-id <1-4294967295>",
- "Set the Virtual Circuit ID\n"
- "Virtual Circuit ID value\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "pwid", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pw_pwid (vty, args);
-}
-
-DEFUN (ldp_pw_status_disable,
- ldp_pw_status_disable_cmd,
- "pw-status disable",
- "Configure PW status\n"
- "Disable PW status\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_l2vpn_pw_pwstatus (vty, args);
-}
-
-DEFUN (ldp_no_control_word_cword,
- ldp_no_control_word_cword_cmd,
- "no control-word (exclude|include)",
- "Negate a command or set its defaults\n"
- "Control-word options\n"
- "Exclude control-word in pseudowire packets\n"
- "Include control-word in pseudowire packets\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "preference", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pw_cword (vty, args);
-}
-
-DEFUN (ldp_no_neighbor_address_addr,
- ldp_no_neighbor_address_addr_cmd,
- "no neighbor address (A.B.C.D|X:X::X:X)",
- "Negate a command or set its defaults\n"
- "Remote endpoint configuration\n"
- "Specify the IPv4 or IPv6 address of the remote endpoint\n"
- "IPv4 address\n"
- "IPv6 address\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pw_nbr_addr (vty, args);
-}
-
-DEFUN (ldp_no_neighbor_lsr_id_ipv4,
- ldp_no_neighbor_lsr_id_ipv4_cmd,
- "no neighbor lsr-id A.B.C.D",
- "Negate a command or set its defaults\n"
- "Remote endpoint configuration\n"
- "Specify the LSR-ID of the remote endpoint\n"
- "IPv4 address\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "lsr-id", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pw_nbr_id (vty, args);
-}
-
-DEFUN (ldp_no_pw_id_pwid,
- ldp_no_pw_id_pwid_cmd,
- "no pw-id <1-4294967295>",
- "Negate a command or set its defaults\n"
- "Set the Virtual Circuit ID\n"
- "Virtual Circuit ID value\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "pwid", .value = argv[0] },
- NULL
- };
- return ldp_vty_l2vpn_pw_pwid (vty, args);
-}
-
-DEFUN (ldp_no_pw_status_disable,
- ldp_no_pw_status_disable_cmd,
- "no pw-status disable",
- "Negate a command or set its defaults\n"
- "Configure PW status\n"
- "Disable PW status\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- NULL
- };
- return ldp_vty_l2vpn_pw_pwstatus (vty, args);
-}
-
-DEFUN (ldp_show_mpls_ldp_neighbor,
- ldp_show_mpls_ldp_neighbor_cmd,
- "show mpls ldp neighbor",
- "Show running system information\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Neighbor information\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_show_neighbor (vty, args);
-}
-
-DEFUN (ldp_show_mpls_ldp_binding,
- ldp_show_mpls_ldp_binding_cmd,
- "show mpls ldp binding",
- "Show running system information\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Label Information Base (LIB) information\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_show_binding (vty, args);
-}
-
-DEFUN (ldp_show_mpls_ldp_discovery,
- ldp_show_mpls_ldp_discovery_cmd,
- "show mpls ldp discovery",
- "Show running system information\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Discovery Hello Information\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_show_discovery (vty, args);
-}
-
-DEFUN (ldp_show_mpls_ldp_interface,
- ldp_show_mpls_ldp_interface_cmd,
- "show mpls ldp interface",
- "Show running system information\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "interface information\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_show_interface (vty, args);
-}
-
-DEFUN (ldp_show_mpls_ldp_address_family_binding,
- ldp_show_mpls_ldp_address_family_binding_cmd,
- "show mpls ldp (ipv4|ipv6) binding",
- "Show running system information\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "IPv4 Address Family\n"
- "IPv6 Address Family\n"
- "Label Information Base (LIB) information\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "address-family", .value = argv[0] },
- NULL
- };
- return ldp_vty_show_binding (vty, args);
-}
-
-DEFUN (ldp_show_mpls_ldp_address_family_discovery,
- ldp_show_mpls_ldp_address_family_discovery_cmd,
- "show mpls ldp (ipv4|ipv6) discovery",
- "Show running system information\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "IPv4 Address Family\n"
- "IPv6 Address Family\n"
- "Discovery Hello Information\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "address-family", .value = argv[0] },
- NULL
- };
- return ldp_vty_show_discovery (vty, args);
-}
-
-DEFUN (ldp_show_mpls_ldp_address_family_interface,
- ldp_show_mpls_ldp_address_family_interface_cmd,
- "show mpls ldp (ipv4|ipv6) interface",
- "Show running system information\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "IPv4 Address Family\n"
- "IPv6 Address Family\n"
- "interface information\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "address-family", .value = argv[0] },
- NULL
- };
- return ldp_vty_show_interface (vty, args);
-}
-
-DEFUN (ldp_show_l2vpn_atom_binding,
- ldp_show_l2vpn_atom_binding_cmd,
- "show l2vpn atom binding",
- "Show running system information\n"
- "Show information about Layer2 VPN\n"
- "Show Any Transport over MPLS information\n"
- "Show AToM label binding information\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_show_atom_binding (vty, args);
-}
-
-DEFUN (ldp_show_l2vpn_atom_vc,
- ldp_show_l2vpn_atom_vc_cmd,
- "show l2vpn atom vc",
- "Show running system information\n"
- "Show information about Layer2 VPN\n"
- "Show Any Transport over MPLS information\n"
- "Show AToM virtual circuit information\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_show_atom_vc (vty, args);
-}
-
-DEFUN (ldp_show_debugging_mpls_ldp,
- ldp_show_debugging_mpls_ldp_cmd,
- "show debugging mpls ldp",
- "Show running system information\n"
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_show_debugging (vty, args);
-}
-
-DEFUN (ldp_clear_mpls_ldp_neighbor,
- ldp_clear_mpls_ldp_neighbor_cmd,
- "clear mpls ldp neighbor",
- "Reset functions\n"
- "Reset MPLS statistical information\n"
- "Clear LDP state\n"
- "Clear LDP neighbor sessions\n")
-{
- struct vty_arg *args[] = { NULL };
- return ldp_vty_clear_nbr (vty, args);
-}
-
-DEFUN (ldp_clear_mpls_ldp_neighbor_addr,
- ldp_clear_mpls_ldp_neighbor_addr_cmd,
- "clear mpls ldp neighbor (A.B.C.D|X:X::X:X)",
- "Reset functions\n"
- "Reset MPLS statistical information\n"
- "Clear LDP state\n"
- "Clear LDP neighbor sessions\n"
- "IPv4 address\n"
- "IPv6 address\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "addr", .value = argv[0] },
- NULL
- };
- return ldp_vty_clear_nbr (vty, args);
-}
-
-DEFUN (ldp_debug_mpls_ldp_discovery_hello_dir,
- ldp_debug_mpls_ldp_discovery_hello_dir_cmd,
- "debug mpls ldp discovery hello (recv|sent)",
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Discovery messages\n"
- "Discovery hello message\n"
- "Received messages\n"
- "Sent messages\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "type", .value = "discovery" },
- &(struct vty_arg) { .name = "dir", .value = argv[0] },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_debug_mpls_ldp_errors,
- ldp_debug_mpls_ldp_errors_cmd,
- "debug mpls ldp errors",
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Errors\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "type", .value = "errors" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_debug_mpls_ldp_event,
- ldp_debug_mpls_ldp_event_cmd,
- "debug mpls ldp event",
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "LDP event information\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "type", .value = "event" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_debug_mpls_ldp_messages_recv,
- ldp_debug_mpls_ldp_messages_recv_cmd,
- "debug mpls ldp messages recv",
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Messages\n"
- "Received messages, excluding periodic Keep Alives\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "type", .value = "messages" },
- &(struct vty_arg) { .name = "dir", .value = "recv" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_debug_mpls_ldp_messages_recv_all,
- ldp_debug_mpls_ldp_messages_recv_all_cmd,
- "debug mpls ldp messages recv all",
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Messages\n"
- "Received messages, excluding periodic Keep Alives\n"
- "Received messages, including periodic Keep Alives\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "type", .value = "messages" },
- &(struct vty_arg) { .name = "dir", .value = "recv" },
- &(struct vty_arg) { .name = "all", .value = "all" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_debug_mpls_ldp_messages_sent,
- ldp_debug_mpls_ldp_messages_sent_cmd,
- "debug mpls ldp messages sent",
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Messages\n"
- "Sent messages, excluding periodic Keep Alives\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "type", .value = "messages" },
- &(struct vty_arg) { .name = "dir", .value = "sent" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_debug_mpls_ldp_messages_sent_all,
- ldp_debug_mpls_ldp_messages_sent_all_cmd,
- "debug mpls ldp messages sent all",
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Messages\n"
- "Sent messages, excluding periodic Keep Alives\n"
- "Sent messages, including periodic Keep Alives\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "type", .value = "messages" },
- &(struct vty_arg) { .name = "dir", .value = "sent" },
- &(struct vty_arg) { .name = "all", .value = "all" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_debug_mpls_ldp_zebra,
- ldp_debug_mpls_ldp_zebra_cmd,
- "debug mpls ldp zebra",
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "LDP zebra information\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "type", .value = "zebra" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_no_debug_mpls_ldp_discovery_hello_dir,
- ldp_no_debug_mpls_ldp_discovery_hello_dir_cmd,
- "no debug mpls ldp discovery hello (recv|sent)",
- "Negate a command or set its defaults\n"
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Discovery messages\n"
- "Discovery hello message\n"
- "Received messages\n"
- "Sent messages\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "type", .value = "discovery" },
- &(struct vty_arg) { .name = "dir", .value = argv[0] },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_no_debug_mpls_ldp_errors,
- ldp_no_debug_mpls_ldp_errors_cmd,
- "no debug mpls ldp errors",
- "Negate a command or set its defaults\n"
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Errors\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "type", .value = "errors" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_no_debug_mpls_ldp_event,
- ldp_no_debug_mpls_ldp_event_cmd,
- "no debug mpls ldp event",
- "Negate a command or set its defaults\n"
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "LDP event information\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "type", .value = "event" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_no_debug_mpls_ldp_messages_recv,
- ldp_no_debug_mpls_ldp_messages_recv_cmd,
- "no debug mpls ldp messages recv",
- "Negate a command or set its defaults\n"
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Messages\n"
- "Received messages, excluding periodic Keep Alives\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "type", .value = "messages" },
- &(struct vty_arg) { .name = "dir", .value = "recv" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_no_debug_mpls_ldp_messages_recv_all,
- ldp_no_debug_mpls_ldp_messages_recv_all_cmd,
- "no debug mpls ldp messages recv all",
- "Negate a command or set its defaults\n"
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Messages\n"
- "Received messages, excluding periodic Keep Alives\n"
- "Received messages, including periodic Keep Alives\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "type", .value = "messages" },
- &(struct vty_arg) { .name = "dir", .value = "recv" },
- &(struct vty_arg) { .name = "all", .value = "all" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_no_debug_mpls_ldp_messages_sent,
- ldp_no_debug_mpls_ldp_messages_sent_cmd,
- "no debug mpls ldp messages sent",
- "Negate a command or set its defaults\n"
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Messages\n"
- "Sent messages, excluding periodic Keep Alives\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "type", .value = "messages" },
- &(struct vty_arg) { .name = "dir", .value = "sent" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_no_debug_mpls_ldp_messages_sent_all,
- ldp_no_debug_mpls_ldp_messages_sent_all_cmd,
- "no debug mpls ldp messages sent all",
- "Negate a command or set its defaults\n"
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "Messages\n"
- "Sent messages, excluding periodic Keep Alives\n"
- "Sent messages, including periodic Keep Alives\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "type", .value = "messages" },
- &(struct vty_arg) { .name = "dir", .value = "sent" },
- &(struct vty_arg) { .name = "all", .value = "all" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-DEFUN (ldp_no_debug_mpls_ldp_zebra,
- ldp_no_debug_mpls_ldp_zebra_cmd,
- "no debug mpls ldp zebra",
- "Negate a command or set its defaults\n"
- "Debugging functions\n"
- "MPLS information\n"
- "Label Distribution Protocol\n"
- "LDP zebra information\n")
-{
- struct vty_arg *args[] =
- {
- &(struct vty_arg) { .name = "no", .value = "no" },
- &(struct vty_arg) { .name = "type", .value = "zebra" },
- NULL
- };
- return ldp_vty_debug (vty, args);
-}
-
-void
-ldp_vty_init (void)
-{
- install_element (CONFIG_NODE, &ldp_mpls_ldp_cmd);
- install_element (CONFIG_NODE, &ldp_l2vpn_word_type_vpls_cmd);
- install_element (CONFIG_NODE, &ldp_no_mpls_ldp_cmd);
- install_element (CONFIG_NODE, &ldp_no_l2vpn_word_type_vpls_cmd);
- install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_discovery_hello_dir_cmd);
- install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_errors_cmd);
- install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_event_cmd);
- install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_recv_cmd);
- install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_recv_all_cmd);
- install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_sent_cmd);
- install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_sent_all_cmd);
- install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_zebra_cmd);
- install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_discovery_hello_dir_cmd);
- install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_errors_cmd);
- install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_event_cmd);
- install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_recv_cmd);
- install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_recv_all_cmd);
- install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_sent_cmd);
- install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_sent_all_cmd);
- install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_zebra_cmd);
- install_node (&ldp_node, ldp_config_write);
- install_default (LDP_NODE);
- install_element (LDP_NODE, &ldp_address_family_ipv4_cmd);
- install_element (LDP_NODE, &ldp_address_family_ipv6_cmd);
- install_element (LDP_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
- install_element (LDP_NODE, &ldp_discovery_targeted_hello_holdtime_disc_time_cmd);
- install_element (LDP_NODE, &ldp_discovery_targeted_hello_interval_disc_time_cmd);
- install_element (LDP_NODE, &ldp_dual_stack_transport_connection_prefer_ipv4_cmd);
- install_element (LDP_NODE, &ldp_dual_stack_cisco_interop_cmd);
- install_element (LDP_NODE, &ldp_neighbor_ipv4_password_word_cmd);
- install_element (LDP_NODE, &ldp_neighbor_ipv4_session_holdtime_session_time_cmd);
- install_element (LDP_NODE, &ldp_neighbor_ipv4_ttl_security_disable_cmd);
- install_element (LDP_NODE, &ldp_neighbor_ipv4_ttl_security_hops_hops_cmd);
- install_element (LDP_NODE, &ldp_router_id_ipv4_cmd);
- install_element (LDP_NODE, &ldp_no_address_family_ipv4_cmd);
- install_element (LDP_NODE, &ldp_no_address_family_ipv6_cmd);
- install_element (LDP_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
- install_element (LDP_NODE, &ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd);
- install_element (LDP_NODE, &ldp_no_discovery_targeted_hello_interval_disc_time_cmd);
- install_element (LDP_NODE, &ldp_no_dual_stack_transport_connection_prefer_ipv4_cmd);
- install_element (LDP_NODE, &ldp_no_dual_stack_cisco_interop_cmd);
- install_element (LDP_NODE, &ldp_no_neighbor_ipv4_password_word_cmd);
- install_element (LDP_NODE, &ldp_no_neighbor_ipv4_session_holdtime_session_time_cmd);
- install_element (LDP_NODE, &ldp_no_neighbor_ipv4_ttl_security_disable_cmd);
- install_element (LDP_NODE, &ldp_no_neighbor_ipv4_ttl_security_hops_hops_cmd);
- install_element (LDP_NODE, &ldp_no_router_id_ipv4_cmd);
- install_node (&ldp_ipv4_node, NULL);
- install_default (LDP_IPV4_NODE);
- install_element (LDP_IPV4_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_discovery_targeted_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_discovery_targeted_hello_interval_disc_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_discovery_targeted_hello_accept_cmd);
- install_element (LDP_IPV4_NODE, &ldp_label_local_advertise_explicit_null_cmd);
- install_element (LDP_IPV4_NODE, &ldp_ttl_security_disable_cmd);
- install_element (LDP_IPV4_NODE, &ldp_session_holdtime_session_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_interface_ifname_cmd);
- install_element (LDP_IPV4_NODE, &ldp_discovery_transport_address_ipv4_cmd);
- install_element (LDP_IPV4_NODE, &ldp_neighbor_ipv4_targeted_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_discovery_targeted_hello_interval_disc_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_discovery_targeted_hello_accept_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_label_local_advertise_explicit_null_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_ttl_security_disable_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_session_holdtime_session_time_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_interface_ifname_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_discovery_transport_address_ipv4_cmd);
- install_element (LDP_IPV4_NODE, &ldp_no_neighbor_ipv4_targeted_cmd);
- install_node (&ldp_ipv6_node, NULL);
- install_default (LDP_IPV6_NODE);
- install_element (LDP_IPV6_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_discovery_targeted_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_discovery_targeted_hello_interval_disc_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_discovery_targeted_hello_accept_cmd);
- install_element (LDP_IPV6_NODE, &ldp_label_local_advertise_explicit_null_cmd);
- install_element (LDP_IPV6_NODE, &ldp_ttl_security_disable_cmd);
- install_element (LDP_IPV6_NODE, &ldp_session_holdtime_session_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_interface_ifname_cmd);
- install_element (LDP_IPV6_NODE, &ldp_discovery_transport_address_ipv6_cmd);
- install_element (LDP_IPV6_NODE, &ldp_neighbor_ipv6_targeted_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_discovery_targeted_hello_interval_disc_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_discovery_targeted_hello_accept_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_label_local_advertise_explicit_null_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_ttl_security_disable_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_session_holdtime_session_time_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_interface_ifname_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_discovery_transport_address_ipv6_cmd);
- install_element (LDP_IPV6_NODE, &ldp_no_neighbor_ipv6_targeted_cmd);
- install_node (&ldp_ipv4_iface_node, NULL);
- install_default (LDP_IPV4_IFACE_NODE);
- install_element (LDP_IPV4_IFACE_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV4_IFACE_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
- install_element (LDP_IPV4_IFACE_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV4_IFACE_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
- install_node (&ldp_ipv6_iface_node, NULL);
- install_default (LDP_IPV6_IFACE_NODE);
- install_element (LDP_IPV6_IFACE_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV6_IFACE_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
- install_element (LDP_IPV6_IFACE_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
- install_element (LDP_IPV6_IFACE_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
- install_node (&ldp_l2vpn_node, ldp_l2vpn_config_write);
- install_default (LDP_L2VPN_NODE);
- install_element (LDP_L2VPN_NODE, &ldp_bridge_ifname_cmd);
- install_element (LDP_L2VPN_NODE, &ldp_mtu_mtu_cmd);
- install_element (LDP_L2VPN_NODE, &ldp_member_interface_ifname_cmd);
- install_element (LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd);
- install_element (LDP_L2VPN_NODE, &ldp_vc_type_pwtype_cmd);
- install_element (LDP_L2VPN_NODE, &ldp_no_bridge_ifname_cmd);
- install_element (LDP_L2VPN_NODE, &ldp_no_mtu_mtu_cmd);
- install_element (LDP_L2VPN_NODE, &ldp_no_member_interface_ifname_cmd);
- install_element (LDP_L2VPN_NODE, &ldp_no_member_pseudowire_ifname_cmd);
- install_element (LDP_L2VPN_NODE, &ldp_no_vc_type_pwtype_cmd);
- install_node (&ldp_pseudowire_node, NULL);
- install_default (LDP_PSEUDOWIRE_NODE);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_control_word_cword_cmd);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_neighbor_address_addr_cmd);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_neighbor_lsr_id_ipv4_cmd);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_pw_id_pwid_cmd);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_pw_status_disable_cmd);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_control_word_cword_cmd);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_neighbor_address_addr_cmd);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_neighbor_lsr_id_ipv4_cmd);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_pw_id_pwid_cmd);
- install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_pw_status_disable_cmd);
- install_node (&ldp_debug_node, ldp_debug_config_write);
- install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_discovery_hello_dir_cmd);
- install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_errors_cmd);
- install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_event_cmd);
- install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_recv_cmd);
- install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_recv_all_cmd);
- install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_sent_cmd);
- install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_sent_all_cmd);
- install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_zebra_cmd);
- install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_discovery_hello_dir_cmd);
- install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_errors_cmd);
- install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_event_cmd);
- install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_recv_cmd);
- install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_recv_all_cmd);
- install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_sent_cmd);
- install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_sent_all_cmd);
- install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_zebra_cmd);
- install_element (VIEW_NODE, &ldp_show_mpls_ldp_neighbor_cmd);
- install_element (VIEW_NODE, &ldp_show_mpls_ldp_binding_cmd);
- install_element (VIEW_NODE, &ldp_show_mpls_ldp_discovery_cmd);
- install_element (VIEW_NODE, &ldp_show_mpls_ldp_interface_cmd);
- install_element (VIEW_NODE, &ldp_show_mpls_ldp_address_family_binding_cmd);
- install_element (VIEW_NODE, &ldp_show_mpls_ldp_address_family_discovery_cmd);
- install_element (VIEW_NODE, &ldp_show_mpls_ldp_address_family_interface_cmd);
- install_element (VIEW_NODE, &ldp_show_l2vpn_atom_binding_cmd);
- install_element (VIEW_NODE, &ldp_show_l2vpn_atom_vc_cmd);
- install_element (VIEW_NODE, &ldp_show_debugging_mpls_ldp_cmd);
- install_element (VIEW_NODE, &ldp_clear_mpls_ldp_neighbor_cmd);
- install_element (VIEW_NODE, &ldp_clear_mpls_ldp_neighbor_addr_cmd);
-} \ No newline at end of file
diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c
index e5acada180..4d1af62146 100644
--- a/ldpd/ldp_vty_conf.c
+++ b/ldpd/ldp_vty_conf.c
@@ -142,7 +142,7 @@ ldp_af_iface_config_write(struct vty *vty, int af)
struct iface *iface;
struct iface_af *ia;
- LIST_FOREACH(iface, &ldpd_conf->iface_list, entry) {
+ RB_FOREACH(iface, iface_head, &ldpd_conf->iface_tree) {
ia = iface_af_get(iface, af);
if (!ia->enabled)
continue;
@@ -182,9 +182,13 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
vty_out(vty, " discovery hello interval %u%s",
af_conf->lhello_interval, VTY_NEWLINE);
- if (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT)
- vty_out(vty, " discovery targeted-hello accept%s",
- VTY_NEWLINE);
+ if (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) {
+ vty_out(vty, " discovery targeted-hello accept");
+ if (af_conf->acl_thello_accept_from[0] != '\0')
+ vty_out(vty, " from %s",
+ af_conf->acl_thello_accept_from);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
if (af_conf->thello_holdtime != TARGETED_DFLT_HOLDTIME &&
af_conf->thello_holdtime != 0)
@@ -202,9 +206,48 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
vty_out(vty, " ! Incomplete config, specify a discovery "
"transport-address%s", VTY_NEWLINE);
- if (af_conf->flags & F_LDPD_AF_EXPNULL)
- vty_out(vty, " label local advertise explicit-null%s",
- VTY_NEWLINE);
+ if ((af_conf->flags & F_LDPD_AF_ALLOCHOSTONLY) ||
+ af_conf->acl_label_allocate_for[0] != '\0') {
+ vty_out(vty, " label local allocate");
+ if (af_conf->flags & F_LDPD_AF_ALLOCHOSTONLY)
+ vty_out(vty, " host-routes");
+ else
+ vty_out(vty, " for %s",
+ af_conf->acl_label_allocate_for);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+
+ if (af_conf->acl_label_advertise_for[0] != '\0' ||
+ af_conf->acl_label_advertise_to[0] != '\0') {
+ vty_out(vty, " label local advertise");
+ if (af_conf->acl_label_advertise_to[0] != '\0')
+ vty_out(vty, " to %s",
+ af_conf->acl_label_advertise_to);
+ if (af_conf->acl_label_advertise_for[0] != '\0')
+ vty_out(vty, " for %s",
+ af_conf->acl_label_advertise_for);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+
+ if (af_conf->flags & F_LDPD_AF_EXPNULL) {
+ vty_out(vty, " label local advertise explicit-null");
+ if (af_conf->acl_label_expnull_for[0] != '\0')
+ vty_out(vty, " for %s",
+ af_conf->acl_label_expnull_for);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+
+ if (af_conf->acl_label_accept_for[0] != '\0' ||
+ af_conf->acl_label_accept_from[0] != '\0') {
+ vty_out(vty, " label remote accept");
+ if (af_conf->acl_label_accept_from[0] != '\0')
+ vty_out(vty, " from %s",
+ af_conf->acl_label_accept_from);
+ if (af_conf->acl_label_accept_for[0] != '\0')
+ vty_out(vty, " for %s",
+ af_conf->acl_label_accept_for);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
if (af_conf->flags & F_LDPD_AF_NO_GTSM)
vty_out(vty, " ttl-security disable%s", VTY_NEWLINE);
@@ -213,7 +256,7 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
vty_out(vty, " session holdtime %u%s", af_conf->keepalive,
VTY_NEWLINE);
- LIST_FOREACH(tnbr, &ldpd_conf->tnbr_list, entry) {
+ RB_FOREACH(tnbr, tnbr_head, &ldpd_conf->tnbr_tree) {
if (tnbr->af == af) {
vty_out(vty, " !%s", VTY_NEWLINE);
vty_out(vty, " neighbor %s targeted%s",
@@ -265,7 +308,7 @@ ldp_config_write(struct vty *vty)
if (ldpd_conf->flags & F_LDPD_DS_CISCO_INTEROP)
vty_out(vty, " dual-stack cisco-interop%s", VTY_NEWLINE);
- LIST_FOREACH(nbrp, &ldpd_conf->nbrp_list, entry) {
+ RB_FOREACH(nbrp, nbrp_head, &ldpd_conf->nbrp_tree) {
if (nbrp->flags & F_NBRP_KEEPALIVE)
vty_out(vty, " neighbor %s session holdtime %u%s",
inet_ntoa(nbrp->lsr_id), nbrp->keepalive,
@@ -341,7 +384,7 @@ ldp_l2vpn_config_write(struct vty *vty)
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
- LIST_FOREACH(l2vpn, &ldpd_conf->l2vpn_list, entry) {
+ RB_FOREACH(l2vpn, l2vpn_head, &ldpd_conf->l2vpn_tree) {
vty_out(vty, "l2vpn %s type vpls%s", l2vpn->name, VTY_NEWLINE);
if (l2vpn->pw_type != DEFAULT_PW_TYPE)
@@ -354,13 +397,13 @@ ldp_l2vpn_config_write(struct vty *vty)
vty_out(vty, " bridge %s%s", l2vpn->br_ifname,
VTY_NEWLINE);
- LIST_FOREACH(lif, &l2vpn->if_list, entry)
+ RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
vty_out(vty, " member interface %s%s", lif->ifname,
VTY_NEWLINE);
- LIST_FOREACH(pw, &l2vpn->pw_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
ldp_l2vpn_pw_config_write(vty, pw);
- LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
ldp_l2vpn_pw_config_write(vty, pw);
vty_out(vty, " !%s", VTY_NEWLINE);
@@ -393,7 +436,7 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname)
if (if_lookup_name(xconf, ifname))
return (1);
- LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
+ RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
if (l2vpn_if_find_name(l2vpn, ifname))
return (1);
if (l2vpn_pw_find_name(l2vpn, ifname))
@@ -444,8 +487,10 @@ ldp_vty_address_family(struct vty *vty, struct vty_arg *args[])
} else if (strcmp(af_str, "ipv6") == 0) {
af = AF_INET6;
af_conf = &vty_conf->ipv6;
- } else
+ } else {
+ ldp_clear_config(vty_conf);
return (CMD_WARNING);
+ }
if (disable) {
af_conf->flags &= ~F_LDPD_AF_ENABLED;
@@ -681,19 +726,28 @@ ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[])
struct ldpd_conf *vty_conf;
struct ldpd_af_conf *af_conf;
int af;
+ const char *acl_from_str;
int disable;
vty_conf = ldp_dup_config(ldpd_conf);
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
+ acl_from_str = vty_get_arg_value(args, "from_acl");
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
- if (disable)
+ if (disable) {
af_conf->flags &= ~F_LDPD_AF_THELLO_ACCEPT;
- else
+ af_conf->acl_thello_accept_from[0] = '\0';
+ } else {
af_conf->flags |= F_LDPD_AF_THELLO_ACCEPT;
+ if (acl_from_str)
+ strlcpy(af_conf->acl_thello_accept_from, acl_from_str,
+ sizeof(af_conf->acl_thello_accept_from));
+ else
+ af_conf->acl_thello_accept_from[0] = '\0';
+ }
ldp_reload(vty_conf);
@@ -740,7 +794,7 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
} else {
if (nbrp == NULL) {
nbrp = nbr_params_new(lsr_id);
- LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry);
+ RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
} else if (nbrp->keepalive == secs)
goto cancel;
@@ -857,7 +911,7 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
ia = iface_af_get(iface, af);
ia->enabled = 1;
- LIST_INSERT_HEAD(&vty_conf->iface_list, iface, entry);
+ RB_INSERT(iface_head, &vty_conf->iface_tree, iface);
ldp_reload_ref(vty_conf, (void **)&iface);
} else {
memset(&kif, 0, sizeof(kif));
@@ -867,7 +921,8 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
if (!ia->enabled) {
ia->enabled = 1;
ldp_reload_ref(vty_conf, (void **)&iface);
- }
+ } else
+ ldp_clear_config(vty_conf);
}
switch (af) {
@@ -955,7 +1010,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
if (tnbr == NULL)
goto cancel;
- LIST_REMOVE(tnbr, entry);
+ RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr);
free(tnbr);
ldp_reload(vty_conf);
return (CMD_SUCCESS);
@@ -966,7 +1021,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
tnbr = tnbr_new(af, &addr);
tnbr->flags |= F_TNBR_CONFIGURED;
- LIST_INSERT_HEAD(&vty_conf->tnbr_list, tnbr, entry);
+ RB_INSERT(tnbr_head, &vty_conf->tnbr_tree, tnbr);
ldp_reload(vty_conf);
@@ -978,23 +1033,143 @@ cancel:
}
int
-ldp_vty_explicit_null(struct vty *vty, struct vty_arg *args[])
+ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[])
{
struct ldpd_conf *vty_conf;
struct ldpd_af_conf *af_conf;
int af;
+ const char *acl_to_str;
+ const char *acl_for_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
+ acl_to_str = vty_get_arg_value(args, "to_acl");
+ acl_for_str = vty_get_arg_value(args, "for_acl");
vty_conf = ldp_dup_config(ldpd_conf);
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
- if (disable)
+ if (disable) {
+ af_conf->acl_label_advertise_to[0] = '\0';
+ af_conf->acl_label_advertise_for[0] = '\0';
+ } else {
+ if (acl_to_str)
+ strlcpy(af_conf->acl_label_advertise_to, acl_to_str,
+ sizeof(af_conf->acl_label_advertise_to));
+ else
+ af_conf->acl_label_advertise_to[0] = '\0';
+ if (acl_for_str)
+ strlcpy(af_conf->acl_label_advertise_for, acl_for_str,
+ sizeof(af_conf->acl_label_advertise_for));
+ else
+ af_conf->acl_label_advertise_for[0] = '\0';
+ }
+
+ ldp_reload(vty_conf);
+
+ return (CMD_SUCCESS);
+}
+
+int
+ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[])
+{
+ struct ldpd_conf *vty_conf;
+ struct ldpd_af_conf *af_conf;
+ int af;
+ const char *acl_for_str;
+ const char *host_routes_str;
+ int disable;
+
+ disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
+ acl_for_str = vty_get_arg_value(args, "for_acl");
+ host_routes_str = vty_get_arg_value(args, "host-routes");
+
+ vty_conf = ldp_dup_config(ldpd_conf);
+ af = ldp_vty_get_af(vty);
+ af_conf = ldp_af_conf_get(vty_conf, af);
+
+ af_conf->flags &= ~F_LDPD_AF_ALLOCHOSTONLY;
+ af_conf->acl_label_allocate_for[0] = '\0';
+ if (!disable) {
+ if (host_routes_str)
+ af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY;
+ else
+ strlcpy(af_conf->acl_label_allocate_for, acl_for_str,
+ sizeof(af_conf->acl_label_allocate_for));
+ }
+
+ ldp_reload(vty_conf);
+
+ return (CMD_SUCCESS);
+}
+
+int
+ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[])
+{
+ struct ldpd_conf *vty_conf;
+ struct ldpd_af_conf *af_conf;
+ int af;
+ const char *acl_for_str;
+ int disable;
+
+ disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
+ acl_for_str = vty_get_arg_value(args, "for_acl");
+
+ vty_conf = ldp_dup_config(ldpd_conf);
+ af = ldp_vty_get_af(vty);
+ af_conf = ldp_af_conf_get(vty_conf, af);
+
+ if (disable) {
af_conf->flags &= ~F_LDPD_AF_EXPNULL;
- else
+ af_conf->acl_label_expnull_for[0] = '\0';
+ } else {
af_conf->flags |= F_LDPD_AF_EXPNULL;
+ if (acl_for_str)
+ strlcpy(af_conf->acl_label_expnull_for, acl_for_str,
+ sizeof(af_conf->acl_label_expnull_for));
+ else
+ af_conf->acl_label_expnull_for[0] = '\0';
+ }
+
+ ldp_reload(vty_conf);
+
+ return (CMD_SUCCESS);
+}
+
+int
+ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[])
+{
+ struct ldpd_conf *vty_conf;
+ struct ldpd_af_conf *af_conf;
+ int af;
+ const char *acl_from_str;
+ const char *acl_for_str;
+ int disable;
+
+ disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
+ acl_from_str = vty_get_arg_value(args, "from_acl");
+ acl_for_str = vty_get_arg_value(args, "for_acl");
+
+ vty_conf = ldp_dup_config(ldpd_conf);
+ af = ldp_vty_get_af(vty);
+ af_conf = ldp_af_conf_get(vty_conf, af);
+
+ if (disable) {
+ af_conf->acl_label_accept_from[0] = '\0';
+ af_conf->acl_label_accept_for[0] = '\0';
+ } else {
+ if (acl_from_str)
+ strlcpy(af_conf->acl_label_accept_from, acl_from_str,
+ sizeof(af_conf->acl_label_accept_from));
+ else
+ af_conf->acl_label_accept_from[0] = '\0';
+ if (acl_for_str)
+ strlcpy(af_conf->acl_label_accept_for, acl_for_str,
+ sizeof(af_conf->acl_label_accept_for));
+ else
+ af_conf->acl_label_accept_for[0] = '\0';
+ }
ldp_reload(vty_conf);
@@ -1129,7 +1304,7 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
} else {
if (nbrp == NULL) {
nbrp = nbr_params_new(lsr_id);
- LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry);
+ RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
} else if (nbrp->auth.method == AUTH_MD5SIG &&
strcmp(nbrp->auth.md5key, password_str) == 0)
goto cancel;
@@ -1195,7 +1370,7 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
} else {
if (nbrp == NULL) {
nbrp = nbr_params_new(lsr_id);
- LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry);
+ RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
}
nbrp->flags |= F_NBRP_GTSM;
@@ -1235,7 +1410,7 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
if (l2vpn == NULL)
goto cancel;
- LIST_REMOVE(l2vpn, entry);
+ RB_REMOVE(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
l2vpn_del(l2vpn);
ldp_reload(vty_conf);
return (CMD_SUCCESS);
@@ -1248,9 +1423,9 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
l2vpn = l2vpn_new(name_str);
l2vpn->type = L2VPN_TYPE_VPLS;
- LIST_INSERT_HEAD(&vty_conf->l2vpn_list, l2vpn, entry);
+ RB_INSERT(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
- ldp_reload(vty_conf);
+ ldp_reload_ref(vty_conf, (void **)&l2vpn);
VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
return (CMD_SUCCESS);
@@ -1369,7 +1544,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
if (lif == NULL)
goto cancel;
- LIST_REMOVE(lif, entry);
+ RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
ldp_reload(vty_conf);
return (CMD_SUCCESS);
@@ -1392,7 +1567,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
}
lif = l2vpn_if_new(l2vpn, &kif);
- LIST_INSERT_HEAD(&l2vpn->if_list, lif, entry);
+ RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
ldp_reload_ref(vty_conf, (void **)&l2vpn);
@@ -1425,14 +1600,14 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
if (pw == NULL)
goto cancel;
- LIST_REMOVE(pw, entry);
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw);
ldp_reload(vty_conf);
return (CMD_SUCCESS);
}
if (pw) {
- VTY_PUSH_CONTEXT(LDP_PSEUDOWIRE_NODE, pw);
+ VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
goto cancel;
}
@@ -1451,10 +1626,10 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
pw = l2vpn_pw_new(l2vpn, &kif);
pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
- LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry);
+ RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
ldp_reload_ref(vty_conf, (void **)&pw);
- VTY_PUSH_CONTEXT(LDP_PSEUDOWIRE_NODE, pw);
+ VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
return (CMD_SUCCESS);
@@ -1474,7 +1649,7 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
preference_str = vty_get_arg_value(args, "preference");
- pw = VTY_GET_CONTEXT(l2vpn_pw);
+ pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable)
@@ -1510,7 +1685,7 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING);
}
- pw = VTY_GET_CONTEXT(l2vpn_pw);
+ pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable) {
@@ -1546,7 +1721,7 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING);
}
- pw = VTY_GET_CONTEXT(l2vpn_pw);
+ pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable)
@@ -1578,7 +1753,7 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING);
}
- pw = VTY_GET_CONTEXT(l2vpn_pw);
+ pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable)
@@ -1600,7 +1775,7 @@ ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[])
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
- pw = VTY_GET_CONTEXT(l2vpn_pw);
+ pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable)
@@ -1618,14 +1793,7 @@ ldp_vty_if_init(void)
{
/* Install interface node. */
install_node (&interface_node, interface_config_write);
-
- install_element(CONFIG_NODE, &interface_cmd);
- install_element(CONFIG_NODE, &no_interface_cmd);
- install_default(INTERFACE_NODE);
-
- /* "description" commands. */
- install_element(INTERFACE_NODE, &interface_desc_cmd);
- install_element(INTERFACE_NODE, &no_interface_desc_cmd);
+ if_cmd_init ();
}
struct iface *
@@ -1648,14 +1816,14 @@ iface_new_api(struct ldpd_conf *conf, const char *name)
}
iface = if_new(&kif);
- LIST_INSERT_HEAD(&conf->iface_list, iface, entry);
+ RB_INSERT(iface_head, &conf->iface_tree, iface);
return (iface);
}
void
-iface_del_api(struct iface *iface)
+iface_del_api(struct ldpd_conf *conf, struct iface *iface)
{
- LIST_REMOVE(iface, entry);
+ RB_REMOVE(iface_head, &conf->iface_tree, iface);
free(iface);
}
@@ -1672,14 +1840,14 @@ tnbr_new_api(struct ldpd_conf *conf, int af, union ldpd_addr *addr)
tnbr = tnbr_new(af, addr);
tnbr->flags |= F_TNBR_CONFIGURED;
- LIST_INSERT_HEAD(&conf->tnbr_list, tnbr, entry);
+ RB_INSERT(tnbr_head, &conf->tnbr_tree, tnbr);
return (tnbr);
}
void
-tnbr_del_api(struct tnbr *tnbr)
+tnbr_del_api(struct ldpd_conf *conf, struct tnbr *tnbr)
{
- LIST_REMOVE(tnbr, entry);
+ RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr);
}
@@ -1692,14 +1860,14 @@ nbrp_new_api(struct ldpd_conf *conf, struct in_addr lsr_id)
return (NULL);
nbrp = nbr_params_new(lsr_id);
- LIST_INSERT_HEAD(&conf->nbrp_list, nbrp, entry);
+ RB_INSERT(nbrp_head, &conf->nbrp_tree, nbrp);
return (nbrp);
}
void
-nbrp_del_api(struct nbr_params *nbrp)
+nbrp_del_api(struct ldpd_conf *conf, struct nbr_params *nbrp)
{
- LIST_REMOVE(nbrp, entry);
+ RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp);
}
@@ -1713,29 +1881,29 @@ l2vpn_new_api(struct ldpd_conf *conf, const char *name)
l2vpn = l2vpn_new(name);
l2vpn->type = L2VPN_TYPE_VPLS;
- LIST_INSERT_HEAD(&conf->l2vpn_list, l2vpn, entry);
+ RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn);
return (l2vpn);
}
void
-l2vpn_del_api(struct l2vpn *l2vpn)
+l2vpn_del_api(struct ldpd_conf *conf, struct l2vpn *l2vpn)
{
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
- while ((lif = LIST_FIRST(&l2vpn->if_list)) != NULL) {
- LIST_REMOVE(lif, entry);
+ while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
+ RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
}
- while ((pw = LIST_FIRST(&l2vpn->pw_list)) != NULL) {
- LIST_REMOVE(pw, entry);
+ while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw);
}
- while ((pw = LIST_FIRST(&l2vpn->pw_inactive_list)) != NULL) {
- LIST_REMOVE(pw, entry);
+ while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw);
}
- LIST_REMOVE(l2vpn, entry);
+ RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
free(l2vpn);
}
@@ -1759,14 +1927,14 @@ l2vpn_if_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
}
lif = l2vpn_if_new(l2vpn, &kif);
- LIST_INSERT_HEAD(&l2vpn->if_list, lif, entry);
+ RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
return (lif);
}
void
-l2vpn_if_del_api(struct l2vpn_if *lif)
+l2vpn_if_del_api(struct l2vpn *l2vpn, struct l2vpn_if *lif)
{
- LIST_REMOVE(lif, entry);
+ RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
}
@@ -1791,13 +1959,13 @@ l2vpn_pw_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
pw = l2vpn_pw_new(l2vpn, &kif);
pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
- LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry);
+ RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
return (pw);
}
void
-l2vpn_pw_del_api(struct l2vpn_pw *pw)
+l2vpn_pw_del_api(struct l2vpn *l2vpn, struct l2vpn_pw *pw)
{
- LIST_REMOVE(pw, entry);
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw);
}
diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c
index a9138be2f2..56a64c84f3 100644
--- a/ldpd/ldp_vty_exec.c
+++ b/ldpd/ldp_vty_exec.c
@@ -27,6 +27,7 @@
#include "lde.h"
#include "log.h"
#include "ldp_vty.h"
+#include "lib/json.h"
#include "command.h"
#include "vty.h"
@@ -41,35 +42,56 @@ enum show_command {
SHOW_L2VPN_BINDING
};
-struct show_filter {
+struct show_params {
int family;
union ldpd_addr addr;
uint8_t prefixlen;
+ int json;
};
#define LDPBUFSIZ 65535
static int show_interface_msg(struct vty *, struct imsg *,
- struct show_filter *);
+ struct show_params *);
+static int show_interface_msg_json(struct imsg *,
+ struct show_params *, json_object *);
static void show_discovery_adj(struct vty *, char *,
struct ctl_adj *);
static int show_discovery_msg(struct vty *, struct imsg *,
- struct show_filter *);
+ struct show_params *);
+static void show_discovery_adj_json(json_object *,
+ struct ctl_adj *);
+static int show_discovery_msg_json(struct imsg *,
+ struct show_params *, json_object *);
static void show_nbr_adj(struct vty *, char *, struct ctl_adj *);
static int show_nbr_msg(struct vty *, struct imsg *,
- struct show_filter *);
+ struct show_params *);
+static void show_nbr_adj_json(struct ctl_adj *, json_object *);
+static int show_nbr_msg_json(struct imsg *, struct show_params *,
+ json_object *);
static int show_lib_msg(struct vty *, struct imsg *,
- struct show_filter *);
-static int show_l2vpn_binding_msg(struct vty *, struct imsg *);
-static int show_l2vpn_pw_msg(struct vty *, struct imsg *);
+ struct show_params *);
+static int show_lib_msg_json(struct imsg *, struct show_params *,
+ json_object *);
+static int show_l2vpn_binding_msg(struct vty *, struct imsg *,
+ struct show_params *);
+static int show_l2vpn_binding_msg_json(struct imsg *,
+ struct show_params *, json_object *);
+static int show_l2vpn_pw_msg(struct vty *, struct imsg *,
+ struct show_params *);
+static int show_l2vpn_pw_msg_json(struct imsg *,
+ struct show_params *, json_object *);
static int ldp_vty_connect(struct imsgbuf *);
+static int ldp_vty_dispatch_msg(struct vty *, struct imsg *,
+ enum show_command, struct show_params *,
+ json_object *);
static int ldp_vty_dispatch(struct vty *, struct imsgbuf *,
- enum show_command, struct show_filter *);
+ enum show_command, struct show_params *);
static int ldp_vty_get_af(const char *, int *);
static int
show_interface_msg(struct vty *vty, struct imsg *imsg,
- struct show_filter *filter)
+ struct show_params *params)
{
struct ctl_iface *iface;
char timers[BUFSIZ];
@@ -78,7 +100,7 @@ show_interface_msg(struct vty *vty, struct imsg *imsg,
case IMSG_CTL_SHOW_INTERFACE:
iface = imsg->data;
- if (filter->family != AF_UNSPEC && filter->family != iface->af)
+ if (params->family != AF_UNSPEC && params->family != iface->af)
break;
snprintf(timers, sizeof(timers), "%u/%u",
@@ -100,6 +122,48 @@ show_interface_msg(struct vty *vty, struct imsg *imsg,
return (0);
}
+static int
+show_interface_msg_json(struct imsg *imsg, struct show_params *params,
+ json_object *json)
+{
+ struct ctl_iface *iface;
+ json_object *json_iface;
+ char key_name[64];
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_INTERFACE:
+ iface = imsg->data;
+
+ if (params->family != AF_UNSPEC && params->family != iface->af)
+ break;
+
+ json_iface = json_object_new_object();
+ json_object_string_add(json_iface, "name", iface->name);
+ json_object_string_add(json_iface, "addressFamily",
+ af_name(iface->af));
+ json_object_string_add(json_iface, "state",
+ if_state_name(iface->state));
+ json_object_string_add(json_iface, "upTime",
+ log_time(iface->uptime));
+ json_object_int_add(json_iface, "helloInterval",
+ iface->hello_interval);
+ json_object_int_add(json_iface, "helloHoldtime",
+ iface->hello_holdtime);
+ json_object_int_add(json_iface, "adjacencyCount",
+ iface->adj_cnt);
+
+ sprintf(key_name, "%s: %s", iface->name, af_name(iface->af));
+ json_object_object_add(json, key_name, json_iface);
+ break;
+ case IMSG_CTL_END:
+ return (1);
+ default:
+ break;
+ }
+
+ return (0);
+}
+
static void
show_discovery_adj(struct vty *vty, char *buffer, struct ctl_adj *adj)
{
@@ -116,7 +180,7 @@ show_discovery_adj(struct vty *vty, char *buffer, struct ctl_adj *adj)
static int
show_discovery_msg(struct vty *vty, struct imsg *imsg,
- struct show_filter *filter)
+ struct show_params *params)
{
struct ctl_adj *adj;
struct ctl_disc_if *iface;
@@ -135,9 +199,9 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg,
case IMSG_CTL_SHOW_DISC_IFACE:
iface = imsg->data;
- if (filter->family != AF_UNSPEC &&
- ((filter->family == AF_INET && !iface->active_v4) ||
- (filter->family == AF_INET6 && !iface->active_v6)))
+ if (params->family != AF_UNSPEC &&
+ ((params->family == AF_INET && !iface->active_v4) ||
+ (params->family == AF_INET6 && !iface->active_v6)))
break;
buflen = strlen(ifaces_buffer);
@@ -148,7 +212,7 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg,
case IMSG_CTL_SHOW_DISC_TNBR:
tnbr = imsg->data;
- if (filter->family != AF_UNSPEC && filter->family != tnbr->af)
+ if (params->family != AF_UNSPEC && params->family != tnbr->af)
break;
trans_addr = &(ldp_af_conf_get(ldpd_conf,
@@ -162,7 +226,7 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg,
case IMSG_CTL_SHOW_DISC_ADJ:
adj = imsg->data;
- if (filter->family != AF_UNSPEC && filter->family != adj->af)
+ if (params->family != AF_UNSPEC && params->family != adj->af)
break;
switch(adj->type) {
@@ -193,6 +257,111 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg,
}
static void
+show_discovery_adj_json(json_object *json, struct ctl_adj *adj)
+{
+ json_object *json_adj;
+ json_object *json_array;
+
+ json_object_object_get_ex(json, "adjacencies", &json_array);
+ if (!json_array) {
+ json_array = json_object_new_array();
+ json_object_object_add(json, "adjacencies", json_array);
+ }
+
+ json_adj = json_object_new_object();
+ json_object_string_add(json_adj, "id", inet_ntoa(adj->id));
+ json_object_string_add(json_adj, "transportAddress", log_addr(adj->af,
+ &adj->trans_addr));
+ json_object_int_add(json_adj, "holdtime", adj->holdtime);
+ json_object_array_add(json_array, json_adj);
+}
+
+static int
+show_discovery_msg_json(struct imsg *imsg, struct show_params *params,
+ json_object *json)
+{
+ struct ctl_adj *adj;
+ struct ctl_disc_if *iface;
+ struct ctl_disc_tnbr *tnbr;
+ struct in_addr rtr_id;
+ union ldpd_addr *trans_addr;
+ json_object *json_interface;
+ json_object *json_target;
+ static json_object *json_interfaces;
+ static json_object *json_targets;
+ static json_object *json_container;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_DISCOVERY:
+ rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf);
+ json_object_string_add(json, "id", inet_ntoa(rtr_id));
+ json_interfaces = json_object_new_object();
+ json_object_object_add(json, "interfaces", json_interfaces);
+ json_targets = json_object_new_object();
+ json_object_object_add(json, "targetedHellos", json_targets);
+ json_container = NULL;
+ break;
+ case IMSG_CTL_SHOW_DISC_IFACE:
+ iface = imsg->data;
+
+ if (params->family != AF_UNSPEC &&
+ ((params->family == AF_INET && !iface->active_v4) ||
+ (params->family == AF_INET6 && !iface->active_v6)))
+ break;
+
+ json_interface = json_object_new_object();
+ json_object_boolean_true_add(json_interface, "transmit");
+ if (!iface->no_adj)
+ json_object_boolean_true_add(json_interface, "receive");
+
+ json_object_object_add(json_interfaces, iface->name,
+ json_interface);
+ json_container = json_interface;
+ break;
+ case IMSG_CTL_SHOW_DISC_TNBR:
+ tnbr = imsg->data;
+
+ if (params->family != AF_UNSPEC && params->family != tnbr->af)
+ break;
+
+ trans_addr = &(ldp_af_conf_get(ldpd_conf, tnbr->af))->trans_addr;
+
+ json_target = json_object_new_object();
+ json_object_string_add(json_target, "sourceAddress",
+ log_addr(tnbr->af, trans_addr));
+ json_object_boolean_true_add(json_target, "transmit");
+ if (!tnbr->no_adj)
+ json_object_boolean_true_add(json_target, "receive");
+
+ json_object_object_add(json_targets, log_addr(tnbr->af,
+ &tnbr->addr), json_target);
+ json_container = json_target;
+ break;
+ case IMSG_CTL_SHOW_DISC_ADJ:
+ adj = imsg->data;
+
+ if (params->family != AF_UNSPEC && params->family != adj->af)
+ break;
+
+ switch(adj->type) {
+ case HELLO_LINK:
+ show_discovery_adj_json(json_container, adj);
+ break;
+ case HELLO_TARGETED:
+ show_discovery_adj_json(json_container, adj);
+ break;
+ }
+ break;
+ case IMSG_CTL_END:
+ return (1);
+ default:
+ break;
+ }
+
+ return (0);
+}
+
+static void
show_nbr_adj(struct vty *vty, char *buffer, struct ctl_adj *adj)
{
size_t buflen = strlen(buffer);
@@ -211,10 +380,10 @@ show_nbr_adj(struct vty *vty, char *buffer, struct ctl_adj *adj)
}
static int
-show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_filter *filter)
+show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
{
- struct ctl_adj *adj;
struct ctl_nbr *nbr;
+ struct ctl_adj *adj;
static char v4adjs_buffer[LDPBUFSIZ];
static char v6adjs_buffer[LDPBUFSIZ];
@@ -272,8 +441,101 @@ show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_filter *filter)
return (0);
}
+static void
+show_nbr_adj_json(struct ctl_adj *adj, json_object *adj_list)
+{
+ char adj_string[128];
+
+ switch (adj->type) {
+ case HELLO_LINK:
+ strlcpy(adj_string, "interface: ", sizeof(adj_string));
+ strlcat(adj_string, adj->ifname, sizeof(adj_string));
+ break;
+ case HELLO_TARGETED:
+ strlcpy(adj_string, "targetedHello: ", sizeof(adj_string));
+ strlcat(adj_string, log_addr(adj->af, &adj->src_addr),
+ sizeof(adj_string));
+ break;
+ }
+
+ json_object_array_add(adj_list, json_object_new_string(adj_string));
+}
+
+static int
+show_nbr_msg_json(struct imsg *imsg, struct show_params *params,
+ json_object *json)
+{
+ struct ctl_nbr *nbr;
+ struct ctl_adj *adj;
+ json_object *json_nbr;
+ static json_object *json_nbr_sources;
+ static json_object *json_v4adjs;
+ static json_object *json_v6adjs;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_NBR:
+ nbr = imsg->data;
+
+ json_nbr = json_object_new_object();
+ json_object_string_add(json_nbr, "peerId", inet_ntoa(nbr->id));
+ json_object_string_add(json_nbr, "tcpLocalAddress",
+ log_addr(nbr->af, &nbr->laddr));
+ json_object_int_add(json_nbr, "tcpLocalPort",
+ ntohs(nbr->lport));
+ json_object_string_add(json_nbr, "tcpRemoteAddress",
+ log_addr(nbr->af, &nbr->raddr));
+ json_object_int_add(json_nbr, "tcpRemotePort",
+ ntohs(nbr->rport));
+ json_object_int_add(json_nbr, "holdtime", nbr->holdtime);
+ json_object_string_add(json_nbr, "state",
+ nbr_state_name(nbr->nbr_state));
+ json_object_string_add(json_nbr, "upTime",
+ log_time(nbr->uptime));
+ json_object_object_add(json, inet_ntoa(nbr->id), json_nbr);
+
+ json_nbr_sources = json_object_new_object();
+ json_object_object_add(json_nbr, "discoverySources",
+ json_nbr_sources);
+ json_v4adjs = NULL;
+ json_v6adjs = NULL;
+ break;
+ case IMSG_CTL_SHOW_NBR_DISC:
+ adj = imsg->data;
+
+ switch (adj->af) {
+ case AF_INET:
+ if (!json_v4adjs) {
+ json_v4adjs = json_object_new_array();
+ json_object_object_add(json_nbr_sources, "ipv4",
+ json_v4adjs);
+ }
+ show_nbr_adj_json(adj, json_v4adjs);
+ break;
+ case AF_INET6:
+ if (!json_v6adjs) {
+ json_v6adjs = json_object_new_array();
+ json_object_object_add(json_nbr_sources, "ipv6",
+ json_v6adjs);
+ }
+ show_nbr_adj_json(adj, json_v6adjs);
+ break;
+ default:
+ fatalx("show_nbr_msg_json: unknown af");
+ }
+ break;
+ case IMSG_CTL_SHOW_NBR_END:
+ break;
+ case IMSG_CTL_END:
+ return (1);
+ default:
+ break;
+ }
+
+ return (0);
+}
+
static int
-show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_filter *filter)
+show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
{
struct ctl_rt *rt;
char dstnet[BUFSIZ];
@@ -282,7 +544,7 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_filter *filter)
case IMSG_CTL_SHOW_LIB:
rt = imsg->data;
- if (filter->family != AF_UNSPEC && filter->family != rt->af)
+ if (params->family != AF_UNSPEC && params->family != rt->af)
break;
snprintf(dstnet, sizeof(dstnet), "%s/%d",
@@ -319,7 +581,58 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_filter *filter)
}
static int
-show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg)
+show_lib_msg_json(struct imsg *imsg, struct show_params *params,
+ json_object *json)
+{
+ struct ctl_rt *rt;
+ char dstnet[BUFSIZ];
+ static json_object *json_binding;
+ static json_object *json_remote_labels;
+ json_object *json_remote_label;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_LIB:
+ rt = imsg->data;
+
+ if (params->family != AF_UNSPEC && params->family != rt->af)
+ break;
+
+ snprintf(dstnet, sizeof(dstnet), "%s/%d",
+ log_addr(rt->af, &rt->prefix), rt->prefixlen);
+
+ if (rt->first) {
+ json_binding = json_object_new_object();
+ json_object_string_add(json_binding, "localLabel",
+ log_label(rt->local_label));
+
+ json_remote_labels = json_object_new_array();
+ json_object_object_add(json_binding, "remoteLabels",
+ json_remote_labels);
+ json_object_object_add(json, dstnet, json_binding);
+ }
+
+ if (rt->remote_label != NO_LABEL) {
+ json_remote_label = json_object_new_object();
+ json_object_string_add(json_remote_label, "nexthop",
+ inet_ntoa(rt->nexthop));
+ json_object_string_add(json_remote_label, "label",
+ log_label(rt->remote_label));
+ json_object_array_add(json_remote_labels,
+ json_remote_label);
+ }
+ break;
+ case IMSG_CTL_END:
+ return (1);
+ default:
+ break;
+ }
+
+ return (0);
+}
+
+static int
+show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg,
+ struct show_params *params)
{
struct ctl_pw *pw;
@@ -369,7 +682,68 @@ show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg)
}
static int
-show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg)
+show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params,
+ json_object *json)
+{
+ struct ctl_pw *pw;
+ json_object *json_pw;
+ char key_name[64];
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_L2VPN_BINDING:
+ pw = imsg->data;
+
+ json_pw = json_object_new_object();
+ json_object_string_add(json_pw, "destination",
+ inet_ntoa(pw->lsr_id));
+ json_object_int_add(json_pw, "vcId", pw->pwid);
+
+ /* local binding */
+ if (pw->local_label != NO_LABEL) {
+ json_object_int_add(json_pw, "localLabel",
+ pw->local_label);
+ json_object_int_add(json_pw, "localControlWord",
+ pw->local_cword);
+ json_object_string_add(json_pw, "localVcType",
+ pw_type_name(pw->type));
+ json_object_int_add(json_pw, "localGroupID",
+ pw->local_gid);
+ json_object_int_add(json_pw, "localIfMtu",
+ pw->local_ifmtu);
+ } else
+ json_object_string_add(json_pw, "localLabel",
+ "unassigned");
+
+ /* remote binding */
+ if (pw->remote_label != NO_LABEL) {
+ json_object_int_add(json_pw, "remoteLabel",
+ pw->remote_label);
+ json_object_int_add(json_pw, "remoteControlWord",
+ pw->remote_cword);
+ json_object_string_add(json_pw, "remoteVcType",
+ pw_type_name(pw->type));
+ json_object_int_add(json_pw, "remoteGroupID",
+ pw->remote_gid);
+ json_object_int_add(json_pw, "remoteIfMtu",
+ pw->remote_ifmtu);
+ } else
+ json_object_string_add(json_pw, "remoteLabel",
+ "unassigned");
+
+ sprintf(key_name, "%s: %u", inet_ntoa(pw->lsr_id), pw->pwid);
+ json_object_object_add(json, key_name, json_pw);
+ break;
+ case IMSG_CTL_END:
+ return (1);
+ default:
+ break;
+ }
+
+ return (0);
+}
+
+static int
+show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
{
struct ctl_pw *pw;
@@ -392,6 +766,36 @@ show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg)
}
static int
+show_l2vpn_pw_msg_json(struct imsg *imsg, struct show_params *params,
+ json_object *json)
+{
+ struct ctl_pw *pw;
+ json_object *json_pw;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_L2VPN_PW:
+ pw = imsg->data;
+
+ json_pw = json_object_new_object();
+ json_object_string_add(json_pw, "peerId", inet_ntoa(pw->lsr_id));
+ json_object_int_add(json_pw, "vcId", pw->pwid);
+ json_object_string_add(json_pw, "VpnName", pw->l2vpn_name);
+ if (pw->status)
+ json_object_string_add(json_pw, "status", "up");
+ else
+ json_object_string_add(json_pw, "status", "down");
+ json_object_object_add(json, pw->ifname, json_pw);
+ break;
+ case IMSG_CTL_END:
+ return (1);
+ default:
+ break;
+ }
+
+ return (0);
+}
+
+static int
ldp_vty_connect(struct imsgbuf *ibuf)
{
struct sockaddr_un s_un;
@@ -418,11 +822,46 @@ ldp_vty_connect(struct imsgbuf *ibuf)
}
static int
+ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
+ struct show_params *params, json_object *json)
+{
+ switch (cmd) {
+ case SHOW_IFACE:
+ if (json)
+ return (show_interface_msg_json(imsg, params, json));
+ return (show_interface_msg(vty, imsg, params));
+ case SHOW_DISC:
+ if (json)
+ return (show_discovery_msg_json(imsg, params, json));
+ return (show_discovery_msg(vty, imsg, params));
+ case SHOW_NBR:
+ if (json)
+ return (show_nbr_msg_json(imsg, params, json));
+ return (show_nbr_msg(vty, imsg, params));
+ case SHOW_LIB:
+ if (json)
+ return (show_lib_msg_json(imsg, params, json));
+ return (show_lib_msg(vty, imsg, params));
+ case SHOW_L2VPN_PW:
+ if (json)
+ return (show_l2vpn_pw_msg_json(imsg, params, json));
+ return (show_l2vpn_pw_msg(vty, imsg, params));
+ case SHOW_L2VPN_BINDING:
+ if (json)
+ return (show_l2vpn_binding_msg_json(imsg, params, json));
+ return (show_l2vpn_binding_msg(vty, imsg, params));
+ default:
+ return (0);
+ }
+}
+
+static int
ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd,
- struct show_filter *filter)
+ struct show_params *params)
{
struct imsg imsg;
- int n, done = 0;
+ int n, done = 0, ret = CMD_SUCCESS;
+ json_object *json = NULL;
while (ibuf->w.queued)
if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) {
@@ -431,55 +870,44 @@ ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd,
return (CMD_WARNING);
}
+ if (params->json)
+ json = json_object_new_object();
+
while (!done) {
if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) {
log_warnx("imsg_read error");
- close(ibuf->fd);
- return (CMD_WARNING);
+ ret = CMD_WARNING;
+ goto done;
}
if (n == 0) {
log_warnx("pipe closed");
- close(ibuf->fd);
- return (CMD_WARNING);
+ ret = CMD_WARNING;
+ goto done;
}
while (!done) {
if ((n = imsg_get(ibuf, &imsg)) == -1) {
log_warnx("imsg_get error");
- close(ibuf->fd);
- return (CMD_WARNING);
+ ret = CMD_WARNING;
+ goto done;
}
if (n == 0)
break;
- switch (cmd) {
- case SHOW_IFACE:
- done = show_interface_msg(vty, &imsg, filter);
- break;
- case SHOW_DISC:
- done = show_discovery_msg(vty, &imsg, filter);
- break;
- case SHOW_NBR:
- done = show_nbr_msg(vty, &imsg, filter);
- break;
- case SHOW_LIB:
- done = show_lib_msg(vty, &imsg, filter);
- break;
- case SHOW_L2VPN_PW:
- done = show_l2vpn_pw_msg(vty, &imsg);
- break;
- case SHOW_L2VPN_BINDING:
- done = show_l2vpn_binding_msg(vty, &imsg);
- break;
- default:
- break;
- }
+ done = ldp_vty_dispatch_msg(vty, &imsg, cmd, params,
+ json);
imsg_free(&imsg);
}
}
+ done:
close(ibuf->fd);
+ if (json) {
+ vty_out(vty, "%s%s", json_object_to_json_string_ext(json,
+ JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
- return (CMD_SUCCESS);
+ return (ret);
}
static int
@@ -503,53 +931,53 @@ int
ldp_vty_show_binding(struct vty *vty, struct vty_arg *args[])
{
struct imsgbuf ibuf;
- struct show_filter filter;
+ struct show_params params;
const char *af_str;
int af;
if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING);
- imsg_compose(&ibuf, IMSG_CTL_SHOW_LIB, 0, 0, -1, NULL, 0);
-
af_str = vty_get_arg_value(args, "address-family");
if (ldp_vty_get_af(af_str, &af) < 0)
return (CMD_ERR_NO_MATCH);
- memset(&filter, 0, sizeof(filter));
- filter.family = af;
+ memset(&params, 0, sizeof(params));
+ params.family = af;
+ params.json = vty_get_arg_value(args, "json") ? 1 : 0;
- return (ldp_vty_dispatch(vty, &ibuf, SHOW_LIB, &filter));
+ imsg_compose(&ibuf, IMSG_CTL_SHOW_LIB, 0, 0, -1, NULL, 0);
+ return (ldp_vty_dispatch(vty, &ibuf, SHOW_LIB, &params));
}
int
ldp_vty_show_discovery(struct vty *vty, struct vty_arg *args[])
{
struct imsgbuf ibuf;
- struct show_filter filter;
+ struct show_params params;
const char *af_str;
int af;
if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING);
- imsg_compose(&ibuf, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0);
-
af_str = vty_get_arg_value(args, "address-family");
if (ldp_vty_get_af(af_str, &af) < 0)
return (CMD_ERR_NO_MATCH);
- memset(&filter, 0, sizeof(filter));
- filter.family = af;
+ memset(&params, 0, sizeof(params));
+ params.family = af;
+ params.json = vty_get_arg_value(args, "json") ? 1 : 0;
- return (ldp_vty_dispatch(vty, &ibuf, SHOW_DISC, &filter));
+ imsg_compose(&ibuf, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0);
+ return (ldp_vty_dispatch(vty, &ibuf, SHOW_DISC, &params));
}
int
ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[])
{
struct imsgbuf ibuf;
- struct show_filter filter;
+ struct show_params params;
unsigned int ifidx = 0;
const char *af_str;
int af;
@@ -557,79 +985,82 @@ ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[])
if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING);
- imsg_compose(&ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, &ifidx,
- sizeof(ifidx));
-
af_str = vty_get_arg_value(args, "address-family");
if (ldp_vty_get_af(af_str, &af) < 0)
return (CMD_ERR_NO_MATCH);
- memset(&filter, 0, sizeof(filter));
- filter.family = af;
+ memset(&params, 0, sizeof(params));
+ params.family = af;
+ params.json = vty_get_arg_value(args, "json") ? 1 : 0;
/* header */
- vty_out(vty, "%-4s %-11s %-6s %-8s %-12s %3s%s", "AF",
- "Interface", "State", "Uptime", "Hello Timers", "ac", VTY_NEWLINE);
+ if (!params.json) {
+ vty_out(vty, "%-4s %-11s %-6s %-8s %-12s %3s%s", "AF",
+ "Interface", "State", "Uptime", "Hello Timers", "ac",
+ VTY_NEWLINE);
+ }
- return (ldp_vty_dispatch(vty, &ibuf, SHOW_IFACE, &filter));
+ imsg_compose(&ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, &ifidx,
+ sizeof(ifidx));
+ return (ldp_vty_dispatch(vty, &ibuf, SHOW_IFACE, &params));
}
int
ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[])
{
struct imsgbuf ibuf;
- struct show_filter filter;
+ struct show_params params;
if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING);
- imsg_compose(&ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0);
-
- /* not used */
- memset(&filter, 0, sizeof(filter));
+ memset(&params, 0, sizeof(params));
+ params.json = vty_get_arg_value(args, "json") ? 1 : 0;
- return (ldp_vty_dispatch(vty, &ibuf, SHOW_NBR, &filter));
+ imsg_compose(&ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0);
+ return (ldp_vty_dispatch(vty, &ibuf, SHOW_NBR, &params));
}
int
ldp_vty_show_atom_binding(struct vty *vty, struct vty_arg *args[])
{
struct imsgbuf ibuf;
- struct show_filter filter;
+ struct show_params params;
if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING);
- imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
-
- /* not used */
- memset(&filter, 0, sizeof(filter));
+ memset(&params, 0, sizeof(params));
+ params.json = vty_get_arg_value(args, "json") ? 1 : 0;
- return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &filter));
+ imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
+ return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params));
}
int
ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[])
{
struct imsgbuf ibuf;
- struct show_filter filter;
+ struct show_params params;
if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING);
- imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_PW, 0, 0, -1, NULL, 0);
-
- /* not used */
- memset(&filter, 0, sizeof(filter));
+ memset(&params, 0, sizeof(params));
+ params.json = vty_get_arg_value(args, "json") ? 1 : 0;
- /* header */
- vty_out(vty, "%-9s %-15s %-10s %-16s %-10s%s",
- "Interface", "Peer ID", "VC ID", "Name", "Status", VTY_NEWLINE);
- vty_out(vty, "%-9s %-15s %-10s %-16s %-10s%s",
- "---------", "---------------", "----------",
- "----------------", "----------", VTY_NEWLINE);
+ if (!params.json) {
+ /* header */
+ vty_out(vty, "%-9s %-15s %-10s %-16s %-10s%s",
+ "Interface", "Peer ID", "VC ID", "Name", "Status",
+ VTY_NEWLINE);
+ vty_out(vty, "%-9s %-15s %-10s %-16s %-10s%s",
+ "---------", "---------------", "----------",
+ "----------------", "----------", VTY_NEWLINE);
+ }
- return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_PW, &filter));
+ imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_PW, 0, 0, -1, NULL, 0);
+ return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_PW, &params));
}
int
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 71c0a21dd4..12954b91af 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -100,10 +100,10 @@ zebra_send_mpls_labels(int cmd, struct kroute *kr)
kr->remote_label == NO_LABEL)
return (0);
- debug_zebra_out("prefix %s/%u nexthop %s labels %s/%s (%s)",
+ debug_zebra_out("prefix %s/%u nexthop %s ifindex %u labels %s/%s (%s)",
log_addr(kr->af, &kr->prefix), kr->prefixlen,
- log_addr(kr->af, &kr->nexthop), log_label(kr->local_label),
- log_label(kr->remote_label),
+ log_addr(kr->af, &kr->nexthop), kr->ifindex,
+ log_label(kr->local_label), log_label(kr->remote_label),
(cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete");
/* Reset stream. */
@@ -127,6 +127,7 @@ zebra_send_mpls_labels(int cmd, struct kroute *kr)
default:
fatalx("kr_change: unknown af");
}
+ stream_putl(s, kr->ifindex);
stream_putc(s, kr->priority);
stream_putl(s, kr->local_label);
stream_putl(s, kr->remote_label);
@@ -352,7 +353,7 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
u_char type;
u_char message_flags;
struct kroute kr;
- int nhnum, nhlen;
+ int nhnum = 0, nhlen;
size_t nhmark;
memset(&kr, 0, sizeof(kr));
@@ -373,8 +374,6 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
stream_getl(s); /* flags, unused */
stream_getw(s); /* instance, unused */
message_flags = stream_getc(s);
- if (!CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP))
- return (0);
switch (command) {
case ZEBRA_REDISTRIBUTE_IPV4_ADD:
@@ -397,16 +396,46 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
(kr.af == AF_INET6 && IN6_IS_SCOPE_EMBED(&kr.prefix.v6)))
return (0);
- nhnum = stream_getc(s);
- nhmark = stream_get_getp(s);
- stream_set_getp(s, nhmark + nhnum * (nhlen + 5));
+ if (kr.af == AF_INET6 &&
+ CHECK_FLAG(message_flags, ZAPI_MESSAGE_SRCPFX)) {
+ uint8_t src_prefixlen;
+
+ src_prefixlen = stream_getc(s);
+
+ /* we completely ignore srcdest routes for now. */
+ if (src_prefixlen)
+ return (0);
+ }
+
+ if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP)) {
+ nhnum = stream_getc(s);
+ nhmark = stream_get_getp(s);
+ stream_set_getp(s, nhmark + nhnum * (nhlen + 5));
+ }
if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_DISTANCE))
kr.priority = stream_getc(s);
if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_METRIC))
stream_getl(s); /* metric, not used */
- stream_set_getp(s, nhmark);
+ if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP))
+ stream_set_getp(s, nhmark);
+
+ if (nhnum == 0) {
+ switch (command) {
+ case ZEBRA_REDISTRIBUTE_IPV4_ADD:
+ case ZEBRA_REDISTRIBUTE_IPV6_ADD:
+ return (0);
+ case ZEBRA_REDISTRIBUTE_IPV4_DEL:
+ case ZEBRA_REDISTRIBUTE_IPV6_DEL:
+ debug_zebra_in("route delete %s/%d (%s)",
+ log_addr(kr.af, &kr.prefix), kr.prefixlen,
+ zebra_route_string(type));
+ break;
+ default:
+ fatalx("ldp_zebra_read_route: unknown command");
+ }
+ }
/* loop through all the nexthops */
for (; nhnum > 0; nhnum--) {
@@ -426,30 +455,19 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
switch (command) {
case ZEBRA_REDISTRIBUTE_IPV4_ADD:
case ZEBRA_REDISTRIBUTE_IPV6_ADD:
- debug_zebra_in("route add %s/%d nexthop %s (%s)",
- log_addr(kr.af, &kr.prefix), kr.prefixlen,
- log_addr(kr.af, &kr.nexthop),
- zebra_route_string(type));
+ debug_zebra_in("route add %s/%d nexthop %s "
+ "ifindex %u (%s)", log_addr(kr.af, &kr.prefix),
+ kr.prefixlen, log_addr(kr.af, &kr.nexthop),
+ kr.ifindex, zebra_route_string(type));
main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
sizeof(kr));
break;
- case ZEBRA_REDISTRIBUTE_IPV4_DEL:
- case ZEBRA_REDISTRIBUTE_IPV6_DEL:
- debug_zebra_in("route delete %s/%d nexthop %s (%s)",
- log_addr(kr.af, &kr.prefix), kr.prefixlen,
- log_addr(kr.af, &kr.nexthop),
- zebra_route_string(type));
- main_imsg_compose_lde(IMSG_NETWORK_DEL, 0, &kr,
- sizeof(kr));
- break;
default:
- fatalx("ldp_zebra_read_route: unknown command");
+ break;
}
}
- if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD ||
- command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
- main_imsg_compose_lde(IMSG_NETWORK_ADD_END, 0, &kr, sizeof(kr));
+ main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
return (0);
}
@@ -485,3 +503,11 @@ ldp_zebra_init(struct thread_master *master)
zclient->redistribute_route_ipv6_add = ldp_zebra_read_route;
zclient->redistribute_route_ipv6_del = ldp_zebra_read_route;
}
+
+void
+ldp_zebra_destroy(void)
+{
+ zclient_stop(zclient);
+ zclient_free(zclient);
+ zclient = NULL;
+}
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index 927af682a1..4e79f8b8ab 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -39,11 +39,12 @@
#include "sigevent.h"
#include "zclient.h"
#include "vrf.h"
+#include "filter.h"
#include "sockopt.h"
#include "qobj.h"
static void ldpd_shutdown(void);
-static pid_t start_child(enum ldpd_process, char *, int,
+static pid_t start_child(enum ldpd_process, char *, int, int,
const char *, const char *, const char *);
static int main_dispatch_ldpe(struct thread *);
static int main_dispatch_lde(struct thread *);
@@ -78,8 +79,8 @@ DEFINE_QOBJ_TYPE(ldpd_conf)
struct ldpd_global global;
struct ldpd_conf *ldpd_conf;
-static struct imsgev *iev_ldpe;
-static struct imsgev *iev_lde;
+static struct imsgev *iev_ldpe, *iev_ldpe_sync;
+static struct imsgev *iev_lde, *iev_lde_sync;
static pid_t ldpe_pid;
static pid_t lde_pid;
@@ -220,8 +221,8 @@ main(int argc, char *argv[])
{
char *saved_argv0;
int lflag = 0, eflag = 0;
- int pipe_parent2ldpe[2];
- int pipe_parent2lde[2];
+ int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
+ int pipe_parent2lde[2], pipe_parent2lde_sync[2];
char *p;
char *vty_addr = NULL;
int vty_port = LDP_VTY_PORT;
@@ -363,6 +364,7 @@ main(int argc, char *argv[])
vty_config_lockless ();
vty_init(master);
vrf_init();
+ access_list_init ();
ldp_vty_init();
ldp_vty_if_init();
@@ -384,22 +386,36 @@ main(int argc, char *argv[])
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1)
fatal("socketpair");
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC,
+ pipe_parent2ldpe_sync) == -1)
+ fatal("socketpair");
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2lde) == -1)
fatal("socketpair");
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC,
+ pipe_parent2lde_sync) == -1)
+ fatal("socketpair");
sock_set_nonblock(pipe_parent2ldpe[0]);
sock_set_cloexec(pipe_parent2ldpe[0]);
sock_set_nonblock(pipe_parent2ldpe[1]);
sock_set_cloexec(pipe_parent2ldpe[1]);
+ sock_set_nonblock(pipe_parent2ldpe_sync[0]);
+ sock_set_cloexec(pipe_parent2ldpe_sync[0]);
+ sock_set_cloexec(pipe_parent2ldpe_sync[1]);
sock_set_nonblock(pipe_parent2lde[0]);
sock_set_cloexec(pipe_parent2lde[0]);
sock_set_nonblock(pipe_parent2lde[1]);
sock_set_cloexec(pipe_parent2lde[1]);
+ sock_set_nonblock(pipe_parent2lde_sync[0]);
+ sock_set_cloexec(pipe_parent2lde_sync[0]);
+ sock_set_cloexec(pipe_parent2lde_sync[1]);
/* start children */
lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
- pipe_parent2lde[1], user, group, ctl_sock_custom_path);
+ pipe_parent2lde[1], pipe_parent2lde_sync[1],
+ user, group, ctl_sock_custom_path);
ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
- pipe_parent2ldpe[1], user, group, ctl_sock_custom_path);
+ pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1],
+ user, group, ctl_sock_custom_path);
/* drop privileges */
if (user)
@@ -415,22 +431,34 @@ main(int argc, char *argv[])
ldp_zebra_init(master);
/* setup pipes to children */
- if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL ||
- (iev_lde = malloc(sizeof(struct imsgev))) == NULL)
+ if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL ||
+ (iev_ldpe_sync = calloc(1, sizeof(struct imsgev))) == NULL ||
+ (iev_lde = calloc(1, sizeof(struct imsgev))) == NULL ||
+ (iev_lde_sync = calloc(1, sizeof(struct imsgev))) == NULL)
fatal(NULL);
imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]);
iev_ldpe->handler_read = main_dispatch_ldpe;
iev_ldpe->ev_read = thread_add_read(master, iev_ldpe->handler_read,
iev_ldpe, iev_ldpe->ibuf.fd);
iev_ldpe->handler_write = ldp_write_handler;
- iev_ldpe->ev_write = NULL;
+
+ imsg_init(&iev_ldpe_sync->ibuf, pipe_parent2ldpe_sync[0]);
+ iev_ldpe_sync->handler_read = main_dispatch_ldpe;
+ iev_ldpe_sync->ev_read = thread_add_read(master,
+ iev_ldpe_sync->handler_read, iev_ldpe_sync, iev_ldpe_sync->ibuf.fd);
+ iev_ldpe_sync->handler_write = ldp_write_handler;
imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]);
iev_lde->handler_read = main_dispatch_lde;
iev_lde->ev_read = thread_add_read(master, iev_lde->handler_read,
iev_lde, iev_lde->ibuf.fd);
iev_lde->handler_write = ldp_write_handler;
- iev_lde->ev_write = NULL;
+
+ imsg_init(&iev_lde_sync->ibuf, pipe_parent2lde_sync[0]);
+ iev_lde_sync->handler_read = main_dispatch_lde;
+ iev_lde_sync->ev_read = thread_add_read(master,
+ iev_lde_sync->handler_read, iev_lde_sync, iev_lde_sync->ibuf.fd);
+ iev_lde_sync->handler_write = ldp_write_handler;
if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
fatal("could not establish imsg links");
@@ -490,12 +518,22 @@ ldpd_shutdown(void)
free(iev_lde);
log_info("terminating");
+
+ vrf_terminate();
+ access_list_reset();
+ cmd_terminate();
+ vty_terminate();
+ ldp_zebra_destroy();
+ zprivs_terminate(&ldpd_privs);
+ thread_master_free(master);
+ closezlog(zlog_default);
+
exit(0);
}
static pid_t
-start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
- const char *group, const char *ctl_sock_custom_path)
+start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync,
+ const char *user, const char *group, const char *ctl_sock_custom_path)
{
char *argv[9];
int argc = 0;
@@ -507,12 +545,15 @@ start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
case 0:
break;
default:
- close(fd);
+ close(fd_async);
+ close(fd_sync);
return (pid);
}
- if (dup2(fd, 3) == -1)
- fatal("cannot setup imsg fd");
+ if (dup2(fd_async, LDPD_FD_ASYNC) == -1)
+ fatal("cannot setup imsg async fd");
+ if (dup2(fd_sync, LDPD_FD_SYNC) == -1)
+ fatal("cannot setup imsg sync fd");
argv[argc++] = argv0;
switch (p) {
@@ -577,6 +618,12 @@ main_dispatch_ldpe(struct thread *thread)
af = imsg.hdr.pid;
main_imsg_send_net_sockets(af);
break;
+ case IMSG_ACL_CHECK:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
+ sizeof(struct acl_check))
+ fatalx("IMSG_ACL_CHECK imsg with wrong len");
+ ldp_acl_reply(iev, (struct acl_check *)imsg.data);
+ break;
default:
log_debug("%s: error handling imsg %d", __func__,
imsg.hdr.type);
@@ -658,6 +705,12 @@ main_dispatch_lde(struct thread *thread)
log_warnx("%s: error unsetting pseudowire",
__func__);
break;
+ case IMSG_ACL_CHECK:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
+ sizeof(struct acl_check))
+ fatalx("IMSG_ACL_CHECK imsg with wrong len");
+ ldp_acl_reply(iev, (struct acl_check *)imsg.data);
+ break;
default:
log_debug("%s: error handling imsg %d", __func__,
imsg.hdr.type);
@@ -734,10 +787,11 @@ main_imsg_compose_both(enum imsg_type type, void *buf, uint16_t len)
void
imsg_event_add(struct imsgev *iev)
{
- THREAD_READ_ON(master, iev->ev_read, iev->handler_read, iev,
- iev->ibuf.fd);
+ if (iev->handler_read)
+ THREAD_READ_ON(master, iev->ev_read, iev->handler_read, iev,
+ iev->ibuf.fd);
- if (iev->ibuf.w.queued)
+ if (iev->handler_write && iev->ibuf.w.queued)
THREAD_WRITE_ON(master, iev->ev_write, iev->handler_write, iev,
iev->ibuf.fd);
}
@@ -835,6 +889,70 @@ main_imsg_send_net_socket(int af, enum socket_type type)
sizeof(type));
}
+int
+ldp_acl_request(struct imsgev *iev, char *acl_name, int af,
+ union ldpd_addr *addr, uint8_t prefixlen)
+{
+ struct imsg imsg;
+ ssize_t n;
+ struct acl_check acl_check;
+
+ if (acl_name[0] == '\0')
+ return FILTER_PERMIT;
+
+ /* build request */
+ strlcpy(acl_check.acl, acl_name, sizeof(acl_check.acl));
+ acl_check.af = af;
+ acl_check.addr = *addr;
+ acl_check.prefixlen = prefixlen;
+
+ /* send (blocking) */
+ imsg_compose_event(iev, IMSG_ACL_CHECK, 0, 0, -1, &acl_check,
+ sizeof(acl_check));
+ imsg_flush(&iev->ibuf);
+
+ /* receive (blocking) and parse result */
+ if ((n = imsg_read(&iev->ibuf)) == -1)
+ fatal("imsg_read error");
+ if ((n = imsg_get(&iev->ibuf, &imsg)) == -1)
+ fatal("imsg_get");
+ if (imsg.hdr.type != IMSG_ACL_CHECK ||
+ imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(int))
+ fatalx("ldp_acl_request: invalid response");
+
+ return (*((int *)imsg.data));
+}
+
+void
+ldp_acl_reply(struct imsgev *iev, struct acl_check *acl_check)
+{
+ struct access_list *alist;
+ struct prefix prefix;
+ int result;
+
+ alist = access_list_lookup(family2afi(acl_check->af), acl_check->acl);
+ if (alist == NULL)
+ result = FILTER_DENY;
+ else {
+ prefix.family = acl_check->af;
+ switch (prefix.family) {
+ case AF_INET:
+ prefix.u.prefix4 = acl_check->addr.v4;
+ break;
+ case AF_INET6:
+ prefix.u.prefix6 = acl_check->addr.v6;
+ break;
+ default:
+ fatalx("ldp_acl_reply: unknown af");
+ }
+ prefix.prefixlen = acl_check->prefixlen;
+ result = access_list_apply(alist, &prefix);
+ }
+
+ imsg_compose_event(iev, IMSG_ACL_CHECK, 0, 0, -1, &result,
+ sizeof(result));
+}
+
struct ldpd_af_conf *
ldp_af_conf_get(struct ldpd_conf *xconf, int af)
{
@@ -891,40 +1009,40 @@ main_imsg_send_config(struct ldpd_conf *xconf)
sizeof(*xconf)) == -1)
return (-1);
- LIST_FOREACH(iface, &xconf->iface_list, entry) {
+ RB_FOREACH(iface, iface_head, &xconf->iface_tree) {
if (main_imsg_compose_both(IMSG_RECONF_IFACE, iface,
sizeof(*iface)) == -1)
return (-1);
}
- LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) {
+ RB_FOREACH(tnbr, tnbr_head, &xconf->tnbr_tree) {
if (main_imsg_compose_both(IMSG_RECONF_TNBR, tnbr,
sizeof(*tnbr)) == -1)
return (-1);
}
- LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) {
+ RB_FOREACH(nbrp, nbrp_head, &xconf->nbrp_tree) {
if (main_imsg_compose_both(IMSG_RECONF_NBRP, nbrp,
sizeof(*nbrp)) == -1)
return (-1);
}
- LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
+ RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN, l2vpn,
sizeof(*l2vpn)) == -1)
return (-1);
- LIST_FOREACH(lif, &l2vpn->if_list, entry) {
+ RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IF, lif,
sizeof(*lif)) == -1)
return (-1);
}
- LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN_PW, pw,
sizeof(*pw)) == -1)
return (-1);
}
- LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IPW, pw,
sizeof(*pw)) == -1)
return (-1);
@@ -971,15 +1089,15 @@ ldp_config_normalize(struct ldpd_conf *xconf, void **ref)
ldp_config_reset_af(xconf, AF_INET6, ref);
}
- LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
- LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
+ RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
if (pw->flags & F_PW_STATIC_NBR_ADDR)
continue;
pw->af = AF_INET;
pw->addr.v4 = pw->lsr_id;
}
- LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
if (pw->flags & F_PW_STATIC_NBR_ADDR)
continue;
@@ -995,17 +1113,17 @@ ldp_config_reset_main(struct ldpd_conf *conf, void **ref)
struct iface *iface;
struct nbr_params *nbrp;
- while ((iface = LIST_FIRST(&conf->iface_list)) != NULL) {
+ while ((iface = RB_ROOT(&conf->iface_tree)) != NULL) {
if (ref && *ref == iface)
*ref = NULL;
- LIST_REMOVE(iface, entry);
+ RB_REMOVE(iface_head, &conf->iface_tree, iface);
free(iface);
}
- while ((nbrp = LIST_FIRST(&conf->nbrp_list)) != NULL) {
+ while ((nbrp = RB_ROOT(&conf->nbrp_tree)) != NULL) {
if (ref && *ref == nbrp)
*ref = NULL;
- LIST_REMOVE(nbrp, entry);
+ RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp);
}
@@ -1028,18 +1146,18 @@ ldp_config_reset_af(struct ldpd_conf *conf, int af, void **ref)
struct iface_af *ia;
struct tnbr *tnbr, *ttmp;
- LIST_FOREACH(iface, &conf->iface_list, entry) {
+ RB_FOREACH(iface, iface_head, &conf->iface_tree) {
ia = iface_af_get(iface, af);
ia->enabled = 0;
}
- LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
+ RB_FOREACH_SAFE(tnbr, tnbr_head, &conf->tnbr_tree, ttmp) {
if (tnbr->af != af)
continue;
if (ref && *ref == tnbr)
*ref = NULL;
- LIST_REMOVE(tnbr, entry);
+ RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr);
}
@@ -1073,46 +1191,46 @@ ldp_dup_config_ref(struct ldpd_conf *conf, void **ref)
} while (0)
COPY(xconf, conf);
- LIST_INIT(&xconf->iface_list);
- LIST_INIT(&xconf->tnbr_list);
- LIST_INIT(&xconf->nbrp_list);
- LIST_INIT(&xconf->l2vpn_list);
+ RB_INIT(&xconf->iface_tree);
+ RB_INIT(&xconf->tnbr_tree);
+ RB_INIT(&xconf->nbrp_tree);
+ RB_INIT(&xconf->l2vpn_tree);
- LIST_FOREACH(iface, &conf->iface_list, entry) {
+ RB_FOREACH(iface, iface_head, &conf->iface_tree) {
COPY(xi, iface);
xi->ipv4.iface = xi;
xi->ipv6.iface = xi;
- LIST_INSERT_HEAD(&xconf->iface_list, xi, entry);
+ RB_INSERT(iface_head, &xconf->iface_tree, xi);
}
- LIST_FOREACH(tnbr, &conf->tnbr_list, entry) {
+ RB_FOREACH(tnbr, tnbr_head, &conf->tnbr_tree) {
COPY(xt, tnbr);
- LIST_INSERT_HEAD(&xconf->tnbr_list, xt, entry);
+ RB_INSERT(tnbr_head, &xconf->tnbr_tree, xt);
}
- LIST_FOREACH(nbrp, &conf->nbrp_list, entry) {
+ RB_FOREACH(nbrp, nbrp_head, &conf->nbrp_tree) {
COPY(xn, nbrp);
- LIST_INSERT_HEAD(&xconf->nbrp_list, xn, entry);
+ RB_INSERT(nbrp_head, &xconf->nbrp_tree, xn);
}
- LIST_FOREACH(l2vpn, &conf->l2vpn_list, entry) {
+ RB_FOREACH(l2vpn, l2vpn_head, &conf->l2vpn_tree) {
COPY(xl, l2vpn);
- LIST_INIT(&xl->if_list);
- LIST_INIT(&xl->pw_list);
- LIST_INIT(&xl->pw_inactive_list);
- LIST_INSERT_HEAD(&xconf->l2vpn_list, xl, entry);
+ RB_INIT(&xl->if_tree);
+ RB_INIT(&xl->pw_tree);
+ RB_INIT(&xl->pw_inactive_tree);
+ RB_INSERT(l2vpn_head, &xconf->l2vpn_tree, xl);
- LIST_FOREACH(lif, &l2vpn->if_list, entry) {
+ RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree) {
COPY(xf, lif);
xf->l2vpn = xl;
- LIST_INSERT_HEAD(&xl->if_list, xf, entry);
+ RB_INSERT(l2vpn_if_head, &xl->if_tree, xf);
}
- LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
COPY(xp, pw);
xp->l2vpn = xl;
- LIST_INSERT_HEAD(&xl->pw_list, xp, entry);
+ RB_INSERT(l2vpn_pw_head, &xl->pw_tree, xp);
}
- LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
COPY(xp, pw);
xp->l2vpn = xl;
- LIST_INSERT_HEAD(&xl->pw_inactive_list, xp, entry);
+ RB_INSERT(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
}
}
#undef COPY
@@ -1134,20 +1252,20 @@ ldp_clear_config(struct ldpd_conf *xconf)
struct nbr_params *nbrp;
struct l2vpn *l2vpn;
- while ((iface = LIST_FIRST(&xconf->iface_list)) != NULL) {
- LIST_REMOVE(iface, entry);
+ while ((iface = RB_ROOT(&xconf->iface_tree)) != NULL) {
+ RB_REMOVE(iface_head, &xconf->iface_tree, iface);
free(iface);
}
- while ((tnbr = LIST_FIRST(&xconf->tnbr_list)) != NULL) {
- LIST_REMOVE(tnbr, entry);
+ while ((tnbr = RB_ROOT(&xconf->tnbr_tree)) != NULL) {
+ RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
free(tnbr);
}
- while ((nbrp = LIST_FIRST(&xconf->nbrp_list)) != NULL) {
- LIST_REMOVE(nbrp, entry);
+ while ((nbrp = RB_ROOT(&xconf->nbrp_tree)) != NULL) {
+ RB_REMOVE(nbrp_head, &xconf->nbrp_tree, nbrp);
free(nbrp);
}
- while ((l2vpn = LIST_FIRST(&xconf->l2vpn_list)) != NULL) {
- LIST_REMOVE(l2vpn, entry);
+ while ((l2vpn = RB_ROOT(&xconf->l2vpn_tree)) != NULL) {
+ RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, l2vpn);
l2vpn_del(l2vpn);
}
@@ -1181,8 +1299,7 @@ merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
/* change of router-id requires resetting all neighborships */
if (conf->rtr_id.s_addr != xconf->rtr_id.s_addr) {
if (ldpd_process == PROC_LDP_ENGINE) {
- ldpe_reset_nbrs(AF_INET);
- ldpe_reset_nbrs(AF_INET6);
+ ldpe_reset_nbrs(AF_UNSPEC);
if (conf->rtr_id.s_addr == INADDR_ANY ||
xconf->rtr_id.s_addr == INADDR_ANY) {
if_update_all(AF_UNSPEC);
@@ -1215,61 +1332,98 @@ merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
static void
merge_af(int af, struct ldpd_af_conf *af_conf, struct ldpd_af_conf *xa)
{
- int egress_label_changed = 0;
- int update_sockets = 0;
-
+ int stop_init_backoff = 0;
+ int remove_dynamic_tnbrs = 0;
+ int change_egress_label = 0;
+ int reset_nbrs_ipv4 = 0;
+ int reset_nbrs = 0;
+ int update_sockets = 0;
+
+ /* update timers */
if (af_conf->keepalive != xa->keepalive) {
af_conf->keepalive = xa->keepalive;
- if (ldpd_process == PROC_LDP_ENGINE)
- ldpe_stop_init_backoff(af);
+ stop_init_backoff = 1;
}
-
af_conf->lhello_holdtime = xa->lhello_holdtime;
af_conf->lhello_interval = xa->lhello_interval;
af_conf->thello_holdtime = xa->thello_holdtime;
af_conf->thello_interval = xa->thello_interval;
/* update flags */
- if (ldpd_process == PROC_LDP_ENGINE &&
- (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) &&
+ if ((af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) &&
!(xa->flags & F_LDPD_AF_THELLO_ACCEPT))
- ldpe_remove_dynamic_tnbrs(af);
-
+ remove_dynamic_tnbrs = 1;
if ((af_conf->flags & F_LDPD_AF_NO_GTSM) !=
(xa->flags & F_LDPD_AF_NO_GTSM)) {
if (af == AF_INET6)
/* need to set/unset IPV6_MINHOPCOUNT */
update_sockets = 1;
- else if (ldpd_process == PROC_LDP_ENGINE)
+ else
/* for LDPv4 just resetting the neighbors is enough */
- ldpe_reset_nbrs(af);
+ reset_nbrs_ipv4 = 1;
}
-
if ((af_conf->flags & F_LDPD_AF_EXPNULL) !=
(xa->flags & F_LDPD_AF_EXPNULL))
- egress_label_changed = 1;
-
+ change_egress_label = 1;
af_conf->flags = xa->flags;
- if (egress_label_changed) {
- switch (ldpd_process) {
- case PROC_LDE_ENGINE:
- lde_change_egress_label(af, af_conf->flags &
- F_LDPD_AF_EXPNULL);
- break;
- default:
- break;
- }
- }
-
+ /* update the transport address */
if (ldp_addrcmp(af, &af_conf->trans_addr, &xa->trans_addr)) {
af_conf->trans_addr = xa->trans_addr;
update_sockets = 1;
}
- if (ldpd_process == PROC_MAIN && iev_ldpe && update_sockets)
- imsg_compose_event(iev_ldpe, IMSG_CLOSE_SOCKETS, af, 0, -1,
- NULL, 0);
+ /* update ACLs */
+ if (strcmp(af_conf->acl_label_advertise_to,
+ xa->acl_label_advertise_to) ||
+ strcmp(af_conf->acl_label_advertise_for,
+ xa->acl_label_advertise_for) ||
+ strcmp(af_conf->acl_label_accept_from,
+ xa->acl_label_accept_from) ||
+ strcmp(af_conf->acl_label_accept_for,
+ xa->acl_label_accept_for))
+ reset_nbrs = 1;
+ if (strcmp(af_conf->acl_thello_accept_from, xa->acl_thello_accept_from))
+ remove_dynamic_tnbrs = 1;
+ if (strcmp(af_conf->acl_label_expnull_for, xa->acl_label_expnull_for))
+ change_egress_label = 1;
+ strlcpy(af_conf->acl_thello_accept_from, xa->acl_thello_accept_from,
+ sizeof(af_conf->acl_thello_accept_from));
+ strlcpy(af_conf->acl_label_allocate_for, xa->acl_label_allocate_for,
+ sizeof(af_conf->acl_label_allocate_for));
+ strlcpy(af_conf->acl_label_advertise_to, xa->acl_label_advertise_to,
+ sizeof(af_conf->acl_label_advertise_to));
+ strlcpy(af_conf->acl_label_advertise_for, xa->acl_label_advertise_for,
+ sizeof(af_conf->acl_label_advertise_for));
+ strlcpy(af_conf->acl_label_accept_from, xa->acl_label_accept_from,
+ sizeof(af_conf->acl_label_accept_from));
+ strlcpy(af_conf->acl_label_accept_for, xa->acl_label_accept_for,
+ sizeof(af_conf->acl_label_accept_for));
+ strlcpy(af_conf->acl_label_expnull_for, xa->acl_label_expnull_for,
+ sizeof(af_conf->acl_label_expnull_for));
+
+ /* apply the new configuration */
+ switch (ldpd_process) {
+ case PROC_LDE_ENGINE:
+ if (change_egress_label)
+ lde_change_egress_label(af);
+ break;
+ case PROC_LDP_ENGINE:
+ if (stop_init_backoff)
+ ldpe_stop_init_backoff(af);
+ if (remove_dynamic_tnbrs)
+ ldpe_remove_dynamic_tnbrs(af);
+ if (reset_nbrs)
+ ldpe_reset_nbrs(AF_UNSPEC);
+ else if (reset_nbrs_ipv4)
+ ldpe_reset_nbrs(AF_INET);
+ break;
+ case PROC_MAIN:
+ if (update_sockets && iev_ldpe)
+ imsg_compose_event(iev_ldpe, IMSG_CLOSE_SOCKETS, af,
+ 0, -1, NULL, 0);
+ break;
+ }
}
static void
@@ -1277,10 +1431,10 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
{
struct iface *iface, *itmp, *xi;
- LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) {
+ RB_FOREACH_SAFE(iface, iface_head, &conf->iface_tree, itmp) {
/* find deleted interfaces */
if ((xi = if_lookup_name(xconf, iface->name)) == NULL) {
- LIST_REMOVE(iface, entry);
+ RB_REMOVE(iface_head, &conf->iface_tree, iface);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@@ -1295,11 +1449,11 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
free(iface);
}
}
- LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) {
+ RB_FOREACH_SAFE(xi, iface_head, &xconf->iface_tree, itmp) {
/* find new interfaces */
if ((iface = if_lookup_name(conf, xi->name)) == NULL) {
- LIST_REMOVE(xi, entry);
- LIST_INSERT_HEAD(&conf->iface_list, xi, entry);
+ RB_REMOVE(iface_head, &xconf->iface_tree, xi);
+ RB_INSERT(iface_head, &conf->iface_tree, xi);
if (ldpd_process == PROC_MAIN) {
QOBJ_REG (xi, iface);
@@ -1312,7 +1466,7 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
/* update existing interfaces */
merge_iface_af(&iface->ipv4, &xi->ipv4);
merge_iface_af(&iface->ipv6, &xi->ipv6);
- LIST_REMOVE(xi, entry);
+ RB_REMOVE(iface_head, &xconf->iface_tree, xi);
if (ref && *ref == xi)
*ref = iface;
free(xi);
@@ -1336,7 +1490,7 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
{
struct tnbr *tnbr, *ttmp, *xt;
- LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
+ RB_FOREACH_SAFE(tnbr, tnbr_head, &conf->tnbr_tree, ttmp) {
if (!(tnbr->flags & F_TNBR_CONFIGURED))
continue;
@@ -1344,26 +1498,26 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
if ((xt = tnbr_find(xconf, tnbr->af, &tnbr->addr)) == NULL) {
switch (ldpd_process) {
case PROC_LDE_ENGINE:
- LIST_REMOVE(tnbr, entry);
+ RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr);
break;
case PROC_LDP_ENGINE:
tnbr->flags &= ~F_TNBR_CONFIGURED;
- tnbr_check(tnbr);
+ tnbr_check(conf, tnbr);
break;
case PROC_MAIN:
- LIST_REMOVE(tnbr, entry);
+ RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
QOBJ_UNREG (tnbr);
free(tnbr);
break;
}
}
}
- LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) {
+ RB_FOREACH_SAFE(xt, tnbr_head, &xconf->tnbr_tree, ttmp) {
/* find new tnbrs */
if ((tnbr = tnbr_find(conf, xt->af, &xt->addr)) == NULL) {
- LIST_REMOVE(xt, entry);
- LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry);
+ RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt);
+ RB_INSERT(tnbr_head, &conf->tnbr_tree, xt);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@@ -1381,7 +1535,7 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
/* update existing tnbrs */
if (!(tnbr->flags & F_TNBR_CONFIGURED))
tnbr->flags |= F_TNBR_CONFIGURED;
- LIST_REMOVE(xt, entry);
+ RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt);
if (ref && *ref == xt)
*ref = tnbr;
free(xt);
@@ -1395,7 +1549,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
struct nbr *nbr;
int nbrp_changed;
- LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) {
+ RB_FOREACH_SAFE(nbrp, nbrp_head, &conf->nbrp_tree, ntmp) {
/* find deleted nbrps */
if ((xn = nbr_params_find(xconf, nbrp->lsr_id)) == NULL) {
switch (ldpd_process) {
@@ -1421,15 +1575,15 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
QOBJ_UNREG (nbrp);
break;
}
- LIST_REMOVE(nbrp, entry);
+ RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp);
}
}
- LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) {
+ RB_FOREACH_SAFE(xn, nbrp_head, &xconf->nbrp_tree, ntmp) {
/* find new nbrps */
if ((nbrp = nbr_params_find(conf, xn->lsr_id)) == NULL) {
- LIST_REMOVE(xn, entry);
- LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry);
+ RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn);
+ RB_INSERT(nbrp_head, &conf->nbrp_tree, xn);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@@ -1496,7 +1650,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
nbr_establish_connection(nbr);
}
}
- LIST_REMOVE(xn, entry);
+ RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn);
if (ref && *ref == xn)
*ref = nbrp;
free(xn);
@@ -1510,10 +1664,10 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
- LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) {
+ RB_FOREACH_SAFE(l2vpn, l2vpn_head, &conf->l2vpn_tree, ltmp) {
/* find deleted l2vpns */
if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) {
- LIST_REMOVE(l2vpn, entry);
+ RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@@ -1523,11 +1677,11 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
ldpe_l2vpn_exit(l2vpn);
break;
case PROC_MAIN:
- LIST_FOREACH(lif, &l2vpn->if_list, entry)
+ RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
QOBJ_UNREG (lif);
- LIST_FOREACH(pw, &l2vpn->pw_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
QOBJ_UNREG (pw);
- LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
+ RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
QOBJ_UNREG (pw);
QOBJ_UNREG (l2vpn);
break;
@@ -1535,11 +1689,11 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
l2vpn_del(l2vpn);
}
}
- LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) {
+ RB_FOREACH_SAFE(xl, l2vpn_head, &xconf->l2vpn_tree, ltmp) {
/* find new l2vpns */
if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
- LIST_REMOVE(xl, entry);
- LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry);
+ RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl);
+ RB_INSERT(l2vpn_head, &conf->l2vpn_tree, xl);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@@ -1557,7 +1711,7 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
/* update existing l2vpns */
merge_l2vpn(conf, l2vpn, xl, ref);
- LIST_REMOVE(xl, entry);
+ RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl);
if (ref && *ref == xl)
*ref = l2vpn;
free(xl);
@@ -1571,42 +1725,42 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
struct l2vpn_pw *pw, *ptmp, *xp;
struct nbr *nbr;
int reset_nbr, reinstall_pwfec, reinstall_tnbr;
- LIST_HEAD(, l2vpn_pw) pw_aux_list;
+ struct l2vpn_pw_head pw_aux_list;
int previous_pw_type, previous_mtu;
previous_pw_type = l2vpn->pw_type;
previous_mtu = l2vpn->mtu;
/* merge intefaces */
- LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) {
+ RB_FOREACH_SAFE(lif, l2vpn_if_head, &l2vpn->if_tree, ftmp) {
/* find deleted interfaces */
if ((xf = l2vpn_if_find_name(xl, lif->ifname)) == NULL) {
if (ldpd_process == PROC_MAIN)
QOBJ_UNREG (lif);
- LIST_REMOVE(lif, entry);
+ RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
}
}
- LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) {
+ RB_FOREACH_SAFE(xf, l2vpn_if_head, &xl->if_tree, ftmp) {
/* find new interfaces */
if ((lif = l2vpn_if_find_name(l2vpn, xf->ifname)) == NULL) {
- LIST_REMOVE(xf, entry);
- LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry);
+ RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf);
+ RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, xf);
xf->l2vpn = l2vpn;
if (ldpd_process == PROC_MAIN)
QOBJ_REG (xf, l2vpn_if);
continue;
}
- LIST_REMOVE(xf, entry);
+ RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf);
if (ref && *ref == xf)
*ref = lif;
free(xf);
}
/* merge active pseudowires */
- LIST_INIT(&pw_aux_list);
- LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) {
+ RB_INIT(&pw_aux_list);
+ RB_FOREACH_SAFE(pw, l2vpn_pw_head, &l2vpn->pw_tree, ptmp) {
/* find deleted active pseudowires */
if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) {
switch (ldpd_process) {
@@ -1621,15 +1775,15 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
break;
}
- LIST_REMOVE(pw, entry);
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw);
}
}
- LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) {
+ RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_tree, ptmp) {
/* find new active pseudowires */
if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) {
- LIST_REMOVE(xp, entry);
- LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
+ RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp);
+ RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, xp);
xp->l2vpn = l2vpn;
switch (ldpd_process) {
@@ -1685,8 +1839,8 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
}
/* remove from active list */
- LIST_REMOVE(pw, entry);
- LIST_INSERT_HEAD(&pw_aux_list, pw, entry);
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
+ RB_INSERT(l2vpn_pw_head, &pw_aux_list, pw);
}
if (ldpd_process == PROC_LDP_ENGINE) {
@@ -1730,27 +1884,27 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
l2vpn->mtu = previous_mtu;
}
- LIST_REMOVE(xp, entry);
+ RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp);
if (ref && *ref == xp)
*ref = pw;
free(xp);
}
/* merge inactive pseudowires */
- LIST_FOREACH_SAFE(pw, &l2vpn->pw_inactive_list, entry, ptmp) {
+ RB_FOREACH_SAFE(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree, ptmp) {
/* find deleted inactive pseudowires */
if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) {
- LIST_REMOVE(pw, entry);
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
if (ldpd_process == PROC_MAIN)
QOBJ_UNREG (pw);
free(pw);
}
}
- LIST_FOREACH_SAFE(xp, &xl->pw_inactive_list, entry, ptmp) {
+ RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_inactive_tree, ptmp) {
/* find new inactive pseudowires */
if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) {
- LIST_REMOVE(xp, entry);
- LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, xp, entry);
+ RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
+ RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, xp);
xp->l2vpn = l2vpn;
if (ldpd_process == PROC_MAIN)
QOBJ_REG (xp, l2vpn_pw);
@@ -1769,8 +1923,8 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
/* check if the pseudowire should be activated */
if (pw->lsr_id.s_addr != INADDR_ANY && pw->pwid != 0) {
/* remove from inactive list */
- LIST_REMOVE(pw, entry);
- LIST_INSERT_HEAD(&l2vpn->pw_list, pw, entry);
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
+ RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, pw);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@@ -1784,16 +1938,16 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
}
}
- LIST_REMOVE(xp, entry);
+ RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
if (ref && *ref == xp)
*ref = pw;
free(xp);
}
/* insert pseudowires that were disabled in the inactive list */
- LIST_FOREACH_SAFE(pw, &pw_aux_list, entry, ptmp) {
- LIST_REMOVE(pw, entry);
- LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry);
+ RB_FOREACH_SAFE(pw, l2vpn_pw_head, &pw_aux_list, ptmp) {
+ RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
+ RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
}
l2vpn->pw_type = xl->pw_type;
@@ -1811,10 +1965,10 @@ config_new_empty(void)
if (xconf == NULL)
fatal(NULL);
- LIST_INIT(&xconf->iface_list);
- LIST_INIT(&xconf->tnbr_list);
- LIST_INIT(&xconf->nbrp_list);
- LIST_INIT(&xconf->l2vpn_list);
+ RB_INIT(&xconf->iface_tree);
+ RB_INIT(&xconf->tnbr_tree);
+ RB_INIT(&xconf->nbrp_tree);
+ RB_INIT(&xconf->l2vpn_tree);
return (xconf);
}
diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h
index e58d8e4852..ff3af19db4 100644
--- a/ldpd/ldpd.h
+++ b/ldpd/ldpd.h
@@ -27,12 +27,16 @@
#include "imsg.h"
#include "thread.h"
#include "qobj.h"
+#include "filter.h"
#include "ldp.h"
#define CONF_FILE "/etc/ldpd.conf"
#define LDPD_USER "_ldpd"
+#define LDPD_FD_ASYNC 3
+#define LDPD_FD_SYNC 4
+
#define LDPD_OPT_VERBOSE 0x00000001
#define LDPD_OPT_VERBOSE2 0x00000002
#define LDPD_OPT_NOACTION 0x00000004
@@ -118,8 +122,7 @@ enum imsg_type {
IMSG_NEIGHBOR_UP,
IMSG_NEIGHBOR_DOWN,
IMSG_NETWORK_ADD,
- IMSG_NETWORK_ADD_END,
- IMSG_NETWORK_DEL,
+ IMSG_NETWORK_UPDATE,
IMSG_SOCKET_IPC,
IMSG_SOCKET_NET,
IMSG_CLOSE_SOCKETS,
@@ -135,7 +138,8 @@ enum imsg_type {
IMSG_RECONF_L2VPN_IPW,
IMSG_RECONF_END,
IMSG_DEBUG_UPDATE,
- IMSG_LOG
+ IMSG_LOG,
+ IMSG_ACL_CHECK
};
union ldpd_addr {
@@ -196,7 +200,10 @@ enum nbr_action {
NBR_ACT_CLOSE_SESSION
};
-TAILQ_HEAD(mapping_head, mapping_entry);
+/* forward declarations */
+RB_HEAD(global_adj_head, adj);
+RB_HEAD(nbr_adj_head, adj);
+RB_HEAD(ia_adj_head, adj);
struct map {
uint8_t type;
@@ -256,7 +263,7 @@ struct iface_af {
int af;
int enabled;
int state;
- LIST_HEAD(, adj) adj_list;
+ struct ia_adj_head adj_tree;
time_t uptime;
struct thread *hello_timer;
uint16_t hello_holdtime;
@@ -264,7 +271,7 @@ struct iface_af {
};
struct iface {
- LIST_ENTRY(iface) entry;
+ RB_ENTRY(iface) entry;
char name[IF_NAMESIZE];
unsigned int ifindex;
struct if_addr_head addr_list;
@@ -275,11 +282,13 @@ struct iface {
struct iface_af ipv6;
QOBJ_FIELDS
};
+RB_HEAD(iface_head, iface);
+RB_PROTOTYPE(iface_head, iface, entry, iface_compare);
DECLARE_QOBJ_TYPE(iface)
/* source of targeted hellos */
struct tnbr {
- LIST_ENTRY(tnbr) entry;
+ RB_ENTRY(tnbr) entry;
struct thread *hello_timer;
struct adj *adj;
int af;
@@ -289,6 +298,8 @@ struct tnbr {
uint8_t flags;
QOBJ_FIELDS
};
+RB_HEAD(tnbr_head, tnbr);
+RB_PROTOTYPE(tnbr_head, tnbr, entry, tnbr_compare);
DECLARE_QOBJ_TYPE(tnbr)
#define F_TNBR_CONFIGURED 0x01
#define F_TNBR_DYNAMIC 0x02
@@ -300,7 +311,7 @@ enum auth_method {
/* neighbor specific parameters */
struct nbr_params {
- LIST_ENTRY(nbr_params) entry;
+ RB_ENTRY(nbr_params) entry;
struct in_addr lsr_id;
uint16_t keepalive;
int gtsm_enabled;
@@ -313,23 +324,27 @@ struct nbr_params {
uint8_t flags;
QOBJ_FIELDS
};
+RB_HEAD(nbrp_head, nbr_params);
+RB_PROTOTYPE(nbrp_head, nbr_params, entry, nbr_params_compare);
DECLARE_QOBJ_TYPE(nbr_params)
#define F_NBRP_KEEPALIVE 0x01
#define F_NBRP_GTSM 0x02
#define F_NBRP_GTSM_HOPS 0x04
struct l2vpn_if {
- LIST_ENTRY(l2vpn_if) entry;
+ RB_ENTRY(l2vpn_if) entry;
struct l2vpn *l2vpn;
char ifname[IF_NAMESIZE];
unsigned int ifindex;
uint16_t flags;
QOBJ_FIELDS
};
+RB_HEAD(l2vpn_if_head, l2vpn_if);
+RB_PROTOTYPE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare);
DECLARE_QOBJ_TYPE(l2vpn_if)
struct l2vpn_pw {
- LIST_ENTRY(l2vpn_pw) entry;
+ RB_ENTRY(l2vpn_pw) entry;
struct l2vpn *l2vpn;
struct in_addr lsr_id;
int af;
@@ -343,6 +358,8 @@ struct l2vpn_pw {
uint8_t flags;
QOBJ_FIELDS
};
+RB_HEAD(l2vpn_pw_head, l2vpn_pw);
+RB_PROTOTYPE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare);
DECLARE_QOBJ_TYPE(l2vpn_pw)
#define F_PW_STATUSTLV_CONF 0x01 /* status tlv configured */
#define F_PW_STATUSTLV 0x02 /* status tlv negotiated */
@@ -352,18 +369,20 @@ DECLARE_QOBJ_TYPE(l2vpn_pw)
#define F_PW_STATIC_NBR_ADDR 0x20 /* static neighbor address configured */
struct l2vpn {
- LIST_ENTRY(l2vpn) entry;
+ RB_ENTRY(l2vpn) entry;
char name[L2VPN_NAME_LEN];
int type;
int pw_type;
int mtu;
char br_ifname[IF_NAMESIZE];
unsigned int br_ifindex;
- LIST_HEAD(, l2vpn_if) if_list;
- LIST_HEAD(, l2vpn_pw) pw_list;
- LIST_HEAD(, l2vpn_pw) pw_inactive_list;
+ struct l2vpn_if_head if_tree;
+ struct l2vpn_pw_head pw_tree;
+ struct l2vpn_pw_head pw_inactive_tree;
QOBJ_FIELDS
};
+RB_HEAD(l2vpn_head, l2vpn);
+RB_PROTOTYPE(l2vpn_head, l2vpn, entry, l2vpn_compare);
DECLARE_QOBJ_TYPE(l2vpn)
#define L2VPN_TYPE_VPWS 1
#define L2VPN_TYPE_VPLS 2
@@ -393,21 +412,29 @@ struct ldpd_af_conf {
uint16_t thello_holdtime;
uint16_t thello_interval;
union ldpd_addr trans_addr;
+ char acl_thello_accept_from[ACL_NAMSIZ];
+ char acl_label_allocate_for[ACL_NAMSIZ];
+ char acl_label_advertise_to[ACL_NAMSIZ];
+ char acl_label_advertise_for[ACL_NAMSIZ];
+ char acl_label_expnull_for[ACL_NAMSIZ];
+ char acl_label_accept_from[ACL_NAMSIZ];
+ char acl_label_accept_for[ACL_NAMSIZ];
int flags;
};
#define F_LDPD_AF_ENABLED 0x0001
#define F_LDPD_AF_THELLO_ACCEPT 0x0002
#define F_LDPD_AF_EXPNULL 0x0004
#define F_LDPD_AF_NO_GTSM 0x0008
+#define F_LDPD_AF_ALLOCHOSTONLY 0x0010
struct ldpd_conf {
struct in_addr rtr_id;
struct ldpd_af_conf ipv4;
struct ldpd_af_conf ipv6;
- LIST_HEAD(, iface) iface_list;
- LIST_HEAD(, tnbr) tnbr_list;
- LIST_HEAD(, nbr_params) nbrp_list;
- LIST_HEAD(, l2vpn) l2vpn_list;
+ struct iface_head iface_tree;
+ struct tnbr_head tnbr_tree;
+ struct nbrp_head nbrp_tree;
+ struct l2vpn_head l2vpn_tree;
uint16_t lhello_holdtime;
uint16_t lhello_interval;
uint16_t thello_holdtime;
@@ -438,7 +465,7 @@ struct ldpd_global {
uint32_t conf_seqnum;
int pfkeysock;
struct if_addr_head addr_list;
- LIST_HEAD(, adj) adj_list;
+ struct global_adj_head adj_tree;
struct in_addr mcast_addr_v4;
struct in6_addr mcast_addr_v6;
TAILQ_HEAD(, pending_conn) pending_conns;
@@ -482,6 +509,13 @@ struct kif {
int mtu;
};
+struct acl_check {
+ char acl[ACL_NAMSIZ];
+ int af;
+ union ldpd_addr addr;
+ uint8_t prefixlen;
+};
+
/* control data structures */
struct ctl_iface {
int af;
@@ -612,6 +646,9 @@ void evbuf_event_add(struct evbuf *);
void evbuf_init(struct evbuf *, int,
int (*)(struct thread *), void *);
void evbuf_clear(struct evbuf *);
+int ldp_acl_request(struct imsgev *, char *, int,
+ union ldpd_addr *, uint8_t);
+void ldp_acl_reply(struct imsgev *, struct acl_check *);
struct ldpd_af_conf *ldp_af_conf_get(struct ldpd_conf *, int);
struct ldpd_af_global *ldp_af_global_get(struct ldpd_global *, int);
int ldp_is_dual_stack(struct ldpd_conf *);
@@ -627,23 +664,28 @@ void config_clear(struct ldpd_conf *);
/* ldp_vty_conf.c */
/* NOTE: the parameters' names should be preserved because of codegen */
-struct iface *iface_new_api(struct ldpd_conf *cfg,
+struct iface *iface_new_api(struct ldpd_conf *conf,
const char *name);
-void iface_del_api(struct iface *iface);
-struct tnbr *tnbr_new_api(struct ldpd_conf *cfg, int af,
+void iface_del_api(struct ldpd_conf *conf,
+ struct iface *iface);
+struct tnbr *tnbr_new_api(struct ldpd_conf *conf, int af,
union ldpd_addr *addr);
-void tnbr_del_api(struct tnbr *tnbr);
-struct nbr_params *nbrp_new_api(struct ldpd_conf *cfg,
+void tnbr_del_api(struct ldpd_conf *conf, struct tnbr *tnbr);
+struct nbr_params *nbrp_new_api(struct ldpd_conf *conf,
struct in_addr lsr_id);
-void nbrp_del_api(struct nbr_params *nbrp);
-struct l2vpn *l2vpn_new_api(struct ldpd_conf *cfg, const char *name);
-void l2vpn_del_api(struct l2vpn *l2vpn);
+void nbrp_del_api(struct ldpd_conf *conf,
+ struct nbr_params *nbrp);
+struct l2vpn *l2vpn_new_api(struct ldpd_conf *conf, const char *name);
+void l2vpn_del_api(struct ldpd_conf *conf,
+ struct l2vpn *l2vpn);
struct l2vpn_if *l2vpn_if_new_api(struct ldpd_conf *conf,
struct l2vpn *l2vpn, const char *ifname);
-void l2vpn_if_del_api(struct l2vpn_if *lif);
+void l2vpn_if_del_api(struct l2vpn *l2vpn,
+ struct l2vpn_if *lif);
struct l2vpn_pw *l2vpn_pw_new_api(struct ldpd_conf *conf,
struct l2vpn *l2vpn, const char *ifname);
-void l2vpn_pw_del_api(struct l2vpn_pw *pw);
+void l2vpn_pw_del_api(struct l2vpn *l2vpn,
+ struct l2vpn_pw *pw);
/* socket.c */
int ldp_create_socket(int, enum socket_type);
@@ -675,7 +717,8 @@ extern struct thread_master *master;
extern char ctl_sock_path[MAXPATHLEN];
/* ldp_zebra.c */
-void ldp_zebra_init(struct thread_master *);
+void ldp_zebra_init(struct thread_master *);
+void ldp_zebra_destroy(void);
/* compatibility */
#ifndef __OpenBSD__
diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c
index 0d0fe5c9e9..7dcc8fbe16 100644
--- a/ldpd/ldpe.c
+++ b/ldpd/ldpe.c
@@ -48,7 +48,7 @@ struct ldpd_conf *leconf;
struct ldpd_sysdep sysdep;
#endif
-static struct imsgev *iev_main;
+static struct imsgev *iev_main, *iev_main_sync;
static struct imsgev *iev_lde;
#ifdef __OpenBSD__
static struct thread *pfkey_ev;
@@ -111,7 +111,7 @@ ldpe(const char *user, const char *group, const char *ctl_path)
ldpd_process = PROC_LDP_ENGINE;
LIST_INIT(&global.addr_list);
- LIST_INIT(&global.adj_list);
+ RB_INIT(&global.adj_tree);
TAILQ_INIT(&global.pending_conns);
if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
fatal("inet_pton");
@@ -143,15 +143,18 @@ ldpe(const char *user, const char *group, const char *ctl_path)
/* setup signal handler */
signal_init(master, array_size(ldpe_signals), ldpe_signals);
- /* setup pipe and event handler to the parent process */
- if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
+ /* setup pipes and event handlers to the parent process */
+ if ((iev_main = calloc(1, sizeof(struct imsgev))) == NULL)
fatal(NULL);
- imsg_init(&iev_main->ibuf, 3);
+ imsg_init(&iev_main->ibuf, LDPD_FD_ASYNC);
iev_main->handler_read = ldpe_dispatch_main;
iev_main->ev_read = thread_add_read(master, iev_main->handler_read,
iev_main, iev_main->ibuf.fd);
iev_main->handler_write = ldp_write_handler;
- iev_main->ev_write = NULL;
+
+ if ((iev_main_sync = calloc(1, sizeof(struct imsgev))) == NULL)
+ fatal(NULL);
+ imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
#ifdef __OpenBSD__
if (sysdep.no_pfkey == 0)
@@ -192,6 +195,8 @@ ldpe_shutdown(void)
msgbuf_write(&iev_main->ibuf.w);
msgbuf_clear(&iev_main->ibuf.w);
close(iev_main->ibuf.fd);
+ msgbuf_clear(&iev_main_sync->ibuf.w);
+ close(iev_main_sync->ibuf.fd);
control_cleanup();
config_clear(leconf);
@@ -210,12 +215,13 @@ ldpe_shutdown(void)
LIST_REMOVE(if_addr, entry);
free(if_addr);
}
- while ((adj = LIST_FIRST(&global.adj_list)) != NULL)
+ while ((adj = RB_ROOT(&global.adj_tree)) != NULL)
adj_del(adj, S_SHUTDOWN);
/* clean up */
free(iev_lde);
free(iev_main);
+ free(iev_main_sync);
free(pkt_ptr);
log_info("ldp engine exiting");
@@ -403,8 +409,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(&global.rtr_id, imsg.data,
sizeof(global.rtr_id));
if (leconf->rtr_id.s_addr == INADDR_ANY) {
- ldpe_reset_nbrs(AF_INET);
- ldpe_reset_nbrs(AF_INET6);
+ ldpe_reset_nbrs(AF_UNSPEC);
}
if_update_all(AF_UNSPEC);
tnbr_update_all(AF_UNSPEC);
@@ -415,10 +420,10 @@ ldpe_dispatch_main(struct thread *thread)
fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
- LIST_INIT(&nconf->iface_list);
- LIST_INIT(&nconf->tnbr_list);
- LIST_INIT(&nconf->nbrp_list);
- LIST_INIT(&nconf->l2vpn_list);
+ RB_INIT(&nconf->iface_tree);
+ RB_INIT(&nconf->tnbr_tree);
+ RB_INIT(&nconf->nbrp_tree);
+ RB_INIT(&nconf->l2vpn_tree);
break;
case IMSG_RECONF_IFACE:
if ((niface = malloc(sizeof(struct iface))) == NULL)
@@ -426,37 +431,37 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(niface, imsg.data, sizeof(struct iface));
LIST_INIT(&niface->addr_list);
- LIST_INIT(&niface->ipv4.adj_list);
- LIST_INIT(&niface->ipv6.adj_list);
+ RB_INIT(&niface->ipv4.adj_tree);
+ RB_INIT(&niface->ipv6.adj_tree);
niface->ipv4.iface = niface;
niface->ipv6.iface = niface;
- LIST_INSERT_HEAD(&nconf->iface_list, niface, entry);
+ RB_INSERT(iface_head, &nconf->iface_tree, niface);
break;
case IMSG_RECONF_TNBR:
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
fatal(NULL);
memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
- LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry);
+ RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
break;
case IMSG_RECONF_NBRP:
if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
fatal(NULL);
memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
- LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry);
+ RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
break;
case IMSG_RECONF_L2VPN:
if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
fatal(NULL);
memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
- LIST_INIT(&nl2vpn->if_list);
- LIST_INIT(&nl2vpn->pw_list);
- LIST_INIT(&nl2vpn->pw_inactive_list);
+ RB_INIT(&nl2vpn->if_tree);
+ RB_INIT(&nl2vpn->pw_tree);
+ RB_INIT(&nl2vpn->pw_inactive_tree);
- LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry);
+ RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
break;
case IMSG_RECONF_L2VPN_IF:
if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
@@ -464,7 +469,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
nlif->l2vpn = nl2vpn;
- LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry);
+ RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
break;
case IMSG_RECONF_L2VPN_PW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@@ -472,7 +477,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn;
- LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry);
+ RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
break;
case IMSG_RECONF_L2VPN_IPW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@@ -480,7 +485,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn;
- LIST_INSERT_HEAD(&nl2vpn->pw_inactive_list, npw, entry);
+ RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
break;
case IMSG_RECONF_END:
merge_config(leconf, nconf);
@@ -717,13 +722,19 @@ ldpe_close_sockets(int af)
}
}
+int
+ldpe_acl_check(char *acl_name, int af, union ldpd_addr *addr, uint8_t prefixlen)
+{
+ return ldp_acl_request(iev_main_sync, acl_name, af, addr, prefixlen);
+}
+
void
ldpe_reset_nbrs(int af)
{
struct nbr *nbr;
RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
- if (nbr->af == af)
+ if (af == AF_UNSPEC || nbr->af == af)
session_shutdown(nbr, S_SHUTDOWN, 0, 0);
}
}
@@ -744,12 +755,12 @@ ldpe_remove_dynamic_tnbrs(int af)
{
struct tnbr *tnbr, *safe;
- LIST_FOREACH_SAFE(tnbr, &leconf->tnbr_list, entry, safe) {
+ RB_FOREACH_SAFE(tnbr, tnbr_head, &leconf->tnbr_tree, safe) {
if (tnbr->af != af)
continue;
tnbr->flags &= ~F_TNBR_DYNAMIC;
- tnbr_check(tnbr);
+ tnbr_check(leconf, tnbr);
}
}
@@ -773,7 +784,7 @@ ldpe_iface_af_ctl(struct ctl_conn *c, int af, unsigned int idx)
struct iface_af *ia;
struct ctl_iface *ictl;
- LIST_FOREACH(iface, &leconf->iface_list, entry) {
+ RB_FOREACH(iface, iface_head, &leconf->iface_tree) {
if (idx == 0 || idx == iface->ifindex) {
ia = iface_af_get(iface, af);
if (!ia->enabled)
@@ -806,7 +817,7 @@ ldpe_adj_ctl(struct ctl_conn *c)
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0);
- LIST_FOREACH(iface, &leconf->iface_list, entry) {
+ RB_FOREACH(iface, iface_head, &leconf->iface_tree) {
memset(&ictl, 0, sizeof(ictl));
ictl.active_v4 = (iface->ipv4.state == IF_STA_ACTIVE);
ictl.active_v6 = (iface->ipv6.state == IF_STA_ACTIVE);
@@ -815,25 +826,25 @@ ldpe_adj_ctl(struct ctl_conn *c)
continue;
strlcpy(ictl.name, iface->name, sizeof(ictl.name));
- if (LIST_EMPTY(&iface->ipv4.adj_list) &&
- LIST_EMPTY(&iface->ipv6.adj_list))
+ if (RB_EMPTY(&iface->ipv4.adj_tree) &&
+ RB_EMPTY(&iface->ipv6.adj_tree))
ictl.no_adj = 1;
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_IFACE, 0, 0,
-1, &ictl, sizeof(ictl));
- LIST_FOREACH(adj, &iface->ipv4.adj_list, ia_entry) {
+ RB_FOREACH(adj, ia_adj_head, &iface->ipv4.adj_tree) {
actl = adj_to_ctl(adj);
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ,
0, 0, -1, actl, sizeof(struct ctl_adj));
}
- LIST_FOREACH(adj, &iface->ipv6.adj_list, ia_entry) {
+ RB_FOREACH(adj, ia_adj_head, &iface->ipv6.adj_tree) {
actl = adj_to_ctl(adj);
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ,
0, 0, -1, actl, sizeof(struct ctl_adj));
}
}
- LIST_FOREACH(tnbr, &leconf->tnbr_list, entry) {
+ RB_FOREACH(tnbr, tnbr_head, &leconf->tnbr_tree) {
memset(&tctl, 0, sizeof(tctl));
tctl.af = tnbr->af;
tctl.addr = tnbr->addr;
@@ -870,7 +881,7 @@ ldpe_nbr_ctl(struct ctl_conn *c)
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl,
sizeof(struct ctl_nbr));
- LIST_FOREACH(adj, &nbr->adj_list, nbr_entry) {
+ RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree) {
actl = adj_to_ctl(adj);
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR_DISC,
0, 0, -1, actl, sizeof(struct ctl_adj));
diff --git a/ldpd/ldpe.h b/ldpd/ldpe.h
index da90c7cad7..052439df88 100644
--- a/ldpd/ldpe.h
+++ b/ldpd/ldpe.h
@@ -32,6 +32,9 @@
#define min(x,y) ((x) <= (y) ? (x) : (y))
#define max(x,y) ((x) > (y) ? (x) : (y))
+/* forward declarations */
+TAILQ_HEAD(mapping_head, mapping_entry);
+
struct hello_source {
enum hello_type type;
struct {
@@ -42,9 +45,7 @@ struct hello_source {
};
struct adj {
- LIST_ENTRY(adj) global_entry;
- LIST_ENTRY(adj) nbr_entry;
- LIST_ENTRY(adj) ia_entry;
+ RB_ENTRY(adj) global_entry, nbr_entry, ia_entry;
struct in_addr lsr_id;
struct nbr *nbr;
int ds_tlv;
@@ -53,6 +54,9 @@ struct adj {
uint16_t holdtime;
union ldpd_addr trans_addr;
};
+RB_PROTOTYPE(global_adj_head, adj, global_entry, adj_compare)
+RB_PROTOTYPE(nbr_adj_head, adj, nbr_entry, adj_compare)
+RB_PROTOTYPE(ia_adj_head, adj, ia_entry, adj_compare)
struct tcp_conn {
struct nbr *nbr;
@@ -67,7 +71,7 @@ struct tcp_conn {
struct nbr {
RB_ENTRY(nbr) id_tree, addr_tree, pid_tree;
struct tcp_conn *tcp;
- LIST_HEAD(, adj) adj_list; /* adjacencies */
+ struct nbr_adj_head adj_tree; /* adjacencies */
struct thread *ev_connect;
struct thread *keepalive_timer;
struct thread *keepalive_timeout;
@@ -188,6 +192,7 @@ int ldpe_imsg_compose_parent(int, pid_t, void *,
uint16_t);
int ldpe_imsg_compose_lde(int, uint32_t, pid_t, void *,
uint16_t);
+int ldpe_acl_check(char *, int, union ldpd_addr *, uint8_t);
void ldpe_reset_nbrs(int);
void ldpe_reset_ds_nbrs(void);
void ldpe_remove_dynamic_tnbrs(int);
@@ -225,7 +230,7 @@ void adj_start_itimer(struct adj *);
void adj_stop_itimer(struct adj *);
struct tnbr *tnbr_new(int, union ldpd_addr *);
struct tnbr *tnbr_find(struct ldpd_conf *, int, union ldpd_addr *);
-struct tnbr *tnbr_check(struct tnbr *);
+struct tnbr *tnbr_check(struct ldpd_conf *, struct tnbr *);
void tnbr_update(struct tnbr *);
void tnbr_update_all(int);
uint16_t tnbr_get_hello_holdtime(struct tnbr *);
diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c
index 8376a01549..d24ceb1229 100644
--- a/ldpd/neighbor.c
+++ b/ldpd/neighbor.c
@@ -39,10 +39,13 @@ static void nbr_start_itimeout(struct nbr *);
static int nbr_idtimer(struct thread *);
static int nbr_act_session_operational(struct nbr *);
static void nbr_send_labelmappings(struct nbr *);
+static __inline int nbr_params_compare(struct nbr_params *,
+ struct nbr_params *);
RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare)
RB_GENERATE(nbr_addr_head, nbr, addr_tree, nbr_addr_compare)
RB_GENERATE(nbr_pid_head, nbr, pid_tree, nbr_pid_compare)
+RB_GENERATE(nbrp_head, nbr_params, entry, nbr_params_compare)
struct {
int state;
@@ -226,7 +229,7 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
if ((nbr = calloc(1, sizeof(*nbr))) == NULL)
fatal(__func__);
- LIST_INIT(&nbr->adj_list);
+ RB_INIT(&nbr->adj_tree);
nbr->state = NBR_STA_PRESENT;
nbr->peerid = 0;
nbr->af = af;
@@ -241,10 +244,10 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
nbr->raddr_scope = scope_id;
nbr->conf_seqnum = 0;
- LIST_FOREACH(adj, &global.adj_list, global_entry) {
+ RB_FOREACH(adj, global_adj_head, &global.adj_tree) {
if (adj->lsr_id.s_addr == nbr->id.s_addr) {
adj->nbr = nbr;
- LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry);
+ RB_INSERT(nbr_adj_head, &nbr->adj_tree, adj);
}
}
@@ -363,7 +366,7 @@ nbr_adj_count(struct nbr *nbr, int af)
struct adj *adj;
int total = 0;
- LIST_FOREACH(adj, &nbr->adj_list, nbr_entry)
+ RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree)
if (adj_get_af(adj) == af)
total++;
@@ -621,7 +624,7 @@ nbr_establish_connection(struct nbr *nbr)
* Send an extra hello to guarantee that the remote peer has formed
* an adjacency as well.
*/
- LIST_FOREACH(adj, &nbr->adj_list, nbr_entry)
+ RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree)
send_hello(adj->source.type, adj->source.link.ia,
adj->source.target);
@@ -752,6 +755,12 @@ nbr_send_labelmappings(struct nbr *nbr)
NULL, 0);
}
+static __inline int
+nbr_params_compare(struct nbr_params *a, struct nbr_params *b)
+{
+ return (ntohl(a->lsr_id.s_addr) - ntohl(b->lsr_id.s_addr));
+}
+
struct nbr_params *
nbr_params_new(struct in_addr lsr_id)
{
@@ -769,13 +778,9 @@ nbr_params_new(struct in_addr lsr_id)
struct nbr_params *
nbr_params_find(struct ldpd_conf *xconf, struct in_addr lsr_id)
{
- struct nbr_params *nbrp;
-
- LIST_FOREACH(nbrp, &xconf->nbrp_list, entry)
- if (nbrp->lsr_id.s_addr == lsr_id.s_addr)
- return (nbrp);
-
- return (NULL);
+ struct nbr_params nbrp;
+ nbrp.lsr_id = lsr_id;
+ return (RB_FIND(nbrp_head, &xconf->nbrp_tree, &nbrp));
}
uint16_t
diff --git a/ldpd/packet.c b/ldpd/packet.c
index 9b3151d720..b085cac055 100644
--- a/ldpd/packet.c
+++ b/ldpd/packet.c
@@ -285,53 +285,24 @@ disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
{
struct iface *iface;
struct iface_af *ia;
- struct if_addr *if_addr;
- in_addr_t mask;
iface = if_lookup(leconf, ifindex);
if (iface == NULL)
return (NULL);
+ ia = iface_af_get(iface, af);
+ if (!ia->enabled)
+ return (NULL);
+
/*
- * For unicast packets, we just need to make sure that the interface
- * is enabled for the given address-family.
+ * RFC 7552 - Section 5.1:
+ * "Link-local IPv6 address MUST be used as the source IP address in
+ * IPv6 LDP Link Hellos".
*/
- if (!multicast) {
- ia = iface_af_get(iface, af);
- if (ia->enabled)
- return (iface);
+ if (multicast && af == AF_INET6 && !IN6_IS_ADDR_LINKLOCAL(&src->v6))
return (NULL);
- }
- switch (af) {
- case AF_INET:
- LIST_FOREACH(if_addr, &iface->addr_list, entry) {
- if (if_addr->af != AF_INET)
- continue;
-
- switch (iface->type) {
- case IF_TYPE_POINTOPOINT:
- if (if_addr->dstbrd.v4.s_addr == src->v4.s_addr)
- return (iface);
- break;
- default:
- mask = prefixlen2mask(if_addr->prefixlen);
- if ((if_addr->addr.v4.s_addr & mask) ==
- (src->v4.s_addr & mask))
- return (iface);
- break;
- }
- }
- break;
- case AF_INET6:
- if (IN6_IS_ADDR_LINKLOCAL(&src->v6))
- return (iface);
- break;
- default:
- fatalx("disc_find_iface: unknown af");
- }
-
- return (NULL);
+ return (iface);
}
int
@@ -715,8 +686,8 @@ struct tcp_conn *
tcp_new(int fd, struct nbr *nbr)
{
struct tcp_conn *tcp;
- struct sockaddr_storage src;
- socklen_t len = sizeof(src);
+ struct sockaddr_storage ss;
+ socklen_t len = sizeof(ss);
if ((tcp = calloc(1, sizeof(*tcp))) == NULL)
fatal(__func__);
@@ -732,10 +703,14 @@ tcp_new(int fd, struct nbr *nbr)
tcp->nbr = nbr;
}
- getsockname(fd, (struct sockaddr *)&src, &len);
- sa2addr((struct sockaddr *)&src, NULL, NULL, &tcp->lport);
- getpeername(fd, (struct sockaddr *)&src, &len);
- sa2addr((struct sockaddr *)&src, NULL, NULL, &tcp->rport);
+ if (getsockname(fd, (struct sockaddr *)&ss, &len) != 0)
+ log_warn("%s: getsockname", __func__);
+ else
+ sa2addr((struct sockaddr *)&ss, NULL, NULL, &tcp->lport);
+ if (getpeername(fd, (struct sockaddr *)&ss, &len) != 0)
+ log_warn("%s: getpeername", __func__);
+ else
+ sa2addr((struct sockaddr *)&ss, NULL, NULL, &tcp->rport);
return (tcp);
}
diff --git a/ldpd/socket.c b/ldpd/socket.c
index 1bb0837401..eaea9973a0 100644
--- a/ldpd/socket.c
+++ b/ldpd/socket.c
@@ -85,6 +85,8 @@ ldp_create_socket(int af, enum socket_type type)
if (ldpd_privs.change(ZPRIVS_RAISE))
log_warn("%s: could not raise privs", __func__);
if (sock_set_reuse(fd, 1) == -1) {
+ if (ldpd_privs.change(ZPRIVS_LOWER))
+ log_warn("%s: could not lower privs", __func__);
close(fd);
return (-1);
}
diff --git a/lib/.gitignore b/lib/.gitignore
index fe75137bca..10b8704ab2 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -15,4 +15,10 @@ gitversion.h.tmp
*~
*.loT
route_types.h
+memtypes.h
+command_lex.c
+command_lex.h
+command_parse.c
+command_parse.h
refix
+grammar_sandbox
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f393836cc0..780d4bc1b8 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,34 +1,45 @@
## Process this file with automake to produce Makefile.in.
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \
- -DVTY_DEPRECATE_INDEX
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
AM_CFLAGS = $(WERROR)
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
+AM_YFLAGS = -d -Dapi.prefix=@BISON_OPENBRACE@cmd_yy@BISON_CLOSEBRACE@ @BISON_VERBOSE@
+
+command_lex.h: command_lex.c
+ @if test ! -f $@; then rm -f command_lex.c; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) command_lex.c; else :; fi
+command_parse.lo: command_lex.h
lib_LTLIBRARIES = libfrr.la
libfrr_la_LDFLAGS = -version-info 0:0:0
libfrr_la_SOURCES = \
network.c pid_output.c getopt.c getopt1.c \
- checksum.c vector.c linklist.c vty.c command.c \
+ checksum.c vector.c linklist.c vty.c \
+ graph.c command_parse.y command_lex.l command_match.c \
+ command.c \
sockunion.c prefix.c thread.c if.c buffer.c table.c hash.c \
filter.c routemap.c distribute.c stream.c log.c plist.c \
zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \
sigevent.c pqueue.c jhash.c workqueue.c nexthop.c json.c \
ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c memory.c memory_vty.c \
imsg-buffer.c imsg.c skiplist.c \
- qobj.c \
+ qobj.c wheel.c \
event_counter.c \
+ grammar_sandbox.c \
+ srcdest_table.c \
strlcpy.c \
strlcat.c
-BUILT_SOURCES = route_types.h gitversion.h
+BUILT_SOURCES = route_types.h gitversion.h command_parse.h command_lex.h
libfrr_la_LIBADD = @LIBCAP@
pkginclude_HEADERS = \
- buffer.h checksum.h command.h filter.h getopt.h hash.h \
+ buffer.h checksum.h filter.h getopt.h hash.h \
if.h linklist.h log.h \
+ graph.h command_match.h \
+ command.h \
memory.h network.h prefix.h routemap.h distribute.h sockunion.h \
stream.h table.h thread.h vector.h version.h vty.h zebra.h \
plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \
@@ -36,14 +47,22 @@ pkginclude_HEADERS = \
workqueue.h route_types.h libospf.h nexthop.h json.h \
ptm_lib.h csv.h bfd.h vrf.h ns.h systemd.h bitfield.h \
fifo.h memory_vty.h mpls.h imsg.h openbsd-queue.h openbsd-tree.h \
- skiplist.h qobj.h \
- event_counter.h
+ skiplist.h qobj.h wheel.h \
+ event_counter.h \
+ monotime.h \
+ srcdest_table.h
noinst_HEADERS = \
plist_int.h
+noinst_PROGRAMS = grammar_sandbox
+
+grammar_sandbox_SOURCES = grammar_sandbox_main.c
+grammar_sandbox_LDADD = libfrr.la
+
EXTRA_DIST = \
queue.h \
+ command_lex.h \
route_types.pl route_types.txt \
gitversion.pl
@@ -64,7 +83,7 @@ GITH=gitversion.h
gitversion.h.tmp: $(srcdir)/../.git
@PERL@ $(srcdir)/gitversion.pl $(srcdir) > ${GITH}.tmp
gitversion.h: gitversion.h.tmp
- { test -f ${GITH} && diff -s -q ${GITH}.tmp ${GITH}; } || cp -v ${GITH}.tmp ${GITH}
+ { test -f ${GITH} && diff -s -q ${GITH}.tmp ${GITH}; } || cp -v ${GITH}.tmp ${GITH}
else
.PHONY: gitversion.h
diff --git a/lib/bfd.c b/lib/bfd.c
index a498daf762..a5edaea217 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -179,11 +179,9 @@ bfd_peer_sendmsg (struct zclient *zclient, struct bfd_info *bfd_info,
case AF_INET:
stream_put_in_addr (s, (struct in_addr *)dst_ip);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
stream_put(s, dst_ip, 16);
break;
-#endif
default:
break;
}
@@ -207,11 +205,9 @@ bfd_peer_sendmsg (struct zclient *zclient, struct bfd_info *bfd_info,
case AF_INET:
stream_put_in_addr (s, (struct in_addr *) src_ip);
break;
- #ifdef HAVE_IPV6
case AF_INET6:
stream_put(s, src_ip, 16);
break;
- #endif
default:
break;
}
@@ -221,13 +217,11 @@ bfd_peer_sendmsg (struct zclient *zclient, struct bfd_info *bfd_info,
else
{
stream_putc(s, 0);
-#ifdef HAVE_IPV6
if ((family == AF_INET6) && (src_ip))
{
stream_putw(s, family);
stream_put(s, src_ip, 16);
}
-#endif
if (if_name)
{
len = strlen(if_name);
@@ -368,7 +362,7 @@ bfd_last_update (time_t last_update, char *buf, size_t len)
}
/* Get current time. */
- quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv);
+ monotime(&tv);
curr = tv.tv_sec;
diff = curr - last_update;
tm = gmtime (&diff);
diff --git a/lib/bfd.h b/lib/bfd.h
index bbe96b07b4..e636e4426f 100644
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -26,11 +26,6 @@
#include "lib/json.h"
-#define BFD_CMD_DETECT_MULT_RANGE "<2-255> "
-#define BFD_CMD_MIN_RX_RANGE "<50-60000> "
-#define BFD_CMD_MIN_TX_RANGE "<50-60000>"
-#define BFD_CMD_TYPE "(multihop|singlehop)"
-
#define BFD_DEF_MIN_RX 300
#define BFD_MIN_MIN_RX 50
#define BFD_MAX_MIN_RX 60000
diff --git a/lib/command.c b/lib/command.c
index 6176640bf6..4a84386858 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -1,25 +1,29 @@
/*
- Command interpreter routine for virtual terminal [aka TeletYpe]
- Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
- Copyright (C) 2013 by Open Source Routing.
- Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
-
-This file is part of GNU Zebra.
-
-GNU Zebra is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published
-by the Free Software Foundation; either version 2, or (at your
-option) any later version.
-
-GNU Zebra is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Zebra; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ * CLI backend interface.
+ *
+ * --
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
+ * Copyright (C) 2013 by Open Source Routing.
+ * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
#include <zebra.h>
@@ -29,58 +33,25 @@ Boston, MA 02111-1307, USA. */
#include <lib/version.h>
#include "thread.h"
#include "vector.h"
+#include "linklist.h"
#include "vty.h"
#include "command.h"
#include "workqueue.h"
#include "vrf.h"
+#include "command_match.h"
#include "qobj.h"
DEFINE_MTYPE( LIB, HOST, "Host config")
DEFINE_MTYPE( LIB, STRVEC, "String vector")
-DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc")
+DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens")
+DEFINE_MTYPE_STATIC(LIB, CMD_DESC, "Command Token Text")
+DEFINE_MTYPE_STATIC(LIB, CMD_TEXT, "Command Token Help")
+DEFINE_MTYPE( LIB, CMD_ARG, "Command Argument")
/* Command vector which includes some level of command lists. Normally
each daemon maintains each own cmdvec. */
vector cmdvec = NULL;
-struct cmd_token token_cr;
-char *command_cr = NULL;
-
-/**
- * Filter types. These tell the parser whether to allow
- * partial matching on tokens.
- */
-enum filter_type
-{
- FILTER_RELAXED,
- FILTER_STRICT
-};
-
-/**
- * Command matcher result value.
- */
-enum matcher_rv
-{
- MATCHER_OK,
- MATCHER_COMPLETE,
- MATCHER_INCOMPLETE,
- MATCHER_NO_MATCH,
- MATCHER_AMBIGUOUS,
- MATCHER_EXCEED_ARGC_MAX
-};
-
-/**
- * Defines which matcher_rv values constitute
- * an error. Should be used against matcher_rv
- * return values to do basic error checking.
- */
-#define MATCHER_ERROR(matcher_rv) \
- ( (matcher_rv) == MATCHER_INCOMPLETE \
- || (matcher_rv) == MATCHER_NO_MATCH \
- || (matcher_rv) == MATCHER_AMBIGUOUS \
- || (matcher_rv) == MATCHER_EXCEED_ARGC_MAX \
- )
-
/* Host information structure. */
struct host host;
@@ -123,7 +94,7 @@ static const struct facility_map {
int facility;
const char *name;
size_t match;
-} syslog_facilities[] =
+} syslog_facilities[] =
{
{ LOG_KERN, "kern", 1 },
{ LOG_USER, "user", 2 },
@@ -175,7 +146,7 @@ static int
level_match(const char *s)
{
int level ;
-
+
for ( level = 0 ; zlog_priority [level] != NULL ; level ++ )
if (!strncmp (s, zlog_priority[level], 2))
return level;
@@ -195,7 +166,7 @@ print_version (const char *progname)
/* Utility function to concatenate argv argument into a single string
with inserting ' ' character between each argument. */
char *
-argv_concat (const char **argv, int argc, int shift)
+argv_concat (struct cmd_token **argv, int argc, int shift)
{
int i;
size_t len;
@@ -204,14 +175,14 @@ argv_concat (const char **argv, int argc, int shift)
len = 0;
for (i = shift; i < argc; i++)
- len += strlen(argv[i])+1;
+ len += strlen(argv[i]->arg)+1;
if (!len)
return NULL;
p = str = XMALLOC(MTYPE_TMP, len);
for (i = shift; i < argc; i++)
{
size_t arglen;
- memcpy(p, argv[i], (arglen = strlen(argv[i])));
+ memcpy(p, argv[i]->arg, (arglen = strlen(argv[i]->arg)));
p += arglen;
*p++ = ' ';
}
@@ -219,6 +190,26 @@ argv_concat (const char **argv, int argc, int shift)
return str;
}
+/**
+ * Convenience function for accessing argv data.
+ *
+ * @param argc
+ * @param argv
+ * @param text definition snippet of the desired token
+ * @param index the starting index, and where to store the
+ * index of the found token if it exists
+ * @return 1 if found, 0 otherwise
+ */
+int
+argv_find (struct cmd_token **argv, int argc, const char *text, int *index)
+{
+ int found = 0;
+ for (int i = *index; i < argc && found == 0; i++)
+ if ((found = strmatch (text, argv[i]->text)))
+ *index = i;
+ return found;
+}
+
static unsigned int
cmd_hash_key (void *p)
{
@@ -233,65 +224,57 @@ cmd_hash_cmp (const void *a, const void *b)
/* Install top node of command vector. */
void
-install_node (struct cmd_node *node,
- int (*func) (struct vty *))
+install_node (struct cmd_node *node,
+ int (*func) (struct vty *))
{
vector_set_index (cmdvec, node->node, node);
node->func = func;
+ node->cmdgraph = graph_new ();
node->cmd_vector = vector_init (VECTOR_MIN_SIZE);
+ // add start node
+ struct cmd_token *token = new_cmd_token (START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ graph_new_node (node->cmdgraph, token, (void (*)(void *)) &del_cmd_token);
node->cmd_hash = hash_create (cmd_hash_key, cmd_hash_cmp);
}
-/* Breaking up string into each command piece. I assume given
- character is separated by a space character. Return value is a
- vector which includes char ** data element. */
+/**
+ * Tokenizes a string, storing tokens in a vector.
+ * Whitespace is ignored.
+ *
+ * Delimiter string = " \n\r\t".
+ *
+ * @param string to tokenize
+ * @return tokenized string
+ */
vector
cmd_make_strvec (const char *string)
{
- const char *cp, *start;
- char *token;
- int strlen;
- vector strvec;
-
- if (string == NULL)
- return NULL;
-
- cp = string;
+ if (!string) return NULL;
- /* Skip white spaces. */
- while (isspace ((int) *cp) && *cp != '\0')
- cp++;
+ char *copy, *copystart;
+ copystart = copy = XSTRDUP (MTYPE_TMP, string);
- /* Return if there is only white spaces */
- if (*cp == '\0')
- return NULL;
+ // skip leading whitespace
+ while (isspace ((int) *copy) && *copy != '\0') copy++;
- if (*cp == '!' || *cp == '#')
+ // if the entire string was whitespace or a comment, return
+ if (*copy == '\0' || *copy == '!' || *copy == '#')
+ {
+ XFREE (MTYPE_TMP, copystart);
return NULL;
+ }
- /* Prepare return vector. */
- strvec = vector_init (VECTOR_MIN_SIZE);
+ vector strvec = vector_init (VECTOR_MIN_SIZE);
+ const char *delim = " \n\r\t", *tok = NULL;
+ while (copy)
+ {
+ tok = strsep (&copy, delim);
+ if (*tok != '\0')
+ vector_set (strvec, XSTRDUP (MTYPE_STRVEC, tok));
+ }
- /* Copy each command piece and set into vector. */
- while (1)
- {
- start = cp;
- while (!(isspace ((int) *cp) || *cp == '\r' || *cp == '\n') &&
- *cp != '\0')
- cp++;
- strlen = cp - start;
- token = XMALLOC (MTYPE_STRVEC, strlen + 1);
- memcpy (token, start, strlen);
- *(token + strlen) = '\0';
- vector_set (strvec, token);
-
- while ((isspace ((int) *cp) || *cp == '\n' || *cp == '\r') &&
- *cp != '\0')
- cp++;
-
- if (*cp == '\0')
- return strvec;
- }
+ XFREE (MTYPE_TMP, copystart);
+ return strvec;
}
/* Free allocated string vector. */
@@ -311,389 +294,6 @@ cmd_free_strvec (vector v)
vector_free (v);
}
-/**
- * State structure for command format parser. Tracks
- * parse tree position and miscellaneous state variables.
- * Used when building a command vector from format strings.
- */
-struct format_parser_state
-{
- vector topvect; /* Top level vector */
- vector intvect; /* Intermediate level vector, used when there's
- a multiple in a keyword. */
- vector curvect; /* current vector where read tokens should be
- appended. */
-
- const char *string; /* pointer to command string, not modified */
- const char *cp; /* pointer in command string, moved along while
- parsing */
- const char *dp; /* pointer in description string, moved along while
- parsing */
-
- int in_keyword; /* flag to remember if we are in a keyword group */
- int in_multiple; /* flag to remember if we are in a multiple group */
- int just_read_word; /* flag to remember if the last thing we read was a
- real word and not some abstract token */
-};
-
-static void
-format_parser_error(struct format_parser_state *state, const char *message)
-{
- int offset = state->cp - state->string + 1;
-
- fprintf(stderr, "\nError parsing command: \"%s\"\n", state->string);
- fprintf(stderr, " %*c\n", offset, '^');
- fprintf(stderr, "%s at offset %d.\n", message, offset);
- fprintf(stderr, "This is a programming error. Check your DEFUNs etc.\n");
- exit(1);
-}
-
-/**
- * Reads out one section of a help string from state->dp.
- * Leading whitespace is trimmed and the string is read until
- * a newline is reached.
- *
- * @param[out] state format parser state
- * @return the help string token read
- */
-static char *
-format_parser_desc_str(struct format_parser_state *state)
-{
- const char *cp, *start;
- char *token;
- int strlen;
-
- cp = state->dp;
-
- if (cp == NULL)
- return NULL;
-
- /* Skip white spaces. */
- while (isspace ((int) *cp) && *cp != '\0')
- cp++;
-
- /* Return if there is only white spaces */
- if (*cp == '\0')
- return NULL;
-
- start = cp;
-
- while (!(*cp == '\r' || *cp == '\n') && *cp != '\0')
- cp++;
-
- strlen = cp - start;
- token = XMALLOC (MTYPE_CMD_TOKENS, strlen + 1);
- memcpy (token, start, strlen);
- *(token + strlen) = '\0';
-
- state->dp = cp;
-
- return token;
-}
-
-/**
- * Transitions format parser state into keyword parsing mode.
- * A cmd_token struct, `token`, representing this keyword token is initialized
- * and appended to state->curvect. token->keyword is initialized as a vector of
- * vector, a new vector is initialized and added to token->keyword, and
- * state->curvect is set to point at this vector. When control returns to the
- * caller newly parsed tokens will be added to this vector.
- *
- * In short:
- * state->curvect[HEAD] = new cmd_token
- * state->curvect[HEAD]->keyword[0] = new vector
- * state->curvect = state->curvect[HEAD]->keyword[0]
- *
- * @param[out] state state struct to transition
- */
-static void
-format_parser_begin_keyword(struct format_parser_state *state)
-{
- struct cmd_token *token;
- vector keyword_vect;
-
- if (state->in_keyword
- || state->in_multiple)
- format_parser_error(state, "Unexpected '{'");
-
- state->cp++;
- state->in_keyword = 1;
-
- token = XCALLOC(MTYPE_CMD_TOKENS, sizeof(*token));
- token->type = TOKEN_KEYWORD;
- token->keyword = vector_init(VECTOR_MIN_SIZE);
-
- keyword_vect = vector_init(VECTOR_MIN_SIZE);
- vector_set(token->keyword, keyword_vect);
-
- vector_set(state->curvect, token);
- state->curvect = keyword_vect;
-}
-
-/**
- * Transitions format parser state into multiple parsing mode.
- * A cmd_token struct, `token`, representing this multiple token is initialized
- * and appended to state->curvect. token->multiple is initialized as a vector
- * of cmd_token and state->curvect is set to point at token->multiple. If
- * state->curvect != state->topvect (i.e. this multiple token is nested inside
- * another composite token) then a pointer to state->curvect is saved in
- * state->intvect.
- *
- * In short:
- * state->curvect[HEAD] = new cmd_token
- * state->curvect[HEAD]->multiple = new vector
- * state->intvect = state->curvect IFF nested token
- * state->curvect = state->curvect[HEAD]->multiple
- *
- * @param[out] state state struct to transition
- */
-static void
-format_parser_begin_multiple(struct format_parser_state *state)
-{
- struct cmd_token *token;
-
- if (state->in_keyword == 1)
- format_parser_error(state, "Keyword starting with '('");
-
- if (state->in_multiple)
- format_parser_error(state, "Nested group");
-
- state->cp++;
- state->in_multiple = 1;
- state->just_read_word = 0;
-
- token = XCALLOC(MTYPE_CMD_TOKENS, sizeof(*token));
- token->type = TOKEN_MULTIPLE;
- token->multiple = vector_init(VECTOR_MIN_SIZE);
-
- vector_set(state->curvect, token);
- if (state->curvect != state->topvect)
- state->intvect = state->curvect;
- state->curvect = token->multiple;
-}
-
-/**
- * Transition format parser state out of keyword parsing mode.
- * This function is called upon encountering '}'.
- * state->curvect is reassigned to the top level vector (as
- * keywords cannot be nested) and state flags are set appropriately.
- *
- * @param[out] state state struct to transition
- */
-static void
-format_parser_end_keyword(struct format_parser_state *state)
-{
- if (state->in_multiple
- || !state->in_keyword)
- format_parser_error(state, "Unexpected '}'");
-
- if (state->in_keyword == 1)
- format_parser_error(state, "Empty keyword group");
-
- state->cp++;
- state->in_keyword = 0;
- state->curvect = state->topvect;
-}
-
-/**
- * Transition format parser state out of multiple parsing mode.
- * This function is called upon encountering ')'.
- * state->curvect is reassigned to its parent vector (state->intvect
- * if the multiple token being exited was nested inside another token,
- * state->topvect otherwise) and state flags are set appropriately.
- *
- * @param[out] state state struct to transition
- */
-static void
-format_parser_end_multiple(struct format_parser_state *state)
-{
- char *dummy;
-
- if (!state->in_multiple)
- format_parser_error(state, "Unexpected ')'");
-
- if (vector_active(state->curvect) == 0)
- format_parser_error(state, "Empty multiple section");
-
- if (!state->just_read_word)
- {
- /* There are constructions like
- * 'show ip ospf database ... (self-originate|)'
- * in use.
- * The old parser reads a description string for the
- * word '' between |) which will never match.
- * Simulate this behvaior by dropping the next desc
- * string in such a case. */
-
- dummy = format_parser_desc_str(state);
- XFREE(MTYPE_CMD_TOKENS, dummy);
- }
-
- state->cp++;
- state->in_multiple = 0;
-
- if (state->intvect)
- state->curvect = state->intvect;
- else
- state->curvect = state->topvect;
-}
-
-/**
- * Format parser handler for pipe '|' character.
- * This character separates subtokens in multiple and keyword type tokens.
- * If the current token is a multiple keyword, the position pointer is
- * simply moved past the pipe and state flags are set appropriately.
- * If the current token is a keyword token, the position pointer is moved
- * past the pipe. Then the cmd_token struct for the keyword is fetched and
- * a new vector of cmd_token is appended to its vector of vector. Finally
- * state->curvect is set to point at this new vector.
- *
- * In short:
- * state->curvect = state->topvect[HEAD]->keyword[HEAD] = new vector
- *
- * @param[out] state state struct to transition
- */
-static void
-format_parser_handle_pipe(struct format_parser_state *state)
-{
- struct cmd_token *keyword_token;
- vector keyword_vect;
-
- if (state->in_multiple)
- {
- state->just_read_word = 0;
- state->cp++;
- }
- else if (state->in_keyword)
- {
- state->in_keyword = 1;
- state->cp++;
-
- keyword_token = vector_slot(state->topvect,
- vector_active(state->topvect) - 1);
- keyword_vect = vector_init(VECTOR_MIN_SIZE);
- vector_set(keyword_token->keyword, keyword_vect);
- state->curvect = keyword_vect;
- }
- else
- {
- format_parser_error(state, "Unexpected '|'");
- }
-}
-
-/**
- * Format parser handler for terminal tokens.
- * Parses the token, appends it to state->curvect, and sets
- * state flags appropriately.
- *
- * @param[out] state state struct for current format parser state
- */
-static void
-format_parser_read_word(struct format_parser_state *state)
-{
- const char *start;
- int len;
- char *cmd;
- struct cmd_token *token;
-
- start = state->cp;
-
- while (state->cp[0] != '\0'
- && !strchr("\r\n(){}|", state->cp[0])
- && !isspace((int)state->cp[0]))
- state->cp++;
-
- len = state->cp - start;
- cmd = XMALLOC(MTYPE_CMD_TOKENS, len + 1);
- memcpy(cmd, start, len);
- cmd[len] = '\0';
-
- token = XCALLOC(MTYPE_CMD_TOKENS, sizeof(*token));
- token->type = TOKEN_TERMINAL;
- if (strcmp (cmd, "A.B.C.D") == 0)
- token->terminal = TERMINAL_IPV4;
- else if (strcmp (cmd, "A.B.C.D/M") == 0)
- token->terminal = TERMINAL_IPV4_PREFIX;
- else if (strcmp (cmd, "X:X::X:X") == 0)
- token->terminal = TERMINAL_IPV6;
- else if (strcmp (cmd, "X:X::X:X/M") == 0)
- token->terminal = TERMINAL_IPV6_PREFIX;
- else if (cmd[0] == '[')
- token->terminal = TERMINAL_OPTION;
- else if (cmd[0] == '.')
- token->terminal = TERMINAL_VARARG;
- else if (cmd[0] == '<')
- token->terminal = TERMINAL_RANGE;
- else if (cmd[0] >= 'A' && cmd[0] <= 'Z')
- token->terminal = TERMINAL_VARIABLE;
- else
- token->terminal = TERMINAL_LITERAL;
-
- token->cmd = cmd;
- token->desc = format_parser_desc_str(state);
- vector_set(state->curvect, token);
-
- if (state->in_keyword == 1)
- state->in_keyword = 2;
-
- state->just_read_word = 1;
-}
-
-/**
- * Parse a given command format string and build a tree of tokens from
- * it that is suitable to be used by the command subsystem.
- *
- * @param string Command format string.
- * @param descstr Description string.
- * @return A vector of struct cmd_token representing the given command,
- * or NULL on error.
- */
-static vector
-cmd_parse_format(const char *string, const char *descstr)
-{
- struct format_parser_state state;
-
- if (string == NULL)
- return NULL;
-
- memset(&state, 0, sizeof(state));
- state.topvect = state.curvect = vector_init(VECTOR_MIN_SIZE);
- state.cp = state.string = string;
- state.dp = descstr;
-
- while (1)
- {
- while (isspace((int)state.cp[0]) && state.cp[0] != '\0')
- state.cp++;
-
- switch (state.cp[0])
- {
- case '\0':
- if (state.in_keyword
- || state.in_multiple)
- format_parser_error(&state, "Unclosed group/keyword");
- return state.topvect;
- case '{':
- format_parser_begin_keyword(&state);
- break;
- case '(':
- format_parser_begin_multiple(&state);
- break;
- case '}':
- format_parser_end_keyword(&state);
- break;
- case ')':
- format_parser_end_multiple(&state);
- break;
- case '|':
- format_parser_handle_pipe(&state);
- break;
- default:
- format_parser_read_word(&state);
- }
- }
-}
-
/* Return prompt character of specified node. */
const char *
cmd_prompt (enum node_type node)
@@ -709,7 +309,7 @@ void
install_element (enum node_type ntype, struct cmd_element *cmd)
{
struct cmd_node *cnode;
-
+
/* cmd_init hasn't been called */
if (!cmdvec)
{
@@ -717,29 +317,28 @@ install_element (enum node_type ntype, struct cmd_element *cmd)
__func__);
return;
}
-
+
cnode = vector_slot (cmdvec, ntype);
- if (cnode == NULL)
+ if (cnode == NULL)
{
fprintf (stderr, "Command node %d doesn't exist, please check it\n",
- ntype);
- exit (1);
+ ntype);
+ exit (EXIT_FAILURE);
}
-
+
if (hash_lookup (cnode->cmd_hash, cmd) != NULL)
{
- fprintf (stderr,
+ fprintf (stderr,
"Multiple command installs to node %d of command:\n%s\n",
ntype, cmd->string);
return;
}
-
+
assert (hash_get (cnode->cmd_hash, cmd, hash_alloc_intern));
-
+
+ command_parse_format (cnode->cmdgraph, cmd);
vector_set (cnode->cmd_vector, cmd);
- if (cmd->tokens == NULL)
- cmd->tokens = cmd_parse_format(cmd->string, cmd->doc);
if (ntype == VIEW_NODE)
install_element (ENABLE_NODE, cmd);
@@ -751,7 +350,7 @@ static const unsigned char itoa64[] =
static void
to64(char *s, long v, int n)
{
- while (--n >= 0)
+ while (--n >= 0)
{
*s++ = itoa64[v&0x3f];
v >>= 6;
@@ -766,7 +365,7 @@ zencrypt (const char *passwd)
char *crypt (const char *, const char *);
gettimeofday(&tv,0);
-
+
to64(&salt[0], random(), 3);
to64(&salt[3], tv.tv_usec, 3);
salt[5] = '\0';
@@ -784,9 +383,9 @@ config_write_host (struct vty *vty)
if (host.encrypt)
{
if (host.password_encrypt)
- vty_out (vty, "password 8 %s%s", host.password_encrypt, VTY_NEWLINE);
+ vty_out (vty, "password 8 %s%s", host.password_encrypt, VTY_NEWLINE);
if (host.enable_encrypt)
- vty_out (vty, "enable password 8 %s%s", host.enable_encrypt, VTY_NEWLINE);
+ vty_out (vty, "enable password 8 %s%s", host.enable_encrypt, VTY_NEWLINE);
}
else
{
@@ -799,17 +398,17 @@ config_write_host (struct vty *vty)
if (zlog_default->default_lvl != LOG_DEBUG)
{
vty_out (vty, "! N.B. The 'log trap' command is deprecated.%s",
- VTY_NEWLINE);
+ VTY_NEWLINE);
vty_out (vty, "log trap %s%s",
- zlog_priority[zlog_default->default_lvl], VTY_NEWLINE);
+ zlog_priority[zlog_default->default_lvl], VTY_NEWLINE);
}
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, " %s",
+ zlog_priority[zlog_default->maxlvl[ZLOG_DEST_FILE]]);
vty_out (vty, "%s", VTY_NEWLINE);
}
@@ -817,8 +416,8 @@ config_write_host (struct vty *vty)
{
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, " %s",
+ zlog_priority[zlog_default->maxlvl[ZLOG_DEST_STDOUT]]);
vty_out (vty, "%s", VTY_NEWLINE);
}
@@ -826,27 +425,27 @@ config_write_host (struct vty *vty)
vty_out(vty,"no log monitor%s",VTY_NEWLINE);
else if (zlog_default->maxlvl[ZLOG_DEST_MONITOR] != zlog_default->default_lvl)
vty_out(vty,"log monitor %s%s",
- zlog_priority[zlog_default->maxlvl[ZLOG_DEST_MONITOR]],VTY_NEWLINE);
+ zlog_priority[zlog_default->maxlvl[ZLOG_DEST_MONITOR]],VTY_NEWLINE);
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, " %s",
+ zlog_priority[zlog_default->maxlvl[ZLOG_DEST_SYSLOG]]);
vty_out (vty, "%s", VTY_NEWLINE);
}
if (zlog_default->facility != LOG_DAEMON)
vty_out (vty, "log facility %s%s",
- facility_name(zlog_default->facility), VTY_NEWLINE);
+ facility_name(zlog_default->facility), VTY_NEWLINE);
if (zlog_default->record_priority == 1)
vty_out (vty, "log record-priority%s", VTY_NEWLINE);
if (zlog_default->timestamp_precision > 0)
vty_out (vty, "log timestamp precision %d%s",
- zlog_default->timestamp_precision, VTY_NEWLINE);
+ zlog_default->timestamp_precision, VTY_NEWLINE);
if (host.advanced)
vty_out (vty, "service advanced-vty%s", VTY_NEWLINE);
@@ -856,7 +455,7 @@ config_write_host (struct vty *vty)
if (host.lines >= 0)
vty_out (vty, "service terminal-length %d%s", host.lines,
- VTY_NEWLINE);
+ VTY_NEWLINE);
if (host.motdfile)
vty_out (vty, "banner motd file %s%s", host.motdfile, VTY_NEWLINE);
@@ -866,1382 +465,132 @@ config_write_host (struct vty *vty)
return 1;
}
-/* Utility function for getting command vector. */
-static vector
-cmd_node_vector (vector v, enum node_type ntype)
+/* Utility function for getting command graph. */
+static struct graph *
+cmd_node_graph (vector v, enum node_type ntype)
{
struct cmd_node *cnode = vector_slot (v, ntype);
- return cnode->cmd_vector;
+ return cnode->cmdgraph;
}
-/* Completion match types. */
-enum match_type
-{
- no_match,
- extend_match,
- ipv4_prefix_match,
- ipv4_match,
- ipv6_prefix_match,
- ipv6_match,
- range_match,
- vararg_match,
- partly_match,
- exact_match
-};
-
-static enum match_type
-cmd_ipv4_match (const char *str)
-{
- const char *sp;
- int dots = 0, nums = 0;
- char buf[4];
-
- if (str == NULL)
- return partly_match;
-
- for (;;)
- {
- memset (buf, 0, sizeof (buf));
- sp = str;
- while (*str != '\0')
- {
- if (*str == '.')
- {
- if (dots >= 3)
- return no_match;
-
- if (*(str + 1) == '.')
- return no_match;
-
- if (*(str + 1) == '\0')
- return partly_match;
-
- dots++;
- break;
- }
- if (!isdigit ((int) *str))
- return no_match;
-
- str++;
- }
-
- if (str - sp > 3)
- return no_match;
-
- strncpy (buf, sp, str - sp);
- if (atoi (buf) > 255)
- return no_match;
-
- nums++;
-
- if (*str == '\0')
- break;
-
- str++;
- }
-
- if (nums < 4)
- return partly_match;
-
- return exact_match;
-}
-
-static enum match_type
-cmd_ipv4_prefix_match (const char *str)
-{
- const char *sp;
- int dots = 0;
- char buf[4];
-
- if (str == NULL)
- return partly_match;
-
- for (;;)
- {
- memset (buf, 0, sizeof (buf));
- sp = str;
- while (*str != '\0' && *str != '/')
- {
- if (*str == '.')
- {
- if (dots == 3)
- return no_match;
-
- if (*(str + 1) == '.' || *(str + 1) == '/')
- return no_match;
-
- if (*(str + 1) == '\0')
- return partly_match;
-
- dots++;
- break;
- }
-
- if (!isdigit ((int) *str))
- return no_match;
-
- str++;
- }
-
- if (str - sp > 3)
- return no_match;
-
- strncpy (buf, sp, str - sp);
- if (atoi (buf) > 255)
- return no_match;
-
- if (dots == 3)
- {
- if (*str == '/')
- {
- if (*(str + 1) == '\0')
- return partly_match;
-
- str++;
- break;
- }
- else if (*str == '\0')
- return partly_match;
- }
-
- if (*str == '\0')
- return partly_match;
-
- str++;
- }
-
- sp = str;
- while (*str != '\0')
- {
- if (!isdigit ((int) *str))
- return no_match;
-
- str++;
- }
-
- if (atoi (sp) > 32)
- return no_match;
-
- return exact_match;
-}
-
-#define IPV6_ADDR_STR "0123456789abcdefABCDEF:."
-#define IPV6_PREFIX_STR "0123456789abcdefABCDEF:./"
-
-#ifdef HAVE_IPV6
-
-static enum match_type
-cmd_ipv6_match (const char *str)
-{
- struct sockaddr_in6 sin6_dummy;
- int ret;
-
- if (str == NULL)
- return partly_match;
-
- if (strspn (str, IPV6_ADDR_STR) != strlen (str))
- return no_match;
-
- /* use inet_pton that has a better support,
- * for example inet_pton can support the automatic addresses:
- * ::1.2.3.4
- */
- ret = inet_pton(AF_INET6, str, &sin6_dummy.sin6_addr);
-
- if (ret == 1)
- return exact_match;
-
- return no_match;
-}
-
-static enum match_type
-cmd_ipv6_prefix_match (const char *str)
-{
- struct sockaddr_in6 sin6_dummy;
- const char *delim = "/\0";
- char *dupe, *prefix, *mask, *context, *endptr;
- int nmask = -1;
- enum match_type ret;
-
- if (str == NULL)
- return partly_match;
-
- if (strspn (str, IPV6_PREFIX_STR) != strlen (str))
- return no_match;
-
- /* tokenize to address + mask */
- dupe = XMALLOC(MTYPE_TMP, strlen(str)+1);
- strncpy(dupe, str, strlen(str)+1);
- prefix = strtok_r(dupe, delim, &context);
- mask = strtok_r(NULL, delim, &context);
-
- ret = exact_match;
- if (!mask)
- ret = partly_match;
- else
- {
- /* validate prefix */
- if (inet_pton(AF_INET6, prefix, &sin6_dummy.sin6_addr) != 1)
- ret = no_match;
- else
- {
- /* validate mask */
- nmask = strtol (mask, &endptr, 10);
- if (*endptr != '\0' || nmask < 0 || nmask > 128)
- ret = no_match;
- }
- }
-
- XFREE(MTYPE_TMP, dupe);
-
- return ret;
-}
-
-#endif /* HAVE_IPV6 */
-
-#define DECIMAL_STRLEN_MAX 20
-
static int
-cmd_range_match (const char *range, const char *str)
-{
- char *p;
- char buf[DECIMAL_STRLEN_MAX + 1];
- char *endptr = NULL;
- signed long long min, max, val;
-
- if (str == NULL)
+cmd_try_do_shortcut (enum node_type node, char* first_word) {
+ if ( first_word != NULL &&
+ node != AUTH_NODE &&
+ node != VIEW_NODE &&
+ node != AUTH_ENABLE_NODE &&
+ node != ENABLE_NODE &&
+ 0 == strcmp( "do", first_word ) )
return 1;
-
- val = strtoll (str, &endptr, 10);
- if (*endptr != '\0')
- return 0;
- val = llabs(val);
-
- range++;
- p = strchr (range, '-');
- if (p == NULL)
- return 0;
- if (p - range > DECIMAL_STRLEN_MAX)
- return 0;
- strncpy (buf, range, p - range);
- buf[p - range] = '\0';
- min = strtoll (buf, &endptr, 10);
- if (*endptr != '\0')
- return 0;
-
- range = p + 1;
- p = strchr (range, '>');
- if (p == NULL)
- return 0;
- if (p - range > DECIMAL_STRLEN_MAX)
- return 0;
- strncpy (buf, range, p - range);
- buf[p - range] = '\0';
- max = strtoll (buf, &endptr, 10);
- if (*endptr != '\0')
- return 0;
-
- if (val < min || val > max)
- return 0;
-
- return 1;
-}
-
-static enum match_type
-cmd_word_match(struct cmd_token *token,
- enum filter_type filter,
- const char *word)
-{
- const char *str;
- enum match_type match_type;
-
- str = token->cmd;
-
- if (filter == FILTER_RELAXED)
- if (!word || !strlen(word))
- return partly_match;
-
- if (!word)
- return no_match;
-
- switch (token->terminal)
- {
- case TERMINAL_VARARG:
- return vararg_match;
-
- case TERMINAL_RANGE:
- if (cmd_range_match(str, word))
- return range_match;
- break;
-
- case TERMINAL_IPV6:
- match_type = cmd_ipv6_match(word);
- if ((filter == FILTER_RELAXED && match_type != no_match)
- || (filter == FILTER_STRICT && match_type == exact_match))
- return ipv6_match;
- break;
-
- case TERMINAL_IPV6_PREFIX:
- match_type = cmd_ipv6_prefix_match(word);
- if ((filter == FILTER_RELAXED && match_type != no_match)
- || (filter == FILTER_STRICT && match_type == exact_match))
- return ipv6_prefix_match;
- break;
-
- case TERMINAL_IPV4:
- match_type = cmd_ipv4_match(word);
- if ((filter == FILTER_RELAXED && match_type != no_match)
- || (filter == FILTER_STRICT && match_type == exact_match))
- return ipv4_match;
- break;
-
- case TERMINAL_IPV4_PREFIX:
- match_type = cmd_ipv4_prefix_match(word);
- if ((filter == FILTER_RELAXED && match_type != no_match)
- || (filter == FILTER_STRICT && match_type == exact_match))
- return ipv4_prefix_match;
- break;
-
- case TERMINAL_OPTION:
- case TERMINAL_VARIABLE:
- return extend_match;
-
- case TERMINAL_LITERAL:
- if (filter == FILTER_RELAXED && !strncmp(str, word, strlen(word)))
- {
- if (!strcmp(str, word))
- return exact_match;
- return partly_match;
- }
- if (filter == FILTER_STRICT && !strcmp(str, word))
- return exact_match;
- break;
-
- default:
- assert (0);
- }
-
- return no_match;
-}
-
-struct cmd_matcher
-{
- struct cmd_element *cmd; /* The command element the matcher is using */
- enum filter_type filter; /* Whether to use strict or relaxed matching */
- vector vline; /* The tokenized commandline which is to be matched */
- unsigned int index; /* The index up to which matching should be done */
-
- /* If set, construct a list of matches at the position given by index */
- enum match_type *match_type;
- vector *match;
-
- unsigned int word_index; /* iterating over vline */
-};
-
-static int
-push_argument(int *argc, const char **argv, const char *arg)
-{
- if (!arg || !strlen(arg))
- arg = NULL;
-
- if (!argc || !argv)
- return 0;
-
- if (*argc >= CMD_ARGC_MAX)
- return -1;
-
- argv[(*argc)++] = arg;
return 0;
}
-static void
-cmd_matcher_record_match(struct cmd_matcher *matcher,
- enum match_type match_type,
- struct cmd_token *token)
-{
- if (matcher->word_index != matcher->index)
- return;
-
- if (matcher->match)
- {
- if (!*matcher->match)
- *matcher->match = vector_init(VECTOR_MIN_SIZE);
- vector_set(*matcher->match, token);
- }
-
- if (matcher->match_type)
- {
- if (match_type > *matcher->match_type)
- *matcher->match_type = match_type;
- }
-}
-
-static int
-cmd_matcher_words_left(struct cmd_matcher *matcher)
-{
- return matcher->word_index < vector_active(matcher->vline);
-}
-
-static const char*
-cmd_matcher_get_word(struct cmd_matcher *matcher)
-{
- assert(cmd_matcher_words_left(matcher));
-
- return vector_slot(matcher->vline, matcher->word_index);
-}
-
-static enum matcher_rv
-cmd_matcher_match_terminal(struct cmd_matcher *matcher,
- struct cmd_token *token,
- int *argc, const char **argv)
-{
- const char *word;
- enum match_type word_match;
-
- assert(token->type == TOKEN_TERMINAL);
-
- if (!cmd_matcher_words_left(matcher))
- {
- if (token->terminal == TERMINAL_OPTION)
- return MATCHER_OK; /* missing optional args are NOT pushed as NULL */
- else
- return MATCHER_INCOMPLETE;
- }
-
- word = cmd_matcher_get_word(matcher);
- word_match = cmd_word_match(token, matcher->filter, word);
- if (word_match == no_match)
- return MATCHER_NO_MATCH;
-
- /* We have to record the input word as argument if it matched
- * against a variable. */
- if (TERMINAL_RECORD (token->terminal))
- {
- if (push_argument(argc, argv, word))
- return MATCHER_EXCEED_ARGC_MAX;
- }
-
- cmd_matcher_record_match(matcher, word_match, token);
-
- matcher->word_index++;
-
- /* A vararg token should consume all left over words as arguments */
- if (token->terminal == TERMINAL_VARARG)
- while (cmd_matcher_words_left(matcher))
- {
- word = cmd_matcher_get_word(matcher);
- if (word && strlen(word))
- push_argument(argc, argv, word);
- matcher->word_index++;
- }
-
- return MATCHER_OK;
-}
-
-static enum matcher_rv
-cmd_matcher_match_multiple(struct cmd_matcher *matcher,
- struct cmd_token *token,
- int *argc, const char **argv)
-{
- enum match_type multiple_match;
- unsigned int multiple_index;
- const char *word;
- const char *arg = NULL;
- struct cmd_token *word_token;
- enum match_type word_match;
-
- assert(token->type == TOKEN_MULTIPLE);
-
- multiple_match = no_match;
-
- if (!cmd_matcher_words_left(matcher))
- return MATCHER_INCOMPLETE;
-
- word = cmd_matcher_get_word(matcher);
- for (multiple_index = 0;
- multiple_index < vector_active(token->multiple);
- multiple_index++)
- {
- word_token = vector_slot(token->multiple, multiple_index);
-
- word_match = cmd_word_match(word_token, matcher->filter, word);
- if (word_match == no_match)
- continue;
-
- cmd_matcher_record_match(matcher, word_match, word_token);
-
- if (word_match > multiple_match)
- {
- multiple_match = word_match;
- arg = word;
- }
- /* To mimic the behavior of the old command implementation, we
- * tolerate any ambiguities here :/ */
- }
-
- matcher->word_index++;
-
- if (multiple_match == no_match)
- return MATCHER_NO_MATCH;
-
- if (push_argument(argc, argv, arg))
- return MATCHER_EXCEED_ARGC_MAX;
-
- return MATCHER_OK;
-}
-
-static enum matcher_rv
-cmd_matcher_read_keywords(struct cmd_matcher *matcher,
- struct cmd_token *token,
- vector args_vector)
-{
- unsigned int i;
- unsigned long keyword_mask;
- unsigned int keyword_found;
- enum match_type keyword_match;
- enum match_type word_match;
- vector keyword_vector;
- struct cmd_token *word_token;
- const char *word;
- int keyword_argc;
- const char **keyword_argv;
- enum matcher_rv rv = MATCHER_OK;
-
- keyword_mask = 0;
- while (1)
- {
- if (!cmd_matcher_words_left(matcher))
- return MATCHER_OK;
-
- word = cmd_matcher_get_word(matcher);
-
- keyword_found = -1;
- keyword_match = no_match;
- for (i = 0; i < vector_active(token->keyword); i++)
- {
- if (keyword_mask & (1 << i))
- continue;
-
- keyword_vector = vector_slot(token->keyword, i);
- word_token = vector_slot(keyword_vector, 0);
-
- word_match = cmd_word_match(word_token, matcher->filter, word);
- if (word_match == no_match)
- continue;
-
- cmd_matcher_record_match(matcher, word_match, word_token);
-
- if (word_match > keyword_match)
- {
- keyword_match = word_match;
- keyword_found = i;
- }
- else if (word_match == keyword_match)
- {
- if (matcher->word_index != matcher->index || args_vector)
- return MATCHER_AMBIGUOUS;
- }
- }
-
- if (keyword_found == (unsigned int)-1)
- return MATCHER_NO_MATCH;
-
- matcher->word_index++;
-
- if (matcher->word_index > matcher->index)
- return MATCHER_OK;
-
- keyword_mask |= (1 << keyword_found);
-
- if (args_vector)
- {
- keyword_argc = 0;
- keyword_argv = XMALLOC(MTYPE_TMP, (CMD_ARGC_MAX + 1) * sizeof(char*));
- /* We use -1 as a marker for unused fields as NULL might be a valid value */
- for (i = 0; i < CMD_ARGC_MAX + 1; i++)
- keyword_argv[i] = (void*)-1;
- vector_set_index(args_vector, keyword_found, keyword_argv);
- }
- else
- {
- keyword_argv = NULL;
- }
-
- keyword_vector = vector_slot(token->keyword, keyword_found);
- /* the keyword itself is at 0. We are only interested in the arguments,
- * so start counting at 1. */
- for (i = 1; i < vector_active(keyword_vector); i++)
- {
- word_token = vector_slot(keyword_vector, i);
-
- switch (word_token->type)
- {
- case TOKEN_TERMINAL:
- rv = cmd_matcher_match_terminal(matcher, word_token,
- &keyword_argc, keyword_argv);
- break;
- case TOKEN_MULTIPLE:
- rv = cmd_matcher_match_multiple(matcher, word_token,
- &keyword_argc, keyword_argv);
- break;
- case TOKEN_KEYWORD:
- assert(!"Keywords should never be nested.");
- break;
- }
-
- if (MATCHER_ERROR(rv))
- return rv;
-
- if (matcher->word_index > matcher->index)
- return MATCHER_OK;
- }
- }
- /* not reached */
-}
-
-static enum matcher_rv
-cmd_matcher_build_keyword_args(struct cmd_matcher *matcher,
- struct cmd_token *token,
- int *argc, const char **argv,
- vector keyword_args_vector)
-{
- unsigned int i, j;
- const char **keyword_args;
- vector keyword_vector;
- struct cmd_token *word_token;
- const char *arg;
- enum matcher_rv rv;
-
- rv = MATCHER_OK;
-
- if (keyword_args_vector == NULL)
- return rv;
-
- for (i = 0; i < vector_active(token->keyword); i++)
- {
- keyword_vector = vector_slot(token->keyword, i);
- keyword_args = vector_lookup(keyword_args_vector, i);
-
- if (vector_active(keyword_vector) == 1)
- {
- /* this is a keyword without arguments */
- if (keyword_args)
- {
- word_token = vector_slot(keyword_vector, 0);
- arg = word_token->cmd;
- XFREE (MTYPE_TMP, keyword_args);
- }
- else
- {
- arg = NULL;
- }
-
- if (push_argument(argc, argv, arg))
- rv = MATCHER_EXCEED_ARGC_MAX;
- }
- else
- {
- /* this is a keyword with arguments */
- if (keyword_args)
- {
- /* the keyword was present, so just fill in the arguments */
- for (j = 0; keyword_args[j] != (void*)-1; j++)
- if (push_argument(argc, argv, keyword_args[j]))
- rv = MATCHER_EXCEED_ARGC_MAX;
- XFREE(MTYPE_TMP, keyword_args);
- }
- else
- {
- /* the keyword was not present, insert NULL for the arguments
- * the keyword would have taken. */
- for (j = 1; j < vector_active(keyword_vector); j++)
- {
- word_token = vector_slot(keyword_vector, j);
- if ((word_token->type == TOKEN_TERMINAL
- && TERMINAL_RECORD (word_token->terminal))
- || word_token->type == TOKEN_MULTIPLE)
- {
- if (push_argument(argc, argv, NULL))
- rv = MATCHER_EXCEED_ARGC_MAX;
- }
- }
- }
- }
- }
- vector_free(keyword_args_vector);
- return rv;
-}
-
-static enum matcher_rv
-cmd_matcher_match_keyword(struct cmd_matcher *matcher,
- struct cmd_token *token,
- int *argc, const char **argv)
-{
- vector keyword_args_vector;
- enum matcher_rv reader_rv;
- enum matcher_rv builder_rv;
-
- assert(token->type == TOKEN_KEYWORD);
-
- if (argc && argv)
- keyword_args_vector = vector_init(VECTOR_MIN_SIZE);
- else
- keyword_args_vector = NULL;
-
- reader_rv = cmd_matcher_read_keywords(matcher, token, keyword_args_vector);
- builder_rv = cmd_matcher_build_keyword_args(matcher, token, argc,
- argv, keyword_args_vector);
- /* keyword_args_vector is consumed by cmd_matcher_build_keyword_args */
-
- if (!MATCHER_ERROR(reader_rv) && MATCHER_ERROR(builder_rv))
- return builder_rv;
-
- return reader_rv;
-}
-
-static void
-cmd_matcher_init(struct cmd_matcher *matcher,
- struct cmd_element *cmd,
- enum filter_type filter,
- vector vline,
- unsigned int index,
- enum match_type *match_type,
- vector *match)
-{
- memset(matcher, 0, sizeof(*matcher));
-
- matcher->cmd = cmd;
- matcher->filter = filter;
- matcher->vline = vline;
- matcher->index = index;
-
- matcher->match_type = match_type;
- if (matcher->match_type)
- *matcher->match_type = no_match;
- matcher->match = match;
-
- matcher->word_index = 0;
-}
-
-static enum matcher_rv
-cmd_element_match(struct cmd_element *cmd_element,
- enum filter_type filter,
- vector vline,
- unsigned int index,
- enum match_type *match_type,
- vector *match,
- int *argc,
- const char **argv)
-{
- struct cmd_matcher matcher;
- unsigned int token_index;
- enum matcher_rv rv = MATCHER_OK;
-
- cmd_matcher_init(&matcher, cmd_element, filter,
- vline, index, match_type, match);
-
- if (argc != NULL)
- *argc = 0;
-
- for (token_index = 0;
- token_index < vector_active(cmd_element->tokens);
- token_index++)
- {
- struct cmd_token *token = vector_slot(cmd_element->tokens, token_index);
-
- switch (token->type)
- {
- case TOKEN_TERMINAL:
- rv = cmd_matcher_match_terminal(&matcher, token, argc, argv);
- break;
- case TOKEN_MULTIPLE:
- rv = cmd_matcher_match_multiple(&matcher, token, argc, argv);
- break;
- case TOKEN_KEYWORD:
- rv = cmd_matcher_match_keyword(&matcher, token, argc, argv);
- }
-
- if (MATCHER_ERROR(rv))
- return rv;
-
- if (matcher.word_index > index)
- return MATCHER_OK;
- }
-
- /* return MATCHER_COMPLETE if all words were consumed */
- if (matcher.word_index >= vector_active(vline))
- return MATCHER_COMPLETE;
-
- /* return MATCHER_COMPLETE also if only an empty word is left. */
- if (matcher.word_index == vector_active(vline) - 1
- && (!vector_slot(vline, matcher.word_index)
- || !strlen((char*)vector_slot(vline, matcher.word_index))))
- return MATCHER_COMPLETE;
-
- return MATCHER_NO_MATCH; /* command is too long to match */
-}
-
-/**
- * Filter a given vector of commands against a given commandline and
- * calculate possible completions.
- *
- * @param commands A vector of struct cmd_element*. Commands that don't
- * match against the given command line will be overwritten
- * with NULL in that vector.
- * @param filter Either FILTER_RELAXED or FILTER_STRICT. This basically
- * determines how incomplete commands are handled, compare with
- * cmd_word_match for details.
- * @param vline A vector of char* containing the tokenized commandline.
- * @param index Only match up to the given token of the commandline.
- * @param match_type Record the type of the best match here.
- * @param matches Record the matches here. For each cmd_element in the commands
- * vector, a match vector will be created in the matches vector.
- * That vector will contain all struct command_token* of the
- * cmd_element which matched against the given vline at the given
- * index.
- * @return A code specifying if an error occured. If all went right, it's
- * CMD_SUCCESS.
- */
-static int
-cmd_vector_filter(vector commands,
- enum filter_type filter,
- vector vline,
- unsigned int index,
- enum match_type *match_type,
- vector *matches)
-{
- unsigned int i;
- struct cmd_element *cmd_element;
- enum match_type best_match;
- enum match_type element_match;
- enum matcher_rv matcher_rv;
-
- best_match = no_match;
- *matches = vector_init(VECTOR_MIN_SIZE);
-
- for (i = 0; i < vector_active (commands); i++)
- if ((cmd_element = vector_slot (commands, i)) != NULL)
- {
- vector_set_index(*matches, i, NULL);
- matcher_rv = cmd_element_match(cmd_element, filter,
- vline, index,
- &element_match,
- (vector*)&vector_slot(*matches, i),
- NULL, NULL);
- if (MATCHER_ERROR(matcher_rv))
- {
- vector_slot(commands, i) = NULL;
- if (matcher_rv == MATCHER_AMBIGUOUS)
- return CMD_ERR_AMBIGUOUS;
- if (matcher_rv == MATCHER_EXCEED_ARGC_MAX)
- return CMD_ERR_EXEED_ARGC_MAX;
- }
- else if (element_match > best_match)
- {
- best_match = element_match;
- }
- }
- *match_type = best_match;
- return CMD_SUCCESS;
-}
-
/**
- * Check whether a given commandline is complete if used for a specific
- * cmd_element.
- *
- * @param cmd_element A cmd_element against which the commandline should be
- * checked.
- * @param vline The tokenized commandline.
- * @return 1 if the given commandline is complete, 0 otherwise.
+ * Compare function for cmd_token.
+ * Used with qsort to sort command completions.
*/
static int
-cmd_is_complete(struct cmd_element *cmd_element,
- vector vline)
+compare_completions (const void *fst, const void *snd)
{
- enum matcher_rv rv;
-
- rv = cmd_element_match(cmd_element,
- FILTER_RELAXED,
- vline, -1,
- NULL, NULL,
- NULL, NULL);
- return (rv == MATCHER_COMPLETE);
+ struct cmd_token *first = *(struct cmd_token **) fst,
+ *secnd = *(struct cmd_token **) snd;
+ return strcmp (first->text, secnd->text);
}
/**
- * Parse a given commandline and construct a list of arguments for the
- * given command_element.
+ * Takes a list of completions returned by command_complete,
+ * dedeuplicates them based on both text and description,
+ * sorts them, and returns them as a vector.
*
- * @param cmd_element The cmd_element for which we want to construct arguments.
- * @param vline The tokenized commandline.
- * @param argc Where to store the argument count.
- * @param argv Where to store the argument list. Should be at least
- * CMD_ARGC_MAX elements long.
- * @return CMD_SUCCESS if everything went alright, an error otherwise.
+ * @param completions linked list of cmd_token
+ * @return deduplicated and sorted vector with
*/
-static int
-cmd_parse(struct cmd_element *cmd_element,
- vector vline,
- int *argc, const char **argv)
+vector
+completions_to_vec (struct list *completions)
{
- enum matcher_rv rv = cmd_element_match(cmd_element,
- FILTER_RELAXED,
- vline, -1,
- NULL, NULL,
- argc, argv);
- switch (rv)
- {
- case MATCHER_COMPLETE:
- return CMD_SUCCESS;
+ vector comps = vector_init (VECTOR_MIN_SIZE);
- case MATCHER_NO_MATCH:
- return CMD_ERR_NO_MATCH;
-
- case MATCHER_AMBIGUOUS:
- return CMD_ERR_AMBIGUOUS;
-
- case MATCHER_EXCEED_ARGC_MAX:
- return CMD_ERR_EXEED_ARGC_MAX;
+ struct listnode *ln;
+ struct cmd_token *token, *cr = NULL;
+ unsigned int i, exists;
+ for (ALL_LIST_ELEMENTS_RO(completions,ln,token))
+ {
+ if (token->type == END_TKN && (cr = token))
+ continue;
- default:
- return CMD_ERR_INCOMPLETE;
+ // linear search for token in completions vector
+ exists = 0;
+ for (i = 0; i < vector_active (comps) && !exists; i++)
+ {
+ struct cmd_token *curr = vector_slot (comps, i);
+#ifdef VTYSH_DEBUG
+ exists = !strcmp (curr->text, token->text) &&
+ !strcmp (curr->desc, token->desc);
+#else
+ exists = !strcmp (curr->text, token->text);
+#endif /* VTYSH_DEBUG */
}
-}
-
-/* Check ambiguous match */
-static int
-is_cmd_ambiguous (vector cmd_vector,
- const char *command,
- vector matches,
- enum match_type type)
-{
- unsigned int i;
- unsigned int j;
- const char *str = NULL;
- const char *matched = NULL;
- vector match_vector;
- struct cmd_token *cmd_token;
- if (command == NULL)
- command = "";
-
- for (i = 0; i < vector_active (matches); i++)
- if ((match_vector = vector_slot (matches, i)) != NULL)
- {
- int match = 0;
-
- for (j = 0; j < vector_active (match_vector); j++)
- if ((cmd_token = vector_slot (match_vector, j)) != NULL)
- {
- enum match_type ret;
-
- assert(cmd_token->type == TOKEN_TERMINAL);
- if (cmd_token->type != TOKEN_TERMINAL)
- continue;
-
- str = cmd_token->cmd;
-
- switch (type)
- {
- case exact_match:
- if (!TERMINAL_RECORD (cmd_token->terminal)
- && strcmp (command, str) == 0)
- match++;
- break;
- case partly_match:
- if (!TERMINAL_RECORD (cmd_token->terminal)
- && strncmp (command, str, strlen (command)) == 0)
- {
- if (matched && strcmp (matched, str) != 0)
- return 1; /* There is ambiguous match. */
- else
- matched = str;
- match++;
- }
- break;
- case range_match:
- if (cmd_range_match (str, command))
- {
- if (matched && strcmp (matched, str) != 0)
- return 1;
- else
- matched = str;
- match++;
- }
- break;
-#ifdef HAVE_IPV6
- case ipv6_match:
- if (cmd_token->terminal == TERMINAL_IPV6)
- match++;
- break;
- case ipv6_prefix_match:
- if ((ret = cmd_ipv6_prefix_match (command)) != no_match)
- {
- if (ret == partly_match)
- return 2; /* There is incomplete match. */
-
- match++;
- }
- break;
-#endif /* HAVE_IPV6 */
- case ipv4_match:
- if (cmd_token->terminal == TERMINAL_IPV4)
- match++;
- break;
- case ipv4_prefix_match:
- if ((ret = cmd_ipv4_prefix_match (command)) != no_match)
- {
- if (ret == partly_match)
- return 2; /* There is incomplete match. */
-
- match++;
- }
- break;
- case extend_match:
- if (TERMINAL_RECORD (cmd_token->terminal))
- match++;
- break;
- case no_match:
- default:
- break;
- }
- }
- if (!match)
- vector_slot (cmd_vector, i) = NULL;
- }
- return 0;
-}
-
-/* If src matches dst return dst string, otherwise return NULL */
-static const char *
-cmd_entry_function (const char *src, struct cmd_token *token)
-{
- const char *dst = token->cmd;
-
- /* Skip variable arguments. */
- if (TERMINAL_RECORD (token->terminal))
- return NULL;
-
- /* In case of 'command \t', given src is NULL string. */
- if (src == NULL)
- return dst;
-
- /* Matched with input string. */
- if (strncmp (src, dst, strlen (src)) == 0)
- return dst;
-
- return NULL;
-}
-
-/* If src matches dst return dst string, otherwise return NULL */
-/* This version will return the dst string always if it is
- CMD_VARIABLE for '?' key processing */
-static const char *
-cmd_entry_function_desc (const char *src, struct cmd_token *token)
-{
- const char *dst = token->cmd;
-
- switch (token->terminal)
- {
- case TERMINAL_VARARG:
- return dst;
-
- case TERMINAL_RANGE:
- if (cmd_range_match (dst, src))
- return dst;
- else
- return NULL;
-
- case TERMINAL_IPV6:
- if (cmd_ipv6_match (src))
- return dst;
- else
- return NULL;
-
- case TERMINAL_IPV6_PREFIX:
- if (cmd_ipv6_prefix_match (src))
- return dst;
- else
- return NULL;
-
- case TERMINAL_IPV4:
- if (cmd_ipv4_match (src))
- return dst;
- else
- return NULL;
-
- case TERMINAL_IPV4_PREFIX:
- if (cmd_ipv4_prefix_match (src))
- return dst;
- else
- return NULL;
-
- /* Optional or variable commands always match on '?' */
- case TERMINAL_OPTION:
- case TERMINAL_VARIABLE:
- return dst;
-
- case TERMINAL_LITERAL:
- /* In case of 'command \t', given src is NULL string. */
- if (src == NULL)
- return dst;
-
- if (strncmp (src, dst, strlen (src)) == 0)
- return dst;
- else
- return NULL;
+ if (!exists)
+ vector_set (comps, token);
+ }
- default:
- assert(0);
- return NULL;
- }
-}
+ // sort completions
+ qsort (comps->index,
+ vector_active (comps),
+ sizeof (void *),
+ &compare_completions);
-/**
- * Check whether a string is already present in a vector of strings.
- * @param v A vector of char*.
- * @param str A char*.
- * @return 0 if str is already present in the vector, 1 otherwise.
- */
-static int
-cmd_unique_string (vector v, const char *str)
-{
- unsigned int i;
- char *match;
+ // make <cr> the first element, if it is present
+ if (cr)
+ {
+ vector_set_index (comps, vector_active (comps), NULL);
+ memmove (comps->index + 1, comps->index, (comps->alloced - 1) * sizeof (void *));
+ vector_set_index (comps, 0, cr);
+ }
- for (i = 0; i < vector_active (v); i++)
- if ((match = vector_slot (v, i)) != NULL)
- if (strcmp (match, str) == 0)
- return 0;
- return 1;
+ return comps;
}
-
/**
- * Check whether a struct cmd_token matching a given string is already
- * present in a vector of struct cmd_token.
- * @param v A vector of struct cmd_token*.
- * @param str A char* which should be searched for.
- * @return 0 if there is a struct cmd_token* with its cmd matching str,
- * 1 otherwise.
+ * Generates a vector of cmd_token representing possible completions
+ * on the current input.
+ *
+ * @param vline the vectorized input line
+ * @param vty the vty with the node to match on
+ * @param status pointer to matcher status code
+ * @return vector of struct cmd_token * with possible completions
*/
-static int
-desc_unique_string (vector v, const char *str)
-{
- unsigned int i;
- struct cmd_token *token;
-
- for (i = 0; i < vector_active (v); i++)
- if ((token = vector_slot (v, i)) != NULL)
- if (strcmp (token->cmd, str) == 0)
- return 0;
- return 1;
-}
-
-static int
-cmd_try_do_shortcut (enum node_type node, char* first_word) {
- if ( first_word != NULL &&
- node != AUTH_NODE &&
- node != VIEW_NODE &&
- node != AUTH_ENABLE_NODE &&
- node != ENABLE_NODE &&
- 0 == strcmp( "do", first_word ) )
- return 1;
- return 0;
-}
-
-static void
-cmd_matches_free(vector *matches)
-{
- unsigned int i;
- vector cmd_matches;
-
- for (i = 0; i < vector_active(*matches); i++)
- if ((cmd_matches = vector_slot(*matches, i)) != NULL)
- vector_free(cmd_matches);
- vector_free(*matches);
- *matches = NULL;
-}
-
-static int
-cmd_describe_cmp(const void *a, const void *b)
-{
- const struct cmd_token *first = *(struct cmd_token * const *)a;
- const struct cmd_token *second = *(struct cmd_token * const *)b;
-
- return strcmp(first->cmd, second->cmd);
-}
-
-static void
-cmd_describe_sort(vector matchvec)
-{
- qsort(matchvec->index, vector_active(matchvec),
- sizeof(void*), cmd_describe_cmp);
-}
-
-/* '?' describe command support. */
static vector
-cmd_describe_command_real (vector vline, struct vty *vty, int *status)
+cmd_complete_command_real (vector vline, struct vty *vty, int *status)
{
- unsigned int i;
- vector cmd_vector;
-#define INIT_MATCHVEC_SIZE 10
- vector matchvec;
- struct cmd_element *cmd_element;
- unsigned int index;
- int ret;
- enum match_type match;
- char *command = NULL;
- vector matches = NULL;
- vector match_vector;
- uint32_t command_found = 0;
- const char *last_word;
-
- /* Set index. */
- if (vector_active (vline) == 0)
- {
- *status = CMD_ERR_NO_MATCH;
- return NULL;
- }
+ struct list *completions;
+ struct graph *cmdgraph = cmd_node_graph (cmdvec, vty->node);
- index = vector_active (vline) - 1;
-
- /* Make copy vector of current node's command vector. */
- cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
-
- /* Prepare match vector */
- matchvec = vector_init (INIT_MATCHVEC_SIZE);
-
- /* Filter commands and build a list how they could possibly continue. */
- for (i = 0; i <= index; i++)
- {
- command = vector_slot (vline, i);
-
- if (matches)
- cmd_matches_free(&matches);
-
- ret = cmd_vector_filter(cmd_vector,
- FILTER_RELAXED,
- vline, i,
- &match,
- &matches);
-
- if (ret != CMD_SUCCESS)
- {
- vector_free (cmd_vector);
- vector_free (matchvec);
- cmd_matches_free(&matches);
- *status = ret;
- return NULL;
- }
-
- /* The last match may well be ambigious, so break here */
- if (i == index)
- break;
-
- if (match == vararg_match)
- {
- /* We found a vararg match - so we can throw out the current matches here
- * and don't need to continue checking the command input */
- unsigned int j, k;
-
- for (j = 0; j < vector_active (matches); j++)
- if ((match_vector = vector_slot (matches, j)) != NULL)
- for (k = 0; k < vector_active (match_vector); k++)
- {
- struct cmd_token *token = vector_slot (match_vector, k);
- vector_set (matchvec, token);
- }
-
- *status = CMD_SUCCESS;
- vector_set(matchvec, &token_cr);
- vector_free (cmd_vector);
- cmd_matches_free(&matches);
- cmd_describe_sort(matchvec);
- return matchvec;
- }
-
- ret = is_cmd_ambiguous(cmd_vector, command, matches, match);
- if (ret == 1)
- {
- vector_free (cmd_vector);
- vector_free (matchvec);
- cmd_matches_free(&matches);
- *status = CMD_ERR_AMBIGUOUS;
- return NULL;
- }
- else if (ret == 2)
- {
- vector_free (cmd_vector);
- vector_free (matchvec);
- cmd_matches_free(&matches);
- *status = CMD_ERR_NO_MATCH;
- return NULL;
- }
- }
-
- /* Make description vector. */
- for (i = 0; i < vector_active (matches); i++) {
- if ((cmd_element = vector_slot (cmd_vector, i)) != NULL &&
- !(cmd_element->attr == CMD_ATTR_DEPRECATED ||
- cmd_element->attr == CMD_ATTR_HIDDEN))
- {
- unsigned int j;
- vector vline_trimmed;
+ enum matcher_rv rv = command_complete (cmdgraph, vline, &completions);
- command_found++;
- last_word = vector_slot(vline, vector_active(vline) - 1);
- if (last_word == NULL || !strlen(last_word))
- {
- vline_trimmed = vector_copy(vline);
- vector_unset(vline_trimmed, vector_active(vline_trimmed) - 1);
-
- if (cmd_is_complete(cmd_element, vline_trimmed)
- && desc_unique_string(matchvec, command_cr))
- {
- if (match != vararg_match)
- vector_set(matchvec, &token_cr);
- }
-
- vector_free(vline_trimmed);
- }
-
- match_vector = vector_slot (matches, i);
- if (match_vector)
- for (j = 0; j < vector_active(match_vector); j++)
- {
- struct cmd_token *token = vector_slot(match_vector, j);
- const char *string;
-
- string = cmd_entry_function_desc(command, token);
- if (string && desc_unique_string(matchvec, string))
- vector_set(matchvec, token);
- }
- }
- }
-
- /*
- * We can get into this situation when the command is complete
- * but the last part of the command is an optional piece of
- * cli.
- */
- last_word = vector_slot(vline, vector_active(vline) - 1);
- if (command_found == 0 && (last_word == NULL || !strlen(last_word))) {
- vector_set(matchvec, &token_cr);
+ if (MATCHER_ERROR(rv))
+ {
+ *status = CMD_ERR_NO_MATCH;
+ return NULL;
}
- vector_free (cmd_vector);
- cmd_matches_free(&matches);
+ vector comps = completions_to_vec (completions);
+ list_delete (completions);
- if (vector_slot (matchvec, 0) == NULL)
- {
- vector_free (matchvec);
+ // set status code appropriately
+ switch (vector_active (comps))
+ {
+ case 0:
*status = CMD_ERR_NO_MATCH;
- return NULL;
- }
+ break;
+ case 1:
+ *status = CMD_COMPLETE_FULL_MATCH;
+ break;
+ default:
+ *status = CMD_COMPLETE_LIST_MATCH;
+ }
- *status = CMD_SUCCESS;
- cmd_describe_sort(matchvec);
- return matchvec;
+ return comps;
}
vector
@@ -2261,291 +610,108 @@ cmd_describe_command (vector vline, struct vty *vty, int *status)
shifted_vline = vector_init (vector_count(vline));
/* use memcpy? */
- for (index = 1; index < vector_active (vline); index++)
- {
- vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
- }
+ for (index = 1; index < vector_active (vline); index++)
+ {
+ vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
+ }
- ret = cmd_describe_command_real (shifted_vline, vty, status);
+ ret = cmd_complete_command_real (shifted_vline, vty, status);
vector_free(shifted_vline);
vty->node = onode;
return ret;
}
-
- return cmd_describe_command_real (vline, vty, status);
+ return cmd_complete_command_real (vline, vty, status);
}
+/**
+ * Generate possible tab-completions for the given input. This function only
+ * returns results that would result in a valid command if used as Readline
+ * completions (as is the case in vtysh). For instance, if the passed vline ends
+ * with '4.3.2', the strings 'A.B.C.D' and 'A.B.C.D/M' will _not_ be returned.
+ *
+ * @param vline vectorized input line
+ * @param vty the vty
+ * @param status location to store matcher status code in
+ * @return set of valid strings for use with Readline as tab-completions.
+ */
-/* Check LCD of matched command. */
-static int
-cmd_lcd (char **matched)
-{
- int i;
- int j;
- int lcd = -1;
- char *s1, *s2;
- char c1, c2;
-
- if (matched[0] == NULL || matched[1] == NULL)
- return 0;
-
- for (i = 1; matched[i] != NULL; i++)
- {
- s1 = matched[i - 1];
- s2 = matched[i];
-
- for (j = 0; (c1 = s1[j]) && (c2 = s2[j]); j++)
- if (c1 != c2)
- break;
-
- if (lcd < 0)
- lcd = j;
- else
- {
- if (lcd > j)
- lcd = j;
- }
- }
- return lcd;
-}
-
-static int
-cmd_complete_cmp(const void *a, const void *b)
+char **
+cmd_complete_command (vector vline, struct vty *vty, int *status)
{
- const char *first = *(char * const *)a;
- const char *second = *(char * const *)b;
-
- if (!first)
- {
- if (!second)
- return 0;
- return 1;
- }
- if (!second)
- return -1;
+ char **ret = NULL;
+ int original_node = vty->node;
+ vector input_line = vector_init (vector_count (vline));
- return strcmp(first, second);
-}
+ // if the first token is 'do' we'll want to execute the command in the enable node
+ int do_shortcut = cmd_try_do_shortcut (vty->node, vector_slot (vline, 0));
+ vty->node = do_shortcut ? ENABLE_NODE : original_node;
-static void
-cmd_complete_sort(vector matchvec)
-{
- qsort(matchvec->index, vector_active(matchvec),
- sizeof(void*), cmd_complete_cmp);
-}
+ // construct the input line we'll be matching on
+ unsigned int offset = (do_shortcut) ? 1 : 0;
+ for (unsigned index = 0; index + offset < vector_active (vline); index++)
+ vector_set_index (input_line, index, vector_lookup (vline, index + offset));
-/* Command line completion support. */
-static char **
-cmd_complete_command_real (vector vline, struct vty *vty, int *status, int islib)
-{
- unsigned int i;
- vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
-#define INIT_MATCHVEC_SIZE 10
- vector matchvec;
- unsigned int index;
- char **match_str;
- struct cmd_token *token;
- char *command;
- int lcd;
- vector matches = NULL;
- vector match_vector;
+ // get token completions -- this is a copying operation
+ vector comps = NULL, initial_comps;
+ initial_comps = cmd_complete_command_real (input_line, vty, status);
- if (vector_active (vline) == 0)
+ if (!MATCHER_ERROR (*status))
+ {
+ assert (initial_comps);
+ // filter out everything that is not suitable for a tab-completion
+ comps = vector_init (VECTOR_MIN_SIZE);
+ for (unsigned int i = 0; i < vector_active(initial_comps); i++)
{
- vector_free (cmd_vector);
- *status = CMD_ERR_NO_MATCH;
- return NULL;
+ struct cmd_token *token = vector_slot (initial_comps, i);
+ if (token->type == WORD_TKN)
+ vector_set (comps, token);
}
- else
- index = vector_active (vline) - 1;
+ vector_free (initial_comps);
- /* First, filter by command string */
- for (i = 0; i <= index; i++)
+ // since we filtered results, we need to re-set status code
+ switch (vector_active (comps))
{
- command = vector_slot (vline, i);
- enum match_type match;
- int ret;
-
- if (matches)
- cmd_matches_free(&matches);
-
- /* First try completion match, if there is exactly match return 1 */
- ret = cmd_vector_filter(cmd_vector,
- FILTER_RELAXED,
- vline, i,
- &match,
- &matches);
-
- if (ret != CMD_SUCCESS)
- {
- vector_free(cmd_vector);
- cmd_matches_free(&matches);
- *status = ret;
- return NULL;
- }
-
- /* Break here - the completion mustn't be checked to be non-ambiguous */
- if (i == index)
- break;
-
- /* If there is exact match then filter ambiguous match else check
- ambiguousness. */
- ret = is_cmd_ambiguous (cmd_vector, command, matches, match);
- if (ret == 1)
- {
- vector_free (cmd_vector);
- cmd_matches_free(&matches);
- *status = CMD_ERR_AMBIGUOUS;
- return NULL;
- }
+ case 0:
+ *status = CMD_ERR_NO_MATCH;
+ break;
+ case 1:
+ *status = CMD_COMPLETE_FULL_MATCH;
+ break;
+ default:
+ *status = CMD_COMPLETE_LIST_MATCH;
}
-
- /* Prepare match vector. */
- matchvec = vector_init (INIT_MATCHVEC_SIZE);
- /* Build the possible list of continuations into a list of completions */
- for (i = 0; i < vector_active (matches); i++)
- if ((match_vector = vector_slot (matches, i)))
+ // copy completions text into an array of char*
+ ret = XMALLOC (MTYPE_TMP, (vector_active (comps)+1) * sizeof (char *));
+ unsigned int i;
+ for (i = 0; i < vector_active (comps); i++)
{
- const char *string;
- unsigned int j;
-
- for (j = 0; j < vector_active (match_vector); j++)
- if ((token = vector_slot (match_vector, j)))
- {
- string = cmd_entry_function (vector_slot (vline, index),
- token);
- if (string && cmd_unique_string (matchvec, string))
- vector_set (matchvec, (islib != 0 ?
- XSTRDUP (MTYPE_TMP, string) :
- strdup (string) /* rl freed */));
- }
+ struct cmd_token *token = vector_slot (comps, i);
+ ret[i] = XSTRDUP (MTYPE_TMP, token->text);
+ vector_unset (comps, i);
}
+ // set the last element to NULL, because this array is used in
+ // a Readline completion_generator function which expects NULL
+ // as a sentinel value
+ ret[i] = NULL;
+ vector_free (comps);
+ comps = NULL;
+ }
+ else if (initial_comps)
+ vector_free (initial_comps);
- /* We don't need cmd_vector any more. */
- vector_free (cmd_vector);
- cmd_matches_free(&matches);
-
- /* No matched command */
- if (vector_slot (matchvec, 0) == NULL)
- {
- vector_free (matchvec);
-
- /* In case of 'command \t' pattern. Do you need '?' command at
- the end of the line. */
- if (vector_slot (vline, index) == '\0')
- *status = CMD_ERR_NOTHING_TODO;
- else
- *status = CMD_ERR_NO_MATCH;
- return NULL;
- }
-
- /* Only one matched */
- if (vector_slot (matchvec, 1) == NULL)
- {
- size_t index_size = matchvec->alloced * sizeof (void *);
- match_str = XMALLOC (MTYPE_TMP, index_size);
- memcpy (match_str, matchvec->index, index_size);
- vector_free (matchvec);
-
- *status = CMD_COMPLETE_FULL_MATCH;
- return match_str;
- }
- /* Make it sure last element is NULL. */
- vector_set (matchvec, NULL);
-
- /* Check LCD of matched strings. */
- if (vector_slot (vline, index) != NULL)
- {
- lcd = cmd_lcd ((char **) matchvec->index);
-
- if (lcd)
- {
- int len = strlen (vector_slot (vline, index));
-
- if (len < lcd)
- {
- char *lcdstr;
-
- lcdstr = (islib != 0 ?
- XMALLOC (MTYPE_TMP, lcd + 1) :
- malloc(lcd + 1));
- memcpy (lcdstr, matchvec->index[0], lcd);
- lcdstr[lcd] = '\0';
-
- /* Free matchvec. */
- for (i = 0; i < vector_active (matchvec); i++)
- {
- if (vector_slot (matchvec, i))
- {
- if (islib != 0)
- XFREE (MTYPE_TMP, vector_slot (matchvec, i));
- else
- free (vector_slot (matchvec, i));
- }
- }
- vector_free (matchvec);
-
- /* Make new matchvec. */
- matchvec = vector_init (INIT_MATCHVEC_SIZE);
- vector_set (matchvec, lcdstr);
-
- size_t index_size = matchvec->alloced * sizeof (void *);
- match_str = XMALLOC (MTYPE_TMP, index_size);
- memcpy (match_str, matchvec->index, index_size);
- vector_free (matchvec);
-
- *status = CMD_COMPLETE_MATCH;
- return match_str;
- }
- }
- }
-
- match_str = (char **) matchvec->index;
- cmd_complete_sort(matchvec);
- vector_only_wrapper_free (matchvec);
- *status = CMD_COMPLETE_LIST_MATCH;
- return match_str;
-}
-
-char **
-cmd_complete_command_lib (vector vline, struct vty *vty, int *status, int islib)
-{
- char **ret;
-
- if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
- {
- enum node_type onode;
- vector shifted_vline;
- unsigned int index;
-
- onode = vty->node;
- vty->node = ENABLE_NODE;
- /* We can try it on enable node, cos' the vty is authenticated */
-
- shifted_vline = vector_init (vector_count(vline));
- /* use memcpy? */
- for (index = 1; index < vector_active (vline); index++)
- {
- vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
- }
-
- ret = cmd_complete_command_real (shifted_vline, vty, status, islib);
+ // comps should always be null here
+ assert (!comps);
- vector_free(shifted_vline);
- vty->node = onode;
- return ret;
- }
+ // free the adjusted input line
+ vector_free (input_line);
- return cmd_complete_command_real (vline, vty, status, islib);
-}
+ // reset vty->node to its original value
+ vty->node = original_node;
-char **
-cmd_complete_command (vector vline, struct vty *vty, int *status)
-{
- return cmd_complete_command_lib (vline, vty, status, 0);
+ return ret;
}
/* return parent node */
@@ -2563,9 +729,10 @@ node_parent ( enum node_type node )
case BGP_VPNV6_NODE:
case BGP_ENCAP_NODE:
case BGP_ENCAPV6_NODE:
+ case BGP_VRF_POLICY_NODE:
case BGP_VNC_DEFAULTS_NODE:
- case BGP_VNC_NVE_GROUP_NODE:
- case BGP_VNC_L2_GROUP_NODE:
+ case BGP_VNC_NVE_GROUP_NODE:
+ case BGP_VNC_L2_GROUP_NODE:
case BGP_IPV4_NODE:
case BGP_IPV4M_NODE:
case BGP_IPV6_NODE:
@@ -2602,109 +769,57 @@ node_parent ( enum node_type node )
/* Execute command by argument vline vector. */
static int
cmd_execute_command_real (vector vline,
- enum filter_type filter,
- struct vty *vty,
- struct cmd_element **cmd)
+ enum filter_type filter,
+ struct vty *vty,
+ const struct cmd_element **cmd)
{
- unsigned int i;
- unsigned int index;
- vector cmd_vector;
- struct cmd_element *cmd_element;
- struct cmd_element *matched_element;
- unsigned int matched_count, incomplete_count;
- int argc;
- const char *argv[CMD_ARGC_MAX];
- enum match_type match = 0;
- char *command;
- int ret;
- vector matches;
-
- /* Make copy of command elements. */
- cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
+ struct list *argv_list;
+ enum matcher_rv status;
+ const struct cmd_element *matched_element = NULL;
- for (index = 0; index < vector_active (vline); index++)
- {
- command = vector_slot (vline, index);
- ret = cmd_vector_filter(cmd_vector,
- filter,
- vline, index,
- &match,
- &matches);
-
- if (ret != CMD_SUCCESS)
- {
- cmd_matches_free(&matches);
- return ret;
- }
-
- if (match == vararg_match)
- {
- cmd_matches_free(&matches);
- break;
- }
-
- ret = is_cmd_ambiguous (cmd_vector, command, matches, match);
- cmd_matches_free(&matches);
-
- if (ret == 1)
- {
- vector_free(cmd_vector);
- return CMD_ERR_AMBIGUOUS;
- }
- else if (ret == 2)
- {
- vector_free(cmd_vector);
- return CMD_ERR_NO_MATCH;
- }
- }
+ struct graph *cmdgraph = cmd_node_graph (cmdvec, vty->node);
+ status = command_match (cmdgraph, vline, &argv_list, &matched_element);
- /* Check matched count. */
- matched_element = NULL;
- matched_count = 0;
- incomplete_count = 0;
-
- for (i = 0; i < vector_active (cmd_vector); i++)
- if ((cmd_element = vector_slot (cmd_vector, i)))
- {
- if (cmd_is_complete(cmd_element, vline))
- {
- matched_element = cmd_element;
- matched_count++;
- }
- else
- {
- incomplete_count++;
- }
- }
-
- /* Finish of using cmd_vector. */
- vector_free (cmd_vector);
+ if (cmd)
+ *cmd = matched_element;
- /* To execute command, matched_count must be 1. */
- if (matched_count == 0)
- {
- if (incomplete_count)
- return CMD_ERR_INCOMPLETE;
- else
- return CMD_ERR_NO_MATCH;
+ // if matcher error, return corresponding CMD_ERR
+ if (MATCHER_ERROR(status))
+ {
+ if (argv_list)
+ list_delete (argv_list);
+ switch (status)
+ {
+ case MATCHER_INCOMPLETE:
+ return CMD_ERR_INCOMPLETE;
+ case MATCHER_AMBIGUOUS:
+ return CMD_ERR_AMBIGUOUS;
+ default:
+ return CMD_ERR_NO_MATCH;
}
+ }
- if (matched_count > 1)
- return CMD_ERR_AMBIGUOUS;
-
- ret = cmd_parse(matched_element, vline, &argc, argv);
- if (ret != CMD_SUCCESS)
- return ret;
+ // build argv array from argv list
+ struct cmd_token **argv = XMALLOC (MTYPE_TMP, argv_list->count * sizeof (struct cmd_token *));
+ struct listnode *ln;
+ struct cmd_token *token;
+ unsigned int i = 0;
+ for (ALL_LIST_ELEMENTS_RO(argv_list,ln,token))
+ argv[i++] = token;
- /* For vtysh execution. */
- if (cmd)
- *cmd = matched_element;
+ int argc = argv_list->count;
+ int ret;
if (matched_element->daemon)
- return CMD_SUCCESS_DAEMON;
+ ret = CMD_SUCCESS_DAEMON;
+ else
+ ret = matched_element->func (matched_element, vty, argc, argv);
- /* Execute matched command. */
- return (*matched_element->func) (matched_element, vty, argc, argv);
+ // delete list and cmd_token's in it
+ list_delete (argv_list);
+ XFREE (MTYPE_TMP, argv);
+
+ return ret;
}
/**
@@ -2723,14 +838,16 @@ cmd_execute_command_real (vector vline,
* as to why no command could be executed.
*/
int
-cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
- int vtysh) {
- int ret, saved_ret, tried = 0;
+cmd_execute_command (vector vline, struct vty *vty,
+ const struct cmd_element **cmd,
+ int vtysh)
+{
+ int ret, saved_ret = 0;
enum node_type onode, try_node;
onode = try_node = vty->node;
- if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
+ if (cmd_try_do_shortcut(vty->node, vector_slot(vline, 0)))
{
vector shifted_vline;
unsigned int index;
@@ -2740,10 +857,8 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
shifted_vline = vector_init (vector_count(vline));
/* use memcpy? */
- for (index = 1; index < vector_active (vline); index++)
- {
- vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
- }
+ for (index = 1; index < vector_active (vline); index++)
+ vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
ret = cmd_execute_command_real (shifted_vline, FILTER_RELAXED, vty, cmd);
@@ -2752,30 +867,27 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
return ret;
}
-
saved_ret = ret = cmd_execute_command_real (vline, FILTER_RELAXED, vty, cmd);
if (vtysh)
return saved_ret;
- /* This assumes all nodes above CONFIG_NODE are childs of CONFIG_NODE */
- while ( ret != CMD_SUCCESS && ret != CMD_WARNING
- && vty->node > CONFIG_NODE )
+ if (ret != CMD_SUCCESS && ret != CMD_WARNING)
{
- try_node = node_parent(try_node);
- vty->node = try_node;
- ret = cmd_execute_command_real (vline, FILTER_RELAXED, vty, cmd);
- tried = 1;
- if (ret == CMD_SUCCESS || ret == CMD_WARNING)
- {
- /* succesfull command, leave the node as is */
- return ret;
- }
+ /* This assumes all nodes above CONFIG_NODE are childs of CONFIG_NODE */
+ while (vty->node > CONFIG_NODE)
+ {
+ try_node = node_parent(try_node);
+ vty->node = try_node;
+ ret = cmd_execute_command_real (vline, FILTER_RELAXED, vty, cmd);
+ if (ret == CMD_SUCCESS || ret == CMD_WARNING)
+ return ret;
+ }
+ /* no command succeeded, reset the vty to the original node */
+ vty->node = onode;
}
- /* no command succeeded, reset the vty to the original node and
- return the error for this node */
- if ( tried )
- vty->node = onode;
+
+ /* return command status for original node */
return saved_ret;
}
@@ -2794,7 +906,7 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
*/
int
cmd_execute_command_strict (vector vline, struct vty *vty,
- struct cmd_element **cmd)
+ const struct cmd_element **cmd)
{
return cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd);
}
@@ -2812,7 +924,7 @@ cmd_execute_command_strict (vector vline, struct vty *vty,
* as to why no command could be executed.
*/
int
-command_config_read_one_line (struct vty *vty, struct cmd_element **cmd, int use_daemon)
+command_config_read_one_line (struct vty *vty, const struct cmd_element **cmd, int use_daemon)
{
vector vline;
int saved_node;
@@ -2838,7 +950,7 @@ command_config_read_one_line (struct vty *vty, struct cmd_element **cmd, int use
while (!(use_daemon && ret == CMD_SUCCESS_DAEMON) &&
!(!use_daemon && ret == CMD_ERR_NOTHING_TODO) &&
- ret != CMD_SUCCESS &&
+ ret != CMD_SUCCESS &&
ret != CMD_WARNING &&
vty->node > CONFIG_NODE) {
vty->node = node_parent(vty->node);
@@ -2849,14 +961,16 @@ command_config_read_one_line (struct vty *vty, struct cmd_element **cmd, int use
// stay at the same node
if (!(use_daemon && ret == CMD_SUCCESS_DAEMON) &&
!(!use_daemon && ret == CMD_ERR_NOTHING_TODO) &&
- ret != CMD_SUCCESS &&
+ ret != CMD_SUCCESS &&
ret != CMD_WARNING)
{
- vty->node = saved_node;
- memcpy(vty->error_buf, vty->buf, VTY_BUFSIZ);
+ vty->node = saved_node;
}
}
+ if (ret != CMD_SUCCESS && ret != CMD_WARNING)
+ memcpy (vty->error_buf, vty->buf, VTY_BUFSIZ);
+
cmd_free_strvec (vline);
return ret;
@@ -2872,13 +986,13 @@ config_from_file (struct vty *vty, FILE *fp, unsigned int *line_num)
while (fgets (vty->buf, VTY_BUFSIZ, fp))
{
if (!error_ret)
- ++(*line_num);
+ ++(*line_num);
ret = command_config_read_one_line (vty, NULL, 0);
if (ret != CMD_SUCCESS && ret != CMD_WARNING &&
- ret != CMD_ERR_NOTHING_TODO)
- error_ret = ret;
+ ret != CMD_ERR_NOTHING_TODO)
+ error_ret = ret;
}
if (error_ret) {
@@ -2906,7 +1020,7 @@ DEFUN (config_terminal,
}
/* Enable command */
-DEFUN (enable,
+DEFUN (enable,
config_enable_cmd,
"enable",
"Turn on privileged mode command\n")
@@ -2922,7 +1036,7 @@ DEFUN (enable,
}
/* Disable command */
-DEFUN (disable,
+DEFUN (disable,
config_disable_cmd,
"disable",
"Turn off privileged mode command\n")
@@ -2938,14 +1052,21 @@ DEFUN (config_exit,
"exit",
"Exit current mode and down to previous mode\n")
{
+ cmd_exit (vty);
+ return CMD_SUCCESS;
+}
+
+void
+cmd_exit (struct vty *vty)
+{
switch (vty->node)
{
case VIEW_NODE:
case ENABLE_NODE:
if (vty_shell (vty))
- exit (0);
+ exit (0);
else
- vty->status = VTY_CLOSE;
+ vty->status = VTY_CLOSE;
break;
case CONFIG_NODE:
vty->node = ENABLE_NODE;
@@ -2976,6 +1097,7 @@ DEFUN (config_exit,
case BGP_VPNV6_NODE:
case BGP_ENCAP_NODE:
case BGP_ENCAPV6_NODE:
+ case BGP_VRF_POLICY_NODE:
case BGP_VNC_DEFAULTS_NODE:
case BGP_VNC_NVE_GROUP_NODE:
case BGP_VNC_L2_GROUP_NODE:
@@ -3005,15 +1127,18 @@ DEFUN (config_exit,
default:
break;
}
- return CMD_SUCCESS;
}
-/* quit is alias of exit. */
-ALIAS (config_exit,
+/* ALIAS_FIXME */
+DEFUN (config_quit,
config_quit_cmd,
"quit",
"Exit current mode and down to previous mode\n")
-
+{
+ return config_exit (self, vty, argc, argv);
+}
+
+
/* End of configuration. */
DEFUN (config_end,
config_end_cmd,
@@ -3036,6 +1161,7 @@ DEFUN (config_end,
case BGP_NODE:
case BGP_ENCAP_NODE:
case BGP_ENCAPV6_NODE:
+ case BGP_VRF_POLICY_NODE:
case BGP_VNC_DEFAULTS_NODE:
case BGP_VNC_NVE_GROUP_NODE:
case BGP_VNC_L2_GROUP_NODE:
@@ -3094,8 +1220,8 @@ DEFUN (config_help,
"help",
"Description of the interactive help system\n")
{
- vty_out (vty,
- "Quagga VTY provides advanced help feature. When you need help,%s\
+ vty_out (vty,
+ "Quagga VTY provides advanced help feature. When you need help,%s\
anytime at the command line please press '?'.%s\
%s\
If nothing matches, the help list will be empty and you must backup%s\
@@ -3107,37 +1233,97 @@ argument.%s\
2. Partial help is provided when an abbreviated argument is entered%s\
and you want to know what arguments match the input%s\
(e.g. 'show me?'.)%s%s", VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE,
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE,
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
+ VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE,
+ VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+static void
+permute (struct graph_node *start, struct vty *vty)
+{
+ static struct list *position = NULL;
+ if (!position) position = list_new ();
+
+ // recursive dfs
+ listnode_add (position, start);
+ for (unsigned int i = 0; i < vector_active (start->to); i++)
+ {
+ struct graph_node *gn = vector_slot (start->to, i);
+ struct cmd_token *tok = gn->data;
+ if (tok->attr == CMD_ATTR_HIDDEN ||
+ tok->attr == CMD_ATTR_DEPRECATED)
+ continue;
+ else if (tok->type == END_TKN || gn == start)
+ {
+ struct graph_node *gnn;
+ struct listnode *ln;
+ vty_out (vty, " ");
+ for (ALL_LIST_ELEMENTS_RO (position,ln,gnn))
+ {
+ struct cmd_token *tt = gnn->data;
+ if (tt->type < SPECIAL_TKN)
+ vty_out (vty, " %s", tt->text);
+ }
+ if (gn == start)
+ vty_out (vty, "...");
+ vty_out (vty, VTY_NEWLINE);
+ }
+ else
+ permute (gn, vty);
+ }
+ list_delete_node (position, listtail(position));
+}
+
+int
+cmd_list_cmds (struct vty *vty, int do_permute)
+{
+ struct cmd_node *node = vector_slot (cmdvec, vty->node);
+
+ if (do_permute)
+ permute (vector_slot (node->cmdgraph->nodes, 0), vty);
+ else
+ {
+ /* loop over all commands at this node */
+ struct cmd_element *element = NULL;
+ for (unsigned int i = 0; i < vector_active(node->cmd_vector); i++)
+ if ((element = vector_slot (node->cmd_vector, i)) &&
+ element->attr != CMD_ATTR_DEPRECATED &&
+ element->attr != CMD_ATTR_HIDDEN)
+ vty_out (vty, " %s%s", element->string, VTY_NEWLINE);
+ }
return CMD_SUCCESS;
}
/* Help display function for all node. */
DEFUN (config_list,
config_list_cmd,
- "list",
- "Print command list\n")
+ "list [permutations]",
+ "Print command list\n"
+ "Print all possible command permutations\n")
{
- unsigned int i;
- struct cmd_node *cnode = vector_slot (cmdvec, vty->node);
- struct cmd_element *cmd;
-
- for (i = 0; i < vector_active (cnode->cmd_vector); i++)
- if ((cmd = vector_slot (cnode->cmd_vector, i)) != NULL
- && !(cmd->attr == CMD_ATTR_DEPRECATED
- || cmd->attr == CMD_ATTR_HIDDEN))
- vty_out (vty, " %s%s", cmd->string,
- VTY_NEWLINE);
- return CMD_SUCCESS;
+ return cmd_list_cmds (vty, argc == 2);
+}
+
+DEFUN (show_commandtree,
+ show_commandtree_cmd,
+ "show commandtree [permutations]",
+ SHOW_STR
+ "Show command tree\n")
+{
+ return cmd_list_cmds (vty, argc == 3);
}
/* Write current configuration into file. */
-DEFUN (config_write_file,
- config_write_file_cmd,
- "write file",
+
+DEFUN (config_write,
+ config_write_cmd,
+ "write [<file|memory|terminal>]",
"Write running configuration to memory, network, or terminal\n"
- "Write to configuration file\n")
+ "Write to configuration file\n"
+ "Write configuration currently in memory\n"
+ "Write configuration to terminal\n")
{
+ int idx_type = 1;
unsigned int i;
int fd, dirfd;
struct cmd_node *node;
@@ -3148,6 +1334,36 @@ DEFUN (config_write_file,
struct vty *file_vty;
struct stat conf_stat;
+ // if command was 'write terminal' or 'show running-config'
+ if (argc == 2 && (!strcmp(argv[idx_type]->text, "terminal") ||
+ !strcmp(argv[0]->text, "show")))
+ {
+ if (vty->type == VTY_SHELL_SERV)
+ {
+ for (i = 0; i < vector_active (cmdvec); i++)
+ if ((node = vector_slot (cmdvec, i)) && node->func && node->vtysh)
+ {
+ if ((*node->func) (vty))
+ vty_out (vty, "!%s", VTY_NEWLINE);
+ }
+ }
+ else
+ {
+ vty_out (vty, "%sCurrent configuration:%s", VTY_NEWLINE,
+ VTY_NEWLINE);
+ vty_out (vty, "!%s", VTY_NEWLINE);
+
+ for (i = 0; i < vector_active (cmdvec); i++)
+ if ((node = vector_slot (cmdvec, i)) && node->func)
+ {
+ if ((*node->func) (vty))
+ vty_out (vty, "!%s", VTY_NEWLINE);
+ }
+ vty_out (vty, "end%s",VTY_NEWLINE);
+ }
+ return CMD_SUCCESS;
+ }
+
if (host.noconfig)
return CMD_SUCCESS;
@@ -3155,7 +1371,7 @@ DEFUN (config_write_file,
if (host.config == NULL)
{
vty_out (vty, "Can't save to configuration file, using vtysh.%s",
- VTY_NEWLINE);
+ VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3185,16 +1401,15 @@ DEFUN (config_write_file,
config_file_tmp = XMALLOC (MTYPE_TMP, strlen (config_file) + 8);
sprintf (config_file_tmp, "%s.XXXXXX", config_file);
-
+
/* Open file to configuration write. */
fd = mkstemp (config_file_tmp);
if (fd < 0)
{
vty_out (vty, "Can't open configuration file %s.%s", config_file_tmp,
- VTY_NEWLINE);
+ VTY_NEWLINE);
goto finished;
}
-
if (fchmod (fd, CONFIGFILE_MASK) != 0)
{
vty_out (vty, "Can't chmod configuration file %s: %s (%d).%s",
@@ -3215,20 +1430,20 @@ DEFUN (config_write_file,
for (i = 0; i < vector_active (cmdvec); i++)
if ((node = vector_slot (cmdvec, i)) && node->func)
{
- if ((*node->func) (file_vty))
- vty_out (file_vty, "!\n");
+ if ((*node->func) (file_vty))
+ vty_out (file_vty, "!\n");
}
vty_close (file_vty);
if (stat(config_file, &conf_stat) >= 0)
{
if (unlink (config_file_sav) != 0)
- if (errno != ENOENT)
- {
- vty_out (vty, "Can't unlink backup configuration file %s.%s", config_file_sav,
- VTY_NEWLINE);
- goto finished;
- }
+ if (errno != ENOENT)
+ {
+ vty_out (vty, "Can't unlink backup configuration file %s.%s", config_file_sav,
+ VTY_NEWLINE);
+ goto finished;
+ }
if (link (config_file, config_file_sav) != 0)
{
vty_out (vty, "Can't backup old configuration file %s.%s", config_file_sav,
@@ -3240,13 +1455,13 @@ DEFUN (config_write_file,
if (rename (config_file_tmp, config_file) != 0)
{
vty_out (vty, "Can't save configuration file %s.%s", config_file,
- VTY_NEWLINE);
+ VTY_NEWLINE);
goto finished;
}
fsync (dirfd);
vty_out (vty, "Configuration saved to %s%s", config_file,
- VTY_NEWLINE);
+ VTY_NEWLINE);
ret = CMD_SUCCESS;
finished:
@@ -3258,76 +1473,34 @@ finished:
return ret;
}
-ALIAS (config_write_file,
- config_write_cmd,
- "write",
- "Write running configuration to memory, network, or terminal\n")
-
-ALIAS (config_write_file,
- config_write_memory_cmd,
- "write memory",
- "Write running configuration to memory, network, or terminal\n"
- "Write configuration to the file (same as write file)\n")
+/* ALIAS_FIXME for 'write <terminal|memory>' */
+DEFUN (show_running_config,
+ show_running_config_cmd,
+ "show running-config",
+ SHOW_STR
+ "running configuration (same as write terminal/memory)\n")
+{
+ return config_write (self, vty, argc, argv);
+}
-ALIAS (config_write_file,
- copy_runningconfig_startupconfig_cmd,
- "copy running-config startup-config",
+/* ALIAS_FIXME for 'write file' */
+DEFUN (copy_runningconf_startupconf,
+ copy_runningconf_startupconf_cmd,
+ "copy running-config startup-config",
"Copy configuration\n"
"Copy running config to... \n"
"Copy running config to startup config (same as write file)\n")
-
-/* Write current configuration into the terminal. */
-DEFUN (config_write_terminal,
- config_write_terminal_cmd,
- "write terminal",
- "Write running configuration to memory, network, or terminal\n"
- "Write to terminal\n")
{
- unsigned int i;
- struct cmd_node *node;
-
- if (host.noconfig)
- return CMD_SUCCESS;
-
- if (vty->type == VTY_SHELL_SERV)
- {
- for (i = 0; i < vector_active (cmdvec); i++)
- if ((node = vector_slot (cmdvec, i)) && node->func && node->vtysh)
- {
- if ((*node->func) (vty))
- vty_out (vty, "!%s", VTY_NEWLINE);
- }
- }
- else
- {
- vty_out (vty, "%sCurrent configuration:%s", VTY_NEWLINE,
- VTY_NEWLINE);
- vty_out (vty, "!%s", VTY_NEWLINE);
-
- for (i = 0; i < vector_active (cmdvec); i++)
- if ((node = vector_slot (cmdvec, i)) && node->func)
- {
- if ((*node->func) (vty))
- vty_out (vty, "!%s", VTY_NEWLINE);
- }
- vty_out (vty, "end%s",VTY_NEWLINE);
- }
- return CMD_SUCCESS;
+ return config_write (self, vty, argc, argv);
}
-
-/* Write current configuration into the terminal. */
-ALIAS (config_write_terminal,
- show_running_config_cmd,
- "show running-config",
- SHOW_STR
- "running configuration\n")
+/** -- **/
/* Write startup configuration into the terminal. */
DEFUN (show_startup_config,
show_startup_config_cmd,
"show startup-config",
SHOW_STR
- "Contentes of startup configuration\n")
+ "Contents of startup configuration\n")
{
char buf[BUFSIZ];
FILE *confp;
@@ -3341,7 +1514,7 @@ DEFUN (show_startup_config,
if (confp == NULL)
{
vty_out (vty, "Can't open configuration file [%s] due to '%s'%s",
- host.config, safe_strerror(errno), VTY_NEWLINE);
+ host.config, safe_strerror(errno), VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3350,7 +1523,7 @@ DEFUN (show_startup_config,
char *cp = buf;
while (*cp != '\r' && *cp != '\n' && *cp != '\0')
- cp++;
+ cp++;
*cp = '\0';
vty_out (vty, "%s%s", buf, VTY_NEWLINE);
@@ -3361,77 +1534,67 @@ DEFUN (show_startup_config,
return CMD_SUCCESS;
}
+int
+cmd_hostname_set (const char *hostname)
+{
+ XFREE (MTYPE_HOST, host.name);
+ host.name = hostname ? XSTRDUP (MTYPE_HOST, hostname) : NULL;
+ return CMD_SUCCESS;
+}
+
/* Hostname configuration */
-DEFUN (config_hostname,
+DEFUN (config_hostname,
hostname_cmd,
"hostname WORD",
"Set system's network name\n"
"This system's network name\n")
{
- if (!isalpha((int) *argv[0]))
+ struct cmd_token *word = argv[1];
+
+ if (!isalpha((int) word->arg[0]))
{
vty_out (vty, "Please specify string starting with alphabet%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (host.name)
- XFREE (MTYPE_HOST, host.name);
-
- host.name = XSTRDUP (MTYPE_HOST, argv[0]);
- return CMD_SUCCESS;
+ return cmd_hostname_set (word->arg);
}
-DEFUN (config_no_hostname,
+DEFUN (config_no_hostname,
no_hostname_cmd,
"no hostname [HOSTNAME]",
NO_STR
"Reset system's network name\n"
"Host name of this router\n")
{
- if (host.name)
- XFREE (MTYPE_HOST, host.name);
- host.name = NULL;
- return CMD_SUCCESS;
+ return cmd_hostname_set (NULL);
}
/* VTY interface password set. */
-DEFUN (config_password, password_cmd,
- "password (8|) WORD",
+DEFUN (config_password,
+ password_cmd,
+ "password [(8-8)] WORD",
"Assign the terminal connection password\n"
"Specifies a HIDDEN password will follow\n"
- "dummy string \n"
- "The HIDDEN line password string\n")
+ "The password string\n")
{
- /* Argument check. */
- if (argc == 0)
- {
- vty_out (vty, "Please specify password.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (argc == 2)
- {
- if (*argv[0] == '8')
- {
- if (host.password)
- XFREE (MTYPE_HOST, host.password);
- host.password = NULL;
- if (host.password_encrypt)
- XFREE (MTYPE_HOST, host.password_encrypt);
- host.password_encrypt = XSTRDUP (MTYPE_HOST, argv[1]);
- return CMD_SUCCESS;
- }
- else
- {
- vty_out (vty, "Unknown encryption type.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
+ int idx_8 = 1;
+ int idx_word = 2;
+ if (argc == 3) // '8' was specified
+ {
+ if (host.password)
+ XFREE (MTYPE_HOST, host.password);
+ host.password = NULL;
+ if (host.password_encrypt)
+ XFREE (MTYPE_HOST, host.password_encrypt);
+ host.password_encrypt = XSTRDUP (MTYPE_HOST, argv[idx_word]->arg);
+ return CMD_SUCCESS;
+ }
- if (!isalnum ((int) *argv[0]))
+ if (!isalnum (argv[idx_8]->arg[0]))
{
- vty_out (vty,
- "Please specify string starting with alphanumeric%s", VTY_NEWLINE);
+ vty_out (vty,
+ "Please specify string starting with alphanumeric%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3442,62 +1605,53 @@ DEFUN (config_password, password_cmd,
if (host.encrypt)
{
if (host.password_encrypt)
- XFREE (MTYPE_HOST, host.password_encrypt);
- host.password_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (argv[0]));
+ XFREE (MTYPE_HOST, host.password_encrypt);
+ host.password_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (argv[idx_8]->arg));
}
else
- host.password = XSTRDUP (MTYPE_HOST, argv[0]);
+ host.password = XSTRDUP (MTYPE_HOST, argv[idx_8]->arg);
return CMD_SUCCESS;
}
-ALIAS (config_password, password_text_cmd,
- "password LINE",
- "Assign the terminal connection password\n"
- "The UNENCRYPTED (cleartext) line password\n")
-
/* VTY enable password set. */
-DEFUN (config_enable_password, enable_password_cmd,
- "enable password (8|) WORD",
+DEFUN (config_enable_password,
+ enable_password_cmd,
+ "enable password [(8-8)] WORD",
"Modify enable password parameters\n"
"Assign the privileged level password\n"
"Specifies a HIDDEN password will follow\n"
- "dummy string \n"
"The HIDDEN 'enable' password string\n")
{
- /* Argument check. */
- if (argc == 0)
- {
- vty_out (vty, "Please specify password.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ int idx_8 = 2;
+ int idx_word = 3;
/* Crypt type is specified. */
- if (argc == 2)
+ if (argc == 4)
{
- if (*argv[0] == '8')
- {
- if (host.enable)
- XFREE (MTYPE_HOST, host.enable);
- host.enable = NULL;
-
- if (host.enable_encrypt)
- XFREE (MTYPE_HOST, host.enable_encrypt);
- host.enable_encrypt = XSTRDUP (MTYPE_HOST, argv[1]);
-
- return CMD_SUCCESS;
- }
+ if (argv[idx_8]->arg[0] == '8')
+ {
+ if (host.enable)
+ XFREE (MTYPE_HOST, host.enable);
+ host.enable = NULL;
+
+ if (host.enable_encrypt)
+ XFREE (MTYPE_HOST, host.enable_encrypt);
+ host.enable_encrypt = XSTRDUP (MTYPE_HOST, argv[idx_word]->arg);
+
+ return CMD_SUCCESS;
+ }
else
- {
- vty_out (vty, "Unknown encryption type.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ {
+ vty_out (vty, "Unknown encryption type.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
}
- if (!isalnum ((int) *argv[0]))
+ if (!isalnum (argv[idx_8]->arg[0]))
{
- vty_out (vty,
- "Please specify string starting with alphanumeric%s", VTY_NEWLINE);
+ vty_out (vty,
+ "Please specify string starting with alphanumeric%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -3509,24 +1663,18 @@ DEFUN (config_enable_password, enable_password_cmd,
if (host.encrypt)
{
if (host.enable_encrypt)
- XFREE (MTYPE_HOST, host.enable_encrypt);
- host.enable_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (argv[0]));
+ XFREE (MTYPE_HOST, host.enable_encrypt);
+ host.enable_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (argv[idx_8]->arg));
}
else
- host.enable = XSTRDUP (MTYPE_HOST, argv[0]);
+ host.enable = XSTRDUP (MTYPE_HOST, argv[idx_8]->arg);
return CMD_SUCCESS;
}
-ALIAS (config_enable_password,
- enable_password_text_cmd,
- "enable password LINE",
- "Modify enable password parameters\n"
- "Assign the privileged level password\n"
- "The UNENCRYPTED (cleartext) 'enable' password\n")
-
/* VTY enable password delete. */
-DEFUN (no_config_enable_password, no_enable_password_cmd,
+DEFUN (no_config_enable_password,
+ no_enable_password_cmd,
"no enable password",
NO_STR
"Modify enable password parameters\n"
@@ -3542,7 +1690,7 @@ DEFUN (no_config_enable_password, no_enable_password_cmd,
return CMD_SUCCESS;
}
-
+
DEFUN (service_password_encrypt,
service_password_encrypt_cmd,
"service password-encryption",
@@ -3557,13 +1705,13 @@ DEFUN (service_password_encrypt,
if (host.password)
{
if (host.password_encrypt)
- XFREE (MTYPE_HOST, host.password_encrypt);
+ XFREE (MTYPE_HOST, host.password_encrypt);
host.password_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (host.password));
}
if (host.enable)
{
if (host.enable_encrypt)
- XFREE (MTYPE_HOST, host.enable_encrypt);
+ XFREE (MTYPE_HOST, host.enable_encrypt);
host.enable_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (host.enable));
}
@@ -3593,16 +1741,18 @@ DEFUN (no_service_password_encrypt,
return CMD_SUCCESS;
}
-DEFUN (config_terminal_length, config_terminal_length_cmd,
- "terminal length <0-512>",
+DEFUN (config_terminal_length,
+ config_terminal_length_cmd,
+ "terminal length (0-512)",
"Set terminal line parameters\n"
"Set number of lines on a screen\n"
"Number of lines on screen (0 for no pausing)\n")
{
+ int idx_number = 2;
int lines;
char *endptr = NULL;
- lines = strtol (argv[0], &endptr, 10);
+ lines = strtol (argv[idx_number]->arg, &endptr, 10);
if (lines < 0 || lines > 512 || *endptr != '\0')
{
vty_out (vty, "length is malformed%s", VTY_NEWLINE);
@@ -3613,7 +1763,8 @@ DEFUN (config_terminal_length, config_terminal_length_cmd,
return CMD_SUCCESS;
}
-DEFUN (config_terminal_no_length, config_terminal_no_length_cmd,
+DEFUN (config_terminal_no_length,
+ config_terminal_no_length_cmd,
"terminal no length",
"Set terminal line parameters\n"
NO_STR
@@ -3623,16 +1774,18 @@ DEFUN (config_terminal_no_length, config_terminal_no_length_cmd,
return CMD_SUCCESS;
}
-DEFUN (service_terminal_length, service_terminal_length_cmd,
- "service terminal-length <0-512>",
+DEFUN (service_terminal_length,
+ service_terminal_length_cmd,
+ "service terminal-length (0-512)",
"Set up miscellaneous service\n"
"System wide terminal length configuration\n"
"Number of lines of VTY (0 means no line control)\n")
{
+ int idx_number = 2;
int lines;
char *endptr = NULL;
- lines = strtol (argv[0], &endptr, 10);
+ lines = strtol (argv[idx_number]->arg, &endptr, 10);
if (lines < 0 || lines > 512 || *endptr != '\0')
{
vty_out (vty, "length is malformed%s", VTY_NEWLINE);
@@ -3643,8 +1796,9 @@ DEFUN (service_terminal_length, service_terminal_length_cmd,
return CMD_SUCCESS;
}
-DEFUN (no_service_terminal_length, no_service_terminal_length_cmd,
- "no service terminal-length [<0-512>]",
+DEFUN (no_service_terminal_length,
+ no_service_terminal_length_cmd,
+ "no service terminal-length [(0-512)]",
NO_STR
"Set up miscellaneous service\n"
"System wide terminal length configuration\n"
@@ -3655,15 +1809,15 @@ DEFUN (no_service_terminal_length, no_service_terminal_length_cmd,
}
DEFUN_HIDDEN (do_echo,
- echo_cmd,
- "echo .MESSAGE",
- "Echo a message back to the vty\n"
- "The message to echo\n")
+ echo_cmd,
+ "echo MESSAGE...",
+ "Echo a message back to the vty\n"
+ "The message to echo\n")
{
char *message;
- vty_out (vty, "%s%s", ((message = argv_concat(argv, argc, 0)) ? message : ""),
- VTY_NEWLINE);
+ vty_out (vty, "%s%s", ((message = argv_concat (argv, argc, 1)) ? message : ""),
+ VTY_NEWLINE);
if (message)
XFREE(MTYPE_TMP, message);
return CMD_SUCCESS;
@@ -3671,18 +1825,20 @@ DEFUN_HIDDEN (do_echo,
DEFUN (config_logmsg,
config_logmsg_cmd,
- "logmsg "LOG_LEVELS" .MESSAGE",
+ "logmsg <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging> MESSAGE...",
"Send a message to enabled logging destinations\n"
LOG_LEVEL_DESC
"The message to send\n")
{
+ int idx_log_level = 1;
+ int idx_message = 2;
int level;
char *message;
- if ((level = level_match(argv[0])) == ZLOG_DISABLED)
+ if ((level = level_match(argv[idx_log_level]->arg)) == ZLOG_DISABLED)
return CMD_ERR_NO_MATCH;
- zlog(NULL, level, "%s", ((message = argv_concat(argv, argc, 1)) ? message : ""));
+ zlog(NULL, level, "%s", ((message = argv_concat(argv, argc, idx_message)) ? message : ""));
if (message)
XFREE(MTYPE_TMP, message);
@@ -3702,8 +1858,8 @@ DEFUN (show_logging,
vty_out (vty, "disabled");
else
vty_out (vty, "level %s, facility %s, ident %s",
- zlog_priority[zl->maxlvl[ZLOG_DEST_SYSLOG]],
- facility_name(zl->facility), zl->ident);
+ zlog_priority[zl->maxlvl[ZLOG_DEST_SYSLOG]],
+ facility_name(zl->facility), zl->ident);
vty_out (vty, "%s", VTY_NEWLINE);
vty_out (vty, "Stdout logging: ");
@@ -3711,7 +1867,7 @@ DEFUN (show_logging,
vty_out (vty, "disabled");
else
vty_out (vty, "level %s",
- zlog_priority[zl->maxlvl[ZLOG_DEST_STDOUT]]);
+ zlog_priority[zl->maxlvl[ZLOG_DEST_STDOUT]]);
vty_out (vty, "%s", VTY_NEWLINE);
vty_out (vty, "Monitor logging: ");
@@ -3719,7 +1875,7 @@ DEFUN (show_logging,
vty_out (vty, "disabled");
else
vty_out (vty, "level %s",
- zlog_priority[zl->maxlvl[ZLOG_DEST_MONITOR]]);
+ zlog_priority[zl->maxlvl[ZLOG_DEST_MONITOR]]);
vty_out (vty, "%s", VTY_NEWLINE);
vty_out (vty, "File logging: ");
@@ -3728,40 +1884,37 @@ DEFUN (show_logging,
vty_out (vty, "disabled");
else
vty_out (vty, "level %s, filename %s",
- zlog_priority[zl->maxlvl[ZLOG_DEST_FILE]],
- zl->filename);
+ zlog_priority[zl->maxlvl[ZLOG_DEST_FILE]],
+ zl->filename);
vty_out (vty, "%s", VTY_NEWLINE);
vty_out (vty, "Protocol name: %s%s",
- zlog_proto_names[zl->protocol], VTY_NEWLINE);
+ zlog_proto_names[zl->protocol], VTY_NEWLINE);
vty_out (vty, "Record priority: %s%s",
- (zl->record_priority ? "enabled" : "disabled"), VTY_NEWLINE);
+ (zl->record_priority ? "enabled" : "disabled"), VTY_NEWLINE);
vty_out (vty, "Timestamp precision: %d%s",
- zl->timestamp_precision, VTY_NEWLINE);
+ zl->timestamp_precision, VTY_NEWLINE);
return CMD_SUCCESS;
}
DEFUN (config_log_stdout,
config_log_stdout_cmd,
- "log stdout",
- "Logging control\n"
- "Set stdout logging level\n")
-{
- zlog_set_level (NULL, ZLOG_DEST_STDOUT, zlog_default->default_lvl);
- return CMD_SUCCESS;
-}
-
-DEFUN (config_log_stdout_level,
- config_log_stdout_level_cmd,
- "log stdout "LOG_LEVELS,
+ "log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
"Logging control\n"
"Set stdout logging level\n"
LOG_LEVEL_DESC)
{
+ int idx_log_level = 2;
+
+ if (argc == idx_log_level)
+ {
+ zlog_set_level (NULL, ZLOG_DEST_STDOUT, zlog_default->default_lvl);
+ return CMD_SUCCESS;
+ }
int level;
- if ((level = level_match(argv[0])) == ZLOG_DISABLED)
+ if ((level = level_match(argv[idx_log_level]->arg)) == ZLOG_DISABLED)
return CMD_ERR_NO_MATCH;
zlog_set_level (NULL, ZLOG_DEST_STDOUT, level);
return CMD_SUCCESS;
@@ -3769,11 +1922,11 @@ DEFUN (config_log_stdout_level,
DEFUN (no_config_log_stdout,
no_config_log_stdout_cmd,
- "no log stdout [LEVEL]",
+ "no log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
NO_STR
"Logging control\n"
"Cancel logging to stdout\n"
- "Logging level\n")
+ LOG_LEVEL_DESC)
{
zlog_set_level (NULL, ZLOG_DEST_STDOUT, ZLOG_DISABLED);
return CMD_SUCCESS;
@@ -3781,24 +1934,21 @@ DEFUN (no_config_log_stdout,
DEFUN (config_log_monitor,
config_log_monitor_cmd,
- "log monitor",
- "Logging control\n"
- "Set terminal line (monitor) logging level\n")
-{
- zlog_set_level (NULL, ZLOG_DEST_MONITOR, zlog_default->default_lvl);
- return CMD_SUCCESS;
-}
-
-DEFUN (config_log_monitor_level,
- config_log_monitor_level_cmd,
- "log monitor "LOG_LEVELS,
+ "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
"Logging control\n"
"Set terminal line (monitor) logging level\n"
LOG_LEVEL_DESC)
{
+ int idx_log_level = 2;
+
+ if (argc == idx_log_level)
+ {
+ zlog_set_level (NULL, ZLOG_DEST_MONITOR, zlog_default->default_lvl);
+ return CMD_SUCCESS;
+ }
int level;
- if ((level = level_match(argv[0])) == ZLOG_DISABLED)
+ if ((level = level_match(argv[idx_log_level]->arg)) == ZLOG_DISABLED)
return CMD_ERR_NO_MATCH;
zlog_set_level (NULL, ZLOG_DEST_MONITOR, level);
return CMD_SUCCESS;
@@ -3806,11 +1956,11 @@ DEFUN (config_log_monitor_level,
DEFUN (no_config_log_monitor,
no_config_log_monitor_cmd,
- "no log monitor [LEVEL]",
+ "no log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
NO_STR
"Logging control\n"
"Disable terminal line (monitor) logging\n"
- "Logging level\n")
+ LOG_LEVEL_DESC)
{
zlog_set_level (NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
return CMD_SUCCESS;
@@ -3822,19 +1972,19 @@ set_log_file(struct vty *vty, const char *fname, int loglevel)
int ret;
char *p = NULL;
const char *fullpath;
-
+
/* Path detection. */
if (! IS_DIRECTORY_SEP (*fname))
{
char cwd[MAXPATHLEN+1];
cwd[MAXPATHLEN] = '\0';
-
+
if (getcwd (cwd, MAXPATHLEN) == NULL)
{
zlog_err ("config_log_file: Unable to alloc mem!");
return CMD_WARNING;
}
-
+
if ( (p = XMALLOC (MTYPE_TMP, strlen (cwd) + strlen (fname) + 2))
== NULL)
{
@@ -3872,36 +2022,34 @@ set_log_file(struct vty *vty, const char *fname, int loglevel)
DEFUN (config_log_file,
config_log_file_cmd,
- "log file FILENAME",
- "Logging control\n"
- "Logging to file\n"
- "Logging filename\n")
-{
- return set_log_file(vty, argv[0], zlog_default->default_lvl);
-}
-
-DEFUN (config_log_file_level,
- config_log_file_level_cmd,
- "log file FILENAME "LOG_LEVELS,
+ "log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
"Logging control\n"
"Logging to file\n"
"Logging filename\n"
LOG_LEVEL_DESC)
{
- int level;
-
- if ((level = level_match(argv[1])) == ZLOG_DISABLED)
- return CMD_ERR_NO_MATCH;
- return set_log_file(vty, argv[0], level);
+ int idx_filename = 2;
+ int idx_log_levels = 3;
+ if (argc == 4)
+ {
+ int level;
+ if ((level = level_match(argv[idx_log_levels]->arg)) == ZLOG_DISABLED)
+ return CMD_ERR_NO_MATCH;
+ return set_log_file(vty, argv[idx_filename]->arg, level);
+ }
+ else
+ return set_log_file(vty, argv[idx_filename]->arg, zlog_default->default_lvl);
}
DEFUN (no_config_log_file,
no_config_log_file_cmd,
- "no log file [FILENAME]",
+ "no log file [FILENAME [LEVEL]]",
NO_STR
"Logging control\n"
"Cancel logging to file\n"
- "Logging file name\n")
+ "Logging file name\n"
+ "Logging file name\n"
+ "Logging level\n")
{
zlog_reset_file (NULL);
@@ -3913,117 +2061,79 @@ DEFUN (no_config_log_file,
return CMD_SUCCESS;
}
-ALIAS (no_config_log_file,
- no_config_log_file_level_cmd,
- "no log file FILENAME LEVEL",
- NO_STR
- "Logging control\n"
- "Cancel logging to file\n"
- "Logging file name\n"
- "Logging level\n")
-
DEFUN (config_log_syslog,
config_log_syslog_cmd,
- "log syslog",
- "Logging control\n"
- "Set syslog logging level\n")
-{
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
- return CMD_SUCCESS;
-}
-
-DEFUN (config_log_syslog_level,
- config_log_syslog_level_cmd,
- "log syslog "LOG_LEVELS,
+ "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
"Logging control\n"
"Set syslog logging level\n"
LOG_LEVEL_DESC)
{
- int level;
-
- if ((level = level_match(argv[0])) == ZLOG_DISABLED)
- return CMD_ERR_NO_MATCH;
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, level);
- return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED (config_log_syslog_facility,
- config_log_syslog_facility_cmd,
- "log syslog facility "LOG_FACILITIES,
- "Logging control\n"
- "Logging goes to syslog\n"
- "(Deprecated) Facility parameter for syslog messages\n"
- LOG_FACILITY_DESC)
-{
- int facility;
-
- if ((facility = facility_match(argv[0])) < 0)
- return CMD_ERR_NO_MATCH;
-
- zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
- zlog_default->facility = facility;
- return CMD_SUCCESS;
+ int idx_log_levels = 2;
+ if (argc == 3)
+ {
+ int level;
+ if ((level = level_match (argv[idx_log_levels]->arg)) == ZLOG_DISABLED)
+ return CMD_ERR_NO_MATCH;
+ zlog_set_level (NULL, ZLOG_DEST_SYSLOG, level);
+ return CMD_SUCCESS;
+ }
+ else
+ {
+ zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
+ return CMD_SUCCESS;
+ }
}
DEFUN (no_config_log_syslog,
no_config_log_syslog_cmd,
- "no log syslog [LEVEL]",
+ "no log syslog [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>] [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
NO_STR
"Logging control\n"
"Cancel logging to syslog\n"
- "Logging level\n")
+ LOG_FACILITY_DESC
+ LOG_LEVEL_DESC)
{
zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
return CMD_SUCCESS;
}
-ALIAS (no_config_log_syslog,
- no_config_log_syslog_facility_cmd,
- "no log syslog facility "LOG_FACILITIES,
- NO_STR
- "Logging control\n"
- "Logging goes to syslog\n"
- "Facility parameter for syslog messages\n"
- LOG_FACILITY_DESC)
-
DEFUN (config_log_facility,
config_log_facility_cmd,
- "log facility "LOG_FACILITIES,
+ "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>",
"Logging control\n"
"Facility parameter for syslog messages\n"
LOG_FACILITY_DESC)
{
- int facility;
+ int idx_target = 2;
+ int facility = facility_match(argv[idx_target]->arg);
- if ((facility = facility_match(argv[0])) < 0)
- return CMD_ERR_NO_MATCH;
zlog_default->facility = facility;
return CMD_SUCCESS;
}
DEFUN (no_config_log_facility,
no_config_log_facility_cmd,
- "no log facility [FACILITY]",
+ "no log facility [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>]",
NO_STR
"Logging control\n"
"Reset syslog facility to default (daemon)\n"
- "Syslog facility\n")
+ LOG_FACILITY_DESC)
{
zlog_default->facility = LOG_DAEMON;
return CMD_SUCCESS;
}
DEFUN_DEPRECATED (config_log_trap,
- config_log_trap_cmd,
- "log trap "LOG_LEVELS,
- "Logging control\n"
- "(Deprecated) Set logging level and default for all destinations\n"
- LOG_LEVEL_DESC)
+ config_log_trap_cmd,
+ "log trap <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
+ "Logging control\n"
+ "(Deprecated) Set logging level and default for all destinations\n"
+ LOG_LEVEL_DESC)
{
int new_level ;
int i;
-
- if ((new_level = level_match(argv[0])) == ZLOG_DISABLED)
+
+ if ((new_level = level_match(argv[2]->arg)) == ZLOG_DISABLED)
return CMD_ERR_NO_MATCH;
zlog_default->default_lvl = new_level;
@@ -4034,12 +2144,12 @@ DEFUN_DEPRECATED (config_log_trap,
}
DEFUN_DEPRECATED (no_config_log_trap,
- no_config_log_trap_cmd,
- "no log trap [LEVEL]",
- NO_STR
- "Logging control\n"
- "Permit all logging information\n"
- "Logging level\n")
+ no_config_log_trap_cmd,
+ "no log trap [emergencies|alerts|critical|errors|warnings|notifications|informational|debugging]",
+ NO_STR
+ "Logging control\n"
+ "Permit all logging information\n"
+ LOG_LEVEL_DESC)
{
zlog_default->default_lvl = LOG_DEBUG;
return CMD_SUCCESS;
@@ -4068,20 +2178,15 @@ DEFUN (no_config_log_record_priority,
DEFUN (config_log_timestamp_precision,
config_log_timestamp_precision_cmd,
- "log timestamp precision <0-6>",
+ "log timestamp precision (0-6)",
"Logging control\n"
"Timestamp configuration\n"
"Set the timestamp precision\n"
"Number of subsecond digits\n")
{
- if (argc != 1)
- {
- vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
+ int idx_number = 3;
VTY_GET_INTEGER_RANGE("Timestamp Precision",
- zlog_default->timestamp_precision, argv[0], 0, 6);
+ zlog_default->timestamp_precision, argv[idx_number]->arg, 0, 6);
return CMD_SUCCESS;
}
@@ -4112,7 +2217,7 @@ cmd_banner_motd_file (const char *file)
if (in == rpath)
{
if (host.motdfile)
- XFREE (MTYPE_HOST, host.motdfile);
+ XFREE (MTYPE_HOST, host.motdfile);
host.motdfile = XSTRDUP (MTYPE_HOST, file);
}
else
@@ -4129,13 +2234,14 @@ DEFUN (banner_motd_file,
"Banner from a file\n"
"Filename\n")
{
- int cmd = cmd_banner_motd_file (argv[0]);
+ int idx_file = 3;
+ const char *filename = argv[idx_file]->arg;
+ int cmd = cmd_banner_motd_file (filename);
if (cmd == CMD_ERR_NO_FILE)
- vty_out (vty, "%s does not exist", argv[0]);
+ vty_out (vty, "%s does not exist", filename);
else if (cmd == CMD_WARNING)
- vty_out (vty, "%s must be in %s",
- argv[0], SYSCONFDIR);
+ vty_out (vty, "%s must be in %s", filename, SYSCONFDIR);
return cmd;
}
@@ -4159,43 +2265,12 @@ DEFUN (no_banner_motd,
"Strings for motd\n")
{
host.motd = NULL;
- if (host.motdfile)
+ if (host.motdfile)
XFREE (MTYPE_HOST, host.motdfile);
host.motdfile = NULL;
return CMD_SUCCESS;
}
-DEFUN (show_commandtree,
- show_commandtree_cmd,
- "show commandtree",
- NO_STR
- "Show command tree\n")
-{
- /* TBD */
- vector cmd_vector;
- unsigned int i;
-
- vty_out (vty, "Current node id: %d%s", vty->node, VTY_NEWLINE);
-
- /* vector of all commands installed at this node */
- cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
-
- /* loop over all commands at this node */
- for (i = 0; i < vector_active(cmd_vector); ++i)
- {
- struct cmd_element *cmd_element;
-
- /* A cmd_element (seems to be) is an individual command */
- if ((cmd_element = vector_slot (cmd_vector, i)) == NULL)
- continue;
-
- vty_out (vty, " %s%s", cmd_element->string, VTY_NEWLINE);
- }
-
- vector_free (cmd_vector);
- return CMD_SUCCESS;
-}
-
/* Set config filename. Called from vty.c */
void
host_config_set (const char *filename)
@@ -4220,9 +2295,6 @@ install_default (enum node_type node)
install_element (node, &config_help_cmd);
install_element (node, &config_list_cmd);
- install_element (node, &config_write_terminal_cmd);
- install_element (node, &config_write_file_cmd);
- install_element (node, &config_write_memory_cmd);
install_element (node, &config_write_cmd);
install_element (node, &show_running_config_cmd);
}
@@ -4237,12 +2309,6 @@ cmd_init (int terminal)
{
qobj_init ();
- command_cr = XSTRDUP(MTYPE_CMD_TOKENS, "<cr>");
- token_cr.type = TOKEN_TERMINAL;
- token_cr.terminal = TERMINAL_LITERAL;
- token_cr.cmd = command_cr;
- token_cr.desc = XSTRDUP(MTYPE_CMD_TOKENS, "");
-
/* Allocate initial top vector of commands. */
cmdvec = vector_init (VECTOR_MIN_SIZE);
@@ -4285,10 +2351,7 @@ cmd_init (int terminal)
install_element (ENABLE_NODE, &config_end_cmd);
install_element (ENABLE_NODE, &config_disable_cmd);
install_element (ENABLE_NODE, &config_terminal_cmd);
- install_element (ENABLE_NODE, &copy_runningconfig_startupconfig_cmd);
- install_element (ENABLE_NODE, &config_write_terminal_cmd);
- install_element (ENABLE_NODE, &config_write_file_cmd);
- install_element (ENABLE_NODE, &config_write_memory_cmd);
+ install_element (ENABLE_NODE, &copy_runningconf_startupconf_cmd);
install_element (ENABLE_NODE, &config_write_cmd);
install_element (ENABLE_NODE, &show_running_config_cmd);
}
@@ -4299,38 +2362,27 @@ cmd_init (int terminal)
install_element (ENABLE_NODE, &config_logmsg_cmd);
install_default (CONFIG_NODE);
- install_element (VIEW_NODE, &show_thread_cpu_cmd);
- install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
-
- install_element (VIEW_NODE, &show_work_queues_cmd);
+ thread_cmd_init ();
+ workqueue_cmd_init ();
}
-
+
install_element (CONFIG_NODE, &hostname_cmd);
install_element (CONFIG_NODE, &no_hostname_cmd);
if (terminal > 0)
{
install_element (CONFIG_NODE, &password_cmd);
- install_element (CONFIG_NODE, &password_text_cmd);
install_element (CONFIG_NODE, &enable_password_cmd);
- install_element (CONFIG_NODE, &enable_password_text_cmd);
install_element (CONFIG_NODE, &no_enable_password_cmd);
install_element (CONFIG_NODE, &config_log_stdout_cmd);
- install_element (CONFIG_NODE, &config_log_stdout_level_cmd);
install_element (CONFIG_NODE, &no_config_log_stdout_cmd);
install_element (CONFIG_NODE, &config_log_monitor_cmd);
- install_element (CONFIG_NODE, &config_log_monitor_level_cmd);
install_element (CONFIG_NODE, &no_config_log_monitor_cmd);
install_element (CONFIG_NODE, &config_log_file_cmd);
- install_element (CONFIG_NODE, &config_log_file_level_cmd);
install_element (CONFIG_NODE, &no_config_log_file_cmd);
- install_element (CONFIG_NODE, &no_config_log_file_level_cmd);
install_element (CONFIG_NODE, &config_log_syslog_cmd);
- install_element (CONFIG_NODE, &config_log_syslog_level_cmd);
- install_element (CONFIG_NODE, &config_log_syslog_facility_cmd);
install_element (CONFIG_NODE, &no_config_log_syslog_cmd);
- install_element (CONFIG_NODE, &no_config_log_syslog_facility_cmd);
install_element (CONFIG_NODE, &config_log_facility_cmd);
install_element (CONFIG_NODE, &no_config_log_facility_cmd);
install_element (CONFIG_NODE, &config_log_trap_cmd);
@@ -4350,89 +2402,77 @@ cmd_init (int terminal)
vrf_install_commands ();
}
srandom(time(NULL));
+
+#ifdef DEV_BUILD
+ grammar_sandbox_init();
+#endif
}
-static void
-cmd_terminate_token(struct cmd_token *token)
+struct cmd_token *
+new_cmd_token (enum cmd_token_type type, u_char attr,
+ const char *text, const char *desc)
{
- unsigned int i, j;
- vector keyword_vect;
+ struct cmd_token *token = XCALLOC (MTYPE_CMD_TOKENS, sizeof (struct cmd_token));
+ token->type = type;
+ token->attr = attr;
+ token->text = text ? XSTRDUP (MTYPE_CMD_TEXT, text) : NULL;
+ token->desc = desc ? XSTRDUP (MTYPE_CMD_DESC, desc) : NULL;
+ token->arg = NULL;
+ token->allowrepeat = false;
- if (token->multiple)
- {
- for (i = 0; i < vector_active(token->multiple); i++)
- cmd_terminate_token(vector_slot(token->multiple, i));
- vector_free(token->multiple);
- token->multiple = NULL;
- }
+ return token;
+}
- if (token->keyword)
- {
- for (i = 0; i < vector_active(token->keyword); i++)
- {
- keyword_vect = vector_slot(token->keyword, i);
- for (j = 0; j < vector_active(keyword_vect); j++)
- cmd_terminate_token(vector_slot(keyword_vect, j));
- vector_free(keyword_vect);
- }
- vector_free(token->keyword);
- token->keyword = NULL;
- }
+void
+del_cmd_token (struct cmd_token *token)
+{
+ if (!token) return;
- XFREE(MTYPE_CMD_TOKENS, token->cmd);
- XFREE(MTYPE_CMD_TOKENS, token->desc);
+ if (token->text)
+ XFREE (MTYPE_CMD_TEXT, token->text);
+ if (token->desc)
+ XFREE (MTYPE_CMD_DESC, token->desc);
+ if (token->arg)
+ XFREE (MTYPE_CMD_ARG, token->arg);
- XFREE(MTYPE_CMD_TOKENS, token);
+ XFREE (MTYPE_CMD_TOKENS, token);
}
-static void
-cmd_terminate_element(struct cmd_element *cmd)
+struct cmd_token *
+copy_cmd_token (struct cmd_token *token)
{
- unsigned int i;
-
- if (cmd->tokens == NULL)
- return;
+ struct cmd_token *copy = new_cmd_token (token->type, token->attr, NULL, NULL);
+ copy->max = token->max;
+ copy->min = token->min;
+ copy->text = token->text ? XSTRDUP (MTYPE_CMD_TEXT, token->text) : NULL;
+ copy->desc = token->desc ? XSTRDUP (MTYPE_CMD_DESC, token->desc) : NULL;
+ copy->arg = token->arg ? XSTRDUP (MTYPE_CMD_ARG, token->arg) : NULL;
- for (i = 0; i < vector_active(cmd->tokens); i++)
- cmd_terminate_token(vector_slot(cmd->tokens, i));
-
- vector_free(cmd->tokens);
- cmd->tokens = NULL;
+ return copy;
}
void
cmd_terminate ()
{
- unsigned int i, j;
struct cmd_node *cmd_node;
- struct cmd_element *cmd_element;
- vector cmd_node_v;
if (cmdvec)
{
- for (i = 0; i < vector_active (cmdvec); i++)
+ for (unsigned int i = 0; i < vector_active (cmdvec); i++)
if ((cmd_node = vector_slot (cmdvec, i)) != NULL)
- {
- cmd_node_v = cmd_node->cmd_vector;
-
- for (j = 0; j < vector_active (cmd_node_v); j++)
- if ((cmd_element = vector_slot (cmd_node_v, j)) != NULL)
- cmd_terminate_element(cmd_element);
-
- vector_free (cmd_node_v);
- hash_clean (cmd_node->cmd_hash, NULL);
- hash_free (cmd_node->cmd_hash);
- cmd_node->cmd_hash = NULL;
- }
+ {
+ // deleting the graph delets the cmd_element as well
+ graph_delete_graph (cmd_node->cmdgraph);
+ vector_free (cmd_node->cmd_vector);
+ hash_clean (cmd_node->cmd_hash, NULL);
+ hash_free (cmd_node->cmd_hash);
+ cmd_node->cmd_hash = NULL;
+ }
vector_free (cmdvec);
cmdvec = NULL;
}
- if (command_cr)
- XFREE(MTYPE_CMD_TOKENS, command_cr);
- if (token_cr.desc)
- XFREE(MTYPE_CMD_TOKENS, token_cr.desc);
if (host.name)
XFREE (MTYPE_HOST, host.name);
if (host.password)
diff --git a/lib/command.h b/lib/command.h
index d2fc969d70..04bba9e412 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -8,7 +8,7 @@
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2, or (at your
* option) any later version.
- *
+ *
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -26,10 +26,12 @@
#include "vector.h"
#include "vty.h"
#include "lib/route_types.h"
+#include "graph.h"
#include "memory.h"
#include "hash.h"
DECLARE_MTYPE(HOST)
+DECLARE_MTYPE(CMD_ARG)
/* for test-commands.c */
DECLARE_MTYPE(STRVEC)
@@ -68,42 +70,43 @@ struct host
};
/* There are some command levels which called from command node. */
-enum node_type
+enum node_type
{
- AUTH_NODE, /* Authentication mode of vty interface. */
- VIEW_NODE, /* View node. Default mode of vty interface. */
- AUTH_ENABLE_NODE, /* Authentication mode for change enable. */
- ENABLE_NODE, /* Enable node. */
- CONFIG_NODE, /* Config node. Default mode of config file. */
- SERVICE_NODE, /* Service node. */
- DEBUG_NODE, /* Debug node. */
+ AUTH_NODE, /* Authentication mode of vty interface. */
+ VIEW_NODE, /* View node. Default mode of vty interface. */
+ AUTH_ENABLE_NODE, /* Authentication mode for change enable. */
+ ENABLE_NODE, /* Enable node. */
+ CONFIG_NODE, /* Config node. Default mode of config file. */
+ SERVICE_NODE, /* Service node. */
+ DEBUG_NODE, /* Debug node. */
VRF_DEBUG_NODE, /* Vrf Debug node. */
DEBUG_VNC_NODE, /* Debug VNC node. */
- AAA_NODE, /* AAA node. */
- KEYCHAIN_NODE, /* Key-chain node. */
- KEYCHAIN_KEY_NODE, /* Key-chain key node. */
- NS_NODE, /* Logical-Router node. */
- VRF_NODE, /* VRF mode node. */
- INTERFACE_NODE, /* Interface mode node. */
- ZEBRA_NODE, /* zebra connection node. */
- TABLE_NODE, /* rtm_table selection node. */
- RIP_NODE, /* RIP protocol mode node. */
- RIPNG_NODE, /* RIPng protocol mode node. */
- BGP_NODE, /* BGP protocol mode which includes BGP4+ */
- BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */
- BGP_VPNV6_NODE, /* BGP MPLS-VPN PE exchange. */
- BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */
- BGP_IPV4M_NODE, /* BGP IPv4 multicast address family. */
- BGP_IPV6_NODE, /* BGP IPv6 address family */
- BGP_IPV6M_NODE, /* BGP IPv6 multicast address family. */
- BGP_ENCAP_NODE, /* BGP ENCAP SAFI */
- BGP_ENCAPV6_NODE, /* BGP ENCAP SAFI */
+ AAA_NODE, /* AAA node. */
+ KEYCHAIN_NODE, /* Key-chain node. */
+ KEYCHAIN_KEY_NODE, /* Key-chain key node. */
+ NS_NODE, /* Logical-Router node. */
+ VRF_NODE, /* VRF mode node. */
+ INTERFACE_NODE, /* Interface mode node. */
+ ZEBRA_NODE, /* zebra connection node. */
+ TABLE_NODE, /* rtm_table selection node. */
+ RIP_NODE, /* RIP protocol mode node. */
+ RIPNG_NODE, /* RIPng protocol mode node. */
+ BGP_NODE, /* BGP protocol mode which includes BGP4+ */
+ BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */
+ BGP_VPNV6_NODE, /* BGP MPLS-VPN PE exchange. */
+ BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */
+ BGP_IPV4M_NODE, /* BGP IPv4 multicast address family. */
+ BGP_IPV6_NODE, /* BGP IPv6 address family */
+ BGP_IPV6M_NODE, /* BGP IPv6 multicast address family. */
+ BGP_ENCAP_NODE, /* BGP ENCAP SAFI */
+ BGP_ENCAPV6_NODE, /* BGP ENCAP SAFI */
+ BGP_VRF_POLICY_NODE, /* BGP VRF policy */
BGP_VNC_DEFAULTS_NODE, /* BGP VNC nve defaults */
BGP_VNC_NVE_GROUP_NODE, /* BGP VNC nve group */
BGP_VNC_L2_GROUP_NODE, /* BGP VNC L2 group */
RFP_DEFAULTS_NODE, /* RFP defaults node */
- OSPF_NODE, /* OSPF protocol mode */
- OSPF6_NODE, /* OSPF protocol for IPv6 mode */
+ OSPF_NODE, /* OSPF protocol mode */
+ OSPF6_NODE, /* OSPF protocol for IPv6 mode */
LDP_NODE, /* LDP protocol mode */
LDP_IPV4_NODE, /* LDP IPv4 address family */
LDP_IPV6_NODE, /* LDP IPv6 address family */
@@ -111,43 +114,46 @@ enum node_type
LDP_IPV6_IFACE_NODE, /* LDP IPv6 Interface */
LDP_L2VPN_NODE, /* LDP L2VPN node */
LDP_PSEUDOWIRE_NODE, /* LDP Pseudowire node */
- ISIS_NODE, /* ISIS protocol mode */
- PIM_NODE, /* PIM protocol mode */
- MASC_NODE, /* MASC for multicast. */
- IRDP_NODE, /* ICMP Router Discovery Protocol mode. */
- IP_NODE, /* Static ip route node. */
- ACCESS_NODE, /* Access list node. */
- PREFIX_NODE, /* Prefix list node. */
- ACCESS_IPV6_NODE, /* Access list node. */
- PREFIX_IPV6_NODE, /* Prefix list node. */
- AS_LIST_NODE, /* AS list node. */
- COMMUNITY_LIST_NODE, /* Community list node. */
- RMAP_NODE, /* Route map node. */
- SMUX_NODE, /* SNMP configuration node. */
- DUMP_NODE, /* Packet dump node. */
- FORWARDING_NODE, /* IP forwarding node. */
+ ISIS_NODE, /* ISIS protocol mode */
+ PIM_NODE, /* PIM protocol mode */
+ MASC_NODE, /* MASC for multicast. */
+ IRDP_NODE, /* ICMP Router Discovery Protocol mode. */
+ IP_NODE, /* Static ip route node. */
+ ACCESS_NODE, /* Access list node. */
+ PREFIX_NODE, /* Prefix list node. */
+ ACCESS_IPV6_NODE, /* Access list node. */
+ PREFIX_IPV6_NODE, /* Prefix list node. */
+ AS_LIST_NODE, /* AS list node. */
+ COMMUNITY_LIST_NODE, /* Community list node. */
+ RMAP_NODE, /* Route map node. */
+ SMUX_NODE, /* SNMP configuration node. */
+ DUMP_NODE, /* Packet dump node. */
+ FORWARDING_NODE, /* IP forwarding node. */
PROTOCOL_NODE, /* protocol filtering node */
MPLS_NODE, /* MPLS config node */
- VTY_NODE, /* Vty node. */
- LINK_PARAMS_NODE, /* Link-parameters node */
+ VTY_NODE, /* Vty node. */
+ LINK_PARAMS_NODE, /* Link-parameters node */
};
/* Node which has some commands and prompt string and configuration
function pointer . */
-struct cmd_node
+struct cmd_node
{
/* Node index. */
- enum node_type node;
+ enum node_type node;
/* Prompt character at vty interface. */
- const char *prompt;
+ const char *prompt;
/* Is this node's configuration goes to vtysh ? */
int vtysh;
-
+
/* Node's configuration write function */
int (*func) (struct vty *);
+ /* Node's command graph */
+ struct graph *cmdgraph;
+
/* Vector of this node's command list. */
vector cmd_vector;
@@ -155,63 +161,64 @@ struct cmd_node
struct hash *cmd_hash;
};
-enum
-{
- CMD_ATTR_DEPRECATED = 1,
- CMD_ATTR_HIDDEN,
-};
-
-/* Structure of command element. */
-struct cmd_element
-{
- const char *string; /* Command specification by string. */
- int (*func) (struct cmd_element *, struct vty *, int, const char *[]);
- const char *doc; /* Documentation of this command. */
- int daemon; /* Daemon to which this command belong. */
- vector tokens; /* Vector of cmd_tokens */
- u_char attr; /* Command attributes */
-};
-
-
+/**
+ * Types for tokens.
+ *
+ * The type determines what kind of data the token can match (in the
+ * matching use case) or hold (in the argv use case).
+ */
enum cmd_token_type
{
- TOKEN_TERMINAL = 0,
- TOKEN_MULTIPLE,
- TOKEN_KEYWORD,
+ WORD_TKN, // words
+ VARIABLE_TKN, // almost anything
+ RANGE_TKN, // integer range
+ IPV4_TKN, // IPV4 addresses
+ IPV4_PREFIX_TKN, // IPV4 network prefixes
+ IPV6_TKN, // IPV6 prefixes
+ IPV6_PREFIX_TKN, // IPV6 network prefixes
+
+ /* plumbing types */
+ FORK_TKN, // marks subgraph beginning
+ JOIN_TKN, // marks subgraph end
+ START_TKN, // first token in line
+ END_TKN, // last token in line
+
+ SPECIAL_TKN = FORK_TKN,
};
-enum cmd_terminal_type
+/* Command attributes */
+enum
{
- _TERMINAL_BUG = 0,
- TERMINAL_LITERAL,
- TERMINAL_OPTION,
- TERMINAL_VARIABLE,
- TERMINAL_VARARG,
- TERMINAL_RANGE,
- TERMINAL_IPV4,
- TERMINAL_IPV4_PREFIX,
- TERMINAL_IPV6,
- TERMINAL_IPV6_PREFIX,
+ CMD_ATTR_NORMAL,
+ CMD_ATTR_DEPRECATED,
+ CMD_ATTR_HIDDEN,
};
-/* argument to be recorded on argv[] if it's not a literal */
-#define TERMINAL_RECORD(t) ((t) >= TERMINAL_OPTION)
-
-/* Command description structure. */
+/* Comamand token struct. */
struct cmd_token
{
- enum cmd_token_type type;
- enum cmd_terminal_type terminal;
+ enum cmd_token_type type; // token type
+ u_char attr; // token attributes
+ bool allowrepeat; // matcher allowed to match token repetively?
+
+ char *text; // token text
+ char *desc; // token description
+ long long min, max; // for ranges
+ char *arg; // user input that matches this token
- /* Used for type == MULTIPLE */
- vector multiple; /* vector of cmd_token, type == FINAL */
+ struct graph_node *forkjoin; // paired FORK/JOIN for JOIN/FORK
+};
- /* Used for type == KEYWORD */
- vector keyword; /* vector of vector of cmd_tokens */
+/* Structure of command element. */
+struct cmd_element
+{
+ const char *string; /* Command specification by string. */
+ const char *doc; /* Documentation of this command. */
+ int daemon; /* Daemon to which this command belong. */
+ u_char attr; /* Command attributes */
- /* Used for type == TERMINAL */
- char *cmd; /* Command string. */
- char *desc; /* Command's description. */
+ /* handler function for command */
+ int (*func) (const struct cmd_element *, struct vty *, int, struct cmd_token *[]);
};
/* Return value of the commands. */
@@ -233,11 +240,11 @@ struct cmd_token
#define CMD_ARGC_MAX 25
/* Turn off these macros when uisng cpp with extract.pl */
-#ifndef VTYSH_EXTRACT_PL
+#ifndef VTYSH_EXTRACT_PL
/* helper defines for end-user DEFUN* macros */
#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
- struct cmd_element cmdname = \
+ static struct cmd_element cmdname = \
{ \
.string = cmdstr, \
.func = funcname, \
@@ -247,179 +254,15 @@ struct cmd_token
};
#define DEFUN_CMD_FUNC_DECL(funcname) \
- static int funcname (struct cmd_element *, struct vty *, int, const char *[]);
+ static int funcname (const struct cmd_element *, struct vty *, int, struct cmd_token *[]);
#define DEFUN_CMD_FUNC_TEXT(funcname) \
static int funcname \
- (struct cmd_element *self __attribute__ ((unused)), \
+ (const struct cmd_element *self __attribute__ ((unused)), \
struct vty *vty __attribute__ ((unused)), \
int argc __attribute__ ((unused)), \
- const char *argv[] __attribute__ ((unused)) )
+ struct cmd_token *argv[] __attribute__ ((unused)) )
-/* DEFUN for vty command interafce. Little bit hacky ;-).
- *
- * DEFUN(funcname, cmdname, cmdstr, helpstr)
- *
- * funcname
- * ========
- *
- * Name of the function that will be defined.
- *
- * cmdname
- * =======
- *
- * Name of the struct that will be defined for the command.
- *
- * cmdstr
- * ======
- *
- * The cmdstr defines the command syntax. It is used by the vty subsystem
- * and vtysh to perform matching and completion in the cli. So you have to take
- * care to construct it adhering to the following grammar. The names used
- * for the production rules losely represent the names used in lib/command.c
- *
- * cmdstr = cmd_token , { " " , cmd_token } ;
- *
- * cmd_token = cmd_terminal
- * | cmd_multiple
- * | cmd_keyword ;
- *
- * cmd_terminal_fixed = fixed_string
- * | variable
- * | range
- * | ipv4
- * | ipv4_prefix
- * | ipv6
- * | ipv6_prefix ;
- *
- * cmd_terminal = cmd_terminal_fixed
- * | option
- * | vararg ;
- *
- * multiple_part = cmd_terminal_fixed ;
- * cmd_multiple = "(" , multiple_part , ( "|" | { "|" , multiple_part } ) , ")" ;
- *
- * keyword_part = fixed_string , { " " , ( cmd_terminal_fixed | cmd_multiple ) } ;
- * cmd_keyword = "{" , keyword_part , { "|" , keyword_part } , "}" ;
- *
- * lowercase = "a" | ... | "z" ;
- * uppercase = "A" | ... | "Z" ;
- * digit = "0" | ... | "9" ;
- * number = digit , { digit } ;
- *
- * fixed_string = (lowercase | digit) , { lowercase | digit | uppercase | "-" | "_" } ;
- * variable = uppercase , { uppercase | "_" } ;
- * range = "<" , number , "-" , number , ">" ;
- * ipv4 = "A.B.C.D" ;
- * ipv4_prefix = "A.B.C.D/M" ;
- * ipv6 = "X:X::X:X" ;
- * ipv6_prefix = "X:X::X:X/M" ;
- * option = "[" , variable , "]" ;
- * vararg = "." , variable ;
- *
- * To put that all in a textual description: A cmdstr is a sequence of tokens,
- * separated by spaces.
- *
- * Terminal Tokens:
- *
- * A very simple cmdstring would be something like: "show ip bgp". It consists
- * of three Terminal Tokens, each containing a fixed string. When this command
- * is called, no arguments will be passed down to the function implementing it,
- * as it only consists of fixed strings.
- *
- * Apart from fixed strings, Terminal Tokens can also contain variables:
- * An example would be "show ip bgp A.B.C.D". This command expects an IPv4
- * as argument. As this is a variable, the IP address entered by the user will
- * be passed down as an argument. Apart from two exceptions, the other options
- * for Terminal Tokens behave exactly as we just discussed and only make a
- * difference for the CLI. The two exceptions will be discussed in the next
- * paragraphs.
- *
- * A Terminal Token can contain a so called option match. This is a simple
- * string variable that the user may omit. An example would be:
- * "show interface [IFNAME]". If the user calls this without an interface as
- * argument, no arguments will be passed down to the function implementing
- * this command. Otherwise, the interface name will be provided to the function
- * as a regular argument.
-
- * Also, a Terminal Token can contain a so called vararg. This is used e.g. in
- * "show ip bgp regexp .LINE". The last token is a vararg match and will
- * consume all the arguments the user inputs on the command line and append
- * those to the list of arguments passed down to the function implementing this
- * command. (Therefore, it doesn't make much sense to have any tokens after a
- * vararg because the vararg will already consume all the words the user entered
- * in the CLI)
- *
- * Multiple Tokens:
- *
- * The Multiple Token type can be used if there are multiple possibilities what
- * arguments may be used for a command, but it should map to the same function
- * nonetheless. An example would be "ip route A.B.C.D/M (reject|blackhole)"
- * In that case both "reject" and "blackhole" would be acceptable as last
- * arguments. The words matched by Multiple Tokens are always added to the
- * argument list, even if they are matched by fixed strings. Such a Multiple
- * Token can contain almost any type of token that would also be acceptable
- * for a Terminal Token, the exception are optional variables and varag.
- *
- * There is one special case that is used in some places of Quagga that should be
- * pointed out here shortly. An example would be "password (8|) WORD". This
- * construct is used to have fixed strings communicated as arguments. (The "8"
- * will be passed down as an argument in this case) It does not mean that
- * the "8" is optional. Another historic and possibly surprising property of
- * this construct is that it consumes two parts of helpstr. (Help
- * strings will be explained later)
- *
- * Keyword Tokens:
- *
- * There are commands that take a lot of different and possibly optional arguments.
- * An example from ospf would be the "default-information originate" command. This
- * command takes a lot of optional arguments that may be provided in any order.
- * To accomodate such commands, the Keyword Token has been implemented.
- * Using the keyword token, the "default-information originate" command and all
- * its possible options can be represented using this single cmdstr:
- * "default-information originate \
- * {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}"
- *
- * Keywords always start with a fixed string and may be followed by arguments.
- * Except optional variables and vararg, everything is permitted here.
- *
- * For the special case of a keyword without arguments, either NULL or the
- * keyword itself will be pushed as an argument, depending on whether the
- * keyword is present.
- * For the other keywords, arguments will be only pushed for
- * variables/Multiple Tokens. If the keyword is not present, the arguments that
- * would have been pushed will be substituted by NULL.
- *
- * A few examples:
- * "default information originate metric-type 1 metric 1000"
- * would yield the following arguments:
- * { NULL, "1000", "1", NULL }
- *
- * "default information originate always route-map RMAP-DEFAULT"
- * would yield the following arguments:
- * { "always", NULL, NULL, "RMAP-DEFAULT" }
- *
- * helpstr
- * =======
- *
- * The helpstr is used to show a short explantion for the commands that
- * are available when the user presses '?' on the CLI. It is the concatenation
- * of the helpstrings for all the tokens that make up the command.
- *
- * There should be one helpstring for each token in the cmdstr except those
- * containing other tokens, like Multiple or Keyword Tokens. For those, there
- * will only be the helpstrings of the contained tokens.
- *
- * The individual helpstrings are expected to be in the same order as their
- * respective Tokens appear in the cmdstr. They should each be terminated with
- * a linefeed. The last helpstring should be terminated with a linefeed as well.
- *
- * Care should also be taken to avoid having similar tokens with different
- * helpstrings. Imagine e.g. the commands "show ip ospf" and "show ip bgp".
- * they both contain a helpstring for "show", but only one will be displayed
- * when the user enters "sh?". If those two helpstrings differ, it is not
- * defined which one will be shown and the behavior is therefore unpredictable.
- */
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_FUNC_DECL(funcname) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
@@ -499,7 +342,6 @@ struct cmd_token
*/
#define CMD_CREATE_STR(s) CMD_CREATE_STR_HELPER(s)
#define CMD_CREATE_STR_HELPER(s) #s
-#define CMD_RANGE_STR(a,s) "<" CMD_CREATE_STR(a) "-" CMD_CREATE_STR(s) ">"
/* Common descriptions. */
#define SHOW_STR "Show running system information\n"
@@ -531,17 +373,16 @@ struct cmd_token
#define IFNAME_STR "Interface name(e.g. ep0)\n"
#define IP6_STR "IPv6 Information\n"
#define OSPF6_STR "Open Shortest Path First (OSPF) for IPv6\n"
-#define OSPF6_ROUTER_STR "Enable a routing process\n"
-#define OSPF6_INSTANCE_STR "<1-65535> Instance ID\n"
-#define SECONDS_STR "<1-65535> Seconds\n"
+#define OSPF6_INSTANCE_STR "(1-65535) Instance ID\n"
+#define SECONDS_STR "Seconds\n"
#define ROUTE_STR "Routing Table\n"
#define PREFIX_LIST_STR "Build a prefix list\n"
#define OSPF6_DUMP_TYPE_LIST \
-"(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
+"<neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr>"
#define ISIS_STR "IS-IS information\n"
#define AREA_TAG_STR "[area tag]\n"
-#define COMMUNITY_AANN_STR "Community number where AA and NN are <0-65535>\n"
-#define COMMUNITY_VAL_STR "Community number in AA:NN format (where AA and NN are <0-65535>) or local-AS|no-advertise|no-export|internet or additive\n"
+#define COMMUNITY_AANN_STR "Community number where AA and NN are (0-65535)\n"
+#define COMMUNITY_VAL_STR "Community number in AA:NN format (where AA and NN are (0-65535)) or local-AS|no-advertise|no-export|internet or additive\n"
#define MPLS_TE_STR "MPLS-TE specific commands\n"
#define LINK_PARAMS_STR "Configure interface link parameters\n"
#define OSPF_RI_STR "OSPF Router Information specific commands\n"
@@ -552,31 +393,9 @@ struct cmd_token
/* IPv4 only machine should not accept IPv6 address for peer's IP
address. So we replace VTY command string like below. */
-#ifdef HAVE_IPV6
-#define NEIGHBOR_CMD "neighbor (A.B.C.D|X:X::X:X) "
-#define NO_NEIGHBOR_CMD "no neighbor (A.B.C.D|X:X::X:X) "
#define NEIGHBOR_ADDR_STR "Neighbor address\nIPv6 address\n"
-#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|X:X::X:X|WORD) "
-#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|X:X::X:X|WORD) "
#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor IPv6 address\nInterface name or neighbor tag\n"
#define NEIGHBOR_ADDR_STR3 "Neighbor address\nIPv6 address\nInterface name\n"
-#else
-#define NEIGHBOR_CMD "neighbor A.B.C.D "
-#define NO_NEIGHBOR_CMD "no neighbor A.B.C.D "
-#define NEIGHBOR_ADDR_STR "Neighbor address\n"
-#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|WORD) "
-#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|WORD) "
-#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor tag\n"
-#endif /* HAVE_IPV6 */
-
-/* Dynamic neighbor (listen range) configuration */
-#ifdef HAVE_IPV6
-#define LISTEN_RANGE_CMD "bgp listen range (A.B.C.D/M|X:X::X:X/M) "
-#define LISTEN_RANGE_ADDR_STR "Neighbor address\nNeighbor IPv6 address\n"
-#else
-#define LISTEN_RANGE_CMD "bgp listen range A.B.C.D/M "
-#define LISTEN_RANGE_ADDR_STR "Neighbor address\n"
-#endif /* HAVE_IPV6 */
/* Prototypes. */
extern void install_node (struct cmd_node *, int (*) (struct vty *));
@@ -586,28 +405,39 @@ extern void install_element (enum node_type, struct cmd_element *);
/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated
string with a space between each element (allocated using
XMALLOC(MTYPE_TMP)). Returns NULL if shift >= argc. */
-extern char *argv_concat (const char **argv, int argc, int shift);
+extern char *argv_concat (struct cmd_token **argv, int argc, int shift);
+extern int argv_find (struct cmd_token **argv, int argc, const char *text, int *index);
extern vector cmd_make_strvec (const char *);
extern void cmd_free_strvec (vector);
extern vector cmd_describe_command (vector, struct vty *, int *status);
extern char **cmd_complete_command (vector, struct vty *, int *status);
-extern char **cmd_complete_command_lib (vector, struct vty *, int *status, int islib);
extern const char *cmd_prompt (enum node_type);
-extern int command_config_read_one_line (struct vty *vty, struct cmd_element **, int use_config_node);
+extern int command_config_read_one_line (struct vty *vty, const struct cmd_element **, int use_config_node);
extern int config_from_file (struct vty *, FILE *, unsigned int *line_num);
extern enum node_type node_parent (enum node_type);
-extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int);
-extern int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **);
+extern int cmd_execute_command (vector, struct vty *, const struct cmd_element **, int);
+extern int cmd_execute_command_strict (vector, struct vty *, const struct cmd_element **);
extern void cmd_init (int);
extern void cmd_terminate (void);
+extern void cmd_exit (struct vty *vty);
+extern int cmd_list_cmds (struct vty *vty, int do_permute);
+
+extern int cmd_hostname_set (const char *hostname);
+
+/* NOT safe for general use; call this only if DEV_BUILD! */
+extern void grammar_sandbox_init (void);
+
+/* memory management for cmd_token */
+extern struct cmd_token *new_cmd_token (enum cmd_token_type, u_char attr,
+ const char *text, const char *desc);
+extern void del_cmd_token (struct cmd_token *);
+extern struct cmd_token *copy_cmd_token (struct cmd_token *);
+
+extern vector completions_to_vec (struct list *completions);
+extern void command_parse_format (struct graph *graph, struct cmd_element *cmd);
/* Export typical functions. */
-extern struct cmd_element config_end_cmd;
-extern struct cmd_element config_exit_cmd;
-extern struct cmd_element config_quit_cmd;
-extern struct cmd_element config_help_cmd;
-extern struct cmd_element config_list_cmd;
extern const char *host_config_get (void);
extern void host_config_set (const char *);
@@ -616,8 +446,9 @@ extern void print_version (const char *);
extern int cmd_banner_motd_file (const char *);
/* struct host global, ick */
-extern struct host host;
+extern struct host host;
+
+/* text for <cr> command */
+#define CMD_CR_TEXT "<cr>"
-/* "<cr>" global */
-extern char *command_cr;
#endif /* _ZEBRA_COMMAND_H */
diff --git a/lib/command_lex.l b/lib/command_lex.l
new file mode 100644
index 0000000000..deec1757c2
--- /dev/null
+++ b/lib/command_lex.l
@@ -0,0 +1,85 @@
+/*
+ * Command format string lexer for CLI backend.
+ *
+ * --
+ * Copyright (C) 2015 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+%{
+#include "command_parse.h"
+
+#define YY_USER_ACTION yylloc->last_column += yyleng;
+#define LOC_STEP do { if (yylloc) { \
+ yylloc->first_column = yylloc->last_column; \
+ yylloc->first_line = yylloc->last_line; \
+ } } while(0)
+%}
+
+WORD (\-|\+)?[a-z0-9\*][-+_a-zA-Z0-9\*]*
+IPV4 A\.B\.C\.D
+IPV4_PREFIX A\.B\.C\.D\/M
+IPV6 X:X::X:X
+IPV6_PREFIX X:X::X:X\/M
+VARIABLE [A-Z][-_a-zA-Z:0-9]+
+NUMBER (\-|\+)?[0-9]{1,20}
+RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
+
+/* yytext shall be a pointer */
+%pointer
+%option noyywrap
+%option nounput
+%option noinput
+%option outfile="command_lex.c"
+%option header-file="command_lex.h"
+%option prefix="cmd_yy"
+%option reentrant
+%option bison-bridge
+%option bison-locations
+
+%%
+%{
+ LOC_STEP;
+%}
+
+[ \t]+ LOC_STEP /* ignore whitespace */;
+{WORD} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return WORD;}
+{IPV4} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV4;}
+{IPV4_PREFIX} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV4_PREFIX;}
+{IPV6} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV6;}
+{IPV6_PREFIX} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV6_PREFIX;}
+{VARIABLE} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return VARIABLE;}
+{RANGE} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return RANGE;}
+. {return yytext[0];}
+%%
+
+YY_BUFFER_STATE buffer;
+
+void set_lexer_string (yyscan_t *scn, const char *string)
+{
+ *scn = NULL;
+ yylex_init(scn);
+ buffer = yy_scan_string (string, *scn);
+}
+
+void cleanup_lexer (yyscan_t *scn)
+{
+ // yy_delete_buffer (buffer, *scn);
+ yylex_destroy(*scn);
+}
diff --git a/lib/command_match.c b/lib/command_match.c
new file mode 100644
index 0000000000..bbd9cd091d
--- /dev/null
+++ b/lib/command_match.c
@@ -0,0 +1,1027 @@
+/*
+ * Input matching routines for CLI backend.
+ *
+ * --
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "command_match.h"
+#include "memory.h"
+
+DEFINE_MTYPE_STATIC(LIB, CMD_MATCHSTACK, "Command Match Stack")
+
+#define MAXDEPTH 64
+
+#ifdef TRACE_MATCHER
+#define TM 1
+#else
+#define TM 0
+#endif
+
+#define trace_matcher(...) \
+ do { if (TM) fprintf (stderr, __VA_ARGS__); } while (0);
+
+/* matcher helper prototypes */
+static int
+add_nexthops (struct list *, struct graph_node *,
+ struct graph_node **, size_t);
+
+static struct list *
+command_match_r (struct graph_node *, vector, unsigned int,
+ struct graph_node **);
+
+static int
+score_precedence (enum cmd_token_type);
+
+static enum match_type
+min_match_level (enum cmd_token_type);
+
+static void
+del_arglist (struct list *);
+
+static struct cmd_token *
+disambiguate_tokens (struct cmd_token *, struct cmd_token *, char *);
+
+static struct list *
+disambiguate (struct list *, struct list *, vector, unsigned int);
+
+int
+compare_completions (const void *, const void *);
+
+/* token matcher prototypes */
+static enum match_type
+match_token (struct cmd_token *, char *);
+
+static enum match_type
+match_ipv4 (const char *);
+
+static enum match_type
+match_ipv4_prefix (const char *);
+
+static enum match_type
+match_ipv6 (const char *);
+
+static enum match_type
+match_ipv6_prefix (const char *);
+
+static enum match_type
+match_range (struct cmd_token *, const char *);
+
+static enum match_type
+match_word (struct cmd_token *, const char *);
+
+static enum match_type
+match_variable (struct cmd_token *, const char *);
+
+/* matching functions */
+static enum matcher_rv matcher_rv;
+
+enum matcher_rv
+command_match (struct graph *cmdgraph,
+ vector vline,
+ struct list **argv,
+ const struct cmd_element **el)
+{
+ struct graph_node *stack[MAXDEPTH];
+ matcher_rv = MATCHER_NO_MATCH;
+
+ // prepend a dummy token to match that pesky start node
+ vector vvline = vector_init (vline->alloced + 1);
+ vector_set_index (vvline, 0, (void *) XSTRDUP (MTYPE_TMP, "dummy"));
+ memcpy (vvline->index + 1, vline->index, sizeof (void *) * vline->alloced);
+ vvline->active = vline->active + 1;
+
+ struct graph_node *start = vector_slot (cmdgraph->nodes, 0);
+ if ((*argv = command_match_r (start, vvline, 0, stack))) // successful match
+ {
+ struct listnode *head = listhead (*argv);
+ struct listnode *tail = listtail (*argv);
+
+ // delete dummy start node
+ del_cmd_token ((struct cmd_token *) head->data);
+ list_delete_node (*argv, head);
+
+ // get cmd_element out of list tail
+ *el = listgetdata (tail);
+ list_delete_node (*argv, tail);
+
+ // now argv is an ordered list of cmd_token matching the user
+ // input, with each cmd_token->arg holding the corresponding input
+ assert (*el);
+ }
+
+ if (!*el) {
+ trace_matcher ("No match\n");
+ }
+ else {
+ trace_matcher ("Matched command\n->string %s\n->desc %s\n", (*el)->string, (*el)->doc);
+ }
+
+ // free the leader token we alloc'd
+ XFREE (MTYPE_TMP, vector_slot (vvline, 0));
+ // free vector
+ vector_free (vvline);
+
+ return matcher_rv;
+}
+
+/**
+ * Builds an argument list given a DFA and a matching input line.
+ *
+ * First the function determines if the node it is passed matches the first
+ * token of input. If it does not, it returns NULL (MATCHER_NO_MATCH). If it
+ * does match, then it saves the input token as the head of an argument list.
+ *
+ * The next step is to see if there is further input in the input line. If
+ * there is not, the current node's children are searched to see if any of them
+ * are leaves (type END_TKN). If this is the case, then the bottom of the
+ * recursion stack has been reached, the leaf is pushed onto the argument list,
+ * the current node is pushed, and the resulting argument list is
+ * returned (MATCHER_OK). If it is not the case, NULL is returned, indicating
+ * that there is no match for the input along this path (MATCHER_INCOMPLETE).
+ *
+ * If there is further input, then the function recurses on each of the current
+ * node's children, passing them the input line minus the token that was just
+ * matched. For each child, the return value of the recursive call is
+ * inspected. If it is null, then there is no match for the input along the
+ * subgraph headed by that child. If it is not null, then there is at least one
+ * input match in that subgraph (more on this in a moment).
+ *
+ * If a recursive call on a child returns a non-null value, then it has matched
+ * the input given it on the subgraph that starts with that child. However, due
+ * to the flexibility of the grammar, it is sometimes the case that two or more
+ * child graphs match the same input (two or more of the recursive calls have
+ * non-NULL return values). This is not a valid state, since only one true
+ * match is possible. In order to resolve this conflict, the function keeps a
+ * reference to the child node that most specifically matches the input. This
+ * is done by assigning each node type a precedence. If a child is found to
+ * match the remaining input, then the precedence values of the current
+ * best-matching child and this new match are compared. The node with higher
+ * precedence is kept, and the other match is discarded. Due to the recursive
+ * nature of this function, it is only necessary to compare the precedence of
+ * immediate children, since all subsequent children will already have been
+ * disambiguated in this way.
+ *
+ * In the event that two children are found to match with the same precedence,
+ * then the input is ambiguous for the passed cmd_element and NULL is returned.
+ *
+ * @param[in] start the start node.
+ * @param[in] vline the vectorized input line.
+ * @param[in] n the index of the first input token.
+ * @return A linked list of n elements. The first n-1 elements are pointers to
+ * struct cmd_token and represent the sequence of tokens matched by the input.
+ * The ->arg field of each token points to a copy of the input matched on it.
+ * The final nth element is a pointer to struct cmd_element, which is the
+ * command that was matched.
+ *
+ * If no match was found, the return value is NULL.
+ */
+static struct list *
+command_match_r (struct graph_node *start, vector vline, unsigned int n,
+ struct graph_node **stack)
+{
+ assert (n < vector_active (vline));
+
+ // get the minimum match level that can count as a full match
+ struct cmd_token *token = start->data;
+ enum match_type minmatch = min_match_level (token->type);
+
+ /* check history/stack of tokens
+ * this disallows matching the same one more than once if there is a
+ * circle in the graph (used for keyword arguments) */
+ if (n == MAXDEPTH)
+ return NULL;
+ if (!token->allowrepeat)
+ for (size_t s = 0; s < n; s++)
+ if (stack[s] == start)
+ return NULL;
+
+ // get the current operating input token
+ char *input_token = vector_slot (vline, n);
+
+#ifdef TRACE_MATCHER
+ fprintf (stdout, "\"%-20s\" matches \"%-30s\" ? ", input_token, token->text);
+ enum match_type mt = match_token (token, input_token);
+ fprintf (stdout, "min: %d - ", minmatch);
+ switch (mt)
+ {
+ case trivial_match:
+ fprintf (stdout, "trivial_match ");
+ break;
+ case no_match:
+ fprintf (stdout, "no_match ");
+ break;
+ case partly_match:
+ fprintf (stdout, "partly_match ");
+ break;
+ case exact_match:
+ fprintf (stdout, "exact_match ");
+ break;
+ }
+ if (mt >= minmatch) fprintf (stdout, " MATCH");
+ fprintf (stdout, "\n");
+#endif
+
+ // if we don't match this node, die
+ if (match_token (token, input_token) < minmatch)
+ return NULL;
+
+ stack[n] = start;
+
+ // pointers for iterating linklist
+ struct listnode *ln;
+ struct graph_node *gn;
+
+ // get all possible nexthops
+ struct list *next = list_new();
+ add_nexthops (next, start, NULL, 0);
+
+ // determine the best match
+ int ambiguous = 0;
+ struct list *currbest = NULL;
+ for (ALL_LIST_ELEMENTS_RO (next,ln,gn))
+ {
+ // if we've matched all input we're looking for END_TKN
+ if (n+1 == vector_active (vline))
+ {
+ struct cmd_token *tok = gn->data;
+ if (tok->type == END_TKN)
+ {
+ if (currbest) // there is more than one END_TKN in the follow set
+ {
+ ambiguous = 1;
+ break;
+ }
+ currbest = list_new();
+ // node should have one child node with the element
+ struct graph_node *leaf = vector_slot (gn->to, 0);
+ // last node in the list will hold the cmd_element;
+ // this is important because list_delete() expects
+ // that all nodes have the same data type, so when
+ // deleting this list the last node must be
+ // manually deleted
+ struct cmd_element *el = leaf->data;
+ listnode_add (currbest, el);
+ currbest->del = (void (*)(void *)) &del_cmd_token;
+ // do not break immediately; continue walking through the follow set
+ // to ensure that there is exactly one END_TKN
+ }
+ continue;
+ }
+
+ // else recurse on candidate child node
+ struct list *result = command_match_r (gn, vline, n+1, stack);
+
+ // save the best match
+ if (result && currbest)
+ {
+ // pick the best of two matches
+ struct list *newbest = disambiguate (currbest, result, vline, n+1);
+ // set ambiguity flag
+ ambiguous = !newbest || (ambiguous && newbest == currbest);
+ // delete the unnecessary result
+ struct list *todelete = ((newbest && newbest == result) ? currbest : result);
+ del_arglist (todelete);
+
+ currbest = newbest ? newbest : currbest;
+ }
+ else if (result)
+ currbest = result;
+ }
+
+ if (currbest)
+ {
+ if (ambiguous)
+ {
+ del_arglist (currbest);
+ currbest = NULL;
+ matcher_rv = MATCHER_AMBIGUOUS;
+ }
+ else
+ {
+ // copy token, set arg and prepend to currbest
+ struct cmd_token *token = start->data;
+ struct cmd_token *copy = copy_cmd_token (token);
+ copy->arg = XSTRDUP (MTYPE_CMD_ARG, input_token);
+ listnode_add_before (currbest, currbest->head, copy);
+ matcher_rv = MATCHER_OK;
+ }
+ }
+ else if (n+1 == vector_active (vline) && matcher_rv == MATCHER_NO_MATCH)
+ matcher_rv = MATCHER_INCOMPLETE;
+
+ // cleanup
+ list_delete (next);
+
+ return currbest;
+}
+
+static void
+stack_del (void *val)
+{
+ XFREE (MTYPE_CMD_MATCHSTACK, val);
+}
+
+enum matcher_rv
+command_complete (struct graph *graph,
+ vector vline,
+ struct list **completions)
+{
+ // pointer to next input token to match
+ char *input_token;
+
+ struct list *current = list_new(), // current nodes to match input token against
+ *next = list_new(); // possible next hops after current input token
+ current->del = next->del = stack_del;
+
+ // pointers used for iterating lists
+ struct graph_node **gstack, **newstack;
+ struct listnode *node;
+
+ // add all children of start node to list
+ struct graph_node *start = vector_slot (graph->nodes, 0);
+ add_nexthops (next, start, &start, 0);
+
+ unsigned int idx;
+ for (idx = 0; idx < vector_active (vline) && next->count > 0; idx++)
+ {
+ list_delete (current);
+ current = next;
+ next = list_new();
+ next->del = stack_del;
+
+ input_token = vector_slot (vline, idx);
+
+ int exact_match_exists = 0;
+ for (ALL_LIST_ELEMENTS_RO (current,node,gstack))
+ if (!exact_match_exists)
+ exact_match_exists = (match_token (gstack[0]->data, input_token) == exact_match);
+ else
+ break;
+
+ for (ALL_LIST_ELEMENTS_RO (current,node,gstack))
+ {
+ struct cmd_token *token = gstack[0]->data;
+
+ if (token->attr == CMD_ATTR_HIDDEN || token->attr == CMD_ATTR_DEPRECATED)
+ continue;
+
+ enum match_type minmatch = min_match_level (token->type);
+ trace_matcher ("\"%s\" matches \"%s\" (%d) ? ",
+ input_token, token->text, token->type);
+
+ unsigned int last_token = (vector_active (vline) - 1 == idx);
+ enum match_type matchtype = match_token (token, input_token);
+ switch (matchtype)
+ {
+ // occurs when last token is whitespace
+ case trivial_match:
+ trace_matcher ("trivial_match\n");
+ assert(last_token);
+ newstack = XMALLOC (MTYPE_CMD_MATCHSTACK,
+ sizeof(struct graph_node *));
+ /* we're not recursing here, just the first element is OK */
+ newstack[0] = gstack[0];
+ listnode_add (next, newstack);
+ break;
+ case partly_match:
+ trace_matcher ("trivial_match\n");
+ if (exact_match_exists && !last_token)
+ break;
+ case exact_match:
+ trace_matcher ("exact_match\n");
+ if (last_token)
+ {
+ newstack = XMALLOC (MTYPE_CMD_MATCHSTACK,
+ sizeof(struct graph_node *));
+ /* same as above, not recursing on this */
+ newstack[0] = gstack[0];
+ listnode_add (next, newstack);
+ }
+ else if (matchtype >= minmatch)
+ add_nexthops (next, gstack[0], gstack, idx + 1);
+ break;
+ default:
+ trace_matcher ("no_match\n");
+ break;
+ }
+ }
+ }
+
+ /* Variable summary
+ * -----------------------------------------------------------------
+ * token = last input token processed
+ * idx = index in `command` of last token processed
+ * current = set of all transitions from the previous input token
+ * next = set of all nodes reachable from all nodes in `matched`
+ */
+
+ matcher_rv =
+ idx == vector_active(vline) && next->count ?
+ MATCHER_OK :
+ MATCHER_NO_MATCH;
+
+ *completions = NULL;
+ if (!MATCHER_ERROR(matcher_rv))
+ {
+ // extract cmd_token into list
+ *completions = list_new ();
+ for (ALL_LIST_ELEMENTS_RO (next,node,gstack)) {
+ listnode_add (*completions, gstack[0]->data);
+ }
+ }
+
+ list_delete (current);
+ list_delete (next);
+
+ return matcher_rv;
+}
+
+/**
+ * Adds all children that are reachable by one parser hop to the given list.
+ * special tokens except END_TKN are treated as transparent.
+ *
+ * @param[in] list to add the nexthops to
+ * @param[in] node to start calculating nexthops from
+ * @param[in] stack listing previously visited nodes, if non-NULL.
+ * @param[in] stackpos how many valid entries are in stack
+ * @return the number of children added to the list
+ *
+ * NB: non-null "stack" means that new stacks will be added to "list" as
+ * output, instead of direct node pointers!
+ */
+static int
+add_nexthops (struct list *list, struct graph_node *node,
+ struct graph_node **stack, size_t stackpos)
+{
+ int added = 0;
+ struct graph_node *child;
+ struct graph_node **nextstack;
+ for (unsigned int i = 0; i < vector_active (node->to); i++)
+ {
+ child = vector_slot (node->to, i);
+ size_t j;
+ struct cmd_token *token = child->data;
+ if (!token->allowrepeat && stack)
+ {
+ for (j = 0; j < stackpos; j++)
+ if (child == stack[j])
+ break;
+ if (j != stackpos)
+ continue;
+ }
+ if (token->type >= SPECIAL_TKN && token->type != END_TKN)
+ {
+ added += add_nexthops (list, child, stack, stackpos);
+ }
+ else
+ {
+ if (stack)
+ {
+ nextstack = XMALLOC (MTYPE_CMD_MATCHSTACK,
+ (stackpos + 1) * sizeof(struct graph_node *));
+ nextstack[0] = child;
+ memcpy(nextstack + 1, stack, stackpos * sizeof(struct graph_node *));
+
+ listnode_add (list, nextstack);
+ }
+ else
+ listnode_add (list, child);
+ added++;
+ }
+ }
+
+ return added;
+}
+
+/**
+ * Determines the node types for which a partial match may count as a full
+ * match. Enables command abbrevations.
+ *
+ * @param[in] type node type
+ * @return minimum match level needed to for a token to fully match
+ */
+static enum match_type
+min_match_level (enum cmd_token_type type)
+{
+ switch (type)
+ {
+ // anything matches a start node, for the sake of recursion
+ case START_TKN:
+ return no_match;
+ // allowing words to partly match enables command abbreviation
+ case WORD_TKN:
+ return partly_match;
+ default:
+ return exact_match;
+ }
+}
+
+/**
+ * Assigns precedence scores to node types.
+ *
+ * @param[in] type node type to score
+ * @return precedence score
+ */
+static int
+score_precedence (enum cmd_token_type type)
+{
+ switch (type)
+ {
+ // some of these are mutually exclusive, so they share
+ // the same precedence value
+ case IPV4_TKN:
+ case IPV4_PREFIX_TKN:
+ case IPV6_TKN:
+ case IPV6_PREFIX_TKN:
+ case RANGE_TKN:
+ return 2;
+ case WORD_TKN:
+ return 3;
+ case VARIABLE_TKN:
+ return 4;
+ default:
+ return 10;
+ }
+}
+
+/**
+ * Picks the better of two possible matches for a token.
+ *
+ * @param[in] first candidate node matching token
+ * @param[in] second candidate node matching token
+ * @param[in] token the token being matched
+ * @return the best-matching node, or NULL if the two are entirely ambiguous
+ */
+static struct cmd_token *
+disambiguate_tokens (struct cmd_token *first,
+ struct cmd_token *second,
+ char *input_token)
+{
+ // if the types are different, simply go off of type precedence
+ if (first->type != second->type)
+ {
+ int firstprec = score_precedence (first->type);
+ int secndprec = score_precedence (second->type);
+ if (firstprec != secndprec)
+ return firstprec < secndprec ? first : second;
+ else
+ return NULL;
+ }
+
+ // if they're the same, return the more exact match
+ enum match_type fmtype = match_token (first, input_token);
+ enum match_type smtype = match_token (second, input_token);
+ if (fmtype != smtype)
+ return fmtype > smtype ? first : second;
+
+ return NULL;
+}
+
+/**
+ * Picks the better of two possible matches for an input line.
+ *
+ * @param[in] first candidate list of cmd_token matching vline
+ * @param[in] second candidate list of cmd_token matching vline
+ * @param[in] vline the input line being matched
+ * @param[in] n index into vline to start comparing at
+ * @return the best-matching list, or NULL if the two are entirely ambiguous
+ */
+static struct list *
+disambiguate (struct list *first,
+ struct list *second,
+ vector vline,
+ unsigned int n)
+{
+ // doesn't make sense for these to be inequal length
+ assert (first->count == second->count);
+ assert (first->count == vector_active (vline) - n+1);
+
+ struct listnode *fnode = listhead (first),
+ *snode = listhead (second);
+ struct cmd_token *ftok = listgetdata (fnode),
+ *stok = listgetdata (snode),
+ *best = NULL;
+
+ // compare each token, if one matches better use that one
+ for (unsigned int i = n; i < vector_active (vline); i++)
+ {
+ char *token = vector_slot(vline, i);
+ if ((best = disambiguate_tokens (ftok, stok, token)))
+ return best == ftok ? first : second;
+ fnode = listnextnode (fnode);
+ snode = listnextnode (snode);
+ ftok = listgetdata (fnode);
+ stok = listgetdata (snode);
+ }
+
+ return NULL;
+}
+
+/*
+ * Deletion function for arglist.
+ *
+ * Since list->del for arglists expects all listnode->data to hold cmd_token,
+ * but arglists have cmd_element as the data for the tail, this function
+ * manually deletes the tail before deleting the rest of the list as usual.
+ *
+ * The cmd_element at the end is *not* a copy. It is the one and only.
+ *
+ * @param list the arglist to delete
+ */
+static void
+del_arglist (struct list *list)
+{
+ // manually delete last node
+ struct listnode *tail = listtail (list);
+ tail->data = NULL;
+ list_delete_node (list, tail);
+
+ // delete the rest of the list as usual
+ list_delete (list);
+}
+
+/*---------- token level matching functions ----------*/
+
+static enum match_type
+match_token (struct cmd_token *token, char *input_token)
+{
+ // nothing trivially matches everything
+ if (!input_token)
+ return trivial_match;
+
+ switch (token->type) {
+ case WORD_TKN:
+ return match_word (token, input_token);
+ case IPV4_TKN:
+ return match_ipv4 (input_token);
+ case IPV4_PREFIX_TKN:
+ return match_ipv4_prefix (input_token);
+ case IPV6_TKN:
+ return match_ipv6 (input_token);
+ case IPV6_PREFIX_TKN:
+ return match_ipv6_prefix (input_token);
+ case RANGE_TKN:
+ return match_range (token, input_token);
+ case VARIABLE_TKN:
+ return match_variable (token, input_token);
+ case END_TKN:
+ default:
+ return no_match;
+ }
+}
+
+#define IPV4_ADDR_STR "0123456789."
+#define IPV4_PREFIX_STR "0123456789./"
+
+static enum match_type
+match_ipv4 (const char *str)
+{
+ const char *sp;
+ int dots = 0, nums = 0;
+ char buf[4];
+
+ for (;;)
+ {
+ memset (buf, 0, sizeof (buf));
+ sp = str;
+ while (*str != '\0')
+ {
+ if (*str == '.')
+ {
+ if (dots >= 3)
+ return no_match;
+
+ if (*(str + 1) == '.')
+ return no_match;
+
+ if (*(str + 1) == '\0')
+ return partly_match;
+
+ dots++;
+ break;
+ }
+ if (!isdigit ((int) *str))
+ return no_match;
+
+ str++;
+ }
+
+ if (str - sp > 3)
+ return no_match;
+
+ strncpy (buf, sp, str - sp);
+ if (atoi (buf) > 255)
+ return no_match;
+
+ nums++;
+
+ if (*str == '\0')
+ break;
+
+ str++;
+ }
+
+ if (nums < 4)
+ return partly_match;
+
+ return exact_match;
+}
+
+static enum match_type
+match_ipv4_prefix (const char *str)
+{
+ const char *sp;
+ int dots = 0;
+ char buf[4];
+
+ for (;;)
+ {
+ memset (buf, 0, sizeof (buf));
+ sp = str;
+ while (*str != '\0' && *str != '/')
+ {
+ if (*str == '.')
+ {
+ if (dots == 3)
+ return no_match;
+
+ if (*(str + 1) == '.' || *(str + 1) == '/')
+ return no_match;
+
+ if (*(str + 1) == '\0')
+ return partly_match;
+
+ dots++;
+ break;
+ }
+
+ if (!isdigit ((int) *str))
+ return no_match;
+
+ str++;
+ }
+
+ if (str - sp > 3)
+ return no_match;
+
+ strncpy (buf, sp, str - sp);
+ if (atoi (buf) > 255)
+ return no_match;
+
+ if (dots == 3)
+ {
+ if (*str == '/')
+ {
+ if (*(str + 1) == '\0')
+ return partly_match;
+
+ str++;
+ break;
+ }
+ else if (*str == '\0')
+ return partly_match;
+ }
+
+ if (*str == '\0')
+ return partly_match;
+
+ str++;
+ }
+
+ sp = str;
+ while (*str != '\0')
+ {
+ if (!isdigit ((int) *str))
+ return no_match;
+
+ str++;
+ }
+
+ if (atoi (sp) > 32)
+ return no_match;
+
+ return exact_match;
+}
+
+
+#define IPV6_ADDR_STR "0123456789abcdefABCDEF:."
+#define IPV6_PREFIX_STR "0123456789abcdefABCDEF:./"
+#define STATE_START 1
+#define STATE_COLON 2
+#define STATE_DOUBLE 3
+#define STATE_ADDR 4
+#define STATE_DOT 5
+#define STATE_SLASH 6
+#define STATE_MASK 7
+
+static enum match_type
+match_ipv6 (const char *str)
+{
+ struct sockaddr_in6 sin6_dummy;
+ int ret;
+
+ if (strspn (str, IPV6_ADDR_STR) != strlen (str))
+ return no_match;
+
+ ret = inet_pton(AF_INET6, str, &sin6_dummy.sin6_addr);
+
+ if (ret == 1)
+ return exact_match;
+
+ return no_match;
+}
+
+static enum match_type
+match_ipv6_prefix (const char *str)
+{
+ int state = STATE_START;
+ int colons = 0, nums = 0, double_colon = 0;
+ int mask;
+ const char *sp = NULL;
+ char *endptr = NULL;
+
+ if (str == NULL)
+ return partly_match;
+
+ if (strspn (str, IPV6_PREFIX_STR) != strlen (str))
+ return no_match;
+
+ while (*str != '\0' && state != STATE_MASK)
+ {
+ switch (state)
+ {
+ case STATE_START:
+ if (*str == ':')
+ {
+ if (*(str + 1) != ':' && *(str + 1) != '\0')
+ return no_match;
+ colons--;
+ state = STATE_COLON;
+ }
+ else
+ {
+ sp = str;
+ state = STATE_ADDR;
+ }
+
+ continue;
+ case STATE_COLON:
+ colons++;
+ if (*(str + 1) == '/')
+ return no_match;
+ else if (*(str + 1) == ':')
+ state = STATE_DOUBLE;
+ else
+ {
+ sp = str + 1;
+ state = STATE_ADDR;
+ }
+ break;
+ case STATE_DOUBLE:
+ if (double_colon)
+ return no_match;
+
+ if (*(str + 1) == ':')
+ return no_match;
+ else
+ {
+ if (*(str + 1) != '\0' && *(str + 1) != '/')
+ colons++;
+ sp = str + 1;
+
+ if (*(str + 1) == '/')
+ state = STATE_SLASH;
+ else
+ state = STATE_ADDR;
+ }
+
+ double_colon++;
+ nums += 1;
+ break;
+ case STATE_ADDR:
+ if (*(str + 1) == ':' || *(str + 1) == '.'
+ || *(str + 1) == '\0' || *(str + 1) == '/')
+ {
+ if (str - sp > 3)
+ return no_match;
+
+ for (; sp <= str; sp++)
+ if (*sp == '/')
+ return no_match;
+
+ nums++;
+
+ if (*(str + 1) == ':')
+ state = STATE_COLON;
+ else if (*(str + 1) == '.')
+ {
+ if (colons || double_colon)
+ state = STATE_DOT;
+ else
+ return no_match;
+ }
+ else if (*(str + 1) == '/')
+ state = STATE_SLASH;
+ }
+ break;
+ case STATE_DOT:
+ state = STATE_ADDR;
+ break;
+ case STATE_SLASH:
+ if (*(str + 1) == '\0')
+ return partly_match;
+
+ state = STATE_MASK;
+ break;
+ default:
+ break;
+ }
+
+ if (nums > 11)
+ return no_match;
+
+ if (colons > 7)
+ return no_match;
+
+ str++;
+ }
+
+ if (state < STATE_MASK)
+ return partly_match;
+
+ mask = strtol (str, &endptr, 10);
+ if (*endptr != '\0')
+ return no_match;
+
+ if (mask < 0 || mask > 128)
+ return no_match;
+
+ return exact_match;
+}
+
+static enum match_type
+match_range (struct cmd_token *token, const char *str)
+{
+ assert (token->type == RANGE_TKN);
+
+ char *endptr = NULL;
+ long long val;
+
+ val = strtoll (str, &endptr, 10);
+ if (*endptr != '\0')
+ return no_match;
+
+ if (val < token->min || val > token->max)
+ return no_match;
+ else
+ return exact_match;
+}
+
+static enum match_type
+match_word (struct cmd_token *token, const char *word)
+{
+ assert (token->type == WORD_TKN);
+
+ // if the passed token is 0 length, partly match
+ if (!strlen(word))
+ return partly_match;
+
+ // if the passed token is strictly a prefix of the full word, partly match
+ if (strlen (word) < strlen (token->text))
+ return !strncmp (token->text, word, strlen (word)) ?
+ partly_match :
+ no_match;
+
+ // if they are the same length and exactly equal, exact match
+ else if (strlen (word) == strlen (token->text))
+ return !strncmp (token->text, word, strlen (word)) ? exact_match : no_match;
+
+ return no_match;
+}
+
+static enum match_type
+match_variable (struct cmd_token *token, const char *word)
+{
+ assert (token->type == VARIABLE_TKN);
+ return exact_match;
+}
diff --git a/lib/command_match.h b/lib/command_match.h
new file mode 100644
index 0000000000..9e18b8d905
--- /dev/null
+++ b/lib/command_match.h
@@ -0,0 +1,113 @@
+/*
+ * Input matching routines for CLI backend.
+ *
+ * --
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _ZEBRA_COMMAND_MATCH_H
+#define _ZEBRA_COMMAND_MATCH_H
+
+#include "graph.h"
+#include "linklist.h"
+#include "command.h"
+
+/* These definitions exist in command.c in the current engine but should be
+ * relocated here in the new engine
+ */
+enum filter_type
+{
+ FILTER_RELAXED,
+ FILTER_STRICT
+};
+
+/* matcher result value */
+enum matcher_rv
+{
+ MATCHER_NO_MATCH,
+ MATCHER_INCOMPLETE,
+ MATCHER_AMBIGUOUS,
+ MATCHER_OK,
+};
+
+/* completion match types */
+enum match_type
+{
+ trivial_match, // the input is null
+ no_match, // the input does not match
+ partly_match, // the input matches but is incomplete
+ exact_match // the input matches and is complete
+};
+
+/* Defines which matcher_rv values constitute an error. Should be used with
+ * matcher_rv return values to do basic error checking.
+ */
+#define MATCHER_ERROR(matcher_rv) \
+ ( (matcher_rv) == MATCHER_INCOMPLETE \
+ || (matcher_rv) == MATCHER_NO_MATCH \
+ || (matcher_rv) == MATCHER_AMBIGUOUS \
+ )
+
+/**
+ * Attempt to find an exact command match for a line of user input.
+ *
+ * @param[in] cmdgraph command graph to match against
+ * @param[in] vline vectorized input string
+ * @param[out] argv pointer to argument list if successful match, NULL
+ * otherwise. The elements of this list are pointers to struct cmd_token
+ * and represent the sequence of tokens matched by the inpu. The ->arg
+ * field of each token points to a copy of the input matched on it. These
+ * may be safely deleted or modified.
+ * @param[out] element pointer to matched cmd_element if successful match,
+ * or NULL when MATCHER_ERROR(rv) is true. The cmd_element may *not* be
+ * safely deleted or modified; it is the instance initialized on startup.
+ * @return matcher status
+ */
+enum matcher_rv
+command_match (struct graph *cmdgraph,
+ vector vline,
+ struct list **argv,
+ const struct cmd_element **element);
+
+/**
+ * Compiles possible completions for a given line of user input.
+ *
+ * @param[in] start the start node of the DFA to match against
+ * @param[in] vline vectorized input string
+ * @param[out] completions pointer to list of cmd_token representing
+ * acceptable next inputs, or NULL when MATCHER_ERROR(rv) is true.
+ * The elements of this list are pointers to struct cmd_token and take on a
+ * variety of forms depending on the passed vline. If the last element in vline
+ * is NULL, all previous elements are considered to be complete words (the case
+ * when a space is the last token of the line) and completions are generated
+ * based on what could follow that input. If the last element in vline is not
+ * NULL and each sequential element matches the corresponding tokens of one or
+ * more commands exactly (e.g. 'encapv4' and not 'en') the same result is
+ * generated. If the last element is not NULL and the best possible match is a
+ * partial match, then the result generated will be all possible continuations
+ * of that element (e.g. 'encapv4', 'encapv6', etc for input 'en').
+ * @return matcher status
+ */
+enum matcher_rv
+command_complete (struct graph *cmdgraph,
+ vector vline,
+ struct list **completions);
+
+#endif /* _ZEBRA_COMMAND_MATCH_H */
diff --git a/lib/command_parse.y b/lib/command_parse.y
new file mode 100644
index 0000000000..1c220b6b69
--- /dev/null
+++ b/lib/command_parse.y
@@ -0,0 +1,540 @@
+/*
+ * Command format string parser for CLI backend.
+ *
+ * --
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+%{
+// compile with debugging facilities
+#define YYDEBUG 1
+%}
+
+%locations
+/* define parse.error verbose */
+%define api.pure full
+/* define api.prefix {cmd_yy} */
+
+/* names for generated header and parser files */
+%defines "command_parse.h"
+%output "command_parse.c"
+
+/* note: code blocks are output in order, to both .c and .h:
+ * 1. %code requires
+ * 2. %union + bison forward decls
+ * 3. %code provides
+ * command_lex.h needs to be included at 3.; it needs the union and YYSTYPE.
+ * struct parser_ctx is needed for the bison forward decls.
+ */
+%code requires {
+ #include "stdlib.h"
+ #include "string.h"
+ #include "memory.h"
+ #include "command.h"
+ #include "log.h"
+ #include "graph.h"
+
+ DECLARE_MTYPE(LEX)
+
+ #define YYSTYPE CMD_YYSTYPE
+ #define YYLTYPE CMD_YYLTYPE
+ struct parser_ctx;
+
+ /* subgraph semantic value */
+ struct subgraph {
+ struct graph_node *start, *end;
+ };
+}
+
+%union {
+ long long number;
+ char *string;
+ struct graph_node *node;
+ struct subgraph subgraph;
+}
+
+%code provides {
+ #ifndef FLEX_SCANNER
+ #include "command_lex.h"
+ #endif
+
+ extern void set_lexer_string (yyscan_t *scn, const char *string);
+ extern void cleanup_lexer (yyscan_t *scn);
+
+ struct parser_ctx {
+ yyscan_t scanner;
+
+ struct cmd_element *el;
+
+ struct graph *graph;
+ struct graph_node *currnode;
+
+ /* pointers to copy of command docstring */
+ char *docstr_start, *docstr;
+ };
+}
+
+/* union types for lexed tokens */
+%token <string> WORD
+%token <string> IPV4
+%token <string> IPV4_PREFIX
+%token <string> IPV6
+%token <string> IPV6_PREFIX
+%token <string> VARIABLE
+%token <string> RANGE
+
+/* union types for parsed rules */
+%type <node> start
+%type <node> literal_token
+%type <node> placeholder_token
+%type <node> simple_token
+%type <subgraph> selector
+%type <subgraph> selector_token
+%type <subgraph> selector_token_seq
+%type <subgraph> selector_seq_seq
+
+%code {
+
+ /* bison declarations */
+ void
+ cmd_yyerror (CMD_YYLTYPE *locp, struct parser_ctx *ctx, char const *msg);
+
+ /* helper functions for parser */
+ static const char *
+ doc_next (struct parser_ctx *ctx);
+
+ static struct graph_node *
+ node_adjacent (struct graph_node *, struct graph_node *);
+
+ static struct graph_node *
+ add_edge_dedup (struct graph_node *, struct graph_node *);
+
+ static int
+ cmp_token (struct cmd_token *, struct cmd_token *);
+
+ static struct graph_node *
+ new_token_node (struct parser_ctx *,
+ enum cmd_token_type type,
+ const char *text,
+ const char *doc);
+
+ static void
+ terminate_graph (CMD_YYLTYPE *locp, struct parser_ctx *ctx,
+ struct graph_node *);
+
+ static void
+ cleanup (struct parser_ctx *ctx);
+
+ #define scanner ctx->scanner
+}
+
+/* yyparse parameters */
+%lex-param {yyscan_t scanner}
+%parse-param {struct parser_ctx *ctx}
+
+/* called automatically before yyparse */
+%initial-action {
+ /* clear state pointers */
+ ctx->currnode = vector_slot (ctx->graph->nodes, 0);
+
+ /* copy docstring and keep a pointer to the copy */
+ if (ctx->el->doc)
+ {
+ // allocate a new buffer, making room for a flag
+ size_t length = (size_t) strlen (ctx->el->doc) + 2;
+ ctx->docstr = malloc (length);
+ memcpy (ctx->docstr, ctx->el->doc, strlen (ctx->el->doc));
+ // set the flag so doc_next knows when to print a warning
+ ctx->docstr[length - 2] = 0x03;
+ // null terminate
+ ctx->docstr[length - 1] = 0x00;
+ }
+ ctx->docstr_start = ctx->docstr;
+}
+
+%%
+
+start:
+ cmd_token_seq
+{
+ // tack on the command element
+ terminate_graph (&@1, ctx, ctx->currnode);
+}
+| cmd_token_seq placeholder_token '.' '.' '.'
+{
+ if ((ctx->currnode = add_edge_dedup (ctx->currnode, $2)) != $2)
+ graph_delete_node (ctx->graph, $2);
+
+ ((struct cmd_token *)ctx->currnode->data)->allowrepeat = 1;
+
+ // adding a node as a child of itself accepts any number
+ // of the same token, which is what we want for variadics
+ add_edge_dedup (ctx->currnode, ctx->currnode);
+
+ // tack on the command element
+ terminate_graph (&@1, ctx, ctx->currnode);
+}
+;
+
+cmd_token_seq:
+ /* empty */
+| cmd_token_seq cmd_token
+;
+
+cmd_token:
+ simple_token
+{
+ if ((ctx->currnode = add_edge_dedup (ctx->currnode, $1)) != $1)
+ graph_delete_node (ctx->graph, $1);
+}
+| selector
+{
+ graph_add_edge (ctx->currnode, $1.start);
+ ctx->currnode = $1.end;
+}
+;
+
+simple_token:
+ literal_token
+| placeholder_token
+;
+
+literal_token: WORD
+{
+ $$ = new_token_node (ctx, WORD_TKN, $1, doc_next(ctx));
+ XFREE (MTYPE_LEX, $1);
+}
+;
+
+placeholder_token:
+ IPV4
+{
+ $$ = new_token_node (ctx, IPV4_TKN, $1, doc_next(ctx));
+ XFREE (MTYPE_LEX, $1);
+}
+| IPV4_PREFIX
+{
+ $$ = new_token_node (ctx, IPV4_PREFIX_TKN, $1, doc_next(ctx));
+ XFREE (MTYPE_LEX, $1);
+}
+| IPV6
+{
+ $$ = new_token_node (ctx, IPV6_TKN, $1, doc_next(ctx));
+ XFREE (MTYPE_LEX, $1);
+}
+| IPV6_PREFIX
+{
+ $$ = new_token_node (ctx, IPV6_PREFIX_TKN, $1, doc_next(ctx));
+ XFREE (MTYPE_LEX, $1);
+}
+| VARIABLE
+{
+ $$ = new_token_node (ctx, VARIABLE_TKN, $1, doc_next(ctx));
+ XFREE (MTYPE_LEX, $1);
+}
+| RANGE
+{
+ $$ = new_token_node (ctx, RANGE_TKN, $1, doc_next(ctx));
+ struct cmd_token *token = $$->data;
+
+ // get the numbers out
+ yylval.string++;
+ token->min = strtoll (yylval.string, &yylval.string, 10);
+ strsep (&yylval.string, "-");
+ token->max = strtoll (yylval.string, &yylval.string, 10);
+
+ // validate range
+ if (token->min > token->max) cmd_yyerror (&@1, ctx, "Invalid range.");
+
+ XFREE (MTYPE_LEX, $1);
+}
+
+/* <selector|set> productions */
+selector: '<' selector_seq_seq '>'
+{
+ $$ = $2;
+};
+
+selector_seq_seq:
+ selector_seq_seq '|' selector_token_seq
+{
+ $$ = $1;
+ graph_add_edge ($$.start, $3.start);
+ graph_add_edge ($3.end, $$.end);
+}
+| selector_token_seq
+{
+ $$.start = new_token_node (ctx, FORK_TKN, NULL, NULL);
+ $$.end = new_token_node (ctx, JOIN_TKN, NULL, NULL);
+ ((struct cmd_token *)$$.start->data)->forkjoin = $$.end;
+ ((struct cmd_token *)$$.end->data)->forkjoin = $$.start;
+
+ graph_add_edge ($$.start, $1.start);
+ graph_add_edge ($1.end, $$.end);
+}
+;
+
+/* {keyword} productions */
+selector: '{' selector_seq_seq '}'
+{
+ $$ = $2;
+ graph_add_edge ($$.end, $$.start);
+ /* there is intentionally no start->end link, for two reasons:
+ * 1) this allows "at least 1 of" semantics, which are otherwise impossible
+ * 2) this would add a start->end->start loop in the graph that the current
+ * loop-avoidal fails to handle
+ * just use [{a|b}] if neccessary, that will work perfectly fine, and reason
+ * #1 is good enough to keep it this way. */
+};
+
+
+selector_token:
+ simple_token
+{
+ $$.start = $$.end = $1;
+}
+| selector
+;
+
+selector_token_seq:
+ selector_token_seq selector_token
+{
+ graph_add_edge ($1.end, $2.start);
+ $$.start = $1.start;
+ $$.end = $2.end;
+}
+| selector_token
+;
+
+/* [option] productions */
+selector: '[' selector_seq_seq ']'
+{
+ $$ = $2;
+ graph_add_edge ($$.start, $$.end);
+}
+;
+
+%%
+
+#undef scanner
+
+DEFINE_MTYPE(LIB, LEX, "Lexer token (temporary)")
+
+void
+command_parse_format (struct graph *graph, struct cmd_element *cmd)
+{
+ struct parser_ctx ctx = { .graph = graph, .el = cmd };
+
+ // set to 1 to enable parser traces
+ yydebug = 0;
+
+ set_lexer_string (&ctx.scanner, cmd->string);
+
+ // parse command into DFA
+ cmd_yyparse (&ctx);
+
+ /* cleanup lexer */
+ cleanup_lexer (&ctx.scanner);
+
+ // cleanup
+ cleanup (&ctx);
+}
+
+/* parser helper functions */
+
+void
+yyerror (CMD_YYLTYPE *loc, struct parser_ctx *ctx, char const *msg)
+{
+ char *tmpstr = strdup(ctx->el->string);
+ char *line, *eol;
+ char spacing[256];
+ int lineno = 0;
+
+ zlog_err ("%s: FATAL parse error: %s", __func__, msg);
+ zlog_err ("%s: %d:%d-%d of this command definition:", __func__, loc->first_line, loc->first_column, loc->last_column);
+
+ line = tmpstr;
+ do {
+ lineno++;
+ eol = strchr(line, '\n');
+ if (eol)
+ *eol++ = '\0';
+
+ zlog_err ("%s: | %s", __func__, line);
+ if (lineno == loc->first_line && lineno == loc->last_line
+ && loc->first_column < (int)sizeof(spacing) - 1
+ && loc->last_column < (int)sizeof(spacing) - 1) {
+
+ int len = loc->last_column - loc->first_column;
+ if (len == 0)
+ len = 1;
+
+ memset(spacing, ' ', loc->first_column - 1);
+ memset(spacing + loc->first_column - 1, '^', len);
+ spacing[loc->first_column - 1 + len] = '\0';
+ zlog_err ("%s: | %s", __func__, spacing);
+ }
+ } while ((line = eol));
+ free(tmpstr);
+}
+
+static void
+cleanup (struct parser_ctx *ctx)
+{
+ /* free resources */
+ free (ctx->docstr_start);
+
+ /* clear state pointers */
+ ctx->currnode = NULL;
+ ctx->docstr_start = ctx->docstr = NULL;
+}
+
+static void
+terminate_graph (CMD_YYLTYPE *locp, struct parser_ctx *ctx,
+ struct graph_node *finalnode)
+{
+ // end of graph should look like this
+ // * -> finalnode -> END_TKN -> cmd_element
+ struct cmd_element *element = ctx->el;
+ struct graph_node *end_token_node =
+ new_token_node (ctx, END_TKN, CMD_CR_TEXT, "");
+ struct graph_node *end_element_node =
+ graph_new_node (ctx->graph, element, NULL);
+
+ if (node_adjacent (finalnode, end_token_node))
+ cmd_yyerror (locp, ctx, "Duplicate command.");
+
+ graph_add_edge (finalnode, end_token_node);
+ graph_add_edge (end_token_node, end_element_node);
+}
+
+static const char *
+doc_next (struct parser_ctx *ctx)
+{
+ const char *piece = ctx->docstr ? strsep (&ctx->docstr, "\n") : "";
+ if (*piece == 0x03)
+ {
+ zlog_debug ("Ran out of docstring while parsing '%s'", ctx->el->string);
+ piece = "";
+ }
+
+ return piece;
+}
+
+static struct graph_node *
+new_token_node (struct parser_ctx *ctx, enum cmd_token_type type,
+ const char *text, const char *doc)
+{
+ struct cmd_token *token = new_cmd_token (type, ctx->el->attr, text, doc);
+ return graph_new_node (ctx->graph, token, (void (*)(void *)) &del_cmd_token);
+}
+
+/**
+ * Determines if there is an out edge from the first node to the second
+ */
+static struct graph_node *
+node_adjacent (struct graph_node *first, struct graph_node *second)
+{
+ struct graph_node *adj;
+ for (unsigned int i = 0; i < vector_active (first->to); i++)
+ {
+ adj = vector_slot (first->to, i);
+ struct cmd_token *ftok = adj->data,
+ *stok = second->data;
+ if (cmp_token (ftok, stok))
+ return adj;
+ }
+ return NULL;
+}
+
+/**
+ * Creates an edge betwen two nodes, unless there is already an edge to an
+ * equivalent node.
+ *
+ * The first node's out edges are searched to see if any of them point to a
+ * node that is equivalent to the second node. If such a node exists, it is
+ * returned. Otherwise an edge is created from the first node to the second.
+ *
+ * @param from start node for edge
+ * @param to end node for edge
+ * @return the node which the new edge points to
+ */
+static struct graph_node *
+add_edge_dedup (struct graph_node *from, struct graph_node *to)
+{
+ struct graph_node *existing = node_adjacent (from, to);
+ if (existing)
+ {
+ struct cmd_token *ex_tok = existing->data;
+ struct cmd_token *to_tok = to->data;
+ // NORMAL takes precedence over DEPRECATED takes precedence over HIDDEN
+ ex_tok->attr = (ex_tok->attr < to_tok->attr) ? ex_tok->attr : to_tok->attr;
+ return existing;
+ }
+ else
+ return graph_add_edge (from, to);
+}
+
+/**
+ * Compares two cmd_token's for equality,
+ *
+ * As such, this function is the working definition of token equality
+ * for parsing purposes and determines overall graph structure.
+ */
+static int
+cmp_token (struct cmd_token *first, struct cmd_token *second)
+{
+ // compare types
+ if (first->type != second->type) return 0;
+
+ switch (first->type) {
+ case WORD_TKN:
+ case VARIABLE_TKN:
+ if (first->text && second->text)
+ {
+ if (strcmp (first->text, second->text))
+ return 0;
+ }
+ else if (first->text != second->text) return 0;
+ break;
+ case RANGE_TKN:
+ if (first->min != second->min || first->max != second->max)
+ return 0;
+ break;
+ /* selectors and options should be equal if their subgraphs are equal,
+ * but the graph isomorphism problem is not known to be solvable in
+ * polynomial time so we consider selectors and options inequal in all
+ * cases; ultimately this forks the graph, but the matcher can handle
+ * this regardless
+ */
+ case FORK_TKN:
+ return 0;
+
+ /* end nodes are always considered equal, since each node may only
+ * have one END_TKN child at a time
+ */
+ case START_TKN:
+ case END_TKN:
+ case JOIN_TKN:
+ default:
+ break;
+ }
+ return 1;
+}
diff --git a/lib/csv.c b/lib/csv.c
index 7df9292647..4fd14918fd 100644
--- a/lib/csv.c
+++ b/lib/csv.c
@@ -239,6 +239,9 @@ csv_encode (csv_t *csv,
rec = malloc(sizeof(csv_record_t));
if (!rec) {
log_error("record malloc failed\n");
+ if (!buf)
+ free(str);
+ va_end(list);
return (NULL);
}
csv_init_record(rec);
@@ -255,6 +258,7 @@ csv_encode (csv_t *csv,
if (!fld) {
log_error("fld malloc failed\n");
csv_remove_record(csv, rec);
+ va_end(list);
return (NULL);
}
if (tempc < (count - 1)) {
@@ -518,7 +522,7 @@ csv_concat_record (csv_t *csv,
curr = (char *)calloc(1, csv->buflen);
if (!curr) {
log_error("field str malloc failed\n");
- return (NULL);
+ goto out_rec;
}
rec->record = curr;
@@ -526,7 +530,7 @@ csv_concat_record (csv_t *csv,
ret = strstr(rec1->record, "\n");
if (!ret) {
log_error("rec1 str not properly formatted\n");
- return (NULL);
+ goto out_curr;
}
snprintf(curr, (int)(ret - rec1->record + 1), "%s", rec1->record);
@@ -535,7 +539,7 @@ csv_concat_record (csv_t *csv,
ret = strstr(rec2->record, "\n");
if (!ret) {
log_error("rec2 str not properly formatted\n");
- return (NULL);
+ goto out_curr;
}
snprintf((curr+strlen(curr)), (int)(ret - rec2->record + 1), "%s",
@@ -556,6 +560,12 @@ csv_concat_record (csv_t *csv,
csv_insert_record(csv, rec);
return rec;
+
+out_curr:
+ free(curr);
+out_rec:
+ free(rec);
+ return NULL;
}
void
@@ -569,6 +579,8 @@ csv_decode (csv_t *csv, char *inbuf)
pos = strpbrk(buf, "\n");
while (pos != NULL) {
rec = calloc(1, sizeof(csv_record_t));
+ if (!rec)
+ return;
csv_init_record(rec);
TAILQ_INSERT_TAIL(&(csv->records), rec, next_record);
csv->num_recs++;
diff --git a/lib/distribute.c b/lib/distribute.c
index 498410c22d..2e76e352cb 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -161,8 +161,8 @@ distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
}
/* Set access-list name to the distribute list. */
-static struct distribute *
-distribute_list_set (const char *ifname, enum distribute_type type,
+static void
+distribute_list_set (const char *ifname, enum distribute_type type,
const char *alist_name)
{
struct distribute *dist;
@@ -175,14 +175,12 @@ distribute_list_set (const char *ifname, enum distribute_type type,
/* Apply this distribute-list to the interface. */
(*distribute_add_hook) (dist);
-
- return dist;
}
/* Unset distribute-list. If matched distribute-list exist then
return 1. */
static int
-distribute_list_unset (const char *ifname, enum distribute_type type,
+distribute_list_unset (const char *ifname, enum distribute_type type,
const char *alist_name)
{
struct distribute *dist;
@@ -192,9 +190,9 @@ distribute_list_unset (const char *ifname, enum distribute_type type,
return 0;
if (!dist->list[type])
- return 0;
+ return 0;
if (strcmp (dist->list[type], alist_name) != 0)
- return 0;
+ return 0;
XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
dist->list[type] = NULL;
@@ -208,7 +206,7 @@ distribute_list_unset (const char *ifname, enum distribute_type type,
}
/* Set access-list name to the distribute list. */
-static struct distribute *
+static void
distribute_list_prefix_set (const char *ifname, enum distribute_type type,
const char *plist_name)
{
@@ -222,8 +220,6 @@ distribute_list_prefix_set (const char *ifname, enum distribute_type type,
/* Apply this distribute-list to the interface. */
(*distribute_add_hook) (dist);
-
- return dist;
}
/* Unset distribute-list. If matched distribute-list exist then
@@ -239,9 +235,9 @@ distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
return 0;
if (!dist->prefix[type])
- return 0;
+ return 0;
if (strcmp (dist->prefix[type], plist_name) != 0)
- return 0;
+ return 0;
XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
dist->prefix[type] = NULL;
@@ -254,525 +250,101 @@ distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
return 1;
}
-DEFUN (distribute_list_all,
- distribute_list_all_cmd,
- "distribute-list WORD (in|out)",
- "Filter networks in routing updates\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-{
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V4_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V4_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Get interface name corresponding distribute list. */
- distribute_list_set (NULL, type, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (ipv6_distribute_list_all,
- ipv6_distribute_list_all_cmd,
- "ipv6 distribute-list WORD (in|out)",
- "Filter networks in routing updates\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-{
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V6_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V6_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Get interface name corresponding distribute list. */
- distribute_list_set (NULL, type, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-ALIAS (ipv6_distribute_list_all,
- ipv6_as_v4_distribute_list_all_cmd,
- "distribute-list WORD (in|out)",
- "Filter networks in routing updates\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-
-DEFUN (no_distribute_list_all,
- no_distribute_list_all_cmd,
- "no distribute-list WORD (in|out)",
- NO_STR
- "Filter networks in routing updates\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-{
- int ret;
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V4_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V4_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ret = distribute_list_unset (NULL, type, argv[0]);
- if (! ret)
- {
- vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ipv6_distribute_list_all,
- no_ipv6_distribute_list_all_cmd,
- "no ipv6 distribute-list WORD (in|out)",
- NO_STR
- "Filter networks in routing updates\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-{
- int ret;
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V6_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V6_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ret = distribute_list_unset (NULL, type, argv[0]);
- if (! ret)
- {
- vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-ALIAS (no_ipv6_distribute_list_all,
- no_ipv6_as_v4_distribute_list_all_cmd,
- "no distribute-list WORD (in|out)",
- NO_STR
- "Filter networks in routing updates\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-
DEFUN (distribute_list,
distribute_list_cmd,
- "distribute-list WORD (in|out) WORD",
+ "distribute-list [prefix] WORD <in|out> [WORD]",
"Filter networks in routing updates\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
{
- enum distribute_type type;
+ int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
/* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V4_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V4_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ enum distribute_type type = argv[2 + prefix]->arg[0] == 'i' ?
+ DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT;
+
+ /* Set appropriate function call */
+ void (*distfn)(const char *, enum distribute_type, const char *) = prefix ?
+ &distribute_list_prefix_set : &distribute_list_set;
+
+ /* if interface is present, get name */
+ const char *ifname = NULL;
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
/* Get interface name corresponding distribute list. */
- distribute_list_set (argv[2], type, argv[0]);
+ distfn (ifname, type, argv[1 + prefix]->arg);
return CMD_SUCCESS;
}
DEFUN (ipv6_distribute_list,
ipv6_distribute_list_cmd,
- "ipv6 distribute-list WORD (in|out) WORD",
- "Filter networks in routing updates\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-{
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V6_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V6_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Get interface name corresponding distribute list. */
- distribute_list_set (argv[2], type, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-ALIAS (ipv6_distribute_list,
- ipv6_as_v4_distribute_list_cmd,
- "distribute-list WORD (in|out) WORD",
- "Filter networks in routing updates\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-
-DEFUN (no_distribute_list, no_distribute_list_cmd,
- "no distribute-list WORD (in|out) WORD",
- NO_STR
+ "ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
+ "IPv6\n"
"Filter networks in routing updates\n"
+ "Specify a prefix\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
{
- int ret;
- enum distribute_type type;
+ int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
/* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V4_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V4_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ enum distribute_type type = argv[3 + prefix]->arg[0] == 'i' ?
+ DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT;
- ret = distribute_list_unset (argv[2], type, argv[0]);
- if (! ret)
- {
- vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ipv6_distribute_list,
- no_ipv6_distribute_list_cmd,
- "no ipv6 distribute-list WORD (in|out) WORD",
- NO_STR
- "Filter networks in routing updates\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-{
- int ret;
- enum distribute_type type;
+ /* Set appropriate function call */
+ void (*distfn)(const char *, enum distribute_type, const char *) = prefix ?
+ &distribute_list_prefix_set : &distribute_list_set;
+
+ /* if interface is present, get name */
+ const char *ifname = NULL;
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V6_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V6_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ /* Get interface name corresponding distribute list. */
+ distfn (ifname, type, argv[1 + prefix]->arg);
- ret = distribute_list_unset (argv[2], type, argv[0]);
- if (! ret)
- {
- vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
return CMD_SUCCESS;
}
-
-ALIAS (no_ipv6_distribute_list,
- no_ipv6_as_v4_distribute_list_cmd,
- "no distribute-list WORD (in|out) WORD",
+
+DEFUN (no_distribute_list,
+ no_distribute_list_cmd,
+ "no [ipv6] distribute-list [prefix] WORD <in|out> [WORD]",
NO_STR
"Filter networks in routing updates\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
-
-DEFUN (distribute_list_prefix_all,
- distribute_list_prefix_all_cmd,
- "distribute-list prefix WORD (in|out)",
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
{
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V4_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V4_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Get interface name corresponding distribute list. */
- distribute_list_prefix_set (NULL, type, argv[0]);
+ int ipv6 = strmatch(argv[1]->text, "ipv6");
+ int prefix = (argv[2 + ipv6]->type == WORD_TKN) ? 1 : 0;
- return CMD_SUCCESS;
-}
-
-DEFUN (ipv6_distribute_list_prefix_all,
- ipv6_distribute_list_prefix_all_cmd,
- "ipv6 distribute-list prefix WORD (in|out)",
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-{
- enum distribute_type type;
+ int idx_alname = 2 + ipv6 + prefix;
+ int idx_disttype = idx_alname + 1;
/* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V6_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V6_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Get interface name corresponding distribute list. */
- distribute_list_prefix_set (NULL, type, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-ALIAS (ipv6_distribute_list_prefix_all,
- ipv6_as_v4_distribute_list_prefix_all_cmd,
- "distribute-list prefix WORD (in|out)",
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
+ enum distribute_type distin = (ipv6) ? DISTRIBUTE_V6_IN : DISTRIBUTE_V4_IN;
+ enum distribute_type distout = (ipv6) ? DISTRIBUTE_V6_OUT : DISTRIBUTE_V4_OUT;
-DEFUN (no_distribute_list_prefix_all,
- no_distribute_list_prefix_all_cmd,
- "no distribute-list prefix WORD (in|out)",
- NO_STR
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-{
- int ret;
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V4_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V4_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ret = distribute_list_prefix_unset (NULL, type, argv[0]);
- if (! ret)
- {
- vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ipv6_distribute_list_prefix_all,
- no_ipv6_distribute_list_prefix_all_cmd,
- "no ipv6 distribute-list prefix WORD (in|out)",
- NO_STR
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-{
- int ret;
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V6_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V6_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ret = distribute_list_prefix_unset (NULL, type, argv[0]);
- if (! ret)
- {
- vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-ALIAS (no_ipv6_distribute_list_prefix_all,
- no_ipv6_as_v4_distribute_list_prefix_all_cmd,
- "no distribute-list prefix WORD (in|out)",
- NO_STR
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n")
-
-DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
- "distribute-list prefix WORD (in|out) WORD",
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-{
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V4_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V4_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Get interface name corresponding distribute list. */
- distribute_list_prefix_set (argv[2], type, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (ipv6_distribute_list_prefix,
- ipv6_distribute_list_prefix_cmd,
- "ipv6 distribute-list prefix WORD (in|out) WORD",
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-{
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V6_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V6_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ enum distribute_type type = argv[idx_disttype]->arg[0] == 'i' ? distin : distout;
+ /* Set appropriate function call */
+ int (*distfn)(const char *, enum distribute_type, const char *) = prefix ?
+ &distribute_list_prefix_unset : &distribute_list_unset;
+
+ /* if interface is present, get name */
+ const char *ifname = NULL;
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
/* Get interface name corresponding distribute list. */
- distribute_list_prefix_set (argv[2], type, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-ALIAS (ipv6_distribute_list_prefix,
- ipv6_as_v4_distribute_list_prefix_cmd,
- "distribute-list prefix WORD (in|out) WORD",
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-
-DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
- "no distribute-list prefix WORD (in|out) WORD",
- NO_STR
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-{
- int ret;
- enum distribute_type type;
+ int ret = distfn (ifname, type, argv[2 + prefix]->arg);
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V4_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V4_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
if (! ret)
{
vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
@@ -781,52 +353,6 @@ DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
return CMD_SUCCESS;
}
-DEFUN (no_ipv6_distribute_list_prefix,
- no_ipv6_distribute_list_prefix_cmd,
- "no ipv6 distribute-list prefix WORD (in|out) WORD",
- NO_STR
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-{
- int ret;
- enum distribute_type type;
-
- /* Check of distribute list type. */
- if (strncmp (argv[1], "i", 1) == 0)
- type = DISTRIBUTE_V6_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
- type = DISTRIBUTE_V6_OUT;
- else
- {
- vty_out (vty, "distribute list direction must be [in|out]%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
- if (! ret)
- {
- vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-ALIAS (no_ipv6_distribute_list_prefix,
- no_ipv6_as_v4_distribute_list_prefix_cmd,
- "no distribute-list prefix WORD (in|out) WORD",
- NO_STR
- "Filter networks in routing updates\n"
- "Filter prefixes in routing updates\n"
- "Name of an IP prefix-list\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-
static int
distribute_print (struct vty *vty, char *tab[], int is_prefix,
enum distribute_type type, int has_print)
@@ -851,7 +377,7 @@ config_show_distribute (struct vty *vty)
/* Output filter configuration. */
dist = distribute_lookup (NULL);
- vty_out(vty, " Outgoing update filter list for all interface is");
+ vty_out (vty, " Outgoing update filter list for all interface is");
has_print = 0;
if (dist)
{
@@ -874,8 +400,8 @@ config_show_distribute (struct vty *vty)
{
dist = mp->data;
if (dist->ifname)
- {
- vty_out (vty, " %s filtered by", dist->ifname);
+ {
+ vty_out (vty, " %s filtered by", dist->ifname);
has_print = 0;
has_print = distribute_print(vty, dist->list, 0,
DISTRIBUTE_V4_OUT, has_print);
@@ -886,16 +412,16 @@ config_show_distribute (struct vty *vty)
has_print = distribute_print(vty, dist->prefix, 1,
DISTRIBUTE_V6_OUT, has_print);
if (has_print)
- vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "%s", VTY_NEWLINE);
else
vty_out(vty, " nothing%s", VTY_NEWLINE);
- }
+ }
}
/* Input filter configuration. */
dist = distribute_lookup (NULL);
- vty_out(vty, " Incoming update filter list for all interface is");
+ vty_out (vty, " Incoming update filter list for all interface is");
has_print = 0;
if (dist)
{
@@ -917,9 +443,9 @@ config_show_distribute (struct vty *vty)
for (mp = disthash->index[i]; mp; mp = mp->next)
{
dist = mp->data;
- if (dist->ifname)
- {
- vty_out (vty, " %s filtered by", dist->ifname);
+ if (dist->ifname)
+ {
+ vty_out (vty, " %s filtered by", dist->ifname);
has_print = 0;
has_print = distribute_print(vty, dist->list, 0,
DISTRIBUTE_V4_IN, has_print);
@@ -930,10 +456,10 @@ config_show_distribute (struct vty *vty)
has_print = distribute_print(vty, dist->prefix, 1,
DISTRIBUTE_V6_IN, has_print);
if (has_print)
- vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "%s", VTY_NEWLINE);
else
vty_out(vty, " nothing%s", VTY_NEWLINE);
- }
+ }
}
return 0;
}
@@ -997,39 +523,30 @@ distribute_list_init (int node)
{
disthash = hash_create (distribute_hash_make,
(int (*) (const void *, const void *)) distribute_cmp);
- /* install v4 */
- if (node == RIP_NODE) {
- install_element (node, &distribute_list_all_cmd);
- install_element (node, &no_distribute_list_all_cmd);
- install_element (node, &distribute_list_cmd);
- install_element (node, &no_distribute_list_cmd);
- install_element (node, &distribute_list_prefix_all_cmd);
- install_element (node, &no_distribute_list_prefix_all_cmd);
- install_element (node, &distribute_list_prefix_cmd);
- install_element (node, &no_distribute_list_prefix_cmd);
- }
+
+ install_element (node, &distribute_list_cmd);
+ install_element (node, &no_distribute_list_cmd);
+/*
+ install_element (RIP_NODE, &distribute_list_cmd);
+ install_element (RIP_NODE, &no_distribute_list_cmd);
+ install_element (RIPNG_NODE, &distribute_list_cmd);
+ install_element (RIPNG_NODE, &no_distribute_list_cmd);
+ */
/* install v6 */
if (node == RIPNG_NODE) {
- install_element (node, &ipv6_distribute_list_all_cmd);
- install_element (node, &no_ipv6_distribute_list_all_cmd);
- install_element (node, &ipv6_distribute_list_cmd);
- install_element (node, &no_ipv6_distribute_list_cmd);
- install_element (node, &ipv6_distribute_list_prefix_all_cmd);
- install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
- install_element (node, &ipv6_distribute_list_prefix_cmd);
- install_element (node, &no_ipv6_distribute_list_prefix_cmd);
+ install_element (RIPNG_NODE, &ipv6_distribute_list_cmd);
}
- /* install v4 syntax command for v6 only protocols. */
- if (node == RIPNG_NODE) {
- install_element (node, &ipv6_as_v4_distribute_list_all_cmd);
- install_element (node, &no_ipv6_as_v4_distribute_list_all_cmd);
- install_element (node, &ipv6_as_v4_distribute_list_cmd);
- install_element (node, &no_ipv6_as_v4_distribute_list_cmd);
- install_element (node, &ipv6_as_v4_distribute_list_prefix_all_cmd);
- install_element (node, &no_ipv6_as_v4_distribute_list_prefix_all_cmd);
- install_element (node, &ipv6_as_v4_distribute_list_prefix_cmd);
- install_element (node, &no_ipv6_as_v4_distribute_list_prefix_cmd);
- }
+ /* TODO: install v4 syntax command for v6 only protocols. */
+ /* if (node == RIPNG_NODE) {
+ * install_element (node, &ipv6_as_v4_distribute_list_all_cmd);
+ * install_element (node, &no_ipv6_as_v4_distribute_list_all_cmd);
+ * install_element (node, &ipv6_as_v4_distribute_list_cmd);
+ * install_element (node, &no_ipv6_as_v4_distribute_list_cmd);
+ * install_element (node, &ipv6_as_v4_distribute_list_prefix_all_cmd);
+ * install_element (node, &no_ipv6_as_v4_distribute_list_prefix_all_cmd);
+ * install_element (node, &ipv6_as_v4_distribute_list_prefix_cmd);
+ * install_element (node, &no_ipv6_as_v4_distribute_list_prefix_cmd);
+ }*/
}
diff --git a/lib/filter.c b/lib/filter.c
index e9ba715c92..2b9ba87137 100644
--- a/lib/filter.c
+++ b/lib/filter.c
@@ -105,7 +105,6 @@ static struct access_master access_master_ipv4 =
NULL,
};
-#ifdef HAVE_IPV6
/* Static structure for IPv6 access_list's master. */
static struct access_master access_master_ipv6 =
{
@@ -114,17 +113,14 @@ static struct access_master access_master_ipv6 =
NULL,
NULL,
};
-#endif /* HAVE_IPV6 */
static struct access_master *
access_master_get (afi_t afi)
{
if (afi == AFI_IP)
return &access_master_ipv4;
-#ifdef HAVE_IPV6
else if (afi == AFI_IP6)
return &access_master_ipv6;
-#endif /* HAVE_IPV6 */
return NULL;
}
@@ -434,9 +430,7 @@ void
access_list_add_hook (void (*func) (struct access_list *access))
{
access_master_ipv4.add_hook = func;
-#ifdef HAVE_IPV6
access_master_ipv6.add_hook = func;
-#endif /* HAVE_IPV6 */
}
/* Delete hook function. */
@@ -444,9 +438,7 @@ void
access_list_delete_hook (void (*func) (struct access_list *access))
{
access_master_ipv4.delete_hook = func;
-#ifdef HAVE_IPV6
access_master_ipv6.delete_hook = func;
-#endif /* HAVE_IPV6 */
}
/* Add new filter to the end of specified access_list. */
@@ -704,7 +696,7 @@ filter_set_cisco (struct vty *vty, const char *name_str, const char *type_str,
/* Standard access-list */
DEFUN (access_list_standard,
access_list_standard_cmd,
- "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
+ "access-list <(1-99)|(1300-1999)> <deny|permit> A.B.C.D A.B.C.D",
"Add an access list entry\n"
"IP standard access list\n"
"IP standard access list (expanded range)\n"
@@ -713,13 +705,17 @@ DEFUN (access_list_standard,
"Address to match\n"
"Wildcard bits\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 3;
+ int idx_ipv4_2 = 4;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
NULL, NULL, 0, 1);
}
DEFUN (access_list_standard_nomask,
access_list_standard_nomask_cmd,
- "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
+ "access-list <(1-99)|(1300-1999)> <deny|permit> A.B.C.D",
"Add an access list entry\n"
"IP standard access list\n"
"IP standard access list (expanded range)\n"
@@ -727,13 +723,16 @@ DEFUN (access_list_standard_nomask,
"Specify packets to forward\n"
"Address to match\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 3;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg, "0.0.0.0",
NULL, NULL, 0, 1);
}
DEFUN (access_list_standard_host,
access_list_standard_host_cmd,
- "access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
+ "access-list <(1-99)|(1300-1999)> <deny|permit> host A.B.C.D",
"Add an access list entry\n"
"IP standard access list\n"
"IP standard access list (expanded range)\n"
@@ -742,13 +741,16 @@ DEFUN (access_list_standard_host,
"A single host address\n"
"Address to match\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 4;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg, "0.0.0.0",
NULL, NULL, 0, 1);
}
DEFUN (access_list_standard_any,
access_list_standard_any_cmd,
- "access-list (<1-99>|<1300-1999>) (deny|permit) any",
+ "access-list <(1-99)|(1300-1999)> <deny|permit> any",
"Add an access list entry\n"
"IP standard access list\n"
"IP standard access list (expanded range)\n"
@@ -756,13 +758,15 @@ DEFUN (access_list_standard_any,
"Specify packets to forward\n"
"Any source host\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
"255.255.255.255", NULL, NULL, 0, 1);
}
DEFUN (no_access_list_standard,
no_access_list_standard_cmd,
- "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
+ "no access-list <(1-99)|(1300-1999)> <deny|permit> A.B.C.D A.B.C.D",
NO_STR
"Add an access list entry\n"
"IP standard access list\n"
@@ -772,13 +776,17 @@ DEFUN (no_access_list_standard,
"Address to match\n"
"Wildcard bits\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
NULL, NULL, 0, 0);
}
DEFUN (no_access_list_standard_nomask,
no_access_list_standard_nomask_cmd,
- "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
+ "no access-list <(1-99)|(1300-1999)> <deny|permit> A.B.C.D",
NO_STR
"Add an access list entry\n"
"IP standard access list\n"
@@ -787,13 +795,16 @@ DEFUN (no_access_list_standard_nomask,
"Specify packets to forward\n"
"Address to match\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 4;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg, "0.0.0.0",
NULL, NULL, 0, 0);
}
DEFUN (no_access_list_standard_host,
no_access_list_standard_host_cmd,
- "no access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
+ "no access-list <(1-99)|(1300-1999)> <deny|permit> host A.B.C.D",
NO_STR
"Add an access list entry\n"
"IP standard access list\n"
@@ -803,13 +814,16 @@ DEFUN (no_access_list_standard_host,
"A single host address\n"
"Address to match\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 5;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg, "0.0.0.0",
NULL, NULL, 0, 0);
}
DEFUN (no_access_list_standard_any,
no_access_list_standard_any_cmd,
- "no access-list (<1-99>|<1300-1999>) (deny|permit) any",
+ "no access-list <(1-99)|(1300-1999)> <deny|permit> any",
NO_STR
"Add an access list entry\n"
"IP standard access list\n"
@@ -818,14 +832,16 @@ DEFUN (no_access_list_standard_any,
"Specify packets to forward\n"
"Any source host\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
"255.255.255.255", NULL, NULL, 0, 0);
}
/* Extended access-list */
DEFUN (access_list_extended,
access_list_extended_cmd,
- "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
+ "access-list <(100-199)|(2000-2699)> <deny|permit> ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
"Add an access list entry\n"
"IP extended access list\n"
"IP extended access list (expanded range)\n"
@@ -837,13 +853,19 @@ DEFUN (access_list_extended,
"Destination address\n"
"Destination Wildcard bits\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[5], 1 ,1);
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
+ int idx_ipv4_3 = 6;
+ int idx_ipv4_4 = 7;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg, argv[idx_ipv4_3]->arg, argv[idx_ipv4_4]->arg, 1 ,1);
}
DEFUN (access_list_extended_mask_any,
access_list_extended_mask_any_cmd,
- "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
+ "access-list <(100-199)|(2000-2699)> <deny|permit> ip A.B.C.D A.B.C.D any",
"Add an access list entry\n"
"IP extended access list\n"
"IP extended access list (expanded range)\n"
@@ -854,14 +876,18 @@ DEFUN (access_list_extended_mask_any,
"Source wildcard bits\n"
"Any destination host\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- argv[3], "0.0.0.0",
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg, "0.0.0.0",
"255.255.255.255", 1, 1);
}
DEFUN (access_list_extended_any_mask,
access_list_extended_any_mask_cmd,
- "access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
+ "access-list <(100-199)|(2000-2699)> <deny|permit> ip any A.B.C.D A.B.C.D",
"Add an access list entry\n"
"IP extended access list\n"
"IP extended access list (expanded range)\n"
@@ -872,14 +898,18 @@ DEFUN (access_list_extended_any_mask,
"Destination address\n"
"Destination Wildcard bits\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
- "255.255.255.255", argv[2],
- argv[3], 1, 1);
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 5;
+ int idx_ipv4_2 = 6;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
+ "255.255.255.255", argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg, 1, 1);
}
DEFUN (access_list_extended_any_any,
access_list_extended_any_any_cmd,
- "access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
+ "access-list <(100-199)|(2000-2699)> <deny|permit> ip any any",
"Add an access list entry\n"
"IP extended access list\n"
"IP extended access list (expanded range)\n"
@@ -889,14 +919,16 @@ DEFUN (access_list_extended_any_any,
"Any source host\n"
"Any destination host\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
"255.255.255.255", "0.0.0.0",
"255.255.255.255", 1, 1);
}
DEFUN (access_list_extended_mask_host,
access_list_extended_mask_host_cmd,
- "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
+ "access-list <(100-199)|(2000-2699)> <deny|permit> ip A.B.C.D A.B.C.D host A.B.C.D",
"Add an access list entry\n"
"IP extended access list\n"
"IP extended access list (expanded range)\n"
@@ -908,14 +940,19 @@ DEFUN (access_list_extended_mask_host,
"A single destination host\n"
"Destination address\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- argv[3], argv[4],
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
+ int idx_ipv4_3 = 7;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg, argv[idx_ipv4_3]->arg,
"0.0.0.0", 1, 1);
}
DEFUN (access_list_extended_host_mask,
access_list_extended_host_mask_cmd,
- "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
+ "access-list <(100-199)|(2000-2699)> <deny|permit> ip host A.B.C.D A.B.C.D A.B.C.D",
"Add an access list entry\n"
"IP extended access list\n"
"IP extended access list (expanded range)\n"
@@ -927,14 +964,19 @@ DEFUN (access_list_extended_host_mask,
"Destination address\n"
"Destination Wildcard bits\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- "0.0.0.0", argv[3],
- argv[4], 1, 1);
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 5;
+ int idx_ipv4_2 = 6;
+ int idx_ipv4_3 = 7;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ "0.0.0.0", argv[idx_ipv4_2]->arg,
+ argv[idx_ipv4_3]->arg, 1, 1);
}
DEFUN (access_list_extended_host_host,
access_list_extended_host_host_cmd,
- "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
+ "access-list <(100-199)|(2000-2699)> <deny|permit> ip host A.B.C.D host A.B.C.D",
"Add an access list entry\n"
"IP extended access list\n"
"IP extended access list (expanded range)\n"
@@ -946,14 +988,18 @@ DEFUN (access_list_extended_host_host,
"A single destination host\n"
"Destination address\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- "0.0.0.0", argv[3],
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 5;
+ int idx_ipv4_2 = 7;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ "0.0.0.0", argv[idx_ipv4_2]->arg,
"0.0.0.0", 1, 1);
}
DEFUN (access_list_extended_any_host,
access_list_extended_any_host_cmd,
- "access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
+ "access-list <(100-199)|(2000-2699)> <deny|permit> ip any host A.B.C.D",
"Add an access list entry\n"
"IP extended access list\n"
"IP extended access list (expanded range)\n"
@@ -964,14 +1010,17 @@ DEFUN (access_list_extended_any_host,
"A single destination host\n"
"Destination address\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
- "255.255.255.255", argv[2],
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 6;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
+ "255.255.255.255", argv[idx_ipv4]->arg,
"0.0.0.0", 1, 1);
}
DEFUN (access_list_extended_host_any,
access_list_extended_host_any_cmd,
- "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
+ "access-list <(100-199)|(2000-2699)> <deny|permit> ip host A.B.C.D any",
"Add an access list entry\n"
"IP extended access list\n"
"IP extended access list (expanded range)\n"
@@ -982,14 +1031,17 @@ DEFUN (access_list_extended_host_any,
"Source address\n"
"Any destination host\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
+ int idx_acl = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4 = 5;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
"0.0.0.0", "0.0.0.0",
"255.255.255.255", 1, 1);
}
DEFUN (no_access_list_extended,
no_access_list_extended_cmd,
- "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
+ "no access-list <(100-199)|(2000-2699)> <deny|permit> ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
NO_STR
"Add an access list entry\n"
"IP extended access list\n"
@@ -1002,13 +1054,19 @@ DEFUN (no_access_list_extended,
"Destination address\n"
"Destination Wildcard bits\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[5], 1, 0);
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 5;
+ int idx_ipv4_2 = 6;
+ int idx_ipv4_3 = 7;
+ int idx_ipv4_4 = 8;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg, argv[idx_ipv4_3]->arg, argv[idx_ipv4_4]->arg, 1, 0);
}
DEFUN (no_access_list_extended_mask_any,
no_access_list_extended_mask_any_cmd,
- "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
+ "no access-list <(100-199)|(2000-2699)> <deny|permit> ip A.B.C.D A.B.C.D any",
NO_STR
"Add an access list entry\n"
"IP extended access list\n"
@@ -1020,14 +1078,18 @@ DEFUN (no_access_list_extended_mask_any,
"Source wildcard bits\n"
"Any destination host\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- argv[3], "0.0.0.0",
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 5;
+ int idx_ipv4_2 = 6;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg, "0.0.0.0",
"255.255.255.255", 1, 0);
}
DEFUN (no_access_list_extended_any_mask,
no_access_list_extended_any_mask_cmd,
- "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
+ "no access-list <(100-199)|(2000-2699)> <deny|permit> ip any A.B.C.D A.B.C.D",
NO_STR
"Add an access list entry\n"
"IP extended access list\n"
@@ -1039,14 +1101,18 @@ DEFUN (no_access_list_extended_any_mask,
"Destination address\n"
"Destination Wildcard bits\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
- "255.255.255.255", argv[2],
- argv[3], 1, 0);
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 6;
+ int idx_ipv4_2 = 7;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
+ "255.255.255.255", argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg, 1, 0);
}
DEFUN (no_access_list_extended_any_any,
no_access_list_extended_any_any_cmd,
- "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
+ "no access-list <(100-199)|(2000-2699)> <deny|permit> ip any any",
NO_STR
"Add an access list entry\n"
"IP extended access list\n"
@@ -1057,14 +1123,16 @@ DEFUN (no_access_list_extended_any_any,
"Any source host\n"
"Any destination host\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
"255.255.255.255", "0.0.0.0",
"255.255.255.255", 1, 0);
}
DEFUN (no_access_list_extended_mask_host,
no_access_list_extended_mask_host_cmd,
- "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
+ "no access-list <(100-199)|(2000-2699)> <deny|permit> ip A.B.C.D A.B.C.D host A.B.C.D",
NO_STR
"Add an access list entry\n"
"IP extended access list\n"
@@ -1077,14 +1145,19 @@ DEFUN (no_access_list_extended_mask_host,
"A single destination host\n"
"Destination address\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- argv[3], argv[4],
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 5;
+ int idx_ipv4_2 = 6;
+ int idx_ipv4_3 = 8;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg, argv[idx_ipv4_3]->arg,
"0.0.0.0", 1, 0);
}
DEFUN (no_access_list_extended_host_mask,
no_access_list_extended_host_mask_cmd,
- "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
+ "no access-list <(100-199)|(2000-2699)> <deny|permit> ip host A.B.C.D A.B.C.D A.B.C.D",
NO_STR
"Add an access list entry\n"
"IP extended access list\n"
@@ -1097,14 +1170,19 @@ DEFUN (no_access_list_extended_host_mask,
"Destination address\n"
"Destination Wildcard bits\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- "0.0.0.0", argv[3],
- argv[4], 1, 0);
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 6;
+ int idx_ipv4_2 = 7;
+ int idx_ipv4_3 = 8;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ "0.0.0.0", argv[idx_ipv4_2]->arg,
+ argv[idx_ipv4_3]->arg, 1, 0);
}
DEFUN (no_access_list_extended_host_host,
no_access_list_extended_host_host_cmd,
- "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
+ "no access-list <(100-199)|(2000-2699)> <deny|permit> ip host A.B.C.D host A.B.C.D",
NO_STR
"Add an access list entry\n"
"IP extended access list\n"
@@ -1117,14 +1195,18 @@ DEFUN (no_access_list_extended_host_host,
"A single destination host\n"
"Destination address\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
- "0.0.0.0", argv[3],
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 6;
+ int idx_ipv4_2 = 8;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
+ "0.0.0.0", argv[idx_ipv4_2]->arg,
"0.0.0.0", 1, 0);
}
DEFUN (no_access_list_extended_any_host,
no_access_list_extended_any_host_cmd,
- "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
+ "no access-list <(100-199)|(2000-2699)> <deny|permit> ip any host A.B.C.D",
NO_STR
"Add an access list entry\n"
"IP extended access list\n"
@@ -1136,14 +1218,17 @@ DEFUN (no_access_list_extended_any_host,
"A single destination host\n"
"Destination address\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
- "255.255.255.255", argv[2],
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 7;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, "0.0.0.0",
+ "255.255.255.255", argv[idx_ipv4]->arg,
"0.0.0.0", 1, 0);
}
DEFUN (no_access_list_extended_host_any,
no_access_list_extended_host_any_cmd,
- "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
+ "no access-list <(100-199)|(2000-2699)> <deny|permit> ip host A.B.C.D any",
NO_STR
"Add an access list entry\n"
"IP extended access list\n"
@@ -1155,7 +1240,10 @@ DEFUN (no_access_list_extended_host_any,
"Source address\n"
"Any destination host\n")
{
- return filter_set_cisco (vty, argv[0], argv[1], argv[2],
+ int idx_acl = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4 = 6;
+ return filter_set_cisco (vty, argv[idx_acl]->arg, argv[idx_permit_deny]->arg, argv[idx_ipv4]->arg,
"0.0.0.0", "0.0.0.0",
"255.255.255.255", 1, 0);
}
@@ -1171,6 +1259,14 @@ filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
struct access_list *access;
struct prefix p;
+ if (strlen(name_str) > ACL_NAMSIZ)
+ {
+ vty_out (vty, "%% ACL name %s is invalid: length exceeds "
+ "%d characters%s",
+ name_str, ACL_NAMSIZ, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
/* Check of filter type. */
if (strncmp (type_str, "p", 1) == 0)
type = FILTER_PERMIT;
@@ -1193,7 +1289,6 @@ filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
return CMD_WARNING;
}
}
-#ifdef HAVE_IPV6
else if (afi == AFI_IP6)
{
ret = str2prefix_ipv6 (prefix_str, (struct prefix_ipv6 *) &p);
@@ -1204,7 +1299,6 @@ filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
return CMD_WARNING;
}
}
-#endif /* HAVE_IPV6 */
else
return CMD_WARNING;
@@ -1241,22 +1335,9 @@ filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
return CMD_SUCCESS;
}
-/* Zebra access-list */
-DEFUN (access_list,
- access_list_cmd,
- "access-list WORD (deny|permit) A.B.C.D/M",
- "Add an access list entry\n"
- "IP zebra access-list name\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Prefix to match. e.g. 10.0.0.0/8\n")
-{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 1);
-}
-
DEFUN (access_list_exact,
access_list_exact_cmd,
- "access-list WORD (deny|permit) A.B.C.D/M exact-match",
+ "access-list WORD <deny|permit> A.B.C.D/M [exact-match]",
"Add an access list entry\n"
"IP zebra access-list name\n"
"Specify packets to reject\n"
@@ -1264,37 +1345,37 @@ DEFUN (access_list_exact,
"Prefix to match. e.g. 10.0.0.0/8\n"
"Exact match of the prefixes\n")
{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 1);
+ int idx;
+ int exact = 0;
+ int idx_word = 1;
+ int idx_permit_deny = 2;
+ int idx_ipv4_prefixlen = 3;
+ idx = idx_ipv4_prefixlen;
+
+ if (argv_find (argv, argc, "exact-match", &idx))
+ exact = 1;
+
+ return filter_set_zebra (vty, argv[idx_word]->arg, argv[idx_permit_deny]->arg,
+ AFI_IP, argv[idx_ipv4_prefixlen]->arg, exact, 1);
}
DEFUN (access_list_any,
access_list_any_cmd,
- "access-list WORD (deny|permit) any",
- "Add an access list entry\n"
- "IP zebra access-list name\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Prefix to match. e.g. 10.0.0.0/8\n")
-{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 1);
-}
-
-DEFUN (no_access_list,
- no_access_list_cmd,
- "no access-list WORD (deny|permit) A.B.C.D/M",
- NO_STR
+ "access-list WORD <deny|permit> any",
"Add an access list entry\n"
"IP zebra access-list name\n"
"Specify packets to reject\n"
"Specify packets to forward\n"
"Prefix to match. e.g. 10.0.0.0/8\n")
{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 0);
+ int idx_word = 1;
+ int idx_permit_deny = 2;
+ return filter_set_zebra (vty, argv[idx_word]->arg, argv[idx_permit_deny]->arg, AFI_IP, "0.0.0.0/0", 0, 1);
}
DEFUN (no_access_list_exact,
no_access_list_exact_cmd,
- "no access-list WORD (deny|permit) A.B.C.D/M exact-match",
+ "no access-list WORD <deny|permit> A.B.C.D/M [exact-match]",
NO_STR
"Add an access list entry\n"
"IP zebra access-list name\n"
@@ -1303,12 +1384,22 @@ DEFUN (no_access_list_exact,
"Prefix to match. e.g. 10.0.0.0/8\n"
"Exact match of the prefixes\n")
{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 0);
+ int idx;
+ int exact = 0;
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4_prefixlen = 4;
+ idx = idx_ipv4_prefixlen;
+
+ if (argv_find (argv, argc, "exact-match", &idx))
+ exact = 1;
+
+ return filter_set_zebra (vty, argv[idx_word]->arg, argv[idx_permit_deny]->arg, AFI_IP, argv[idx_ipv4_prefixlen]->arg, exact, 0);
}
DEFUN (no_access_list_any,
no_access_list_any_cmd,
- "no access-list WORD (deny|permit) any",
+ "no access-list WORD <deny|permit> any",
NO_STR
"Add an access list entry\n"
"IP zebra access-list name\n"
@@ -1316,12 +1407,14 @@ DEFUN (no_access_list_any,
"Specify packets to forward\n"
"Prefix to match. e.g. 10.0.0.0/8\n")
{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 0);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ return filter_set_zebra (vty, argv[idx_word]->arg, argv[idx_permit_deny]->arg, AFI_IP, "0.0.0.0/0", 0, 0);
}
DEFUN (no_access_list_all,
no_access_list_all_cmd,
- "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
+ "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD>",
NO_STR
"Add an access list entry\n"
"IP standard access list\n"
@@ -1330,14 +1423,15 @@ DEFUN (no_access_list_all,
"IP extended access list (expanded range)\n"
"IP zebra access-list name\n")
{
+ int idx_acl = 2;
struct access_list *access;
struct access_master *master;
/* Looking up access_list. */
- access = access_list_lookup (AFI_IP, argv[0]);
+ access = access_list_lookup (AFI_IP, argv[idx_acl]->arg);
if (access == NULL)
{
- vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
+ vty_out (vty, "%% access-list %s doesn't exist%s", argv[idx_acl]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1357,7 +1451,7 @@ DEFUN (no_access_list_all,
DEFUN (access_list_remark,
access_list_remark_cmd,
- "access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
+ "access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD> remark LINE...",
"Add an access list entry\n"
"IP standard access list\n"
"IP extended access list\n"
@@ -1367,23 +1461,25 @@ DEFUN (access_list_remark,
"Access list entry comment\n"
"Comment up to 100 characters\n")
{
+ int idx_acl = 1;
+ int idx_remark = 3;
struct access_list *access;
- access = access_list_get (AFI_IP, argv[0]);
+ access = access_list_get (AFI_IP, argv[idx_acl]->arg);
if (access->remark)
{
XFREE (MTYPE_TMP, access->remark);
access->remark = NULL;
}
- access->remark = argv_concat(argv, argc, 1);
+ access->remark = argv_concat(argv, argc, idx_remark);
return CMD_SUCCESS;
}
DEFUN (no_access_list_remark,
no_access_list_remark_cmd,
- "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark",
+ "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD> remark",
NO_STR
"Add an access list entry\n"
"IP standard access list\n"
@@ -1393,12 +1489,14 @@ DEFUN (no_access_list_remark,
"IP zebra access-list\n"
"Access list entry comment\n")
{
- return vty_access_list_remark_unset (vty, AFI_IP, argv[0]);
+ int idx_acl = 2;
+ return vty_access_list_remark_unset (vty, AFI_IP, argv[idx_acl]->arg);
}
-
-ALIAS (no_access_list_remark,
- no_access_list_remark_arg_cmd,
- "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
+
+/* ALIAS_FIXME */
+DEFUN (no_access_list_remark_comment,
+ no_access_list_remark_comment_cmd,
+ "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD> remark LINE...",
NO_STR
"Add an access list entry\n"
"IP standard access list\n"
@@ -1408,38 +1506,38 @@ ALIAS (no_access_list_remark,
"IP zebra access-list\n"
"Access list entry comment\n"
"Comment up to 100 characters\n")
-
-#ifdef HAVE_IPV6
-DEFUN (ipv6_access_list,
- ipv6_access_list_cmd,
- "ipv6 access-list WORD (deny|permit) X:X::X:X/M",
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Prefix to match. e.g. 3ffe:506::/32\n")
{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
+ return no_access_list_remark (self, vty, argc, argv);
}
DEFUN (ipv6_access_list_exact,
ipv6_access_list_exact_cmd,
- "ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
+ "ipv6 access-list WORD <deny|permit> X:X::X:X/M [exact-match]",
IPV6_STR
"Add an access list entry\n"
"IPv6 zebra access-list\n"
"Specify packets to reject\n"
"Specify packets to forward\n"
- "Prefix to match. e.g. 3ffe:506::/32\n"
+ "IPv6 prefix\n"
"Exact match of the prefixes\n")
{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
+ int idx;
+ int exact = 0;
+ int idx_word = 2;
+ int idx_allow = 3;
+ int idx_addr = 4;
+ idx = idx_addr;
+
+ if (argv_find (argv, argc, "exact-match", &idx))
+ exact = 1;
+
+ return filter_set_zebra (vty, argv[idx_word]->arg, argv[idx_allow]->text,
+ AFI_IP6, argv[idx_addr]->arg, exact, 1);
}
DEFUN (ipv6_access_list_any,
ipv6_access_list_any_cmd,
- "ipv6 access-list WORD (deny|permit) any",
+ "ipv6 access-list WORD <deny|permit> any",
IPV6_STR
"Add an access list entry\n"
"IPv6 zebra access-list\n"
@@ -1447,26 +1545,14 @@ DEFUN (ipv6_access_list_any,
"Specify packets to forward\n"
"Any prefixi to match\n")
{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
-}
-
-DEFUN (no_ipv6_access_list,
- no_ipv6_access_list_cmd,
- "no ipv6 access-list WORD (deny|permit) X:X::X:X/M",
- NO_STR
- IPV6_STR
- "Add an access list entry\n"
- "IPv6 zebra access-list\n"
- "Specify packets to reject\n"
- "Specify packets to forward\n"
- "Prefix to match. e.g. 3ffe:506::/32\n")
-{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ return filter_set_zebra (vty, argv[idx_word]->arg, argv[idx_permit_deny]->arg, AFI_IP6, "::/0", 0, 1);
}
DEFUN (no_ipv6_access_list_exact,
no_ipv6_access_list_exact_cmd,
- "no ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
+ "no ipv6 access-list WORD <deny|permit> X:X::X:X/M [exact-match]",
NO_STR
IPV6_STR
"Add an access list entry\n"
@@ -1476,12 +1562,23 @@ DEFUN (no_ipv6_access_list_exact,
"Prefix to match. e.g. 3ffe:506::/32\n"
"Exact match of the prefixes\n")
{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
+ int idx;
+ int exact = 0;
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv6_prefixlen = 5;
+ idx = idx_ipv6_prefixlen;
+
+ if (argv_find (argv, argc, "exact-match", &idx))
+ exact = 1;
+
+ return filter_set_zebra (vty, argv[idx_word]->arg, argv[idx_permit_deny]->arg,
+ AFI_IP6, argv[idx_ipv6_prefixlen]->arg, exact, 0);
}
DEFUN (no_ipv6_access_list_any,
no_ipv6_access_list_any_cmd,
- "no ipv6 access-list WORD (deny|permit) any",
+ "no ipv6 access-list WORD <deny|permit> any",
NO_STR
IPV6_STR
"Add an access list entry\n"
@@ -1490,7 +1587,9 @@ DEFUN (no_ipv6_access_list_any,
"Specify packets to forward\n"
"Any prefixi to match\n")
{
- return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ return filter_set_zebra (vty, argv[idx_word]->arg, argv[idx_permit_deny]->arg, AFI_IP6, "::/0", 0, 0);
}
@@ -1502,14 +1601,15 @@ DEFUN (no_ipv6_access_list_all,
"Add an access list entry\n"
"IPv6 zebra access-list\n")
{
+ int idx_word = 3;
struct access_list *access;
struct access_master *master;
/* Looking up access_list. */
- access = access_list_lookup (AFI_IP6, argv[0]);
+ access = access_list_lookup (AFI_IP6, argv[idx_word]->arg);
if (access == NULL)
{
- vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
+ vty_out (vty, "%% access-list %s doesn't exist%s", argv[idx_word]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1529,23 +1629,25 @@ DEFUN (no_ipv6_access_list_all,
DEFUN (ipv6_access_list_remark,
ipv6_access_list_remark_cmd,
- "ipv6 access-list WORD remark .LINE",
+ "ipv6 access-list WORD remark LINE...",
IPV6_STR
"Add an access list entry\n"
"IPv6 zebra access-list\n"
"Access list entry comment\n"
"Comment up to 100 characters\n")
{
+ int idx_word = 2;
+ int idx_line = 4;
struct access_list *access;
- access = access_list_get (AFI_IP6, argv[0]);
+ access = access_list_get (AFI_IP6, argv[idx_word]->arg);
if (access->remark)
{
XFREE (MTYPE_TMP, access->remark);
access->remark = NULL;
}
- access->remark = argv_concat(argv, argc, 1);
+ access->remark = argv_concat(argv, argc, idx_line);
return CMD_SUCCESS;
}
@@ -1559,19 +1661,23 @@ DEFUN (no_ipv6_access_list_remark,
"IPv6 zebra access-list\n"
"Access list entry comment\n")
{
- return vty_access_list_remark_unset (vty, AFI_IP6, argv[0]);
+ int idx_word = 3;
+ return vty_access_list_remark_unset (vty, AFI_IP6, argv[idx_word]->arg);
}
-
-ALIAS (no_ipv6_access_list_remark,
- no_ipv6_access_list_remark_arg_cmd,
- "no ipv6 access-list WORD remark .LINE",
+
+/* ALIAS_FIXME */
+DEFUN (no_ipv6_access_list_remark_comment,
+ no_ipv6_access_list_remark_comment_cmd,
+ "no ipv6 access-list WORD remark LINE...",
NO_STR
IPV6_STR
"Add an access list entry\n"
"IPv6 zebra access-list\n"
"Access list entry comment\n"
"Comment up to 100 characters\n")
-#endif /* HAVE_IPV6 */
+{
+ return no_ipv6_access_list_remark (self, vty, argc, argv);
+}
void config_write_access_zebra (struct vty *, struct filter *);
void config_write_access_cisco (struct vty *, struct filter *);
@@ -1695,7 +1801,7 @@ DEFUN (show_ip_access_list,
DEFUN (show_ip_access_list_name,
show_ip_access_list_name_cmd,
- "show ip access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
+ "show ip access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD>",
SHOW_STR
IP_STR
"List IP access lists\n"
@@ -1705,10 +1811,10 @@ DEFUN (show_ip_access_list_name,
"IP extended access list (expanded range)\n"
"IP zebra access-list\n")
{
- return filter_show (vty, argv[0], AFI_IP);
+ int idx_acl = 3;
+ return filter_show (vty, argv[idx_acl]->arg, AFI_IP);
}
-#ifdef HAVE_IPV6
DEFUN (show_ipv6_access_list,
show_ipv6_access_list_cmd,
"show ipv6 access-list",
@@ -1727,9 +1833,9 @@ DEFUN (show_ipv6_access_list_name,
"List IPv6 access lists\n"
"IPv6 zebra access-list\n")
{
- return filter_show (vty, argv[0], AFI_IP6);
+ int idx_word = 3;
+ return filter_show (vty, argv[idx_word]->arg, AFI_IP6);
}
-#endif /* HAVE_IPV6 */
void
config_write_access_cisco (struct vty *vty, struct filter *mfilter)
@@ -1918,10 +2024,8 @@ access_list_init_ipv4 (void)
install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
/* Zebra access-list */
- install_element (CONFIG_NODE, &access_list_cmd);
install_element (CONFIG_NODE, &access_list_exact_cmd);
install_element (CONFIG_NODE, &access_list_any_cmd);
- install_element (CONFIG_NODE, &no_access_list_cmd);
install_element (CONFIG_NODE, &no_access_list_exact_cmd);
install_element (CONFIG_NODE, &no_access_list_any_cmd);
@@ -1958,10 +2062,9 @@ access_list_init_ipv4 (void)
install_element (CONFIG_NODE, &access_list_remark_cmd);
install_element (CONFIG_NODE, &no_access_list_all_cmd);
install_element (CONFIG_NODE, &no_access_list_remark_cmd);
- install_element (CONFIG_NODE, &no_access_list_remark_arg_cmd);
+ install_element (CONFIG_NODE, &no_access_list_remark_comment_cmd);
}
-#ifdef HAVE_IPV6
static struct cmd_node access_ipv6_node =
{
ACCESS_IPV6_NODE,
@@ -2012,34 +2115,27 @@ access_list_init_ipv6 (void)
install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
- install_element (CONFIG_NODE, &ipv6_access_list_cmd);
install_element (CONFIG_NODE, &ipv6_access_list_exact_cmd);
install_element (CONFIG_NODE, &ipv6_access_list_any_cmd);
install_element (CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
- install_element (CONFIG_NODE, &no_ipv6_access_list_cmd);
install_element (CONFIG_NODE, &no_ipv6_access_list_any_cmd);
install_element (CONFIG_NODE, &no_ipv6_access_list_all_cmd);
install_element (CONFIG_NODE, &ipv6_access_list_remark_cmd);
install_element (CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
- install_element (CONFIG_NODE, &no_ipv6_access_list_remark_arg_cmd);
+ install_element (CONFIG_NODE, &no_ipv6_access_list_remark_comment_cmd);
}
-#endif /* HAVE_IPV6 */
void
access_list_init ()
{
access_list_init_ipv4 ();
-#ifdef HAVE_IPV6
access_list_init_ipv6();
-#endif /* HAVE_IPV6 */
}
void
access_list_reset ()
{
access_list_reset_ipv4 ();
-#ifdef HAVE_IPV6
access_list_reset_ipv6();
-#endif /* HAVE_IPV6 */
}
diff --git a/lib/filter.h b/lib/filter.h
index e6ccd33b3a..6b5ccb52ec 100644
--- a/lib/filter.h
+++ b/lib/filter.h
@@ -25,6 +25,9 @@
#include "if.h"
+/* Maximum ACL name length */
+#define ACL_NAMSIZ 128
+
/* Filter direction. */
#define FILTER_IN 0
#define FILTER_OUT 1
diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c
new file mode 100644
index 0000000000..315bd4d59c
--- /dev/null
+++ b/lib/grammar_sandbox.c
@@ -0,0 +1,493 @@
+/*
+ * Testing shim and API examples for the new CLI backend.
+ *
+ * This unit defines a number of commands in the old engine that can
+ * be used to test and interact with the new engine.
+ * --
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "command.h"
+#include "memory_vty.h"
+#include "graph.h"
+#include "command_match.h"
+
+#define GRAMMAR_STR "CLI grammar sandbox\n"
+
+DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc")
+
+#define MAXDEPTH 64
+
+/** headers **/
+void
+grammar_sandbox_init (void);
+void
+pretty_print_graph (struct vty *vty, struct graph_node *, int, int, struct graph_node **, size_t);
+static void
+pretty_print_dot (FILE *ofd, unsigned opts, struct graph_node *start,
+ struct graph_node **stack, size_t stackpos,
+ struct graph_node **visited, size_t *visitpos);
+void
+init_cmdgraph (struct vty *, struct graph **);
+
+/** shim interface commands **/
+struct graph *nodegraph = NULL, *nodegraph_free = NULL;
+
+DEFUN (grammar_test,
+ grammar_test_cmd,
+ "grammar parse LINE...",
+ GRAMMAR_STR
+ "parse a command\n"
+ "command to pass to new parser\n")
+{
+ int idx_command = 2;
+ // make a string from tokenized command line
+ char *command = argv_concat (argv, argc, idx_command);
+
+ // create cmd_element for parser
+ struct cmd_element *cmd = XCALLOC (MTYPE_CMD_TOKENS, sizeof (struct cmd_element));
+ cmd->string = command;
+ cmd->doc = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n";
+ cmd->func = NULL;
+
+ // parse the command and install it into the command graph
+ command_parse_format (nodegraph, cmd);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (grammar_test_complete,
+ grammar_test_complete_cmd,
+ "grammar complete COMMAND...",
+ GRAMMAR_STR
+ "attempt to complete input on DFA\n"
+ "command to complete\n")
+{
+ int idx_command = 2;
+ char *cmdstr = argv_concat (argv, argc, idx_command);
+ if (!cmdstr)
+ return CMD_SUCCESS;
+
+ vector command = cmd_make_strvec (cmdstr);
+
+ // generate completions of user input
+ struct list *completions;
+ enum matcher_rv result = command_complete (nodegraph, command, &completions);
+
+ // print completions or relevant error message
+ if (!MATCHER_ERROR(result))
+ {
+ vector comps = completions_to_vec (completions);
+ struct cmd_token *tkn;
+
+ // calculate length of longest tkn->text in completions
+ unsigned int width = 0, i = 0;
+ for (i = 0; i < vector_active (comps); i++) {
+ tkn = vector_slot (comps, i);
+ unsigned int len = strlen (tkn->text);
+ width = len > width ? len : width;
+ }
+
+ // print completions
+ for (i = 0; i < vector_active (comps); i++) {
+ tkn = vector_slot (comps, i);
+ vty_out (vty, " %-*s %s%s", width, tkn->text, tkn->desc, VTY_NEWLINE);
+ }
+
+ for (i = 0; i < vector_active (comps); i++)
+ del_cmd_token ((struct cmd_token *) vector_slot (comps, i));
+ vector_free (comps);
+ }
+ else
+ vty_out (vty, "%% No match%s", VTY_NEWLINE);
+
+ // free resources
+ list_delete (completions);
+ cmd_free_strvec (command);
+ free (cmdstr);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (grammar_test_match,
+ grammar_test_match_cmd,
+ "grammar match COMMAND...",
+ GRAMMAR_STR
+ "attempt to match input on DFA\n"
+ "command to match\n")
+{
+ int idx_command = 2;
+ if (argv[2]->arg[0] == '#')
+ return CMD_SUCCESS;
+
+ char *cmdstr = argv_concat(argv, argc, idx_command);
+ vector command = cmd_make_strvec (cmdstr);
+
+ struct list *argvv = NULL;
+ const struct cmd_element *element = NULL;
+ enum matcher_rv result = command_match (nodegraph, command, &argvv, &element);
+
+ // print completions or relevant error message
+ if (element)
+ {
+ vty_out (vty, "Matched: %s%s", element->string, VTY_NEWLINE);
+ struct listnode *ln;
+ struct cmd_token *token;
+ for (ALL_LIST_ELEMENTS_RO(argvv,ln,token))
+ vty_out (vty, "%s -- %s%s", token->text, token->arg, VTY_NEWLINE);
+
+ vty_out (vty, "func: %p%s", element->func, VTY_NEWLINE);
+
+ list_delete (argvv);
+ }
+ else {
+ assert(MATCHER_ERROR(result));
+ switch (result) {
+ case MATCHER_NO_MATCH:
+ vty_out (vty, "%% Unknown command%s", VTY_NEWLINE);
+ break;
+ case MATCHER_INCOMPLETE:
+ vty_out (vty, "%% Incomplete command%s", VTY_NEWLINE);
+ break;
+ case MATCHER_AMBIGUOUS:
+ vty_out (vty, "%% Ambiguous command%s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out (vty, "%% Unknown error%s", VTY_NEWLINE);
+ break;
+ }
+ }
+
+ // free resources
+ cmd_free_strvec (command);
+ free (cmdstr);
+
+ return CMD_SUCCESS;
+}
+
+/**
+ * Testing shim to test docstrings
+ */
+DEFUN (grammar_test_doc,
+ grammar_test_doc_cmd,
+ "grammar test docstring",
+ GRAMMAR_STR
+ "Test function for docstring\n"
+ "Command end\n")
+{
+ // create cmd_element with docstring
+ struct cmd_element *cmd = XCALLOC (MTYPE_CMD_TOKENS, sizeof (struct cmd_element));
+ cmd->string = XSTRDUP (MTYPE_CMD_TOKENS, "test docstring <example|selector follow> (1-255) end VARIABLE [OPTION|set lol] . VARARG");
+ cmd->doc = XSTRDUP (MTYPE_CMD_TOKENS,
+ "Test stuff\n"
+ "docstring thing\n"
+ "first example\n"
+ "second example\n"
+ "follow\n"
+ "random range\n"
+ "end thingy\n"
+ "variable\n"
+ "optional variable\n"
+ "optional set\n"
+ "optional lol\n"
+ "vararg!\n");
+ cmd->func = NULL;
+
+ // parse element
+ command_parse_format (nodegraph, cmd);
+
+ return CMD_SUCCESS;
+}
+
+/**
+ * Debugging command to print command graph
+ */
+DEFUN (grammar_test_show,
+ grammar_test_show_cmd,
+ "grammar show [doc]",
+ GRAMMAR_STR
+ "print current accumulated DFA\n"
+ "include docstrings\n")
+{
+ struct graph_node *stack[MAXDEPTH];
+
+ if (!nodegraph)
+ vty_out(vty, "nodegraph uninitialized\r\n");
+ else
+ pretty_print_graph (vty, vector_slot (nodegraph->nodes, 0), 0, argc >= 3, stack, 0);
+ return CMD_SUCCESS;
+}
+
+DEFUN (grammar_test_dot,
+ grammar_test_dot_cmd,
+ "grammar dotfile OUTNAME",
+ GRAMMAR_STR
+ "print current graph for dot\n"
+ ".dot filename\n")
+{
+ struct graph_node *stack[MAXDEPTH];
+ struct graph_node *visited[MAXDEPTH*MAXDEPTH];
+ size_t vpos = 0;
+
+ if (!nodegraph) {
+ vty_out(vty, "nodegraph uninitialized\r\n");
+ return CMD_SUCCESS;
+ }
+ FILE *ofd = fopen(argv[2]->arg, "w");
+ if (!ofd) {
+ vty_out(vty, "%s: %s\r\n", argv[2]->arg, strerror(errno));
+ return CMD_SUCCESS;
+ }
+
+ fprintf(ofd, "digraph {\n graph [ rankdir = LR ];\n node [ fontname = \"Fira Mono\", fontsize = 9 ];\n\n");
+ pretty_print_dot (ofd, 0,
+ vector_slot (nodegraph->nodes, 0),
+ stack, 0, visited, &vpos);
+ fprintf(ofd, "}\n");
+ fclose(ofd);
+ return CMD_SUCCESS;
+}
+
+DEFUN (grammar_init_graph,
+ grammar_init_graph_cmd,
+ "grammar init",
+ GRAMMAR_STR
+ "(re)initialize graph\n")
+{
+ if (nodegraph_free)
+ graph_delete_graph (nodegraph_free);
+ nodegraph_free = NULL;
+
+ init_cmdgraph (vty, &nodegraph);
+ return CMD_SUCCESS;
+}
+
+extern vector cmdvec;
+
+DEFUN (grammar_access,
+ grammar_access_cmd,
+ "grammar access (0-65535)",
+ GRAMMAR_STR
+ "access node graph\n"
+ "node number\n")
+{
+ if (nodegraph_free)
+ graph_delete_graph (nodegraph_free);
+ nodegraph_free = NULL;
+
+ struct cmd_node *cnode;
+
+ cnode = vector_slot (cmdvec, atoi (argv[2]->arg));
+ if (!cnode)
+ {
+ vty_out (vty, "%% no such node%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty_out (vty, "node %d%s", (int)cnode->node, VTY_NEWLINE);
+ nodegraph = cnode->cmdgraph;
+ return CMD_SUCCESS;
+}
+
+/* this is called in vtysh.c to set up the testing shim */
+void grammar_sandbox_init(void) {
+ init_cmdgraph (NULL, &nodegraph);
+
+ // install all enable elements
+ install_element (ENABLE_NODE, &grammar_test_cmd);
+ install_element (ENABLE_NODE, &grammar_test_show_cmd);
+ install_element (ENABLE_NODE, &grammar_test_dot_cmd);
+ install_element (ENABLE_NODE, &grammar_test_match_cmd);
+ install_element (ENABLE_NODE, &grammar_test_complete_cmd);
+ install_element (ENABLE_NODE, &grammar_test_doc_cmd);
+ install_element (ENABLE_NODE, &grammar_init_graph_cmd);
+ install_element (ENABLE_NODE, &grammar_access_cmd);
+}
+
+#define item(x) { x, #x }
+struct message tokennames[] = {
+ item(WORD_TKN), // words
+ item(VARIABLE_TKN), // almost anything
+ item(RANGE_TKN), // integer range
+ item(IPV4_TKN), // IPV4 addresses
+ item(IPV4_PREFIX_TKN), // IPV4 network prefixes
+ item(IPV6_TKN), // IPV6 prefixes
+ item(IPV6_PREFIX_TKN), // IPV6 network prefixes
+
+ /* plumbing types */
+ item(FORK_TKN),
+ item(JOIN_TKN),
+ item(START_TKN), // first token in line
+ item(END_TKN), // last token in line
+ { 0, NULL }
+};
+size_t tokennames_max = array_size(tokennames);
+
+/**
+ * Pretty-prints a graph, assuming it is a tree.
+ *
+ * @param start the node to take as the root
+ * @param level indent level for recursive calls, always pass 0
+ */
+void
+pretty_print_graph (struct vty *vty, struct graph_node *start, int level,
+ int desc, struct graph_node **stack, size_t stackpos)
+{
+ // print this node
+ char tokennum[32];
+ struct cmd_token *tok = start->data;
+
+ snprintf(tokennum, sizeof(tokennum), "%d?", tok->type);
+ vty_out(vty, "%s", LOOKUP_DEF(tokennames, tok->type, tokennum));
+ if (tok->text)
+ vty_out(vty, ":\"%s\"", tok->text);
+ if (desc)
+ vty_out(vty, " ?'%s'", tok->desc);
+ vty_out(vty, " ");
+
+ if (stackpos == MAXDEPTH)
+ {
+ vty_out(vty, " -aborting! (depth limit)%s", VTY_NEWLINE);
+ return;
+ }
+ stack[stackpos++] = start;
+
+ int numto = desc ? 2 : vector_active (start->to);
+ if (numto)
+ {
+ if (numto > 1)
+ vty_out(vty, "%s", VTY_NEWLINE);
+ for (unsigned int i = 0; i < vector_active (start->to); i++)
+ {
+ struct graph_node *adj = vector_slot (start->to, i);
+ // if we're listing multiple children, indent!
+ if (numto > 1)
+ for (int j = 0; j < level+1; j++)
+ vty_out(vty, " ");
+ // if this node is a vararg, just print *
+ if (adj == start)
+ vty_out(vty, "*");
+ else if (((struct cmd_token *)adj->data)->type == END_TKN)
+ vty_out(vty, "--END%s", VTY_NEWLINE);
+ else {
+ size_t k;
+ for (k = 0; k < stackpos; k++)
+ if (stack[k] == adj) {
+ vty_out(vty, "<<loop@%zu %s", k, VTY_NEWLINE);
+ break;
+ }
+ if (k == stackpos)
+ pretty_print_graph (vty, adj, numto > 1 ? level+1 : level, desc, stack, stackpos);
+ }
+ }
+ }
+ else
+ vty_out(vty, "%s", VTY_NEWLINE);
+}
+
+static void
+pretty_print_dot (FILE *ofd, unsigned opts, struct graph_node *start,
+ struct graph_node **stack, size_t stackpos,
+ struct graph_node **visited, size_t *visitpos)
+{
+ // print this node
+ char tokennum[32];
+ struct cmd_token *tok = start->data;
+ const char *color;
+
+ for (size_t i = 0; i < (*visitpos); i++)
+ if (visited[i] == start)
+ return;
+ visited[(*visitpos)++] = start;
+ if ((*visitpos) == MAXDEPTH*MAXDEPTH)
+ return;
+
+ snprintf(tokennum, sizeof(tokennum), "%d?", tok->type);
+ fprintf(ofd, " n%016llx [ shape=box, label=<", (unsigned long long)start);
+
+ fprintf(ofd, "<b>%s</b>", LOOKUP_DEF(tokennames, tok->type, tokennum));
+ if (tok->attr == CMD_ATTR_DEPRECATED)
+ fprintf(ofd, " (d)");
+ else if (tok->attr == CMD_ATTR_HIDDEN)
+ fprintf(ofd, " (h)");
+ if (tok->text) {
+ if (tok->type == WORD_TKN)
+ fprintf(ofd, "<br/>\"<font color=\"#0055ff\" point-size=\"11\"><b>%s</b></font>\"", tok->text);
+ else
+ fprintf(ofd, "<br/>%s", tok->text);
+ }
+/* if (desc)
+ fprintf(ofd, " ?'%s'", tok->desc); */
+ switch (tok->type) {
+ case START_TKN: color = "#ccffcc"; break;
+ case FORK_TKN: color = "#aaddff"; break;
+ case JOIN_TKN: color = "#ddaaff"; break;
+ case WORD_TKN: color = "#ffffff"; break;
+ default: color = "#ffffff"; break;
+ }
+ fprintf(ofd, ">, style = filled, fillcolor = \"%s\" ];\n", color);
+
+ if (stackpos == MAXDEPTH)
+ return;
+ stack[stackpos++] = start;
+
+ for (unsigned int i = 0; i < vector_active (start->to); i++)
+ {
+ struct graph_node *adj = vector_slot (start->to, i);
+ // if this node is a vararg, just print *
+ if (adj == start) {
+ fprintf(ofd, " n%016llx -> n%016llx;\n",
+ (unsigned long long)start,
+ (unsigned long long)start);
+ } else if (((struct cmd_token *)adj->data)->type == END_TKN) {
+ //struct cmd_token *et = adj->data;
+ fprintf(ofd, " n%016llx -> end%016llx;\n",
+ (unsigned long long)start,
+ (unsigned long long)adj);
+ fprintf(ofd, " end%016llx [ shape=box, label=<end>, style = filled, fillcolor = \"#ffddaa\" ];\n",
+ (unsigned long long)adj);
+ } else {
+ fprintf(ofd, " n%016llx -> n%016llx;\n",
+ (unsigned long long)start,
+ (unsigned long long)adj);
+ size_t k;
+ for (k = 0; k < stackpos; k++)
+ if (stack[k] == adj)
+ break;
+ if (k == stackpos) {
+ pretty_print_dot (ofd, opts, adj, stack, stackpos, visited, visitpos);
+ }
+ }
+ }
+}
+
+
+/** stuff that should go in command.c + command.h */
+void
+init_cmdgraph (struct vty *vty, struct graph **graph)
+{
+ // initialize graph, add start noe
+ *graph = graph_new ();
+ nodegraph_free = *graph;
+ struct cmd_token *token = new_cmd_token (START_TKN, 0, NULL, NULL);
+ graph_new_node (*graph, token, (void (*)(void *)) &del_cmd_token);
+ if (vty)
+ vty_out (vty, "initialized graph%s", VTY_NEWLINE);
+}
diff --git a/lib/grammar_sandbox_main.c b/lib/grammar_sandbox_main.c
new file mode 100644
index 0000000000..5deef406c1
--- /dev/null
+++ b/lib/grammar_sandbox_main.c
@@ -0,0 +1,64 @@
+/*
+ * Testing shim and API examples for the new CLI backend.
+ *
+ * Minimal main() to run grammar_sandbox standalone.
+ * [split off grammar_sandbox.c 2017-01-23]
+ * --
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Copyright (C) 2017 David Lamparter for NetDEF, Inc.
+ *
+ * This file is part of FreeRangeRouting (FRR).
+ *
+ * FRR is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2, or (at your option) any later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FRR; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "command.h"
+#include "memory_vty.h"
+
+static void vty_do_exit(void)
+{
+ printf ("\nend.\n");
+ exit (0);
+}
+
+struct thread_master *master;
+
+int main(int argc, char **argv)
+{
+ struct thread thread;
+
+ master = thread_master_create ();
+
+ zlog_default = openzlog ("grammar_sandbox", ZLOG_NONE, 0,
+ LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
+ zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
+ zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);
+ zlog_set_level (NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
+
+ /* Library inits. */
+ cmd_init (1);
+ host.name = strdup ("test");
+
+ vty_init (master);
+ memory_init ();
+
+ vty_stdio (vty_do_exit);
+
+ /* Fetch next active thread. */
+ while (thread_fetch (master, &thread))
+ thread_call (&thread);
+
+ /* Not reached. */
+ exit (0);
+}
diff --git a/lib/graph.c b/lib/graph.c
new file mode 100644
index 0000000000..0992059ef1
--- /dev/null
+++ b/lib/graph.c
@@ -0,0 +1,148 @@
+/*
+ * Graph data structure.
+ *
+ * --
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include <zebra.h>
+#include "graph.h"
+#include "memory.h"
+
+DEFINE_MTYPE_STATIC(LIB, GRAPH, "Graph")
+DEFINE_MTYPE_STATIC(LIB, GRAPH_NODE, "Graph Node")
+struct graph *
+graph_new ()
+{
+ struct graph *graph = XCALLOC (MTYPE_GRAPH, sizeof(struct graph));
+ graph->nodes = vector_init (VECTOR_MIN_SIZE);
+
+ return graph;
+}
+
+struct graph_node *
+graph_new_node (struct graph *graph, void *data, void (*del) (void*))
+{
+ struct graph_node *node =
+ XCALLOC(MTYPE_GRAPH_NODE, sizeof(struct graph_node));
+
+ node->from = vector_init (VECTOR_MIN_SIZE);
+ node->to = vector_init (VECTOR_MIN_SIZE);
+ node->data = data;
+ node->del = del;
+
+ vector_set (graph->nodes, node);
+
+ return node;
+}
+
+static void
+vector_remove (vector v, unsigned int ix)
+{
+ if (ix >= v->active)
+ return;
+
+ /* v->active is guaranteed >= 1 because ix can't be lower than 0
+ * and v->active is > ix. */
+ v->active--;
+ /* if ix == v->active--, we set the item to itself, then to NULL...
+ * still correct, no check neccessary. */
+ v->index[ix] = v->index[v->active];
+ v->index[v->active] = NULL;
+}
+
+void
+graph_delete_node (struct graph *graph, struct graph_node *node)
+{
+ if (!node) return;
+
+ // an adjacent node
+ struct graph_node *adj;
+
+ // remove all edges from other nodes to us
+ for (unsigned int i = vector_active (node->from); i--; /**/)
+ {
+ adj = vector_slot (node->from, i);
+ graph_remove_edge (adj, node);
+ }
+
+ // remove all edges from us to other nodes
+ for (unsigned int i = vector_active (node->to); i--; /**/)
+ {
+ adj = vector_slot (node->to, i);
+ graph_remove_edge (node, adj);
+ }
+
+ // if there is a deletion callback, call it
+ if (node->del && node->data)
+ (*node->del) (node->data);
+
+ // free adjacency lists
+ vector_free (node->to);
+ vector_free (node->from);
+
+ // remove node from graph->nodes
+ for (unsigned int i = vector_active (graph->nodes); i--; /**/)
+ if (vector_slot (graph->nodes, i) == node)
+ {
+ vector_remove (graph->nodes, i);
+ break;
+ }
+
+ // free the node itself
+ XFREE (MTYPE_GRAPH_NODE, node);
+}
+
+struct graph_node *
+graph_add_edge (struct graph_node *from, struct graph_node *to)
+{
+ vector_set (from->to, to);
+ vector_set (to->from, from);
+ return to;
+}
+
+void
+graph_remove_edge (struct graph_node *from, struct graph_node *to)
+{
+ // remove from from to->from
+ for (unsigned int i = vector_active (to->from); i--; /**/)
+ if (vector_slot (to->from, i) == from)
+ {
+ vector_remove (to->from, i);
+ break;
+ }
+ // remove to from from->to
+ for (unsigned int i = vector_active (from->to); i--; /**/)
+ if (vector_slot (from->to, i) == to)
+ {
+ vector_remove (from->to, i);
+ break;
+ }
+}
+
+void
+graph_delete_graph (struct graph *graph)
+{
+ // delete each node in the graph
+ for (unsigned int i = vector_active (graph->nodes); i--; /**/)
+ graph_delete_node (graph, vector_slot (graph->nodes, i));
+
+ vector_free (graph->nodes);
+ XFREE (MTYPE_GRAPH, graph);
+}
diff --git a/lib/graph.h b/lib/graph.h
new file mode 100644
index 0000000000..8d8aa3823b
--- /dev/null
+++ b/lib/graph.h
@@ -0,0 +1,101 @@
+/*
+ * Graph data structure.
+ *
+ * --
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _ZEBRA_COMMAND_GRAPH_H
+#define _ZEBRA_COMMAND_GRAPH_H
+
+#include "vector.h"
+
+struct graph
+{
+ vector nodes;
+};
+
+struct graph_node
+{
+ vector from; // nodes which have edges to this node
+ vector to; // nodes which this node has edges to
+
+ void *data; // node data
+ void (*del) (void *data); // deletion callback
+};
+
+struct graph *
+graph_new (void);
+
+/**
+ * Creates a new node.
+ *
+ * @struct graph the graph this node exists in
+ * @param[in] data this node's data
+ * @param[in] del data deletion callback
+ * @return the new node
+ */
+struct graph_node *
+graph_new_node (struct graph *graph, void *data, void (*del) (void*));
+
+/**
+ * Deletes a node.
+ *
+ * Before deletion, this function removes all edges to and from this node from
+ * any neighbor nodes.
+ *
+ * If *data and *del are non-null, the following call is made:
+ * (*node->del) (node->data);
+ *
+ * @param[in] graph the graph this node belongs to
+ * @param[out] node pointer to node to delete
+ */
+void
+graph_delete_node (struct graph *graph, struct graph_node *node);
+
+/**
+ * Makes a directed edge between two nodes.
+ *
+ * @param[in] from
+ * @param[in] to
+ * @return to
+ */
+struct graph_node *
+graph_add_edge (struct graph_node *from, struct graph_node *to);
+
+/**
+ * Removes a directed edge between two nodes.
+ *
+ * @param[in] from
+ * @param[in] to
+ */
+void
+graph_remove_edge (struct graph_node *from, struct graph_node *to);
+
+/**
+ * Deletes a graph.
+ * Calls graph_delete_node on each node before freeing the graph struct itself.
+ *
+ * @param graph the graph to delete
+ */
+void
+graph_delete_graph (struct graph *graph);
+
+#endif /* _ZEBRA_COMMAND_GRAPH_H */
diff --git a/lib/if.c b/lib/if.c
index 9161796160..6ee84e126c 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -374,7 +374,7 @@ if_lookup_exact_address_vrf (void *src, int family, vrf_id_t vrf_id)
}
else if (family == AF_INET6)
{
- if (IPV6_ADDR_SAME (&p->u.prefix4, (struct in6_addr *)src))
+ if (IPV6_ADDR_SAME (&p->u.prefix6, (struct in6_addr *)src))
return ifp;
}
}
@@ -671,25 +671,23 @@ if_dump_all (void)
if_dump (p);
}
-DEFUN (interface_desc,
+DEFUN (interface_desc,
interface_desc_cmd,
- "description .LINE",
+ "description LINE...",
"Interface specific description\n"
"Characters describing this interface\n")
{
+ int idx_line = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
- if (argc == 0)
- return CMD_SUCCESS;
-
if (ifp->desc)
XFREE (MTYPE_TMP, ifp->desc);
- ifp->desc = argv_concat(argv, argc, 0);
+ ifp->desc = argv_concat(argv, argc, idx_line);
return CMD_SUCCESS;
}
-DEFUN (no_interface_desc,
+DEFUN (no_interface_desc,
no_interface_desc_cmd,
"no description",
NO_STR
@@ -748,69 +746,72 @@ if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
DEFUN (interface,
interface_cmd,
- "interface IFNAME",
+ "interface IFNAME [vrf NAME]",
"Select an interface to configure\n"
- "Interface's name\n")
+ "Interface's name\n"
+ VRF_CMD_HELP_STR)
{
+ int idx_ifname = 1;
+ int idx_vrf = 3;
+ const char *ifname = argv[idx_ifname]->arg;
+ const char *vrfname = (argc > 2) ? argv[idx_vrf]->arg : NULL;
+
struct interface *ifp;
size_t sl;
vrf_id_t vrf_id = VRF_DEFAULT;
- if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
+ if ((sl = strlen(ifname)) > INTERFACE_NAMSIZ)
{
vty_out (vty, "%% Interface name %s is invalid: length exceeds "
"%d characters%s",
- argv[0], INTERFACE_NAMSIZ, VTY_NEWLINE);
+ ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
return CMD_WARNING;
}
/*Pending: need proper vrf name based lookup/(possible creation of VRF)
Imagine forward reference of a vrf by name in this interface config */
- if (argc > 1)
- VRF_GET_ID (vrf_id, argv[1]);
+ if (vrfname)
+ VRF_GET_ID (vrf_id, vrfname);
#ifdef SUNOS_5
- ifp = if_sunwzebra_get (argv[0], sl, vrf_id);
+ ifp = if_sunwzebra_get (ifname, sl, vrf_id);
#else
- ifp = if_get_by_name_len_vrf (argv[0], sl, vrf_id, 1);
+ ifp = if_get_by_name_len_vrf (ifname, sl, vrf_id, 1);
#endif /* SUNOS_5 */
if (!ifp)
{
- vty_out (vty, "%% interface %s not in %s%s", argv[0], argv[1], VTY_NEWLINE);
+ vty_out (vty, "%% interface %s not in %s%s", ifname, vrfname, VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_PUSH_CONTEXT_COMPAT (INTERFACE_NODE, ifp);
+ VTY_PUSH_CONTEXT (INTERFACE_NODE, ifp);
return CMD_SUCCESS;
}
-ALIAS (interface,
- interface_vrf_cmd,
- "interface IFNAME " VRF_CMD_STR,
- "Select an interface to configure\n"
- "Interface's name\n"
- VRF_CMD_HELP_STR)
-
DEFUN_NOSH (no_interface,
no_interface_cmd,
- "no interface IFNAME",
+ "no interface IFNAME [vrf NAME]",
NO_STR
"Delete a pseudo interface's configuration\n"
- "Interface's name\n")
+ "Interface's name\n"
+ VRF_CMD_HELP_STR)
{
+ const char *ifname = argv[2]->arg;
+ const char *vrfname = (argc > 3) ? argv[3]->arg : NULL;
+
// deleting interface
struct interface *ifp;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1)
- VRF_GET_ID (vrf_id, argv[1]);
+ if (argc > 3)
+ VRF_GET_ID (vrf_id, vrfname);
- ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
+ ifp = if_lookup_by_name_vrf (ifname, vrf_id);
if (ifp == NULL)
{
- vty_out (vty, "%% Interface %s does not exist%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -826,21 +827,27 @@ DEFUN_NOSH (no_interface,
return CMD_SUCCESS;
}
-ALIAS (no_interface,
- no_interface_vrf_cmd,
- "no interface IFNAME " VRF_CMD_STR,
- NO_STR
- "Delete a pseudo interface's configuration\n"
- "Interface's name\n"
- VRF_CMD_HELP_STR)
+void
+if_cmd_init (void)
+{
+ install_element (CONFIG_NODE, &interface_cmd);
+ install_element (CONFIG_NODE, &no_interface_cmd);
+
+ install_default (INTERFACE_NODE);
+ install_element (INTERFACE_NODE, &interface_desc_cmd);
+ install_element (INTERFACE_NODE, &no_interface_desc_cmd);
+}
+#if 0
/* For debug purpose. */
DEFUN (show_address,
show_address_cmd,
- "show address",
+ "show address [vrf NAME]",
SHOW_STR
- "address\n")
+ "address\n"
+ VRF_CMD_HELP_STR)
{
+ int idx_vrf = 3;
struct listnode *node;
struct listnode *node2;
struct interface *ifp;
@@ -848,8 +855,8 @@ DEFUN (show_address,
struct prefix *p;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 0)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (argc > 2)
+ VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
{
@@ -865,16 +872,9 @@ DEFUN (show_address,
return CMD_SUCCESS;
}
-ALIAS (show_address,
- show_address_vrf_cmd,
- "show address " VRF_CMD_STR,
- SHOW_STR
- "address\n"
- VRF_CMD_HELP_STR)
-
DEFUN (show_address_vrf_all,
show_address_vrf_all_cmd,
- "show address " VRF_ALL_CMD_STR,
+ "show address vrf all",
SHOW_STR
"address\n"
VRF_ALL_CMD_HELP_STR)
@@ -908,6 +908,7 @@ DEFUN (show_address_vrf_all,
}
return CMD_SUCCESS;
}
+#endif
/* Allocate connected structure. */
struct connected *
@@ -1018,11 +1019,9 @@ connected_same_prefix (struct prefix *p1, struct prefix *p2)
if (p1->family == AF_INET &&
IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4))
return 1;
-#ifdef HAVE_IPV6
if (p1->family == AF_INET6 &&
IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6))
return 1;
-#endif /* HAVE_IPV6 */
}
return 0;
}
@@ -1301,7 +1300,7 @@ if_link_params_get (struct interface *ifp)
sizeof (struct if_link_params));
if (iflp == NULL) return NULL;
- /* Set TE metric == standard metric */
+ /* Set TE metric equal to standard metric */
iflp->te_metric = ifp->metric;
/* Compute default bandwidth based on interface */
@@ -1315,7 +1314,7 @@ if_link_params_get (struct interface *ifp)
iflp->unrsv_bw[i] = iflp->default_bw;
/* Update Link parameters status */
- iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
+ iflp->lp_status = LP_TE_METRIC | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
/* Finally attach newly created Link Parameters */
ifp->link_params = iflp;
diff --git a/lib/if.h b/lib/if.h
index c53b9ff0e7..32e5d92a97 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -146,9 +146,13 @@ struct if_stats
#define MAX_CLASS_TYPE 8
#define MAX_PKT_LOSS 50.331642
-/* Link Parameters Status: 0: unset, 1: set, */
+/*
+ * Link Parameters Status:
+ * equal to 0: unset
+ * different from 0: set
+ */
#define LP_UNSET 0x0000
-#define LP_TE 0x0001
+#define LP_TE_METRIC 0x0001
#define LP_MAX_BW 0x0002
#define LP_MAX_RSV_BW 0x0004
#define LP_UNRSV_BW 0x0008
@@ -161,7 +165,6 @@ struct if_stats
#define LP_RES_BW 0x0400
#define LP_AVA_BW 0x0800
#define LP_USE_BW 0x1000
-#define LP_TE_METRIC 0x2000
#define IS_PARAM_UNSET(lp, st) !(lp->lp_status & st)
#define IS_PARAM_SET(lp, st) (lp->lp_status & st)
@@ -224,7 +227,7 @@ struct interface
uint64_t flags;
/* Interface metric */
- int metric;
+ uint32_t metric;
/* Interface MTU. */
unsigned int mtu; /* IPv4 MTU */
@@ -447,6 +450,7 @@ extern int if_is_pointopoint (struct interface *);
extern int if_is_multicast (struct interface *);
extern void if_add_hook (int, int (*)(struct interface *));
extern void if_init (struct list **);
+extern void if_cmd_init (void);
extern void if_terminate (struct list **);
extern void if_dump_all (void);
extern const char *if_flag_dump(unsigned long);
@@ -485,19 +489,4 @@ struct nbr_connected *nbr_connected_check (struct interface *, struct prefix *);
struct if_link_params *if_link_params_get (struct interface *);
void if_link_params_free (struct interface *);
-/* Exported variables. */
-extern struct cmd_element interface_desc_cmd;
-extern struct cmd_element no_interface_desc_cmd;
-extern struct cmd_element interface_cmd;
-extern struct cmd_element no_interface_cmd;
-extern struct cmd_element interface_vrf_cmd;
-extern struct cmd_element no_interface_vrf_cmd;
-extern struct cmd_element interface_pseudo_cmd;
-extern struct cmd_element no_interface_pseudo_cmd;
-extern struct cmd_element show_address_cmd;
-extern struct cmd_element show_address_vrf_cmd;
-extern struct cmd_element show_address_vrf_all_cmd;
-extern struct cmd_element vrf_cmd;
-extern struct cmd_element no_vrf_cmd;
-
#endif /* _ZEBRA_IF_H */
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index 736f2e237d..2afb08c7ca 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -211,18 +211,21 @@ if_rmap_unset (const char *ifname, enum if_rmap_type type,
DEFUN (if_rmap,
if_rmap_cmd,
- "route-map RMAP_NAME (in|out) IFNAME",
+ "route-map RMAP_NAME <in|out> IFNAME",
"Route map set\n"
"Route map name\n"
"Route map set for input filtering\n"
"Route map set for output filtering\n"
"Route map interface name\n")
{
+ int idx_rmap_name = 1;
+ int idx_in_out = 2;
+ int idx_ifname = 3;
enum if_rmap_type type;
- if (strncmp (argv[1], "i", 1) == 0)
+ if (strncmp (argv[idx_in_out]->text, "in", 1) == 0)
type = IF_RMAP_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
+ else if (strncmp (argv[idx_in_out]->text, "out", 1) == 0)
type = IF_RMAP_OUT;
else
{
@@ -230,23 +233,14 @@ DEFUN (if_rmap,
return CMD_WARNING;
}
- if_rmap_set (argv[2], type, argv[0]);
+ if_rmap_set (argv[idx_ifname]->arg, type, argv[idx_rmap_name]->arg);
return CMD_SUCCESS;
-}
-
-ALIAS (if_rmap,
- if_ipv6_rmap_cmd,
- "route-map RMAP_NAME (in|out) IFNAME",
- "Route map set\n"
- "Route map name\n"
- "Route map set for input filtering\n"
- "Route map set for output filtering\n"
- "Route map interface name\n")
+}
DEFUN (no_if_rmap,
no_if_rmap_cmd,
- "no route-map ROUTEMAP_NAME (in|out) IFNAME",
+ "no route-map ROUTEMAP_NAME <in|out> IFNAME",
NO_STR
"Route map unset\n"
"Route map name\n"
@@ -254,12 +248,15 @@ DEFUN (no_if_rmap,
"Route map for output filtering\n"
"Route map interface name\n")
{
+ int idx_routemap_name = 2;
+ int idx_in_out = 3;
+ int idx_ifname = 4;
int ret;
enum if_rmap_type type;
- if (strncmp (argv[1], "i", 1) == 0)
+ if (strncmp (argv[idx_in_out]->arg, "i", 1) == 0)
type = IF_RMAP_IN;
- else if (strncmp (argv[1], "o", 1) == 0)
+ else if (strncmp (argv[idx_in_out]->arg, "o", 1) == 0)
type = IF_RMAP_OUT;
else
{
@@ -267,24 +264,15 @@ DEFUN (no_if_rmap,
return CMD_WARNING;
}
- ret = if_rmap_unset (argv[2], type, argv[0]);
+ ret = if_rmap_unset (argv[idx_ifname]->arg, type, argv[idx_routemap_name]->arg);
if (! ret)
{
vty_out (vty, "route-map doesn't exist%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
-}
+}
-ALIAS (no_if_rmap,
- no_if_ipv6_rmap_cmd,
- "no route-map ROUTEMAP_NAME (in|out) IFNAME",
- NO_STR
- "Route map unset\n"
- "Route map name\n"
- "Route map for input filtering\n"
- "Route map for output filtering\n"
- "Route map interface name\n")
/* Configuration write function. */
int
@@ -333,8 +321,6 @@ if_rmap_init (int node)
{
ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp);
if (node == RIPNG_NODE) {
- install_element (RIPNG_NODE, &if_ipv6_rmap_cmd);
- install_element (RIPNG_NODE, &no_if_ipv6_rmap_cmd);
} else if (node == RIP_NODE) {
install_element (RIP_NODE, &if_rmap_cmd);
install_element (RIP_NODE, &no_if_rmap_cmd);
diff --git a/lib/imsg.c b/lib/imsg.c
index 246430cdd5..fc62c13734 100644
--- a/lib/imsg.c
+++ b/lib/imsg.c
@@ -182,7 +182,8 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
else
imsg->fd = -1;
- memcpy(imsg->data, ibuf->r.rptr, datalen);
+ if (imsg->data)
+ memcpy(imsg->data, ibuf->r.rptr, datalen);
if (imsg->hdr.len < av) {
left = av - imsg->hdr.len;
diff --git a/lib/json.c b/lib/json.c
index c49a4f9074..ccbecb726a 100644
--- a/lib/json.c
+++ b/lib/json.c
@@ -21,6 +21,7 @@
#include <zebra.h>
+#include "command.h"
#include "lib/json.h"
/*
@@ -29,12 +30,12 @@
* what.
*/
int
-use_json (const int argc, const char *argv[])
+use_json (const int argc, struct cmd_token *argv[])
{
if (argc == 0)
return 0;
- if (argv[argc-1] && strcmp(argv[argc-1], "json") == 0)
+ if (argv[argc-1]->arg && strcmp(argv[argc-1]->arg, "json") == 0)
return 1;
return 0;
@@ -86,3 +87,18 @@ json_object_free(struct json_object *obj)
{
json_object_put(obj);
}
+
+#if !defined(HAVE_JSON_C_JSON_H)
+int
+json_object_object_get_ex(struct json_object *obj,
+ const char *key,
+ struct json_object **value)
+{
+ *value = json_object_object_get(obj, key);
+
+ if (*value)
+ return 1;
+
+ return 0;
+}
+#endif
diff --git a/lib/json.h b/lib/json.h
index b217df0a7b..7e98614280 100644
--- a/lib/json.h
+++ b/lib/json.h
@@ -32,9 +32,15 @@
* so let's just turn it back to the original usage.
*/
#define json_object_to_json_string_ext(A, B) json_object_to_json_string (A)
+
+extern int json_object_object_get_ex(struct json_object *obj,
+ const char *key,
+ struct json_object **value);
#endif
-extern int use_json(const int argc, const char *argv[]);
+#include "command.h"
+
+extern int use_json(const int argc, struct cmd_token *argv[]);
extern void json_object_string_add(struct json_object* obj, const char *key,
const char *s);
extern void json_object_int_add(struct json_object* obj, const char *key,
diff --git a/lib/keychain.c b/lib/keychain.c
index c090956487..cd8039b95b 100644
--- a/lib/keychain.c
+++ b/lib/keychain.c
@@ -247,10 +247,11 @@ DEFUN (key_chain,
"Key-chain management\n"
"Key-chain name\n")
{
+ int idx_word = 2;
struct keychain *keychain;
- keychain = keychain_get (argv[0]);
- VTY_PUSH_CONTEXT_COMPAT (KEYCHAIN_NODE, keychain);
+ keychain = keychain_get (argv[idx_word]->arg);
+ VTY_PUSH_CONTEXT (KEYCHAIN_NODE, keychain);
return CMD_SUCCESS;
}
@@ -263,13 +264,14 @@ DEFUN (no_key_chain,
"Key-chain management\n"
"Key-chain name\n")
{
+ int idx_word = 3;
struct keychain *keychain;
- keychain = keychain_lookup (argv[0]);
+ keychain = keychain_lookup (argv[idx_word]->arg);
if (! keychain)
{
- vty_out (vty, "Can't find keychain %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "Can't find keychain %s%s", argv[idx_word]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -280,33 +282,35 @@ DEFUN (no_key_chain,
DEFUN (key,
key_cmd,
- "key <0-2147483647>",
+ "key (0-2147483647)",
"Configure a key\n"
"Key identifier number\n")
{
+ int idx_number = 1;
VTY_DECLVAR_CONTEXT (keychain, keychain);
struct key *key;
u_int32_t index;
- VTY_GET_INTEGER ("key identifier", index, argv[0]);
+ VTY_GET_INTEGER ("key identifier", index, argv[idx_number]->arg);
key = key_get (keychain, index);
VTY_PUSH_CONTEXT_SUB (KEYCHAIN_KEY_NODE, key);
-
+
return CMD_SUCCESS;
}
DEFUN (no_key,
no_key_cmd,
- "no key <0-2147483647>",
+ "no key (0-2147483647)",
NO_STR
"Delete a key\n"
"Key identifier number\n")
{
+ int idx_number = 2;
VTY_DECLVAR_CONTEXT (keychain, keychain);
struct key *key;
u_int32_t index;
-
- VTY_GET_INTEGER ("key identifier", index, argv[0]);
+
+ VTY_GET_INTEGER ("key identifier", index, argv[idx_number]->arg);
key = key_lookup (keychain, index);
if (! key)
{
@@ -327,11 +331,12 @@ DEFUN (key_string,
"Set key string\n"
"The key\n")
{
+ int idx_line = 1;
VTY_DECLVAR_CONTEXT_SUB (key, key);
if (key->string)
XFREE(MTYPE_KEY, key->string);
- key->string = XSTRDUP(MTYPE_KEY, argv[0]);
+ key->string = XSTRDUP(MTYPE_KEY, argv[idx_line]->arg);
return CMD_SUCCESS;
}
@@ -541,7 +546,7 @@ key_lifetime_infinite_set (struct vty *vty, struct key_range *krange,
DEFUN (accept_lifetime_day_month_day_month,
accept_lifetime_day_month_day_month_cmd,
- "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
+ "accept-lifetime HH:MM:SS (1-31) MONTH (1993-2035) HH:MM:SS (1-31) MONTH (1993-2035)",
"Set accept lifetime of the key\n"
"Time to start\n"
"Day of th month to start\n"
@@ -552,15 +557,23 @@ DEFUN (accept_lifetime_day_month_day_month,
"Month of the year to expire\n"
"Year to expire\n")
{
+ int idx_hhmmss = 1;
+ int idx_number = 2;
+ int idx_month = 3;
+ int idx_number_2 = 4;
+ int idx_hhmmss_2 = 5;
+ int idx_number_3 = 6;
+ int idx_month_2 = 7;
+ int idx_number_4 = 8;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[5], argv[6], argv[7]);
+ return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
+ argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
}
DEFUN (accept_lifetime_day_month_month_day,
accept_lifetime_day_month_month_day_cmd,
- "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
+ "accept-lifetime HH:MM:SS (1-31) MONTH (1993-2035) HH:MM:SS MONTH (1-31) (1993-2035)",
"Set accept lifetime of the key\n"
"Time to start\n"
"Day of th month to start\n"
@@ -571,15 +584,23 @@ DEFUN (accept_lifetime_day_month_month_day,
"Day of th month to expire\n"
"Year to expire\n")
{
+ int idx_hhmmss = 1;
+ int idx_number = 2;
+ int idx_month = 3;
+ int idx_number_2 = 4;
+ int idx_hhmmss_2 = 5;
+ int idx_month_2 = 6;
+ int idx_number_3 = 7;
+ int idx_number_4 = 8;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[6], argv[5], argv[7]);
+ return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
+ argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
}
DEFUN (accept_lifetime_month_day_day_month,
accept_lifetime_month_day_day_month_cmd,
- "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
+ "accept-lifetime HH:MM:SS MONTH (1-31) (1993-2035) HH:MM:SS (1-31) MONTH (1993-2035)",
"Set accept lifetime of the key\n"
"Time to start\n"
"Month of the year to start\n"
@@ -590,15 +611,23 @@ DEFUN (accept_lifetime_month_day_day_month,
"Month of the year to expire\n"
"Year to expire\n")
{
+ int idx_hhmmss = 1;
+ int idx_month = 2;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_hhmmss_2 = 5;
+ int idx_number_3 = 6;
+ int idx_month_2 = 7;
+ int idx_number_4 = 8;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1],
- argv[3], argv[4], argv[5], argv[6], argv[7]);
+ return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
+ argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
}
DEFUN (accept_lifetime_month_day_month_day,
accept_lifetime_month_day_month_day_cmd,
- "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
+ "accept-lifetime HH:MM:SS MONTH (1-31) (1993-2035) HH:MM:SS MONTH (1-31) (1993-2035)",
"Set accept lifetime of the key\n"
"Time to start\n"
"Month of the year to start\n"
@@ -609,15 +638,23 @@ DEFUN (accept_lifetime_month_day_month_day,
"Day of th month to expire\n"
"Year to expire\n")
{
+ int idx_hhmmss = 1;
+ int idx_month = 2;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_hhmmss_2 = 5;
+ int idx_month_2 = 6;
+ int idx_number_3 = 7;
+ int idx_number_4 = 8;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1],
- argv[3], argv[4], argv[6], argv[5], argv[7]);
+ return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
+ argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
}
DEFUN (accept_lifetime_infinite_day_month,
accept_lifetime_infinite_day_month_cmd,
- "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> infinite",
+ "accept-lifetime HH:MM:SS (1-31) MONTH (1993-2035) infinite",
"Set accept lifetime of the key\n"
"Time to start\n"
"Day of th month to start\n"
@@ -625,15 +662,19 @@ DEFUN (accept_lifetime_infinite_day_month,
"Year to start\n"
"Never expires")
{
+ int idx_hhmmss = 1;
+ int idx_number = 2;
+ int idx_month = 3;
+ int idx_number_2 = 4;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[1],
- argv[2], argv[3]);
+ return key_lifetime_infinite_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
+ argv[idx_month]->arg, argv[idx_number_2]->arg);
}
DEFUN (accept_lifetime_infinite_month_day,
accept_lifetime_infinite_month_day_cmd,
- "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> infinite",
+ "accept-lifetime HH:MM:SS MONTH (1-31) (1993-2035) infinite",
"Set accept lifetime of the key\n"
"Time to start\n"
"Month of the year to start\n"
@@ -641,15 +682,19 @@ DEFUN (accept_lifetime_infinite_month_day,
"Year to start\n"
"Never expires")
{
+ int idx_hhmmss = 1;
+ int idx_month = 2;
+ int idx_number = 3;
+ int idx_number_2 = 4;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[2],
- argv[1], argv[3]);
+ return key_lifetime_infinite_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
+ argv[idx_month]->arg, argv[idx_number_2]->arg);
}
DEFUN (accept_lifetime_duration_day_month,
accept_lifetime_duration_day_month_cmd,
- "accept-lifetime HH:MM:SS <1-31> MONTH <1993-2035> duration <1-2147483646>",
+ "accept-lifetime HH:MM:SS (1-31) MONTH (1993-2035) duration (1-2147483646)",
"Set accept lifetime of the key\n"
"Time to start\n"
"Day of th month to start\n"
@@ -658,15 +703,20 @@ DEFUN (accept_lifetime_duration_day_month,
"Duration of the key\n"
"Duration seconds\n")
{
+ int idx_hhmmss = 1;
+ int idx_number = 2;
+ int idx_month = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 6;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[1],
- argv[2], argv[3], argv[4]);
+ return key_lifetime_duration_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
+ argv[idx_month]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg);
}
DEFUN (accept_lifetime_duration_month_day,
accept_lifetime_duration_month_day_cmd,
- "accept-lifetime HH:MM:SS MONTH <1-31> <1993-2035> duration <1-2147483646>",
+ "accept-lifetime HH:MM:SS MONTH (1-31) (1993-2035) duration (1-2147483646)",
"Set accept lifetime of the key\n"
"Time to start\n"
"Month of the year to start\n"
@@ -675,15 +725,20 @@ DEFUN (accept_lifetime_duration_month_day,
"Duration of the key\n"
"Duration seconds\n")
{
+ int idx_hhmmss = 1;
+ int idx_month = 2;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 6;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[2],
- argv[1], argv[3], argv[4]);
+ return key_lifetime_duration_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
+ argv[idx_month]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg);
}
DEFUN (send_lifetime_day_month_day_month,
send_lifetime_day_month_day_month_cmd,
- "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
+ "send-lifetime HH:MM:SS (1-31) MONTH (1993-2035) HH:MM:SS (1-31) MONTH (1993-2035)",
"Set send lifetime of the key\n"
"Time to start\n"
"Day of th month to start\n"
@@ -694,15 +749,23 @@ DEFUN (send_lifetime_day_month_day_month,
"Month of the year to expire\n"
"Year to expire\n")
{
+ int idx_hhmmss = 1;
+ int idx_number = 2;
+ int idx_month = 3;
+ int idx_number_2 = 4;
+ int idx_hhmmss_2 = 5;
+ int idx_number_3 = 6;
+ int idx_month_2 = 7;
+ int idx_number_4 = 8;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6], argv[7]);
+ return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg,
+ argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
}
DEFUN (send_lifetime_day_month_month_day,
send_lifetime_day_month_month_day_cmd,
- "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
+ "send-lifetime HH:MM:SS (1-31) MONTH (1993-2035) HH:MM:SS MONTH (1-31) (1993-2035)",
"Set send lifetime of the key\n"
"Time to start\n"
"Day of th month to start\n"
@@ -713,15 +776,23 @@ DEFUN (send_lifetime_day_month_month_day,
"Day of th month to expire\n"
"Year to expire\n")
{
+ int idx_hhmmss = 1;
+ int idx_number = 2;
+ int idx_month = 3;
+ int idx_number_2 = 4;
+ int idx_hhmmss_2 = 5;
+ int idx_month_2 = 6;
+ int idx_number_3 = 7;
+ int idx_number_4 = 8;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3],
- argv[4], argv[6], argv[5], argv[7]);
+ return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg,
+ argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
}
DEFUN (send_lifetime_month_day_day_month,
send_lifetime_month_day_day_month_cmd,
- "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS <1-31> MONTH <1993-2035>",
+ "send-lifetime HH:MM:SS MONTH (1-31) (1993-2035) HH:MM:SS (1-31) MONTH (1993-2035)",
"Set send lifetime of the key\n"
"Time to start\n"
"Month of the year to start\n"
@@ -732,15 +803,23 @@ DEFUN (send_lifetime_month_day_day_month,
"Month of the year to expire\n"
"Year to expire\n")
{
+ int idx_hhmmss = 1;
+ int idx_month = 2;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_hhmmss_2 = 5;
+ int idx_number_3 = 6;
+ int idx_month_2 = 7;
+ int idx_number_4 = 8;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3],
- argv[4], argv[5], argv[6], argv[7]);
+ return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg,
+ argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
}
DEFUN (send_lifetime_month_day_month_day,
send_lifetime_month_day_month_day_cmd,
- "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> HH:MM:SS MONTH <1-31> <1993-2035>",
+ "send-lifetime HH:MM:SS MONTH (1-31) (1993-2035) HH:MM:SS MONTH (1-31) (1993-2035)",
"Set send lifetime of the key\n"
"Time to start\n"
"Month of the year to start\n"
@@ -751,15 +830,23 @@ DEFUN (send_lifetime_month_day_month_day,
"Day of th month to expire\n"
"Year to expire\n")
{
+ int idx_hhmmss = 1;
+ int idx_month = 2;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_hhmmss_2 = 5;
+ int idx_month_2 = 6;
+ int idx_number_3 = 7;
+ int idx_number_4 = 8;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3],
- argv[4], argv[6], argv[5], argv[7]);
+ return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg,
+ argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
}
DEFUN (send_lifetime_infinite_day_month,
send_lifetime_infinite_day_month_cmd,
- "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> infinite",
+ "send-lifetime HH:MM:SS (1-31) MONTH (1993-2035) infinite",
"Set send lifetime of the key\n"
"Time to start\n"
"Day of th month to start\n"
@@ -767,15 +854,19 @@ DEFUN (send_lifetime_infinite_day_month,
"Year to start\n"
"Never expires")
{
+ int idx_hhmmss = 1;
+ int idx_number = 2;
+ int idx_month = 3;
+ int idx_number_2 = 4;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[1], argv[2],
- argv[3]);
+ return key_lifetime_infinite_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
+ argv[idx_number_2]->arg);
}
DEFUN (send_lifetime_infinite_month_day,
send_lifetime_infinite_month_day_cmd,
- "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> infinite",
+ "send-lifetime HH:MM:SS MONTH (1-31) (1993-2035) infinite",
"Set send lifetime of the key\n"
"Time to start\n"
"Month of the year to start\n"
@@ -783,15 +874,19 @@ DEFUN (send_lifetime_infinite_month_day,
"Year to start\n"
"Never expires")
{
+ int idx_hhmmss = 1;
+ int idx_month = 2;
+ int idx_number = 3;
+ int idx_number_2 = 4;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[2], argv[1],
- argv[3]);
+ return key_lifetime_infinite_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
+ argv[idx_number_2]->arg);
}
DEFUN (send_lifetime_duration_day_month,
send_lifetime_duration_day_month_cmd,
- "send-lifetime HH:MM:SS <1-31> MONTH <1993-2035> duration <1-2147483646>",
+ "send-lifetime HH:MM:SS (1-31) MONTH (1993-2035) duration (1-2147483646)",
"Set send lifetime of the key\n"
"Time to start\n"
"Day of th month to start\n"
@@ -800,15 +895,20 @@ DEFUN (send_lifetime_duration_day_month,
"Duration of the key\n"
"Duration seconds\n")
{
+ int idx_hhmmss = 1;
+ int idx_number = 2;
+ int idx_month = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 6;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_duration_set (vty, &key->send, argv[0], argv[1], argv[2],
- argv[3], argv[4]);
+ return key_lifetime_duration_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
+ argv[idx_number_2]->arg, argv[idx_number_3]->arg);
}
DEFUN (send_lifetime_duration_month_day,
send_lifetime_duration_month_day_cmd,
- "send-lifetime HH:MM:SS MONTH <1-31> <1993-2035> duration <1-2147483646>",
+ "send-lifetime HH:MM:SS MONTH (1-31) (1993-2035) duration (1-2147483646)",
"Set send lifetime of the key\n"
"Time to start\n"
"Month of the year to start\n"
@@ -817,10 +917,15 @@ DEFUN (send_lifetime_duration_month_day,
"Duration of the key\n"
"Duration seconds\n")
{
+ int idx_hhmmss = 1;
+ int idx_month = 2;
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 6;
VTY_DECLVAR_CONTEXT_SUB (key, key);
- return key_lifetime_duration_set (vty, &key->send, argv[0], argv[2], argv[1],
- argv[3], argv[4]);
+ return key_lifetime_duration_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
+ argv[idx_number_2]->arg, argv[idx_number_3]->arg);
}
static struct cmd_node keychain_node =
diff --git a/lib/log.c b/lib/log.c
index 6a3ce07799..a421f60443 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -24,6 +24,7 @@
#include <zebra.h>
+#include "zclient.h"
#include "log.h"
#include "memory.h"
#include "command.h"
@@ -118,7 +119,6 @@ quagga_timestamp(int timestamp_precision, char *buf, size_t buflen)
} cache;
struct timeval clock;
- /* would it be sufficient to use global 'recent_time' here? I fear not... */
gettimeofday(&clock, NULL);
/* first, we update the cache if the time has changed */
@@ -989,6 +989,7 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY (ZEBRA_IPV4_NEXTHOP_DELETE),
DESC_ENTRY (ZEBRA_IPV6_NEXTHOP_ADD),
DESC_ENTRY (ZEBRA_IPV6_NEXTHOP_DELETE),
+ DESC_ENTRY (ZEBRA_IPMR_ROUTE_STATS),
};
#undef DESC_ENTRY
@@ -1061,49 +1062,49 @@ proto_redistnum(int afi, const char *s)
if (afi == AFI_IP)
{
- if (strncmp (s, "k", 1) == 0)
+ if (strmatch (s, "kernel"))
return ZEBRA_ROUTE_KERNEL;
- else if (strncmp (s, "c", 1) == 0)
+ else if (strmatch (s, "connected"))
return ZEBRA_ROUTE_CONNECT;
- else if (strncmp (s, "s", 1) == 0)
+ else if (strmatch (s, "static"))
return ZEBRA_ROUTE_STATIC;
- else if (strncmp (s, "r", 1) == 0)
+ else if (strmatch (s, "rip"))
return ZEBRA_ROUTE_RIP;
- else if (strncmp (s, "o", 1) == 0)
+ else if (strmatch (s, "ospf"))
return ZEBRA_ROUTE_OSPF;
- else if (strncmp (s, "i", 1) == 0)
+ else if (strmatch (s, "isis"))
return ZEBRA_ROUTE_ISIS;
- else if (strncmp (s, "bg", 2) == 0)
+ else if (strmatch (s, "bgp"))
return ZEBRA_ROUTE_BGP;
- else if (strncmp (s, "ta", 2) == 0)
+ else if (strmatch (s, "table"))
return ZEBRA_ROUTE_TABLE;
- else if (strcmp (s, "vnc-direct") == 0)
- return ZEBRA_ROUTE_VNC_DIRECT;
- else if (strcmp (s, "vnc") == 0)
+ else if (strmatch (s, "vnc"))
return ZEBRA_ROUTE_VNC;
+ else if (strmatch (s, "vnc-direct"))
+ return ZEBRA_ROUTE_VNC_DIRECT;
}
if (afi == AFI_IP6)
{
- if (strncmp (s, "k", 1) == 0)
+ if (strmatch (s, "kernel"))
return ZEBRA_ROUTE_KERNEL;
- else if (strncmp (s, "c", 1) == 0)
+ else if (strmatch (s, "connected"))
return ZEBRA_ROUTE_CONNECT;
- else if (strncmp (s, "s", 1) == 0)
+ else if (strmatch (s, "static"))
return ZEBRA_ROUTE_STATIC;
- else if (strncmp (s, "r", 1) == 0)
+ else if (strmatch (s, "ripng"))
return ZEBRA_ROUTE_RIPNG;
- else if (strncmp (s, "o", 1) == 0)
+ else if (strmatch (s, "ospf6"))
return ZEBRA_ROUTE_OSPF6;
- else if (strncmp (s, "i", 1) == 0)
+ else if (strmatch (s, "isis"))
return ZEBRA_ROUTE_ISIS;
- else if (strncmp (s, "bg", 2) == 0)
+ else if (strmatch (s, "bgp"))
return ZEBRA_ROUTE_BGP;
- else if (strncmp (s, "ta", 2) == 0)
+ else if (strmatch (s, "table"))
return ZEBRA_ROUTE_TABLE;
- else if (strcmp (s, "vnc-direct") == 0)
- return ZEBRA_ROUTE_VNC_DIRECT;
- else if (strcmp (s, "vnc") == 0)
+ else if (strmatch (s, "vnc"))
return ZEBRA_ROUTE_VNC;
+ else if (strmatch (s, "vnc-direct"))
+ return ZEBRA_ROUTE_VNC_DIRECT;
}
return -1;
}
diff --git a/lib/log.h b/lib/log.h
index cb6379cb2a..3413cae5a9 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -205,8 +205,6 @@ struct timestamp_control {
/* Defines for use in command construction: */
-#define LOG_LEVELS "(emergencies|alerts|critical|errors|warnings|notifications|informational|debugging)"
-
#define LOG_LEVEL_DESC \
"System is unusable\n" \
"Immediate action needed\n" \
@@ -217,8 +215,6 @@ struct timestamp_control {
"Informational messages\n" \
"Debugging messages\n"
-#define LOG_FACILITIES "(kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7)"
-
#define LOG_FACILITY_DESC \
"Kernel\n" \
"User process\n" \
diff --git a/lib/memory.c b/lib/memory.c
index 9ec564151a..ad55366f64 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -41,11 +41,7 @@ mt_count_alloc (struct memtype *mt, size_t size)
static inline void
mt_count_free (struct memtype *mt)
{
- if (mt->n_alloc == 0)
- {
- zlog_err ("memory allocation count underflow for \"%s\"", mt->name);
- zlog_backtrace (LOG_ERR);
- }
+ assert(mt->n_alloc);
mt->n_alloc--;
}
diff --git a/lib/monotime.h b/lib/monotime.h
new file mode 100644
index 0000000000..0fd4940431
--- /dev/null
+++ b/lib/monotime.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017 David Lamparter, for NetDEF, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FRR_MONOTIME_H
+#define _FRR_MONOTIME_H
+
+#include <stdint.h>
+#include <time.h>
+#include <sys/time.h>
+
+#ifndef TIMESPEC_TO_TIMEVAL
+/* should be in sys/time.h on BSD & Linux libcs */
+#define TIMESPEC_TO_TIMEVAL(tv, ts) do { \
+ (tv)->tv_sec = (ts)->tv_sec; \
+ (tv)->tv_usec = (ts)->tv_nsec / 1000; \
+ } while (0)
+#endif
+#ifndef TIMEVAL_TO_TIMESPEC
+/* should be in sys/time.h on BSD & Linux libcs */
+#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \
+ (ts)->tv_sec = (tv)->tv_sec; \
+ (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+ } while (0)
+#endif
+
+static inline time_t monotime(struct timeval *tvo)
+{
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ if (tvo) {
+ TIMESPEC_TO_TIMEVAL(tvo, &ts);
+ }
+ return ts.tv_sec;
+}
+
+/* the following two return microseconds, not time_t!
+ *
+ * also, they're negative forms of each other, but having both makes the
+ * code more readable
+ */
+static inline int64_t monotime_since(const struct timeval *ref,
+ struct timeval *out)
+{
+ struct timeval tv;
+ monotime(&tv);
+ timersub(&tv, ref, &tv);
+ if (out)
+ *out = tv;
+ return (int64_t)tv.tv_sec * 1000000LL + tv.tv_usec;
+}
+
+static inline int64_t monotime_until(const struct timeval *ref,
+ struct timeval *out)
+{
+ struct timeval tv;
+ monotime(&tv);
+ timersub(ref, &tv, &tv);
+ if (out)
+ *out = tv;
+ return (int64_t)tv.tv_sec * 1000000LL + tv.tv_usec;
+}
+
+#endif /* _FRR_MONOTIME_H */
diff --git a/lib/network.c b/lib/network.c
index 506e019136..2b6f2fbab5 100644
--- a/lib/network.c
+++ b/lib/network.c
@@ -62,8 +62,13 @@ writen(int fd, const u_char *ptr, int nbytes)
while (nleft > 0)
{
nwritten = write(fd, ptr, nleft);
-
- if (nwritten <= 0)
+
+ if (nwritten < 0)
+ {
+ if (!ERRNO_IO_RETRY(errno))
+ return nwritten;
+ }
+ if (nwritten == 0)
return (nwritten);
nleft -= nwritten;
diff --git a/lib/ns.c b/lib/ns.c
index e6d6a9f9a8..1673ac0a66 100644
--- a/lib/ns.c
+++ b/lib/ns.c
@@ -306,20 +306,22 @@ ns_netns_pathname (struct vty *vty, const char *name)
DEFUN (ns_netns,
ns_netns_cmd,
- "logical-router <1-65535> ns NAME",
+ "logical-router (1-65535) ns NAME",
"Enable a logical-router\n"
"Specify the logical-router indentifier\n"
"The Name Space\n"
"The file name in " NS_RUN_DIR ", or a full pathname\n")
{
+ int idx_number = 1;
+ int idx_name = 3;
ns_id_t ns_id = NS_DEFAULT;
struct ns *ns = NULL;
- char *pathname = ns_netns_pathname (vty, argv[1]);
+ char *pathname = ns_netns_pathname (vty, argv[idx_name]->arg);
if (!pathname)
return CMD_WARNING;
- VTY_GET_INTEGER ("NS ID", ns_id, argv[0]);
+ VTY_GET_INTEGER ("NS ID", ns_id, argv[idx_number]->arg);
ns = ns_get (ns_id);
if (ns->name && strcmp (ns->name, pathname) != 0)
@@ -344,21 +346,23 @@ DEFUN (ns_netns,
DEFUN (no_ns_netns,
no_ns_netns_cmd,
- "no logical-router <1-65535> ns NAME",
+ "no logical-router (1-65535) ns NAME",
NO_STR
"Enable a Logical-Router\n"
"Specify the Logical-Router identifier\n"
"The Name Space\n"
"The file name in " NS_RUN_DIR ", or a full pathname\n")
{
+ int idx_number = 2;
+ int idx_name = 4;
ns_id_t ns_id = NS_DEFAULT;
struct ns *ns = NULL;
- char *pathname = ns_netns_pathname (vty, argv[1]);
+ char *pathname = ns_netns_pathname (vty, argv[idx_name]->arg);
if (!pathname)
return CMD_WARNING;
- VTY_GET_INTEGER ("NS ID", ns_id, argv[0]);
+ VTY_GET_INTEGER ("NS ID", ns_id, argv[idx_number]->arg);
ns = ns_lookup (ns_id);
if (!ns)
diff --git a/lib/plist.c b/lib/plist.c
index 6f19565688..4539d82972 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -20,7 +20,6 @@
*/
#include <zebra.h>
-#include "lib/json.h"
#include "prefix.h"
#include "command.h"
@@ -31,6 +30,7 @@
#include "stream.h"
#include "log.h"
#include "routemap.h"
+#include "lib/json.h"
#include "plist_int.h"
@@ -103,7 +103,6 @@ static struct prefix_master prefix_master_ipv4 =
PLC_MAXLEVELV4,
};
-#ifdef HAVE_IPV6
/* Static structure of IPv6 prefix-list's master. */
static struct prefix_master prefix_master_ipv6 =
{
@@ -115,7 +114,6 @@ static struct prefix_master prefix_master_ipv6 =
NULL,
PLC_MAXLEVELV6,
};
-#endif /* HAVE_IPV6*/
/* Static structure of BGP ORF prefix_list's master. */
static struct prefix_master prefix_master_orf_v4 =
@@ -412,9 +410,7 @@ void
prefix_list_add_hook (void (*func) (struct prefix_list *plist))
{
prefix_master_ipv4.add_hook = func;
-#ifdef HAVE_IPV6
prefix_master_ipv6.add_hook = func;
-#endif /* HAVE_IPV6 */
}
/* Delete hook function. */
@@ -422,9 +418,7 @@ void
prefix_list_delete_hook (void (*func) (struct prefix_list *plist))
{
prefix_master_ipv4.delete_hook = func;
-#ifdef HAVE_IPV6
prefix_master_ipv6.delete_hook = func;
-#endif /* HAVE_IPVt6 */
}
/* Calculate new sequential number. */
@@ -563,10 +557,11 @@ prefix_list_entry_delete (struct prefix_list *plist,
struct prefix_list_entry *pentry,
int update_list)
{
- prefix_list_trie_del (plist, pentry);
-
if (plist == NULL || pentry == NULL)
return;
+
+ prefix_list_trie_del (plist, pentry);
+
if (pentry->prev)
pentry->prev->next = pentry->next;
else
@@ -1106,7 +1101,6 @@ vty_prefix_list_uninstall (struct vty *vty, afi_t afi, const char *name,
return CMD_WARNING;
}
}
-#ifdef HAVE_IPV6
else if (afi == AFI_IP6)
{
if (strncmp ("any", prefix, strlen (prefix)) == 0)
@@ -1124,7 +1118,6 @@ vty_prefix_list_uninstall (struct vty *vty, afi_t afi, const char *name,
return CMD_WARNING;
}
}
-#endif /* HAVE_IPV6 */
/* Lookup prefix entry. */
pentry = prefix_list_entry_lookup(plist, &p, type, seqnum, lenum, genum);
@@ -1424,7 +1417,7 @@ vty_clear_prefix_list (struct vty *vty, afi_t afi, const char *name,
DEFUN (ip_prefix_list,
ip_prefix_list_cmd,
- "ip prefix-list WORD (deny|permit) (A.B.C.D/M|any)",
+ "ip prefix-list WORD <deny|permit> <A.B.C.D/M|any>",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1433,13 +1426,16 @@ DEFUN (ip_prefix_list,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Any prefix match. Same as \"0.0.0.0/0 le 32\"\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL,
- argv[1], argv[2], NULL, NULL);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4_any = 4;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, NULL,
+ argv[idx_permit_deny]->arg, argv[idx_ipv4_any]->arg, NULL, NULL);
}
DEFUN (ip_prefix_list_ge,
ip_prefix_list_ge_cmd,
- "ip prefix-list WORD (deny|permit) A.B.C.D/M ge <0-32>",
+ "ip prefix-list WORD <deny|permit> A.B.C.D/M ge (0-32)",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1449,13 +1445,17 @@ DEFUN (ip_prefix_list_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL, argv[1],
- argv[2], argv[3], NULL);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4_prefixlen = 4;
+ int idx_number = 6;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number]->arg, NULL);
}
DEFUN (ip_prefix_list_ge_le,
ip_prefix_list_ge_le_cmd,
- "ip prefix-list WORD (deny|permit) A.B.C.D/M ge <0-32> le <0-32>",
+ "ip prefix-list WORD <deny|permit> A.B.C.D/M ge (0-32) le (0-32)",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1467,13 +1467,18 @@ DEFUN (ip_prefix_list_ge_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL, argv[1],
- argv[2], argv[3], argv[4]);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4_prefixlen = 4;
+ int idx_number = 6;
+ int idx_number_2 = 8;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number]->arg, argv[idx_number_2]->arg);
}
DEFUN (ip_prefix_list_le,
ip_prefix_list_le_cmd,
- "ip prefix-list WORD (deny|permit) A.B.C.D/M le <0-32>",
+ "ip prefix-list WORD <deny|permit> A.B.C.D/M le (0-32)",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1483,13 +1488,17 @@ DEFUN (ip_prefix_list_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL, argv[1],
- argv[2], NULL, argv[3]);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4_prefixlen = 4;
+ int idx_number = 6;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_number]->arg);
}
DEFUN (ip_prefix_list_le_ge,
ip_prefix_list_le_ge_cmd,
- "ip prefix-list WORD (deny|permit) A.B.C.D/M le <0-32> ge <0-32>",
+ "ip prefix-list WORD <deny|permit> A.B.C.D/M le (0-32) ge (0-32)",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1501,13 +1510,18 @@ DEFUN (ip_prefix_list_le_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL, argv[1],
- argv[2], argv[4], argv[3]);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv4_prefixlen = 4;
+ int idx_number = 6;
+ int idx_number_2 = 8;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number_2]->arg, argv[idx_number]->arg);
}
DEFUN (ip_prefix_list_seq,
ip_prefix_list_seq_cmd,
- "ip prefix-list WORD seq <1-4294967295> (deny|permit) (A.B.C.D/M|any)",
+ "ip prefix-list WORD seq (1-4294967295) <deny|permit> <A.B.C.D/M|any>",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1518,13 +1532,17 @@ DEFUN (ip_prefix_list_seq,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Any prefix match. Same as \"0.0.0.0/0 le 32\"\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], NULL, NULL);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv4_any = 6;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_any]->arg, NULL, NULL);
}
DEFUN (ip_prefix_list_seq_ge,
ip_prefix_list_seq_ge_cmd,
- "ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M ge <0-32>",
+ "ip prefix-list WORD seq (1-4294967295) <deny|permit> A.B.C.D/M ge (0-32)",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1536,13 +1554,18 @@ DEFUN (ip_prefix_list_seq_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], argv[4], NULL);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv4_prefixlen = 6;
+ int idx_number_2 = 8;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number_2]->arg, NULL);
}
DEFUN (ip_prefix_list_seq_ge_le,
ip_prefix_list_seq_ge_le_cmd,
- "ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M ge <0-32> le <0-32>",
+ "ip prefix-list WORD seq (1-4294967295) <deny|permit> A.B.C.D/M ge (0-32) le (0-32)",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1556,13 +1579,19 @@ DEFUN (ip_prefix_list_seq_ge_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[5]);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv4_prefixlen = 6;
+ int idx_number_2 = 8;
+ int idx_number_3 = 10;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg);
}
DEFUN (ip_prefix_list_seq_le,
ip_prefix_list_seq_le_cmd,
- "ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M le <0-32>",
+ "ip prefix-list WORD seq (1-4294967295) <deny|permit> A.B.C.D/M le (0-32)",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1574,13 +1603,18 @@ DEFUN (ip_prefix_list_seq_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], NULL, argv[4]);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv4_prefixlen = 6;
+ int idx_number_2 = 8;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_number_2]->arg);
}
DEFUN (ip_prefix_list_seq_le_ge,
ip_prefix_list_seq_le_ge_cmd,
- "ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M le <0-32> ge <0-32>",
+ "ip prefix-list WORD seq (1-4294967295) <deny|permit> A.B.C.D/M le (0-32) ge (0-32)",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -1594,8 +1628,14 @@ DEFUN (ip_prefix_list_seq_le_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], argv[5], argv[4]);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv4_prefixlen = 6;
+ int idx_number_2 = 8;
+ int idx_number_3 = 10;
+ return vty_prefix_list_install (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number_3]->arg, argv[idx_number_2]->arg);
}
DEFUN (no_ip_prefix_list,
@@ -1606,13 +1646,14 @@ DEFUN (no_ip_prefix_list,
PREFIX_LIST_STR
"Name of a prefix list\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, NULL,
+ int idx_word = 3;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, NULL, NULL,
NULL, NULL, NULL);
}
DEFUN (no_ip_prefix_list_prefix,
no_ip_prefix_list_prefix_cmd,
- "no ip prefix-list WORD (deny|permit) (A.B.C.D/M|any)",
+ "no ip prefix-list WORD <deny|permit> <A.B.C.D/M|any>",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1622,13 +1663,16 @@ DEFUN (no_ip_prefix_list_prefix,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Any prefix match. Same as \"0.0.0.0/0 le 32\"\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
- argv[2], NULL, NULL);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv4_any = 5;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_any]->arg, NULL, NULL);
}
DEFUN (no_ip_prefix_list_ge,
no_ip_prefix_list_ge_cmd,
- "no ip prefix-list WORD (deny|permit) A.B.C.D/M ge <0-32>",
+ "no ip prefix-list WORD <deny|permit> A.B.C.D/M ge (0-32)",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1639,13 +1683,17 @@ DEFUN (no_ip_prefix_list_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
- argv[2], argv[3], NULL);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv4_prefixlen = 5;
+ int idx_number = 7;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number]->arg, NULL);
}
DEFUN (no_ip_prefix_list_ge_le,
no_ip_prefix_list_ge_le_cmd,
- "no ip prefix-list WORD (deny|permit) A.B.C.D/M ge <0-32> le <0-32>",
+ "no ip prefix-list WORD <deny|permit> A.B.C.D/M ge (0-32) le (0-32)",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1658,13 +1706,18 @@ DEFUN (no_ip_prefix_list_ge_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
- argv[2], argv[3], argv[4]);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv4_prefixlen = 5;
+ int idx_number = 7;
+ int idx_number_2 = 9;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number]->arg, argv[idx_number_2]->arg);
}
DEFUN (no_ip_prefix_list_le,
no_ip_prefix_list_le_cmd,
- "no ip prefix-list WORD (deny|permit) A.B.C.D/M le <0-32>",
+ "no ip prefix-list WORD <deny|permit> A.B.C.D/M le (0-32)",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1675,13 +1728,17 @@ DEFUN (no_ip_prefix_list_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
- argv[2], NULL, argv[3]);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv4_prefixlen = 5;
+ int idx_number = 7;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_number]->arg);
}
DEFUN (no_ip_prefix_list_le_ge,
no_ip_prefix_list_le_ge_cmd,
- "no ip prefix-list WORD (deny|permit) A.B.C.D/M le <0-32> ge <0-32>",
+ "no ip prefix-list WORD <deny|permit> A.B.C.D/M le (0-32) ge (0-32)",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1694,13 +1751,18 @@ DEFUN (no_ip_prefix_list_le_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
- argv[2], argv[4], argv[3]);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv4_prefixlen = 5;
+ int idx_number = 7;
+ int idx_number_2 = 9;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number_2]->arg, argv[idx_number]->arg);
}
DEFUN (no_ip_prefix_list_seq,
no_ip_prefix_list_seq_cmd,
- "no ip prefix-list WORD seq <1-4294967295> (deny|permit) (A.B.C.D/M|any)",
+ "no ip prefix-list WORD seq (1-4294967295) <deny|permit> <A.B.C.D/M|any>",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1712,13 +1774,17 @@ DEFUN (no_ip_prefix_list_seq,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Any prefix match. Same as \"0.0.0.0/0 le 32\"\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], NULL, NULL);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv4_any = 7;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_any]->arg, NULL, NULL);
}
DEFUN (no_ip_prefix_list_seq_ge,
no_ip_prefix_list_seq_ge_cmd,
- "no ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M ge <0-32>",
+ "no ip prefix-list WORD seq (1-4294967295) <deny|permit> A.B.C.D/M ge (0-32)",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1731,13 +1797,18 @@ DEFUN (no_ip_prefix_list_seq_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], argv[4], NULL);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv4_prefixlen = 7;
+ int idx_number_2 = 9;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number_2]->arg, NULL);
}
DEFUN (no_ip_prefix_list_seq_ge_le,
no_ip_prefix_list_seq_ge_le_cmd,
- "no ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M ge <0-32> le <0-32>",
+ "no ip prefix-list WORD seq (1-4294967295) <deny|permit> A.B.C.D/M ge (0-32) le (0-32)",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1752,13 +1823,19 @@ DEFUN (no_ip_prefix_list_seq_ge_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[5]);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv4_prefixlen = 7;
+ int idx_number_2 = 9;
+ int idx_number_3 = 11;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg);
}
DEFUN (no_ip_prefix_list_seq_le,
no_ip_prefix_list_seq_le_cmd,
- "no ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M le <0-32>",
+ "no ip prefix-list WORD seq (1-4294967295) <deny|permit> A.B.C.D/M le (0-32)",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1771,13 +1848,18 @@ DEFUN (no_ip_prefix_list_seq_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], NULL, argv[4]);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv4_prefixlen = 7;
+ int idx_number_2 = 9;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_number_2]->arg);
}
DEFUN (no_ip_prefix_list_seq_le_ge,
no_ip_prefix_list_seq_le_ge_cmd,
- "no ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M le <0-32> ge <0-32>",
+ "no ip prefix-list WORD seq (1-4294967295) <deny|permit> A.B.C.D/M le (0-32) ge (0-32)",
NO_STR
IP_STR
PREFIX_LIST_STR
@@ -1792,8 +1874,14 @@ DEFUN (no_ip_prefix_list_seq_le_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
- argv[3], argv[5], argv[4]);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv4_prefixlen = 7;
+ int idx_number_2 = 9;
+ int idx_number_3 = 11;
+ return vty_prefix_list_uninstall (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_number_3]->arg, argv[idx_number_2]->arg);
}
DEFUN (ip_prefix_list_sequence_number,
@@ -1821,26 +1909,28 @@ DEFUN (no_ip_prefix_list_sequence_number,
DEFUN (ip_prefix_list_description,
ip_prefix_list_description_cmd,
- "ip prefix-list WORD description .LINE",
+ "ip prefix-list WORD description LINE...",
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
"Prefix-list specific description\n"
"Up to 80 characters describing this prefix-list\n")
{
+ int idx_word = 2;
+ int idx_line = 4;
struct prefix_list *plist;
- plist = prefix_list_get (AFI_IP, 0, argv[0]);
+ plist = prefix_list_get (AFI_IP, 0, argv[idx_word]->arg);
if (plist->desc)
{
XFREE (MTYPE_TMP, plist->desc);
plist->desc = NULL;
}
- plist->desc = argv_concat(argv, argc, 1);
+ plist->desc = argv_concat(argv, argc, idx_line);
return CMD_SUCCESS;
-}
+}
DEFUN (no_ip_prefix_list_description,
no_ip_prefix_list_description_cmd,
@@ -1851,18 +1941,23 @@ DEFUN (no_ip_prefix_list_description,
"Name of a prefix list\n"
"Prefix-list specific description\n")
{
- return vty_prefix_list_desc_unset (vty, AFI_IP, argv[0]);
+ int idx_word = 3;
+ return vty_prefix_list_desc_unset (vty, AFI_IP, argv[idx_word]->arg);
}
-ALIAS (no_ip_prefix_list_description,
- no_ip_prefix_list_description_arg_cmd,
- "no ip prefix-list WORD description .LINE",
+/* ALIAS_FIXME */
+DEFUN (no_ip_prefix_list_description_comment,
+ no_ip_prefix_list_description_comment_cmd,
+ "no ip prefix-list WORD description LINE...",
NO_STR
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
"Prefix-list specific description\n"
"Up to 80 characters describing this prefix-list\n")
+{
+ return no_ip_prefix_list_description (self, vty, argc, argv);
+}
DEFUN (show_ip_prefix_list,
show_ip_prefix_list_cmd,
@@ -1882,12 +1977,13 @@ DEFUN (show_ip_prefix_list_name,
PREFIX_LIST_STR
"Name of a prefix list\n")
{
- return vty_show_prefix_list (vty, AFI_IP, argv[0], NULL, normal_display);
+ int idx_word = 3;
+ return vty_show_prefix_list (vty, AFI_IP, argv[idx_word]->arg, NULL, normal_display);
}
DEFUN (show_ip_prefix_list_name_seq,
show_ip_prefix_list_name_seq_cmd,
- "show ip prefix-list WORD seq <1-4294967295>",
+ "show ip prefix-list WORD seq (1-4294967295)",
SHOW_STR
IP_STR
PREFIX_LIST_STR
@@ -1895,7 +1991,9 @@ DEFUN (show_ip_prefix_list_name_seq,
"sequence number of an entry\n"
"Sequence number\n")
{
- return vty_show_prefix_list (vty, AFI_IP, argv[0], argv[1], sequential_display);
+ int idx_word = 3;
+ int idx_number = 5;
+ return vty_show_prefix_list (vty, AFI_IP, argv[idx_word]->arg, argv[idx_number]->arg, sequential_display);
}
DEFUN (show_ip_prefix_list_prefix,
@@ -1907,7 +2005,9 @@ DEFUN (show_ip_prefix_list_prefix,
"Name of a prefix list\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
{
- return vty_show_prefix_list_prefix (vty, AFI_IP, argv[0], argv[1], normal_display);
+ int idx_word = 3;
+ int idx_ipv4_prefixlen = 4;
+ return vty_show_prefix_list_prefix (vty, AFI_IP, argv[idx_word]->arg, argv[idx_ipv4_prefixlen]->arg, normal_display);
}
DEFUN (show_ip_prefix_list_prefix_longer,
@@ -1920,7 +2020,9 @@ DEFUN (show_ip_prefix_list_prefix_longer,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Lookup longer prefix\n")
{
- return vty_show_prefix_list_prefix (vty, AFI_IP, argv[0], argv[1], longer_display);
+ int idx_word = 3;
+ int idx_ipv4_prefixlen = 4;
+ return vty_show_prefix_list_prefix (vty, AFI_IP, argv[idx_word]->arg, argv[idx_ipv4_prefixlen]->arg, longer_display);
}
DEFUN (show_ip_prefix_list_prefix_first_match,
@@ -1933,7 +2035,9 @@ DEFUN (show_ip_prefix_list_prefix_first_match,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"First matched prefix\n")
{
- return vty_show_prefix_list_prefix (vty, AFI_IP, argv[0], argv[1], first_match_display);
+ int idx_word = 3;
+ int idx_ipv4_prefixlen = 4;
+ return vty_show_prefix_list_prefix (vty, AFI_IP, argv[idx_word]->arg, argv[idx_ipv4_prefixlen]->arg, first_match_display);
}
DEFUN (show_ip_prefix_list_summary,
@@ -1956,7 +2060,8 @@ DEFUN (show_ip_prefix_list_summary_name,
"Summary of prefix lists\n"
"Name of a prefix list\n")
{
- return vty_show_prefix_list (vty, AFI_IP, argv[0], NULL, summary_display);
+ int idx_word = 4;
+ return vty_show_prefix_list (vty, AFI_IP, argv[idx_word]->arg, NULL, summary_display);
}
@@ -1980,7 +2085,8 @@ DEFUN (show_ip_prefix_list_detail_name,
"Detail of prefix lists\n"
"Name of a prefix list\n")
{
- return vty_show_prefix_list (vty, AFI_IP, argv[0], NULL, detail_display);
+ int idx_word = 4;
+ return vty_show_prefix_list (vty, AFI_IP, argv[idx_word]->arg, NULL, detail_display);
}
DEFUN (clear_ip_prefix_list,
@@ -2001,7 +2107,8 @@ DEFUN (clear_ip_prefix_list_name,
PREFIX_LIST_STR
"Name of a prefix list\n")
{
- return vty_clear_prefix_list (vty, AFI_IP, argv[0], NULL);
+ int idx_word = 3;
+ return vty_clear_prefix_list (vty, AFI_IP, argv[idx_word]->arg, NULL);
}
DEFUN (clear_ip_prefix_list_name_prefix,
@@ -2013,13 +2120,14 @@ DEFUN (clear_ip_prefix_list_name_prefix,
"Name of a prefix list\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
{
- return vty_clear_prefix_list (vty, AFI_IP, argv[0], argv[1]);
+ int idx_word = 3;
+ int idx_ipv4_prefixlen = 4;
+ return vty_clear_prefix_list (vty, AFI_IP, argv[idx_word]->arg, argv[idx_ipv4_prefixlen]->arg);
}
-#ifdef HAVE_IPV6
DEFUN (ipv6_prefix_list,
ipv6_prefix_list_cmd,
- "ipv6 prefix-list WORD (deny|permit) (X:X::X:X/M|any)",
+ "ipv6 prefix-list WORD <deny|permit> <X:X::X:X/M|any>",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2028,13 +2136,16 @@ DEFUN (ipv6_prefix_list,
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
"Any prefix match. Same as \"::0/0 le 128\"\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL,
- argv[1], argv[2], NULL, NULL);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv6_any = 4;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, NULL,
+ argv[idx_permit_deny]->arg, argv[idx_ipv6_any]->arg, NULL, NULL);
}
DEFUN (ipv6_prefix_list_ge,
ipv6_prefix_list_ge_cmd,
- "ipv6 prefix-list WORD (deny|permit) X:X::X:X/M ge <0-128>",
+ "ipv6 prefix-list WORD <deny|permit> X:X::X:X/M ge (0-128)",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2044,13 +2155,17 @@ DEFUN (ipv6_prefix_list_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL, argv[1],
- argv[2], argv[3], NULL);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv6_prefixlen = 4;
+ int idx_number = 6;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number]->arg, NULL);
}
DEFUN (ipv6_prefix_list_ge_le,
ipv6_prefix_list_ge_le_cmd,
- "ipv6 prefix-list WORD (deny|permit) X:X::X:X/M ge <0-128> le <0-128>",
+ "ipv6 prefix-list WORD <deny|permit> X:X::X:X/M ge (0-128) le (0-128)",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2063,13 +2178,18 @@ DEFUN (ipv6_prefix_list_ge_le,
"Maximum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL, argv[1],
- argv[2], argv[3], argv[4]);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv6_prefixlen = 4;
+ int idx_number = 6;
+ int idx_number_2 = 8;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number]->arg, argv[idx_number_2]->arg);
}
DEFUN (ipv6_prefix_list_le,
ipv6_prefix_list_le_cmd,
- "ipv6 prefix-list WORD (deny|permit) X:X::X:X/M le <0-128>",
+ "ipv6 prefix-list WORD <deny|permit> X:X::X:X/M le (0-128)",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2079,13 +2199,17 @@ DEFUN (ipv6_prefix_list_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL, argv[1],
- argv[2], NULL, argv[3]);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv6_prefixlen = 4;
+ int idx_number = 6;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, NULL, argv[idx_number]->arg);
}
DEFUN (ipv6_prefix_list_le_ge,
ipv6_prefix_list_le_ge_cmd,
- "ipv6 prefix-list WORD (deny|permit) X:X::X:X/M le <0-128> ge <0-128>",
+ "ipv6 prefix-list WORD <deny|permit> X:X::X:X/M le (0-128) ge (0-128)",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2097,13 +2221,18 @@ DEFUN (ipv6_prefix_list_le_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL, argv[1],
- argv[2], argv[4], argv[3]);
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_ipv6_prefixlen = 4;
+ int idx_number = 6;
+ int idx_number_2 = 8;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number_2]->arg, argv[idx_number]->arg);
}
DEFUN (ipv6_prefix_list_seq,
ipv6_prefix_list_seq_cmd,
- "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) (X:X::X:X/M|any)",
+ "ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> <X:X::X:X/M|any>",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2114,13 +2243,17 @@ DEFUN (ipv6_prefix_list_seq,
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
"Any prefix match. Same as \"::0/0 le 128\"\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], NULL, NULL);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv6_any = 6;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_any]->arg, NULL, NULL);
}
DEFUN (ipv6_prefix_list_seq_ge,
ipv6_prefix_list_seq_ge_cmd,
- "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M ge <0-128>",
+ "ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> X:X::X:X/M ge (0-128)",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2132,13 +2265,18 @@ DEFUN (ipv6_prefix_list_seq_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], argv[4], NULL);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv6_prefixlen = 6;
+ int idx_number_2 = 8;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number_2]->arg, NULL);
}
DEFUN (ipv6_prefix_list_seq_ge_le,
ipv6_prefix_list_seq_ge_le_cmd,
- "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M ge <0-128> le <0-128>",
+ "ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> X:X::X:X/M ge (0-128) le (0-128)",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2152,13 +2290,19 @@ DEFUN (ipv6_prefix_list_seq_ge_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[5]);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv6_prefixlen = 6;
+ int idx_number_2 = 8;
+ int idx_number_3 = 10;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg);
}
DEFUN (ipv6_prefix_list_seq_le,
ipv6_prefix_list_seq_le_cmd,
- "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M le <0-128>",
+ "ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> X:X::X:X/M le (0-128)",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2170,13 +2314,18 @@ DEFUN (ipv6_prefix_list_seq_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], NULL, argv[4]);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv6_prefixlen = 6;
+ int idx_number_2 = 8;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, NULL, argv[idx_number_2]->arg);
}
DEFUN (ipv6_prefix_list_seq_le_ge,
ipv6_prefix_list_seq_le_ge_cmd,
- "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M le <0-128> ge <0-128>",
+ "ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> X:X::X:X/M le (0-128) ge (0-128)",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
@@ -2190,8 +2339,14 @@ DEFUN (ipv6_prefix_list_seq_le_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], argv[5], argv[4]);
+ int idx_word = 2;
+ int idx_number = 4;
+ int idx_permit_deny = 5;
+ int idx_ipv6_prefixlen = 6;
+ int idx_number_2 = 8;
+ int idx_number_3 = 10;
+ return vty_prefix_list_install (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number_3]->arg, argv[idx_number_2]->arg);
}
DEFUN (no_ipv6_prefix_list,
@@ -2202,13 +2357,14 @@ DEFUN (no_ipv6_prefix_list,
PREFIX_LIST_STR
"Name of a prefix list\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, NULL,
+ int idx_word = 3;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, NULL, NULL,
NULL, NULL, NULL);
}
DEFUN (no_ipv6_prefix_list_prefix,
no_ipv6_prefix_list_prefix_cmd,
- "no ipv6 prefix-list WORD (deny|permit) (X:X::X:X/M|any)",
+ "no ipv6 prefix-list WORD <deny|permit> <X:X::X:X/M|any>",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2218,13 +2374,16 @@ DEFUN (no_ipv6_prefix_list_prefix,
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
"Any prefix match. Same as \"::0/0 le 128\"\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
- argv[2], NULL, NULL);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv6_any = 5;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_any]->arg, NULL, NULL);
}
DEFUN (no_ipv6_prefix_list_ge,
no_ipv6_prefix_list_ge_cmd,
- "no ipv6 prefix-list WORD (deny|permit) X:X::X:X/M ge <0-128>",
+ "no ipv6 prefix-list WORD <deny|permit> X:X::X:X/M ge (0-128)",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2235,13 +2394,17 @@ DEFUN (no_ipv6_prefix_list_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
- argv[2], argv[3], NULL);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv6_prefixlen = 5;
+ int idx_number = 7;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number]->arg, NULL);
}
DEFUN (no_ipv6_prefix_list_ge_le,
no_ipv6_prefix_list_ge_le_cmd,
- "no ipv6 prefix-list WORD (deny|permit) X:X::X:X/M ge <0-128> le <0-128>",
+ "no ipv6 prefix-list WORD <deny|permit> X:X::X:X/M ge (0-128) le (0-128)",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2254,13 +2417,18 @@ DEFUN (no_ipv6_prefix_list_ge_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
- argv[2], argv[3], argv[4]);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv6_prefixlen = 5;
+ int idx_number = 7;
+ int idx_number_2 = 9;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number]->arg, argv[idx_number_2]->arg);
}
DEFUN (no_ipv6_prefix_list_le,
no_ipv6_prefix_list_le_cmd,
- "no ipv6 prefix-list WORD (deny|permit) X:X::X:X/M le <0-128>",
+ "no ipv6 prefix-list WORD <deny|permit> X:X::X:X/M le (0-128)",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2271,13 +2439,17 @@ DEFUN (no_ipv6_prefix_list_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
- argv[2], NULL, argv[3]);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv6_prefixlen = 5;
+ int idx_number = 7;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, NULL, argv[idx_number]->arg);
}
DEFUN (no_ipv6_prefix_list_le_ge,
no_ipv6_prefix_list_le_ge_cmd,
- "no ipv6 prefix-list WORD (deny|permit) X:X::X:X/M le <0-128> ge <0-128>",
+ "no ipv6 prefix-list WORD <deny|permit> X:X::X:X/M le (0-128) ge (0-128)",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2290,13 +2462,18 @@ DEFUN (no_ipv6_prefix_list_le_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
- argv[2], argv[4], argv[3]);
+ int idx_word = 3;
+ int idx_permit_deny = 4;
+ int idx_ipv6_prefixlen = 5;
+ int idx_number = 7;
+ int idx_number_2 = 9;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, NULL, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number_2]->arg, argv[idx_number]->arg);
}
DEFUN (no_ipv6_prefix_list_seq,
no_ipv6_prefix_list_seq_cmd,
- "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) (X:X::X:X/M|any)",
+ "no ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> <X:X::X:X/M|any>",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2308,13 +2485,17 @@ DEFUN (no_ipv6_prefix_list_seq,
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
"Any prefix match. Same as \"::0/0 le 128\"\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], NULL, NULL);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv6_any = 7;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_any]->arg, NULL, NULL);
}
DEFUN (no_ipv6_prefix_list_seq_ge,
no_ipv6_prefix_list_seq_ge_cmd,
- "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M ge <0-128>",
+ "no ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> X:X::X:X/M ge (0-128)",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2327,13 +2508,18 @@ DEFUN (no_ipv6_prefix_list_seq_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], argv[4], NULL);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv6_prefixlen = 7;
+ int idx_number_2 = 9;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number_2]->arg, NULL);
}
DEFUN (no_ipv6_prefix_list_seq_ge_le,
no_ipv6_prefix_list_seq_ge_le_cmd,
- "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M ge <0-128> le <0-128>",
+ "no ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> X:X::X:X/M ge (0-128) le (0-128)",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2348,13 +2534,19 @@ DEFUN (no_ipv6_prefix_list_seq_ge_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[5]);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv6_prefixlen = 7;
+ int idx_number_2 = 9;
+ int idx_number_3 = 11;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg);
}
DEFUN (no_ipv6_prefix_list_seq_le,
no_ipv6_prefix_list_seq_le_cmd,
- "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M le <0-128>",
+ "no ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> X:X::X:X/M le (0-128)",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2367,13 +2559,18 @@ DEFUN (no_ipv6_prefix_list_seq_le,
"Maximum prefix length to be matched\n"
"Maximum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], NULL, argv[4]);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv6_prefixlen = 7;
+ int idx_number_2 = 9;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, NULL, argv[idx_number_2]->arg);
}
DEFUN (no_ipv6_prefix_list_seq_le_ge,
no_ipv6_prefix_list_seq_le_ge_cmd,
- "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M le <0-128> ge <0-128>",
+ "no ipv6 prefix-list WORD seq (1-4294967295) <deny|permit> X:X::X:X/M le (0-128) ge (0-128)",
NO_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2388,8 +2585,14 @@ DEFUN (no_ipv6_prefix_list_seq_le_ge,
"Minimum prefix length to be matched\n"
"Minimum prefix length\n")
{
- return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
- argv[3], argv[5], argv[4]);
+ int idx_word = 3;
+ int idx_number = 5;
+ int idx_permit_deny = 6;
+ int idx_ipv6_prefixlen = 7;
+ int idx_number_2 = 9;
+ int idx_number_3 = 11;
+ return vty_prefix_list_uninstall (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, argv[idx_permit_deny]->arg,
+ argv[idx_ipv6_prefixlen]->arg, argv[idx_number_3]->arg, argv[idx_number_2]->arg);
}
DEFUN (ipv6_prefix_list_sequence_number,
@@ -2417,26 +2620,28 @@ DEFUN (no_ipv6_prefix_list_sequence_number,
DEFUN (ipv6_prefix_list_description,
ipv6_prefix_list_description_cmd,
- "ipv6 prefix-list WORD description .LINE",
+ "ipv6 prefix-list WORD description LINE...",
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
"Prefix-list specific description\n"
"Up to 80 characters describing this prefix-list\n")
{
+ int idx_word = 2;
+ int iddx_line = 4;
struct prefix_list *plist;
- plist = prefix_list_get (AFI_IP6, 0, argv[0]);
+ plist = prefix_list_get (AFI_IP6, 0, argv[idx_word]->arg);
if (plist->desc)
{
XFREE (MTYPE_TMP, plist->desc);
plist->desc = NULL;
}
- plist->desc = argv_concat(argv, argc, 1);
+ plist->desc = argv_concat(argv, argc, iddx_line);
return CMD_SUCCESS;
-}
+}
DEFUN (no_ipv6_prefix_list_description,
no_ipv6_prefix_list_description_cmd,
@@ -2447,18 +2652,24 @@ DEFUN (no_ipv6_prefix_list_description,
"Name of a prefix list\n"
"Prefix-list specific description\n")
{
- return vty_prefix_list_desc_unset (vty, AFI_IP6, argv[0]);
+ int idx_word = 3;
+ return vty_prefix_list_desc_unset (vty, AFI_IP6, argv[idx_word]->arg);
}
-ALIAS (no_ipv6_prefix_list_description,
- no_ipv6_prefix_list_description_arg_cmd,
- "no ipv6 prefix-list WORD description .LINE",
+/* ALIAS_FIXME */
+DEFUN (no_ipv6_prefix_list_description_comment,
+ no_ipv6_prefix_list_description_comment_cmd,
+ "no ipv6 prefix-list WORD description LINE...",
NO_STR
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
"Prefix-list specific description\n"
"Up to 80 characters describing this prefix-list\n")
+{
+ return no_ipv6_prefix_list_description (self, vty, argc, argv);
+}
+
DEFUN (show_ipv6_prefix_list,
show_ipv6_prefix_list_cmd,
@@ -2478,12 +2689,13 @@ DEFUN (show_ipv6_prefix_list_name,
PREFIX_LIST_STR
"Name of a prefix list\n")
{
- return vty_show_prefix_list (vty, AFI_IP6, argv[0], NULL, normal_display);
+ int idx_word = 3;
+ return vty_show_prefix_list (vty, AFI_IP6, argv[idx_word]->arg, NULL, normal_display);
}
DEFUN (show_ipv6_prefix_list_name_seq,
show_ipv6_prefix_list_name_seq_cmd,
- "show ipv6 prefix-list WORD seq <1-4294967295>",
+ "show ipv6 prefix-list WORD seq (1-4294967295)",
SHOW_STR
IPV6_STR
PREFIX_LIST_STR
@@ -2491,7 +2703,9 @@ DEFUN (show_ipv6_prefix_list_name_seq,
"sequence number of an entry\n"
"Sequence number\n")
{
- return vty_show_prefix_list (vty, AFI_IP6, argv[0], argv[1], sequential_display);
+ int idx_word = 3;
+ int idx_number = 5;
+ return vty_show_prefix_list (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_number]->arg, sequential_display);
}
DEFUN (show_ipv6_prefix_list_prefix,
@@ -2503,7 +2717,9 @@ DEFUN (show_ipv6_prefix_list_prefix,
"Name of a prefix list\n"
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
{
- return vty_show_prefix_list_prefix (vty, AFI_IP6, argv[0], argv[1], normal_display);
+ int idx_word = 3;
+ int idx_ipv6_prefixlen = 4;
+ return vty_show_prefix_list_prefix (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_ipv6_prefixlen]->arg, normal_display);
}
DEFUN (show_ipv6_prefix_list_prefix_longer,
@@ -2516,7 +2732,9 @@ DEFUN (show_ipv6_prefix_list_prefix_longer,
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
"Lookup longer prefix\n")
{
- return vty_show_prefix_list_prefix (vty, AFI_IP6, argv[0], argv[1], longer_display);
+ int idx_word = 3;
+ int idx_ipv6_prefixlen = 4;
+ return vty_show_prefix_list_prefix (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_ipv6_prefixlen]->arg, longer_display);
}
DEFUN (show_ipv6_prefix_list_prefix_first_match,
@@ -2529,7 +2747,9 @@ DEFUN (show_ipv6_prefix_list_prefix_first_match,
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
"First matched prefix\n")
{
- return vty_show_prefix_list_prefix (vty, AFI_IP6, argv[0], argv[1], first_match_display);
+ int idx_word = 3;
+ int idx_ipv6_prefixlen = 4;
+ return vty_show_prefix_list_prefix (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_ipv6_prefixlen]->arg, first_match_display);
}
DEFUN (show_ipv6_prefix_list_summary,
@@ -2552,7 +2772,8 @@ DEFUN (show_ipv6_prefix_list_summary_name,
"Summary of prefix lists\n"
"Name of a prefix list\n")
{
- return vty_show_prefix_list (vty, AFI_IP6, argv[0], NULL, summary_display);
+ int idx_word = 4;
+ return vty_show_prefix_list (vty, AFI_IP6, argv[idx_word]->arg, NULL, summary_display);
}
DEFUN (show_ipv6_prefix_list_detail,
@@ -2575,7 +2796,8 @@ DEFUN (show_ipv6_prefix_list_detail_name,
"Detail of prefix lists\n"
"Name of a prefix list\n")
{
- return vty_show_prefix_list (vty, AFI_IP6, argv[0], NULL, detail_display);
+ int idx_word = 4;
+ return vty_show_prefix_list (vty, AFI_IP6, argv[idx_word]->arg, NULL, detail_display);
}
DEFUN (clear_ipv6_prefix_list,
@@ -2596,7 +2818,8 @@ DEFUN (clear_ipv6_prefix_list_name,
PREFIX_LIST_STR
"Name of a prefix list\n")
{
- return vty_clear_prefix_list (vty, AFI_IP6, argv[0], NULL);
+ int idx_word = 3;
+ return vty_clear_prefix_list (vty, AFI_IP6, argv[idx_word]->arg, NULL);
}
DEFUN (clear_ipv6_prefix_list_name_prefix,
@@ -2608,9 +2831,10 @@ DEFUN (clear_ipv6_prefix_list_name_prefix,
"Name of a prefix list\n"
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
{
- return vty_clear_prefix_list (vty, AFI_IP6, argv[0], argv[1]);
+ int idx_word = 3;
+ int idx_ipv6_prefixlen = 4;
+ return vty_clear_prefix_list (vty, AFI_IP6, argv[idx_word]->arg, argv[idx_ipv6_prefixlen]->arg);
}
-#endif /* HAVE_IPV6 */
/* Configuration write function. */
static int
@@ -2964,7 +3188,7 @@ prefix_list_init_ipv4 (void)
install_element (CONFIG_NODE, &ip_prefix_list_description_cmd);
install_element (CONFIG_NODE, &no_ip_prefix_list_description_cmd);
- install_element (CONFIG_NODE, &no_ip_prefix_list_description_arg_cmd);
+ install_element (CONFIG_NODE, &no_ip_prefix_list_description_comment_cmd);
install_element (CONFIG_NODE, &ip_prefix_list_sequence_number_cmd);
install_element (CONFIG_NODE, &no_ip_prefix_list_sequence_number_cmd);
@@ -2985,7 +3209,6 @@ prefix_list_init_ipv4 (void)
install_element (ENABLE_NODE, &clear_ip_prefix_list_name_prefix_cmd);
}
-#ifdef HAVE_IPV6
/* Prefix-list node. */
static struct cmd_node prefix_ipv6_node =
{
@@ -3030,7 +3253,7 @@ prefix_list_init_ipv6 (void)
install_element (CONFIG_NODE, &ipv6_prefix_list_description_cmd);
install_element (CONFIG_NODE, &no_ipv6_prefix_list_description_cmd);
- install_element (CONFIG_NODE, &no_ipv6_prefix_list_description_arg_cmd);
+ install_element (CONFIG_NODE, &no_ipv6_prefix_list_description_comment_cmd);
install_element (CONFIG_NODE, &ipv6_prefix_list_sequence_number_cmd);
install_element (CONFIG_NODE, &no_ipv6_prefix_list_sequence_number_cmd);
@@ -3050,15 +3273,12 @@ prefix_list_init_ipv6 (void)
install_element (ENABLE_NODE, &clear_ipv6_prefix_list_name_cmd);
install_element (ENABLE_NODE, &clear_ipv6_prefix_list_name_prefix_cmd);
}
-#endif /* HAVE_IPV6 */
void
prefix_list_init ()
{
prefix_list_init_ipv4 ();
-#ifdef HAVE_IPV6
prefix_list_init_ipv6 ();
-#endif /* HAVE_IPV6 */
}
void
diff --git a/lib/prefix.c b/lib/prefix.c
index 84a04c5300..bc1c681058 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -207,10 +207,8 @@ afi2family (afi_t afi)
{
if (afi == AFI_IP)
return AF_INET;
-#ifdef HAVE_IPV6
else if (afi == AFI_IP6)
return AF_INET6;
-#endif /* HAVE_IPV6 */
else if (afi == AFI_ETHER)
return AF_ETHERNET;
return 0;
@@ -221,10 +219,8 @@ family2afi (int family)
{
if (family == AF_INET)
return AFI_IP;
-#ifdef HAVE_IPV6
else if (family == AF_INET6)
return AFI_IP6;
-#endif /* HAVE_IPV6 */
else if (family == AF_ETHERNET)
return AFI_ETHER;
return 0;
@@ -302,10 +298,8 @@ prefix_copy (struct prefix *dest, const struct prefix *src)
if (src->family == AF_INET)
dest->u.prefix4 = src->u.prefix4;
-#ifdef HAVE_IPV6
else if (src->family == AF_INET6)
dest->u.prefix6 = src->u.prefix6;
-#endif /* HAVE_IPV6 */
else if (src->family == AF_UNSPEC)
{
dest->u.lp.id = src->u.lp.id;
@@ -345,11 +339,9 @@ prefix_same (const struct prefix *p1, const struct prefix *p2)
if (p1->family == AF_INET)
if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
return 1;
-#ifdef HAVE_IPV6
if (p1->family == AF_INET6 )
if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
return 1;
-#endif /* HAVE_IPV6 */
if (p1->family == AF_ETHERNET) {
if (!memcmp(p1->u.prefix_eth.octet, p2->u.prefix_eth.octet, ETHER_ADDR_LEN))
return 1;
@@ -414,10 +406,8 @@ prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
if (p1->family == AF_INET)
length = IPV4_MAX_BYTELEN;
-#ifdef HAVE_IPV6
if (p1->family == AF_INET6)
length = IPV6_MAX_BYTELEN;
-#endif
if (p1->family != p2->family || !length)
return -1;
@@ -441,10 +431,8 @@ prefix_family_str (const struct prefix *p)
{
if (p->family == AF_INET)
return "inet";
-#ifdef HAVE_IPV6
if (p->family == AF_INET6)
return "inet6";
-#endif /* HAVE_IPV6 */
if (p->family == AF_ETHERNET)
return "ether";
return "unspec";
@@ -617,8 +605,6 @@ prefix_ipv4_any (const struct prefix_ipv4 *p)
return (p->prefix.s_addr == 0 && p->prefixlen == 0);
}
-#ifdef HAVE_IPV6
-
/* Allocate a new ip version 6 route */
struct prefix_ipv6 *
prefix_ipv6_new (void)
@@ -737,21 +723,6 @@ apply_mask_ipv6 (struct prefix_ipv6 *p)
}
void
-str2in6_addr (const char *str, struct in6_addr *addr)
-{
- int i;
- unsigned int x;
-
- /* %x must point to unsinged int */
- for (i = 0; i < 16; i++)
- {
- sscanf (str + (i * 2), "%02x", &x);
- addr->s6_addr[i] = x & 0xff;
- }
-}
-#endif /* HAVE_IPV6 */
-
-void
apply_mask (struct prefix *p)
{
switch (p->family)
@@ -759,11 +730,9 @@ apply_mask (struct prefix *p)
case AF_INET:
apply_mask_ipv4 ((struct prefix_ipv4 *)p);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
apply_mask_ipv6 ((struct prefix_ipv6 *)p);
break;
-#endif /* HAVE_IPV6 */
default:
break;
}
@@ -786,7 +755,6 @@ sockunion2prefix (const union sockunion *dest,
p->prefixlen = ip_masklen (mask->sin.sin_addr);
return (struct prefix *) p;
}
-#ifdef HAVE_IPV6
if (dest->sa.sa_family == AF_INET6)
{
struct prefix_ipv6 *p;
@@ -797,7 +765,6 @@ sockunion2prefix (const union sockunion *dest,
memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
return (struct prefix *) p;
}
-#endif /* HAVE_IPV6 */
return NULL;
}
@@ -815,7 +782,6 @@ sockunion2hostprefix (const union sockunion *su, struct prefix *prefix)
p->prefixlen = IPV4_MAX_BITLEN;
return (struct prefix *) p;
}
-#ifdef HAVE_IPV6
if (su->sa.sa_family == AF_INET6)
{
struct prefix_ipv6 *p;
@@ -826,7 +792,6 @@ sockunion2hostprefix (const union sockunion *su, struct prefix *prefix)
memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
return (struct prefix *) p;
}
-#endif /* HAVE_IPV6 */
return NULL;
}
@@ -838,10 +803,8 @@ prefix2sockunion (const struct prefix *p, union sockunion *su)
su->sa.sa_family = p->family;
if (p->family == AF_INET)
su->sin.sin_addr = p->u.prefix4;
-#ifdef HAVE_IPV6
if (p->family == AF_INET6)
memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
-#endif /* HAVE_IPV6 */
}
int
@@ -852,11 +815,9 @@ prefix_blen (const struct prefix *p)
case AF_INET:
return IPV4_MAX_BYTELEN;
break;
-#ifdef HAVE_IPV6
case AF_INET6:
return IPV6_MAX_BYTELEN;
break;
-#endif /* HAVE_IPV6 */
case AF_ETHERNET:
return ETHER_ADDR_LEN;
}
@@ -874,12 +835,10 @@ str2prefix (const char *str, struct prefix *p)
if (ret)
return ret;
-#ifdef HAVE_IPV6
/* Next we try to convert string to struct prefix_ipv6. */
ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
if (ret)
return ret;
-#endif /* HAVE_IPV6 */
/* Next we try to convert string to struct prefix_eth. */
ret = str2prefix_eth (str, (struct prefix_eth *) p);
@@ -1035,7 +994,6 @@ netmask_str2prefix_str (const char *net_str, const char *mask_str,
return 1;
}
-#ifdef HAVE_IPV6
/* Utility function for making IPv6 address string. */
const char *
inet6_ntoa (struct in6_addr addr)
@@ -1045,4 +1003,3 @@ inet6_ntoa (struct in6_addr addr)
inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
return buf;
}
-#endif /* HAVE_IPV6 */
diff --git a/lib/prefix.h b/lib/prefix.h
index 85488ccea7..eb69e98f04 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -74,9 +74,7 @@ struct prefix
{
u_char prefix;
struct in_addr prefix4;
-#ifdef HAVE_IPV6
struct in6_addr prefix6;
-#endif /* HAVE_IPV6 */
struct
{
struct in_addr id;
@@ -97,14 +95,12 @@ struct prefix_ipv4
};
/* IPv6 prefix structure. */
-#ifdef HAVE_IPV6
struct prefix_ipv6
{
u_char family;
u_char prefixlen;
struct in6_addr prefix __attribute__ ((aligned (8)));
};
-#endif /* HAVE_IPV6 */
struct prefix_ls
{
@@ -138,6 +134,14 @@ struct prefix_ptr
uintptr_t prefix __attribute__ ((aligned (8)));
};
+struct prefix_sg
+{
+ u_char family;
+ u_char prefixlen;
+ struct in_addr src __attribute ((aligned (8)));
+ struct in_addr grp;
+};
+
/* helper to get type safety/avoid casts on calls
* (w/o this, functions accepting all prefix types need casts on the caller
* side, which strips type safety since the cast will accept any pointer
@@ -226,13 +230,8 @@ extern const char *prefix_family_str (const struct prefix *);
extern int prefix_blen (const struct prefix *);
extern int str2prefix (const char *, struct prefix *);
-/*
- * 8 groups of 4 bytes of hexadecimal + 7 seperators is 39
- * /128 = 4 bytes
- * Null = 1 byte
- * 39 + 4 + 1 = 44 bytes
- */
-#define PREFIX2STR_BUFFER 44
+#define PREFIX2STR_BUFFER PREFIX_STRLEN
+
extern const char *prefix2str (union prefix46constptr, char *, int);
extern int prefix_match (const struct prefix *, const struct prefix *);
extern int prefix_same (const struct prefix *, const struct prefix *);
@@ -271,7 +270,6 @@ extern in_addr_t ipv4_broadcast_addr (in_addr_t hostaddr, int masklen);
extern int netmask_str2prefix_str (const char *, const char *, char *);
-#ifdef HAVE_IPV6
extern struct prefix_ipv6 *prefix_ipv6_new (void);
extern void prefix_ipv6_free (struct prefix_ipv6 *);
extern int str2prefix_ipv6 (const char *, struct prefix_ipv6 *);
@@ -283,7 +281,6 @@ extern void apply_mask_ipv6 (struct prefix_ipv6 *);
extern int ip6_masklen (struct in6_addr);
extern void masklen2ip6 (const int, struct in6_addr *);
-extern void str2in6_addr (const char *, struct in6_addr *);
extern const char *inet6_ntoa (struct in6_addr);
static inline int ipv6_martian (struct in6_addr *addr)
@@ -298,8 +295,6 @@ static inline int ipv6_martian (struct in6_addr *addr)
return 0;
}
-#endif /* HAVE_IPV6 */
-
extern int all_digit (const char *);
/* NOTE: This routine expects the address argument in network byte order. */
diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c
index 0666797fad..a93d7b8476 100644
--- a/lib/ptm_lib.c
+++ b/lib/ptm_lib.c
@@ -458,7 +458,7 @@ ptm_lib_register(char *client_name,
hdl = calloc(1, sizeof(*hdl));
if (hdl) {
- strcpy(hdl->client_name, client_name);
+ strncpy(hdl->client_name, client_name, PTMLIB_MAXNAMELEN - 1);
hdl->cmd_cb = cmd_cb;
hdl->notify_cb = notify_cb;
hdl->response_cb = response_cb;
diff --git a/lib/qobj.c b/lib/qobj.c
index f64972e32a..8a386d2486 100644
--- a/lib/qobj.c
+++ b/lib/qobj.c
@@ -49,7 +49,7 @@ void qobj_reg(struct qobj_node *node, struct qobj_nodetype *type)
node->nid = (uint64_t)random();
node->nid ^= (uint64_t)random() << 32;
}
- while (hash_get (nodes, node, hash_alloc_intern) != node);
+ while (!node->nid || hash_get (nodes, node, hash_alloc_intern) != node);
}
void qobj_unreg(struct qobj_node *node)
@@ -73,7 +73,8 @@ void *qobj_get_typed(uint64_t id, struct qobj_nodetype *type)
void qobj_init (void)
{
- nodes = hash_create (qobj_key, qobj_cmp);
+ if (!nodes)
+ nodes = hash_create (qobj_key, qobj_cmp);
}
void qobj_finish (void)
diff --git a/lib/qobj.h b/lib/qobj.h
index 4c326731ed..64a6774bff 100644
--- a/lib/qobj.h
+++ b/lib/qobj.h
@@ -109,6 +109,8 @@ void *qobj_get_typed(uint64_t id, struct qobj_nodetype *type);
#define QOBJ_ID(ptr) \
((ptr)->qobj_node.nid)
+#define QOBJ_ID_0SAFE(ptr) \
+ ({ typeof (ptr) _ptr = (ptr); _ptr ? _ptr->qobj_node.nid : 0ULL; })
void qobj_init(void);
void qobj_finish(void);
diff --git a/lib/route_types.pl b/lib/route_types.pl
index 62c7417b84..27ca950787 100755
--- a/lib/route_types.pl
+++ b/lib/route_types.pl
@@ -149,7 +149,7 @@ sub collect {
push @names, "any";
push @help, " \"Any of the above protocols\\n\"";
}
- return ("\"(" . join("|", @names) . ")\"", join(" \\\n", @help));
+ return ("\"<" . join("|", @names) . ">\"", join(" \\\n", @help));
}
for my $daemon (sort keys %daemons) {
diff --git a/lib/route_types.txt b/lib/route_types.txt
index 154f03f01c..74d4f2a49c 100644
--- a/lib/route_types.txt
+++ b/lib/route_types.txt
@@ -48,7 +48,7 @@ ZEBRA_ROUTE_STATIC, static, zebra, 'S', 1, 1, "static"
ZEBRA_ROUTE_RIP, rip, ripd, 'R', 1, 0, "RIP"
ZEBRA_ROUTE_RIPNG, ripng, ripngd, 'R', 0, 1, "RIPng"
ZEBRA_ROUTE_OSPF, ospf, ospfd, 'O', 1, 0, "OSPF"
-ZEBRA_ROUTE_OSPF6, ospf6, ospf6d, 'O', 0, 1, "OSPFv6"
+ZEBRA_ROUTE_OSPF6, ospf6, ospf6d, 'O', 0, 1, "OSPFv3"
ZEBRA_ROUTE_ISIS, isis, isisd, 'I', 1, 1, "IS-IS"
ZEBRA_ROUTE_BGP, bgp, bgpd, 'B', 1, 1, "BGP"
ZEBRA_ROUTE_PIM, pim, pimd, 'P', 1, 0, "PIM"
diff --git a/lib/routemap.c b/lib/routemap.c
index ace4961f72..39d9a5d375 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -24,9 +24,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "memory.h"
#include "vector.h"
#include "prefix.h"
+#include "vty.h"
#include "routemap.h"
#include "command.h"
-#include "vty.h"
#include "log.h"
#include "hash.h"
@@ -47,6 +47,594 @@ static vector route_match_vec;
/* Vector for route set rules. */
static vector route_set_vec;
+struct route_map_match_set_hooks
+{
+ /* match interface */
+ int (*match_interface) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match interface */
+ int (*no_match_interface) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ip address */
+ int (*match_ip_address) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ip address */
+ int (*no_match_ip_address) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ip address prefix list */
+ int (*match_ip_address_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ip address prefix list */
+ int (*no_match_ip_address_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ip next hop */
+ int (*match_ip_next_hop) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ip next hop */
+ int (*no_match_ip_next_hop) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ip next hop prefix list */
+ int (*match_ip_next_hop_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ip next hop prefix list */
+ int (*no_match_ip_next_hop_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match ipv6 address */
+ int (*match_ipv6_address) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ipv6 address */
+ int (*no_match_ipv6_address) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+
+ /* match ipv6 address prefix list */
+ int (*match_ipv6_address_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ipv6 address prefix list */
+ int (*no_match_ipv6_address_prefix_list) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match metric */
+ int (*match_metric) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match metric */
+ int (*no_match_metric) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* match tag */
+ int (*match_tag) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match tag */
+ int (*no_match_tag) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* set ip nexthop */
+ int (*set_ip_nexthop) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* no set ip nexthop */
+ int (*no_set_ip_nexthop) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* set ipv6 nexthop local */
+ int (*set_ipv6_nexthop_local) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* no set ipv6 nexthop local */
+ int (*no_set_ipv6_nexthop_local) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* set metric */
+ int (*set_metric) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* no set metric */
+ int (*no_set_metric) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* set tag */
+ int (*set_tag) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+ /* no set tag */
+ int (*no_set_tag) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg);
+
+};
+
+struct route_map_match_set_hooks rmap_match_set_hook;
+
+/* match interface */
+void
+route_map_match_interface_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_interface = func;
+}
+
+/* no match interface */
+void
+route_map_no_match_interface_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_interface = func;
+}
+
+/* match ip address */
+void
+route_map_match_ip_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ip_address = func;
+}
+
+/* no match ip address */
+void
+route_map_no_match_ip_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ip_address = func;
+}
+
+/* match ip address prefix list */
+void
+route_map_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ip_address_prefix_list = func;
+}
+
+/* no match ip address prefix list */
+void
+route_map_no_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ip_address_prefix_list = func;
+}
+
+/* match ip next hop */
+void
+route_map_match_ip_next_hop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ip_next_hop = func;
+}
+
+/* no match ip next hop */
+void
+route_map_no_match_ip_next_hop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ip_next_hop = func;
+}
+
+/* match ip next hop prefix list */
+void
+route_map_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ip_next_hop_prefix_list = func;
+}
+
+/* no match ip next hop prefix list */
+void
+route_map_no_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ip_next_hop_prefix_list = func;
+}
+
+/* match ipv6 address */
+void
+route_map_match_ipv6_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ipv6_address = func;
+}
+
+/* no match ipv6 address */
+void
+route_map_no_match_ipv6_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ipv6_address = func;
+}
+
+
+/* match ipv6 address prefix list */
+void
+route_map_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_ipv6_address_prefix_list = func;
+}
+
+/* no match ipv6 address prefix list */
+void
+route_map_no_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ipv6_address_prefix_list = func;
+}
+
+/* match metric */
+void
+route_map_match_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_metric = func;
+}
+
+/* no match metric */
+void
+route_map_no_match_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_metric = func;
+}
+
+/* match tag */
+void
+route_map_match_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.match_tag = func;
+}
+
+/* no match tag */
+void
+route_map_no_match_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_tag = func;
+}
+
+/* set ip nexthop */
+void
+route_map_set_ip_nexthop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.set_ip_nexthop = func;
+}
+
+/* no set ip nexthop */
+void
+route_map_no_set_ip_nexthop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.no_set_ip_nexthop = func;
+}
+
+/* set ipv6 nexthop local */
+void
+route_map_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.set_ipv6_nexthop_local = func;
+}
+
+/* no set ipv6 nexthop local */
+void
+route_map_no_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.no_set_ipv6_nexthop_local = func;
+}
+
+/* set metric */
+void
+route_map_set_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.set_metric = func;
+}
+
+/* no set metric */
+void
+route_map_no_set_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.no_set_metric = func;
+}
+
+/* set tag */
+void
+route_map_set_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.set_tag = func;
+}
+
+/* no set tag */
+void
+route_map_no_set_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg))
+{
+ rmap_match_set_hook.no_set_tag = func;
+}
+
+int
+generic_match_add (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg,
+ route_map_event_t type)
+{
+ int ret;
+
+ ret = route_map_add_match (index, command, arg);
+ if (ret)
+ {
+ switch (ret)
+ {
+ case RMAP_RULE_MISSING:
+ vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ case RMAP_COMPILE_ERROR:
+ vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ if (type != RMAP_EVENT_MATCH_ADDED)
+ {
+ route_map_upd8_dependency (type, arg, index->map->name);
+ }
+ return CMD_SUCCESS;
+}
+
+int
+generic_match_delete (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg,
+ route_map_event_t type)
+{
+ int ret;
+ char *dep_name = NULL;
+ const char *tmpstr;
+ char *rmap_name = NULL;
+
+ if (type != RMAP_EVENT_MATCH_DELETED)
+ {
+ /* ignore the mundane, the types without any dependency */
+ if (arg == NULL)
+ {
+ if ((tmpstr = route_map_get_match_arg(index, command)) != NULL)
+ dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
+ }
+ else
+ {
+ dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg);
+ }
+ rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
+ }
+
+ ret = route_map_delete_match (index, command, dep_name);
+ if (ret)
+ {
+ switch (ret)
+ {
+ case RMAP_RULE_MISSING:
+ vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
+ break;
+ case RMAP_COMPILE_ERROR:
+ vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
+ break;
+ }
+ if (dep_name)
+ XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+ if (rmap_name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+ return CMD_WARNING;
+ }
+
+ if (type != RMAP_EVENT_MATCH_DELETED && dep_name)
+ route_map_upd8_dependency(type, dep_name, rmap_name);
+
+ if (dep_name)
+ XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+ if (rmap_name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+
+ return CMD_SUCCESS;
+}
+
+int
+generic_set_add (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg)
+{
+ int ret;
+
+ ret = route_map_add_set (index, command, arg);
+ if (ret)
+ {
+ switch (ret)
+ {
+ case RMAP_RULE_MISSING:
+ vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ case RMAP_COMPILE_ERROR:
+ vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+int
+generic_set_delete (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg)
+{
+ int ret;
+
+ ret = route_map_delete_set (index, command, arg);
+ if (ret)
+ {
+ switch (ret)
+ {
+ case RMAP_RULE_MISSING:
+ vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ case RMAP_COMPILE_ERROR:
+ vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+
/* Route map rule. This rule has both `match' rule and `set' rule. */
struct route_map_rule
{
@@ -122,6 +710,7 @@ enum route_map_dep_type
ROUTE_MAP_DEP_RMAP = 1,
ROUTE_MAP_DEP_CLIST,
ROUTE_MAP_DEP_ECLIST,
+ ROUTE_MAP_DEP_LCLIST,
ROUTE_MAP_DEP_PLIST,
ROUTE_MAP_DEP_ASPATH,
ROUTE_MAP_DEP_FILTER,
@@ -211,29 +800,29 @@ route_map_free_map (struct route_map *map)
struct route_map_list *list;
struct route_map_index *index;
+ if (map == NULL)
+ return;
+
while ((index = map->head) != NULL)
route_map_index_delete (index, 0);
list = &route_map_master;
- if (map != NULL)
- {
- QOBJ_UNREG (map);
+ QOBJ_UNREG (map);
- if (map->next)
- map->next->prev = map->prev;
- else
- list->tail = map->prev;
+ if (map->next)
+ map->next->prev = map->prev;
+ else
+ list->tail = map->prev;
- if (map->prev)
- map->prev->next = map->next;
- else
- list->head = map->next;
+ if (map->prev)
+ map->prev->next = map->next;
+ else
+ list->head = map->next;
- hash_release(route_map_master_hash, map);
- XFREE (MTYPE_ROUTE_MAP_NAME, map->name);
- XFREE (MTYPE_ROUTE_MAP, map);
- }
+ hash_release(route_map_master_hash, map);
+ XFREE (MTYPE_ROUTE_MAP_NAME, map->name);
+ XFREE (MTYPE_ROUTE_MAP, map);
}
/* Route map delete from list. */
@@ -401,9 +990,11 @@ vty_show_route_map_entry (struct vty *vty, struct route_map *map)
/* Print the name of the protocol */
if (zlog_default)
+ {
vty_out (vty, "%s", zlog_proto_names[zlog_default->protocol]);
- if (zlog_default->instance)
- vty_out (vty, " %d", zlog_default->instance);
+ if (zlog_default->instance)
+ vty_out (vty, " %d", zlog_default->instance);
+ }
vty_out (vty, ":%s", VTY_NEWLINE);
for (index = map->head; index; index = index->next)
@@ -462,7 +1053,7 @@ vty_show_route_map (struct vty *vty, const char *name)
{
if (zlog_default)
vty_out (vty, "%s", zlog_proto_names[zlog_default->protocol]);
- if (zlog_default->instance)
+ if (zlog_default && zlog_default->instance)
vty_out (vty, " %d", zlog_default->instance);
vty_out (vty, ": 'route-map %s' not found%s", name, VTY_NEWLINE);
return CMD_SUCCESS;
@@ -1229,6 +1820,7 @@ route_map_dep_update (struct hash *dephash, const char *dep_name,
case RMAP_EVENT_CLIST_ADDED:
case RMAP_EVENT_ECLIST_ADDED:
case RMAP_EVENT_ASLIST_ADDED:
+ case RMAP_EVENT_LLIST_ADDED:
case RMAP_EVENT_CALL_ADDED:
case RMAP_EVENT_FILTER_ADDED:
if (rmap_debug)
@@ -1250,6 +1842,7 @@ route_map_dep_update (struct hash *dephash, const char *dep_name,
case RMAP_EVENT_CLIST_DELETED:
case RMAP_EVENT_ECLIST_DELETED:
case RMAP_EVENT_ASLIST_DELETED:
+ case RMAP_EVENT_LLIST_DELETED:
case RMAP_EVENT_CALL_DELETED:
case RMAP_EVENT_FILTER_DELETED:
if (rmap_debug)
@@ -1312,6 +1905,10 @@ route_map_get_dep_hash (route_map_event_t event)
case RMAP_EVENT_ASLIST_DELETED:
upd8_hash = route_map_dep_hash[ROUTE_MAP_DEP_ASPATH];
break;
+ case RMAP_EVENT_LLIST_ADDED:
+ case RMAP_EVENT_LLIST_DELETED:
+ upd8_hash = route_map_dep_hash[ROUTE_MAP_DEP_LCLIST];
+ break;
case RMAP_EVENT_CALL_ADDED:
case RMAP_EVENT_CALL_DELETED:
upd8_hash = route_map_dep_hash[ROUTE_MAP_DEP_RMAP];
@@ -1386,52 +1983,586 @@ route_map_notify_dependencies (const char *affected_name, route_map_event_t even
XFREE (MTYPE_ROUTE_MAP_NAME, name);
}
+
/* VTY related functions. */
-DEFUN (route_map,
- route_map_cmd,
- "route-map WORD (deny|permit) <1-65535>",
- "Create route-map or enter route-map command mode\n"
- "Route map tag\n"
- "Route map denies set operations\n"
- "Route map permits set operations\n"
- "Sequence to insert to/delete from existing route-map entry\n")
+DEFUN (match_interface,
+ match_interface_cmd,
+ "match interface WORD",
+ MATCH_STR
+ "match first hop interface of route\n"
+ "Interface name\n")
+{
+ int idx_word = 2;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_interface)
+ return rmap_match_set_hook.match_interface (vty, index, "interface", argv[idx_word]->arg, RMAP_EVENT_MATCH_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_match_interface,
+ no_match_interface_cmd,
+ "no match interface [INTERFACE]",
+ NO_STR
+ MATCH_STR
+ "Match first hop interface of route\n"
+ "Interface name\n")
{
- int permit;
- unsigned long pref;
- struct route_map *map;
- struct route_map_index *index;
- char *endptr = NULL;
+ char *iface = (argc == 4) ? argv[3]->arg : NULL;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
- /* Permit check. */
- if (strncmp (argv[1], "permit", strlen (argv[1])) == 0)
- permit = RMAP_PERMIT;
- else if (strncmp (argv[1], "deny", strlen (argv[1])) == 0)
- permit = RMAP_DENY;
- else
+ if (rmap_match_set_hook.no_match_interface)
+ return rmap_match_set_hook.no_match_interface (vty, index, "interface", iface, RMAP_EVENT_MATCH_DELETED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ip_address,
+ match_ip_address_cmd,
+ "match ip address <(1-199)|(1300-2699)|WORD>",
+ MATCH_STR
+ IP_STR
+ "Match address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n")
+{
+ int idx_acl = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ip_address)
+ return rmap_match_set_hook.match_ip_address (vty, index, "ip address", argv[idx_acl]->arg,
+ RMAP_EVENT_FILTER_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_ip_address,
+ no_match_ip_address_cmd,
+ "no match ip address [<(1-199)|(1300-2699)|WORD>]",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ip_address)
+ {
+ if (argc <= idx_word)
+ return rmap_match_set_hook.no_match_ip_address (vty, index, "ip address", NULL,
+ RMAP_EVENT_FILTER_DELETED);
+ return rmap_match_set_hook.no_match_ip_address (vty, index, "ip address", argv[idx_word]->arg,
+ RMAP_EVENT_FILTER_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ip_address_prefix_list,
+ match_ip_address_prefix_list_cmd,
+ "match ip address prefix-list WORD",
+ MATCH_STR
+ IP_STR
+ "Match address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ip_address_prefix_list)
+ return rmap_match_set_hook.match_ip_address_prefix_list (vty, index, "ip address prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_ip_address_prefix_list,
+ no_match_ip_address_prefix_list_cmd,
+ "no match ip address prefix-list [WORD]",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 5;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ip_address_prefix_list)
+ {
+ if (argc <= idx_word)
+ return rmap_match_set_hook.no_match_ip_address_prefix_list (vty, index, "ip address prefix-list",
+ NULL, RMAP_EVENT_PLIST_DELETED);
+ return rmap_match_set_hook.no_match_ip_address_prefix_list(vty, index, "ip address prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ip_next_hop,
+ match_ip_next_hop_cmd,
+ "match ip next-hop <(1-199)|(1300-2699)|WORD>",
+ MATCH_STR
+ IP_STR
+ "Match next-hop address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n")
+{
+ int idx_acl = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ip_next_hop)
+ return rmap_match_set_hook.match_ip_next_hop (vty, index, "ip next-hop", argv[idx_acl]->arg,
+ RMAP_EVENT_FILTER_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_ip_next_hop,
+ no_match_ip_next_hop_cmd,
+ "no match ip next-hop [<(1-199)|(1300-2699)|WORD>]",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match next-hop address of route\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ip_next_hop)
+ {
+ if (argc <= idx_word)
+ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop", NULL,
+ RMAP_EVENT_FILTER_DELETED);
+ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop", argv[idx_word]->arg,
+ RMAP_EVENT_FILTER_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ip_next_hop_prefix_list,
+ match_ip_next_hop_prefix_list_cmd,
+ "match ip next-hop prefix-list WORD",
+ MATCH_STR
+ IP_STR
+ "Match next-hop address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ip_next_hop_prefix_list)
+ return rmap_match_set_hook.match_ip_next_hop_prefix_list (vty, index, "ip next-hop prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_match_ip_next_hop_prefix_list,
+ no_match_ip_next_hop_prefix_list_cmd,
+ "no match ip next-hop prefix-list [WORD]",
+ NO_STR
+ MATCH_STR
+ IP_STR
+ "Match next-hop address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 5;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ip_next_hop)
+ {
+ if (argc <= idx_word)
+ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop prefix-list",
+ NULL, RMAP_EVENT_PLIST_DELETED);
+ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ipv6_address,
+ match_ipv6_address_cmd,
+ "match ipv6 address WORD",
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 address of route\n"
+ "IPv6 access-list name\n")
+{
+ int idx_word = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ipv6_address)
+ return rmap_match_set_hook.match_ipv6_address (vty, index, "ipv6 address", argv[idx_word]->arg,
+ RMAP_EVENT_FILTER_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_match_ipv6_address,
+ no_match_ipv6_address_cmd,
+ "no match ipv6 address WORD",
+ NO_STR
+ MATCH_STR
+ IPV6_STR
+ "Match IPv6 address of route\n"
+ "IPv6 access-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ipv6_address)
+ return rmap_match_set_hook.no_match_ipv6_address (vty, index, "ipv6 address", argv[idx_word]->arg,
+ RMAP_EVENT_FILTER_DELETED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_ipv6_address_prefix_list,
+ match_ipv6_address_prefix_list_cmd,
+ "match ipv6 address prefix-list WORD",
+ MATCH_STR
+ IPV6_STR
+ "Match address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_ipv6_address_prefix_list)
+ return rmap_match_set_hook.match_ipv6_address_prefix_list (vty, index, "ipv6 address prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_match_ipv6_address_prefix_list,
+ no_match_ipv6_address_prefix_list_cmd,
+ "no match ipv6 address prefix-list WORD",
+ NO_STR
+ MATCH_STR
+ IPV6_STR
+ "Match address of route\n"
+ "Match entries of prefix-lists\n"
+ "IP prefix-list name\n")
+{
+ int idx_word = 5;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ipv6_address_prefix_list)
+ return rmap_match_set_hook.no_match_ipv6_address_prefix_list(vty, index, "ipv6 address prefix-list",
+ argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_metric,
+ match_metric_cmd,
+ "match metric (0-4294967295)",
+ MATCH_STR
+ "Match metric of route\n"
+ "Metric value\n")
+{
+ int idx_number = 2;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_metric)
+ return rmap_match_set_hook.match_metric(vty, index, "metric", argv[idx_number]->arg,
+ RMAP_EVENT_MATCH_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_metric,
+ no_match_metric_cmd,
+ "no match metric [(0-4294967295)]",
+ NO_STR
+ MATCH_STR
+ "Match metric of route\n"
+ "Metric value\n")
+{
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_metric)
{
- vty_out (vty, "the third field must be [permit|deny]%s", VTY_NEWLINE);
+ if (argc <= idx_number)
+ return rmap_match_set_hook.no_match_metric (vty, index, "metric",
+ NULL, RMAP_EVENT_MATCH_DELETED);
+ return rmap_match_set_hook.no_match_metric(vty, index, "metric",
+ argv[idx_number]->arg,
+ RMAP_EVENT_MATCH_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (match_tag,
+ match_tag_cmd,
+ "match tag (1-4294967295)",
+ MATCH_STR
+ "Match tag of route\n"
+ "Tag value\n")
+{
+ int idx_number = 2;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.match_tag)
+ return rmap_match_set_hook.match_tag(vty, index, "tag", argv[idx_number]->arg,
+ RMAP_EVENT_MATCH_ADDED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_match_tag,
+ no_match_tag_cmd,
+ "no match tag [(1-4294967295)]",
+ NO_STR
+ MATCH_STR
+ "Match tag of route\n"
+ "Tag value\n")
+{
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ int idx = 0;
+ char *arg = argv_find (argv, argc, "(1-4294967295)", &idx) ?
+ argv[idx]->arg : NULL;
+
+ if (rmap_match_set_hook.no_match_tag)
+ return rmap_match_set_hook.no_match_tag (vty, index, "tag", arg,
+ RMAP_EVENT_MATCH_DELETED);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (set_ip_nexthop,
+ set_ip_nexthop_cmd,
+ "set ip next-hop A.B.C.D",
+ SET_STR
+ IP_STR
+ "Next hop address\n"
+ "IP address of next hop\n")
+{
+ int idx_ipv4 = 3;
+ union sockunion su;
+ int ret;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ ret = str2sockunion (argv[idx_ipv4]->arg, &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (su.sin.sin_addr.s_addr == 0 ||
+ IPV4_CLASS_DE(su.sin.sin_addr.s_addr))
+ {
+ vty_out (vty, "%% nexthop address cannot be 0.0.0.0, multicast "
+ "or reserved%s", VTY_NEWLINE);
return CMD_WARNING;
}
- /* Preference check. */
- pref = strtoul (argv[2], &endptr, 10);
- if (pref == ULONG_MAX || *endptr != '\0')
+ if (rmap_match_set_hook.set_ip_nexthop)
+ return rmap_match_set_hook.set_ip_nexthop(vty, index, "ip next-hop", argv[idx_ipv4]->arg);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_set_ip_nexthop,
+ no_set_ip_nexthop_cmd,
+ "no set ip next-hop [<peer-address|A.B.C.D>]",
+ NO_STR
+ SET_STR
+ IP_STR
+ "Next hop address\n"
+ "Use peer address (for BGP only)\n"
+ "IP address of next hop\n")
+{
+ int idx_peer = 4;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_set_ip_nexthop)
{
- vty_out (vty, "the fourth field must be positive integer%s",
- VTY_NEWLINE);
+ if (argc <= idx_peer)
+ return rmap_match_set_hook.no_set_ip_nexthop (vty, index, "ip next-hop", NULL);
+ return rmap_match_set_hook.no_set_ip_nexthop (vty, index, "ip next-hop", argv[idx_peer]->arg);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (set_ipv6_nexthop_local,
+ set_ipv6_nexthop_local_cmd,
+ "set ipv6 next-hop local X:X::X:X",
+ SET_STR
+ IPV6_STR
+ "IPv6 next-hop address\n"
+ "IPv6 local address\n"
+ "IPv6 address of next hop\n")
+{
+ int idx_ipv6 = 4;
+ struct in6_addr addr;
+ int ret;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ ret = inet_pton (AF_INET6, argv[idx_ipv6]->arg, &addr);
+ if (!ret)
+ {
+ vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
return CMD_WARNING;
}
- if (pref == 0 || pref > 65535)
+ if (!IN6_IS_ADDR_LINKLOCAL(&addr))
{
- vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE);
+ vty_out (vty, "%% Invalid link-local nexthop address%s", VTY_NEWLINE);
return CMD_WARNING;
}
+ if (rmap_match_set_hook.set_ipv6_nexthop_local)
+ return rmap_match_set_hook.set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", argv[idx_ipv6]->arg);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_set_ipv6_nexthop_local,
+ no_set_ipv6_nexthop_local_cmd,
+ "no set ipv6 next-hop local [X:X::X:X]",
+ NO_STR
+ SET_STR
+ IPV6_STR
+ "IPv6 next-hop address\n"
+ "IPv6 local address\n"
+ "IPv6 address of next hop\n")
+{
+ int idx_ipv6 = 5;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_set_ipv6_nexthop_local)
+ {
+ if (argc <= idx_ipv6)
+ return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", NULL);
+ return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", argv[5]->arg);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN (set_metric,
+ set_metric_cmd,
+ "set metric <(0-4294967295)|rtt|+rtt|-rtt|+metric|-metric>",
+ SET_STR
+ "Metric value for destination routing protocol\n"
+ "Metric value\n"
+ "Assign round trip time\n"
+ "Add round trip time\n"
+ "Subtract round trip time\n"
+ "Add metric\n"
+ "Subtract metric\n")
+{
+ int idx_number = 2;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.set_metric)
+ return rmap_match_set_hook.set_metric (vty, index, "metric", argv[idx_number]->arg);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_set_metric,
+ no_set_metric_cmd,
+ "no set metric [(0-4294967295)]",
+ NO_STR
+ SET_STR
+ "Metric value for destination routing protocol\n"
+ "Metric value\n")
+{
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ if (rmap_match_set_hook.no_set_metric)
+ {
+ if (argc <= idx_number)
+ return rmap_match_set_hook.no_set_metric (vty, index, "metric", NULL);
+ return rmap_match_set_hook.no_set_metric (vty, index, "metric", argv[idx_number]->arg);
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (set_tag,
+ set_tag_cmd,
+ "set tag (1-4294967295)",
+ SET_STR
+ "Tag value for routing protocol\n"
+ "Tag value\n")
+{
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ int idx_number = 2;
+ if (rmap_match_set_hook.set_tag)
+ return rmap_match_set_hook.set_tag (vty, index, "tag", argv[idx_number]->arg);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (no_set_tag,
+ no_set_tag_cmd,
+ "no set tag [(1-4294967295)]",
+ NO_STR
+ SET_STR
+ "Tag value for routing protocol\n"
+ "Tag value\n")
+{
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+
+ int idx_number = 3;
+ if (rmap_match_set_hook.no_set_tag)
+ {
+ if (argc <= idx_number)
+ return rmap_match_set_hook.no_set_tag (vty, index, "tag", NULL);
+ return rmap_match_set_hook.no_set_tag (vty, index, "tag", argv[idx_number]->arg);
+ }
+ return CMD_SUCCESS;
+}
+
+
+
+DEFUN (route_map,
+ route_map_cmd,
+ "route-map WORD <deny|permit> (1-65535)",
+ "Create route-map or enter route-map command mode\n"
+ "Route map tag\n"
+ "Route map denies set operations\n"
+ "Route map permits set operations\n"
+ "Sequence to insert to/delete from existing route-map entry\n")
+{
+ int idx_word = 1;
+ int idx_permit_deny = 2;
+ int idx_number = 3;
+ struct route_map *map;
+ struct route_map_index *index;
+ char *endptr = NULL;
+ int permit = argv[idx_permit_deny]->arg[0] == 'p' ? RMAP_PERMIT : RMAP_DENY;
+ unsigned long pref = strtoul (argv[idx_number]->arg, &endptr, 10);
+ const char *mapname = argv[idx_word]->arg;
+
/* Get route map. */
- map = route_map_get (argv[0]);
+ map = route_map_get (mapname);
index = route_map_index_get (map, permit, pref);
- VTY_PUSH_CONTEXT_COMPAT (RMAP_NODE, index);
+ VTY_PUSH_CONTEXT (RMAP_NODE, index);
return CMD_SUCCESS;
}
@@ -1442,13 +2573,14 @@ DEFUN (no_route_map_all,
"Create route-map or enter route-map command mode\n"
"Route map tag\n")
{
+ int idx_word = 2;
+ const char *mapname = argv[idx_word]->arg;
struct route_map *map;
- map = route_map_lookup_by_name (argv[0]);
+ map = route_map_lookup_by_name (mapname);
if (map == NULL)
{
- vty_out (vty, "%% Could not find route-map %s%s",
- argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Could not find route-map %s%s", mapname, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1459,7 +2591,7 @@ DEFUN (no_route_map_all,
DEFUN (no_route_map,
no_route_map_cmd,
- "no route-map WORD (deny|permit) <1-65535>",
+ "no route-map WORD <deny|permit> (1-65535)",
NO_STR
"Create route-map or enter route-map command mode\n"
"Route map tag\n"
@@ -1467,43 +2599,22 @@ DEFUN (no_route_map,
"Route map permits set operations\n"
"Sequence to insert to/delete from existing route-map entry\n")
{
- int permit;
- unsigned long pref;
+ int idx_word = 2;
+ int idx_permit_deny = 3;
+ int idx_number = 4;
struct route_map *map;
struct route_map_index *index;
char *endptr = NULL;
-
- /* Permit check. */
- if (strncmp (argv[1], "permit", strlen (argv[1])) == 0)
- permit = RMAP_PERMIT;
- else if (strncmp (argv[1], "deny", strlen (argv[1])) == 0)
- permit = RMAP_DENY;
- else
- {
- vty_out (vty, "the third field must be [permit|deny]%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Preference. */
- pref = strtoul (argv[2], &endptr, 10);
- if (pref == ULONG_MAX || *endptr != '\0')
- {
- vty_out (vty, "the fourth field must be positive integer%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (pref == 0 || pref > 65535)
- {
- vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ int permit = argv[idx_permit_deny]->arg[0] == 'p' ? RMAP_PERMIT : RMAP_DENY;
+ const char *prefstr = argv[idx_number]->arg;
+ const char *mapname = argv[idx_word]->arg;
+ unsigned long pref = strtoul (prefstr, &endptr, 10);
/* Existence check. */
- map = route_map_lookup_by_name (argv[0]);
+ map = route_map_lookup_by_name (mapname);
if (map == NULL)
{
- vty_out (vty, "%% Could not find route-map %s%s",
- argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Could not find route-map %s%s", mapname, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1512,7 +2623,7 @@ DEFUN (no_route_map,
if (index == NULL)
{
vty_out (vty, "%% Could not find route-map entry %s %s%s",
- argv[0], argv[2], VTY_NEWLINE);
+ mapname, prefstr, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1556,7 +2667,7 @@ DEFUN (no_rmap_onmatch_next,
"Next clause\n")
{
struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
-
+
if (index)
index->exitpolicy = RMAP_EXIT;
@@ -1565,11 +2676,14 @@ DEFUN (no_rmap_onmatch_next,
DEFUN (rmap_onmatch_goto,
rmap_onmatch_goto_cmd,
- "on-match goto <1-65535>",
+ "on-match goto (1-65535)",
"Exit policy on matches\n"
"Goto Clause number\n"
"Number\n")
{
+ int idx = 0;
+ char *num = argv_find (argv, argc, "(1-65535)", &idx) ? argv[idx]->arg : NULL;
+
struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
int d = 0;
@@ -1583,16 +2697,15 @@ DEFUN (rmap_onmatch_goto,
return CMD_WARNING;
}
- if (argc == 1 && argv[0])
- VTY_GET_INTEGER_RANGE("route-map index", d, argv[0], 1, 65535);
+ if (num)
+ VTY_GET_INTEGER_RANGE("route-map index", d, num, 1, 65535);
else
d = index->pref + 1;
if (d <= index->pref)
{
/* Can't allow you to do that, Dave */
- vty_out (vty, "can't jump backwards in route-maps%s",
- VTY_NEWLINE);
+ vty_out (vty, "can't jump backwards in route-maps%s", VTY_NEWLINE);
return CMD_WARNING;
}
else
@@ -1619,31 +2732,28 @@ DEFUN (no_rmap_onmatch_goto,
return CMD_SUCCESS;
}
-/* Cisco/GNU Zebra compatible ALIASes for on-match next */
-ALIAS (rmap_onmatch_goto,
+/* Cisco/GNU Zebra compatibility aliases */
+/* ALIAS_FIXME */
+DEFUN (rmap_continue,
rmap_continue_cmd,
- "continue",
- "Continue on a different entry within the route-map\n")
-
-ALIAS (no_rmap_onmatch_goto,
- no_rmap_continue_cmd,
- "no continue",
- NO_STR
- "Continue on a different entry within the route-map\n")
-
-/* GNU Zebra compatible */
-ALIAS (rmap_onmatch_goto,
- rmap_continue_seq_cmd,
- "continue <1-65535>",
+ "continue (1-65535)",
"Continue on a different entry within the route-map\n"
"Route-map entry sequence number\n")
+{
+ return rmap_onmatch_goto (self, vty, argc, argv);
+}
-ALIAS (no_rmap_onmatch_goto,
- no_rmap_continue_seq,
- "no continue <1-65535>",
+/* ALIAS_FIXME */
+DEFUN (no_rmap_continue,
+ no_rmap_continue_cmd,
+ "no continue [(1-65535)]",
NO_STR
"Continue on a different entry within the route-map\n"
"Route-map entry sequence number\n")
+{
+ return no_rmap_onmatch_goto (self, vty, argc, argv);
+}
+
DEFUN (rmap_show_name,
rmap_show_name_cmd,
@@ -1652,37 +2762,31 @@ DEFUN (rmap_show_name,
"route-map information\n"
"route-map name\n")
{
- const char *name = NULL;
- if (argc)
- name = argv[0];
- return vty_show_route_map (vty, name);
+ int idx_word = 2;
+ const char *name = (argc == 3) ? argv[idx_word]->arg : NULL;
+ return vty_show_route_map (vty, name);
}
-ALIAS (rmap_onmatch_goto,
- rmap_continue_index_cmd,
- "continue <1-65535>",
- "Exit policy on matches\n"
- "Goto Clause number\n")
-
DEFUN (rmap_call,
rmap_call_cmd,
"call WORD",
"Jump to another Route-Map after match+set\n"
"Target route-map name\n")
{
+ int idx_word = 1;
struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
+ const char *rmap = argv[idx_word]->arg;
- if (index)
+ assert(index);
+
+ if (index->nextrm)
{
- if (index->nextrm)
- {
- route_map_upd8_dependency (RMAP_EVENT_CALL_DELETED,
- index->nextrm,
- index->map->name);
- XFREE (MTYPE_ROUTE_MAP_NAME, index->nextrm);
- }
- index->nextrm = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[0]);
+ route_map_upd8_dependency (RMAP_EVENT_CALL_DELETED,
+ index->nextrm,
+ index->map->name);
+ XFREE (MTYPE_ROUTE_MAP_NAME, index->nextrm);
}
+ index->nextrm = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap);
/* Execute event hook. */
route_map_upd8_dependency (RMAP_EVENT_CALL_ADDED,
@@ -1713,17 +2817,18 @@ DEFUN (no_rmap_call,
DEFUN (rmap_description,
rmap_description_cmd,
- "description .LINE",
+ "description LINE...",
"Route-map comment\n"
"Comment describing this route-map rule\n")
{
+ int idx_line = 1;
struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
if (index)
{
if (index->description)
XFREE (MTYPE_TMP, index->description);
- index->description = argv_concat (argv, argc, 0);
+ index->description = argv_concat (argv, argc, idx_line);
}
return CMD_SUCCESS;
}
@@ -1884,11 +2989,10 @@ route_map_init (void)
install_element (RMAP_NODE, &no_rmap_onmatch_next_cmd);
install_element (RMAP_NODE, &rmap_onmatch_goto_cmd);
install_element (RMAP_NODE, &no_rmap_onmatch_goto_cmd);
-
- /* Install the continue stuff (ALIAS of on-match). */
install_element (RMAP_NODE, &rmap_continue_cmd);
install_element (RMAP_NODE, &no_rmap_continue_cmd);
- install_element (RMAP_NODE, &rmap_continue_index_cmd);
+
+ /* Install the continue stuff (ALIAS of on-match). */
/* Install the call stuff. */
install_element (RMAP_NODE, &rmap_call_cmd);
@@ -1900,4 +3004,44 @@ route_map_init (void)
/* Install show command */
install_element (ENABLE_NODE, &rmap_show_name_cmd);
+
+ install_element (RMAP_NODE, &match_interface_cmd);
+ install_element (RMAP_NODE, &no_match_interface_cmd);
+
+ install_element (RMAP_NODE, &match_ip_address_cmd);
+ install_element (RMAP_NODE, &no_match_ip_address_cmd);
+
+ install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
+ install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
+
+ install_element (RMAP_NODE, &match_ip_next_hop_cmd);
+ install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
+
+ install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
+ install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
+
+ install_element (RMAP_NODE, &match_ipv6_address_cmd);
+ install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
+
+ install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
+ install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
+
+ install_element (RMAP_NODE, &match_metric_cmd);
+ install_element (RMAP_NODE, &no_match_metric_cmd);
+
+ install_element (RMAP_NODE, &match_tag_cmd);
+ install_element (RMAP_NODE, &no_match_tag_cmd);
+
+ install_element (RMAP_NODE, &set_ip_nexthop_cmd);
+ install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
+
+ install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
+ install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
+
+ install_element (RMAP_NODE, &set_metric_cmd);
+ install_element (RMAP_NODE, &no_set_metric_cmd);
+
+ install_element (RMAP_NODE, &set_tag_cmd);
+ install_element (RMAP_NODE, &no_set_tag_cmd);
+
}
diff --git a/lib/routemap.h b/lib/routemap.h
index b5cdd27277..b378c64eae 100644
--- a/lib/routemap.h
+++ b/lib/routemap.h
@@ -25,6 +25,8 @@
#include "prefix.h"
#include "memory.h"
#include "qobj.h"
+#include "vty.h"
+
DECLARE_MTYPE(ROUTE_MAP_NAME)
DECLARE_MTYPE(ROUTE_MAP_RULE)
DECLARE_MTYPE(ROUTE_MAP_COMPILED)
@@ -82,6 +84,8 @@ typedef enum
RMAP_EVENT_CLIST_DELETED,
RMAP_EVENT_ECLIST_ADDED,
RMAP_EVENT_ECLIST_DELETED,
+ RMAP_EVENT_LLIST_ADDED,
+ RMAP_EVENT_LLIST_DELETED,
RMAP_EVENT_ASLIST_ADDED,
RMAP_EVENT_ASLIST_DELETED,
RMAP_EVENT_FILTER_ADDED,
@@ -234,6 +238,172 @@ extern void route_map_upd8_dependency (route_map_event_t type, const char *arg,
extern void route_map_notify_dependencies (const char *affected_name,
route_map_event_t event);
+extern int generic_match_add (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+extern int generic_match_delete (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+extern int generic_set_add (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg);
+extern int generic_set_delete (struct vty *vty, struct route_map_index *index,
+ const char *command, const char *arg);
+
+
+/* match interface */
+extern void route_map_match_interface_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* no match interface */
+extern void route_map_no_match_interface_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* match ip address */
+extern void route_map_match_ip_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* no match ip address */
+extern void route_map_no_match_ip_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* match ip address prefix list */
+extern void route_map_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* no match ip address prefix list */
+extern void route_map_no_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* match ip next hop */
+extern void route_map_match_ip_next_hop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* no match ip next hop */
+extern void route_map_no_match_ip_next_hop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* match ip next hop prefix list */
+extern void route_map_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* no match ip next hop prefix list */
+extern void route_map_no_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* match ipv6 address */
+extern void route_map_match_ipv6_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* no match ipv6 address */
+extern void route_map_no_match_ipv6_address_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* match ipv6 address prefix list */
+extern void route_map_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* no match ipv6 address prefix list */
+extern void route_map_no_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* match metric */
+extern void route_map_match_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* no match metric */
+extern void route_map_no_match_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* match tag */
+extern void route_map_match_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* no match tag */
+extern void route_map_no_match_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type));
+/* set ip nexthop */
+extern void route_map_set_ip_nexthop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg));
+/* no set ip nexthop */
+extern void route_map_no_set_ip_nexthop_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg));
+/* set ipv6 nexthop local */
+extern void route_map_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg));
+/* no set ipv6 nexthop local */
+extern void route_map_no_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg));
+/* set metric */
+extern void route_map_set_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg));
+/* no set metric */
+extern void route_map_no_set_metric_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg));
+/* set tag */
+extern void route_map_set_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg));
+/* no set tag */
+extern void route_map_no_set_tag_hook (int (*func) (struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg));
+
extern void *route_map_rule_tag_compile (const char *arg);
extern void route_map_rule_tag_free (void *rule);
diff --git a/lib/smux.c b/lib/smux.c
index a9c99e1545..3abfadcd28 100644
--- a/lib/smux.c
+++ b/lib/smux.c
@@ -154,16 +154,10 @@ static int
smux_socket (void)
{
int ret;
-#ifdef HAVE_IPV6
struct addrinfo hints, *res0, *res;
int gai;
-#else
- struct sockaddr_in serv;
- struct servent *sp;
-#endif
int sock = 0;
-#ifdef HAVE_IPV6
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
@@ -183,9 +177,7 @@ smux_socket (void)
for(res=res0; res; res=res->ai_next)
{
if (res->ai_family != AF_INET
-#ifdef HAVE_IPV6
&& res->ai_family != AF_INET6
-#endif /* HAVE_IPV6 */
)
continue;
@@ -206,40 +198,6 @@ smux_socket (void)
freeaddrinfo(res0);
if (sock < 0)
zlog_warn ("Can't connect to SNMP agent with SMUX");
-#else
- sock = socket (AF_INET, SOCK_STREAM, 0);
- if (sock < 0)
- {
- zlog_warn ("Can't make socket for SNMP");
- return -1;
- }
-
- memset (&serv, 0, sizeof (struct sockaddr_in));
- serv.sin_family = AF_INET;
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- serv.sin_len = sizeof (struct sockaddr_in);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
-
- sp = getservbyname ("smux", "tcp");
- if (sp != NULL)
- serv.sin_port = sp->s_port;
- else
- serv.sin_port = htons (SMUX_PORT_DEFAULT);
-
- serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-
- sockopt_reuseaddr (sock);
- sockopt_reuseport (sock);
-
- ret = connect (sock, (struct sockaddr *) &serv, sizeof (struct sockaddr_in));
- if (ret < 0)
- {
- close (sock);
- smux_sock = -1;
- zlog_warn ("Can't connect to SNMP agent with SMUX");
- return -1;
- }
-#endif
return sock;
}
@@ -1370,7 +1328,8 @@ DEFUN (smux_peer,
"SNMP MUX peer settings\n"
"Object ID used in SMUX peering\n")
{
- if (smux_peer_oid (vty, argv[0], NULL) == 0)
+ int idx_oid = 2;
+ if (smux_peer_oid (vty, argv[idx_oid]->arg, NULL) == 0)
{
smux_start();
return CMD_SUCCESS;
@@ -1387,7 +1346,8 @@ DEFUN (smux_peer_password,
"SMUX peering object ID\n"
"SMUX peering password\n")
{
- if (smux_peer_oid (vty, argv[0], argv[1]) == 0)
+ int idx_oid = 2;
+ if (smux_peer_oid (vty, argv[idx_oid]->arg, argv[3]->rg) == 0)
{
smux_start();
return CMD_SUCCESS;
@@ -1398,32 +1358,17 @@ DEFUN (smux_peer_password,
DEFUN (no_smux_peer,
no_smux_peer_cmd,
- "no smux peer",
+ "no smux peer [OID [PASSWORD]]",
NO_STR
"SNMP MUX protocol settings\n"
- "SNMP MUX peer settings\n")
+ "SNMP MUX peer settings\n"
+ "SMUX peering object ID\n"
+ "SMUX peering password\n")
{
smux_stop();
return smux_peer_default ();
}
-ALIAS (no_smux_peer,
- no_smux_peer_oid_cmd,
- "no smux peer OID",
- NO_STR
- "SNMP MUX protocol settings\n"
- "SNMP MUX peer settings\n"
- "SMUX peering object ID\n")
-
-ALIAS (no_smux_peer,
- no_smux_peer_oid_password_cmd,
- "no smux peer OID PASSWORD",
- NO_STR
- "SNMP MUX protocol settings\n"
- "SNMP MUX peer settings\n"
- "SMUX peering object ID\n"
- "SMUX peering password\n")
-
static int
config_write_smux (struct vty *vty)
{
diff --git a/lib/sockopt.c b/lib/sockopt.c
index e661b4cc56..91b0602b3a 100644
--- a/lib/sockopt.c
+++ b/lib/sockopt.c
@@ -109,7 +109,6 @@ getsockopt_cmsg_data (struct msghdr *msgh, int level, int type)
return NULL;
}
-#ifdef HAVE_IPV6
/* Set IPv6 packet info to the socket. */
int
setsockopt_ipv6_pktinfo (int sock, int val)
@@ -221,7 +220,6 @@ setsockopt_ipv6_tclass(int sock, int tclass)
#endif
return ret;
}
-#endif /* HAVE_IPV6 */
/*
* Process multicast socket options for IPv4 in an OS-dependent manner.
@@ -467,11 +465,9 @@ setsockopt_ifindex (int af, int sock, ifindex_t val)
case AF_INET:
ret = setsockopt_ipv4_ifindex (sock, val);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
ret = setsockopt_ipv6_pktinfo (sock, val);
break;
-#endif
default:
zlog_warn ("setsockopt_ifindex: unknown address family %d", af);
}
@@ -558,11 +554,9 @@ getsockopt_ifindex (int af, struct msghdr *msgh)
case AF_INET:
return (getsockopt_ipv4_ifindex (msgh));
break;
-#ifdef HAVE_IPV6
case AF_INET6:
return (getsockopt_ipv6_ifindex (msgh));
break;
-#endif
default:
zlog_warn ("getsockopt_ifindex: unknown address family %d", af);
return 0;
@@ -669,7 +663,6 @@ sockopt_tcp_signature (int sock, union sockunion *su, const char *password)
return 0;
}
-#ifdef HAVE_IPV6
/* If this does not work, then all users of this sockopt will need to
* differentiate between IPv4 and IPv6, and keep seperate sockets for
* each.
@@ -686,7 +679,6 @@ sockopt_tcp_signature (int sock, union sockunion *su, const char *password)
su2->sin6.sin6_addr.s6_addr32[2] = htonl(0xffff);
memcpy (&su2->sin6.sin6_addr.s6_addr32[3], &su->sin.sin_addr, 4);
}
-#endif
}
memset (&md5sig, 0, sizeof (md5sig));
diff --git a/lib/sockopt.h b/lib/sockopt.h
index 7e1bd62446..d5724ce60f 100644
--- a/lib/sockopt.h
+++ b/lib/sockopt.h
@@ -32,7 +32,6 @@ extern void setsockopt_so_recvbuf (int sock, int size);
extern void setsockopt_so_sendbuf (const int sock, int size);
extern int getsockopt_so_sendbuf (const int sock);
-#ifdef HAVE_IPV6
extern int setsockopt_ipv6_pktinfo (int, int);
extern int setsockopt_ipv6_checksum (int, int);
extern int setsockopt_ipv6_multicast_hops (int, int);
@@ -40,13 +39,7 @@ extern int setsockopt_ipv6_unicast_hops (int, int);
extern int setsockopt_ipv6_hoplimit (int, int);
extern int setsockopt_ipv6_multicast_loop (int, int);
extern int setsockopt_ipv6_tclass (int, int);
-#endif /* HAVE_IPV6 */
-/*
- * It is OK to reference in6_pktinfo here without a protecting #if
- * because this macro will only be used #if HAVE_IPV6, and in6_pktinfo
- * is not optional for HAVE_IPV6.
- */
#define SOPT_SIZE_CMSG_PKTINFO_IPV6() (sizeof (struct in6_pktinfo));
/*
diff --git a/lib/sockunion.c b/lib/sockunion.c
index f4b6ce12cc..5b508d1bf8 100644
--- a/lib/sockunion.c
+++ b/lib/sockunion.c
@@ -38,11 +38,9 @@ inet_sutop (const union sockunion *su, char *str)
case AF_INET:
inet_ntop (AF_INET, &su->sin.sin_addr, str, INET_ADDRSTRLEN);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
inet_ntop (AF_INET6, &su->sin6.sin6_addr, str, INET6_ADDRSTRLEN);
break;
-#endif /* HAVE_IPV6 */
}
return str;
}
@@ -63,7 +61,6 @@ str2sockunion (const char *str, union sockunion *su)
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
return 0;
}
-#ifdef HAVE_IPV6
ret = inet_pton (AF_INET6, str, &su->sin6.sin6_addr);
if (ret > 0) /* Valid IPv6 address format. */
{
@@ -73,7 +70,6 @@ str2sockunion (const char *str, union sockunion *su)
#endif /* SIN6_LEN */
return 0;
}
-#endif /* HAVE_IPV6 */
return -1;
}
@@ -87,10 +83,8 @@ sockunion2str (const union sockunion *su, char *buf, size_t len)
return buf;
case AF_INET:
return inet_ntop (AF_INET, &su->sin.sin_addr, buf, len);
-#ifdef HAVE_IPV6
case AF_INET6:
return inet_ntop (AF_INET6, &su->sin6.sin6_addr, buf, len);
-#endif /* HAVE_IPV6 */
}
snprintf (buf, len, "(af %d)", sockunion_family(su));
return buf;
@@ -114,7 +108,6 @@ sockunion_normalise_mapped (union sockunion *su)
{
struct sockaddr_in sin;
-#ifdef HAVE_IPV6
if (su->sa.sa_family == AF_INET6
&& IN6_IS_ADDR_V4MAPPED (&su->sin6.sin6_addr))
{
@@ -124,7 +117,6 @@ sockunion_normalise_mapped (union sockunion *su)
memcpy (&sin.sin_addr, ((char *)&su->sin6.sin6_addr) + 12, 4);
memcpy (su, &sin, sizeof (struct sockaddr_in));
}
-#endif /* HAVE_IPV6 */
}
/* return sockunion structure : this function should be revised. */
@@ -190,11 +182,9 @@ sockunion_sizeof (const union sockunion *su)
case AF_INET:
ret = sizeof (struct sockaddr_in);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
ret = sizeof (struct sockaddr_in6);
break;
-#endif /* AF_INET6 */
}
return ret;
}
@@ -218,7 +208,6 @@ sockunion_connect (int fd, const union sockunion *peersu, unsigned short port,
case AF_INET:
su.sin.sin_port = port;
break;
-#ifdef HAVE_IPV6
case AF_INET6:
su.sin6.sin6_port = port;
#ifdef KAME
@@ -229,7 +218,6 @@ sockunion_connect (int fd, const union sockunion *peersu, unsigned short port,
}
#endif /* KAME */
break;
-#endif /* HAVE_IPV6 */
}
/* Make socket non-block. */
@@ -299,7 +287,6 @@ sockunion_bind (int sock, union sockunion *su, unsigned short port,
if (su_addr == NULL)
sockunion2ip (su) = htonl (INADDR_ANY);
}
-#ifdef HAVE_IPV6
else if (su->sa.sa_family == AF_INET6)
{
size = sizeof (struct sockaddr_in6);
@@ -316,8 +303,6 @@ sockunion_bind (int sock, union sockunion *su, unsigned short port,
#endif /* LINUX_IPV6 */
}
}
-#endif /* HAVE_IPV6 */
-
ret = bind (sock, (struct sockaddr *)su, size);
if (ret < 0)
@@ -388,7 +373,6 @@ sockopt_ttl (int family, int sock, int ttl)
return 0;
}
#endif /* IP_TTL */
-#ifdef HAVE_IPV6
if (family == AF_INET6)
{
ret = setsockopt (sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
@@ -401,7 +385,6 @@ sockopt_ttl (int family, int sock, int ttl)
}
return 0;
}
-#endif /* HAVE_IPV6 */
return 0;
}
@@ -469,7 +452,6 @@ sockopt_v6only (int family, int sock)
{
int ret, on = 1;
-#ifdef HAVE_IPV6
#ifdef IPV6_V6ONLY
if (family == AF_INET6)
{
@@ -484,7 +466,6 @@ sockopt_v6only (int family, int sock)
return 0;
}
#endif /* IPV6_V6ONLY */
-#endif /* HAVE_IPV6 */
return 0;
}
@@ -503,7 +484,6 @@ sockunion_same (const union sockunion *su1, const union sockunion *su2)
ret = memcmp (&su1->sin.sin_addr, &su2->sin.sin_addr,
sizeof (struct in_addr));
break;
-#ifdef HAVE_IPV6
case AF_INET6:
ret = memcmp (&su1->sin6.sin6_addr, &su2->sin6.sin6_addr,
sizeof (struct in6_addr));
@@ -514,7 +494,6 @@ sockunion_same (const union sockunion *su1, const union sockunion *su2)
ret = (su1->sin6.sin6_scope_id == su2->sin6.sin6_scope_id) ? 0 : 1;
}
break;
-#endif /* HAVE_IPV6 */
}
if (ret == 0)
return 1;
@@ -529,10 +508,8 @@ sockunion_hash (const union sockunion *su)
{
case AF_INET:
return jhash_1word(su->sin.sin_addr.s_addr, 0);
-#ifdef HAVE_IPV6
case AF_INET6:
return jhash2(su->sin6.sin6_addr.s6_addr32, ZEBRA_NUM_OF(su->sin6.sin6_addr.s6_addr32), 0);
-#endif /* HAVE_IPV6 */
}
return 0;
}
@@ -544,10 +521,8 @@ family2addrsize(int family)
{
case AF_INET:
return sizeof(struct in_addr);
-#ifdef HAVE_IPV6
case AF_INET6:
return sizeof(struct in6_addr);
-#endif /* HAVE_IPV6 */
}
return 0;
}
@@ -565,10 +540,8 @@ sockunion_get_addr(const union sockunion *su)
{
case AF_INET:
return (const u_char *) &su->sin.sin_addr.s_addr;
-#ifdef HAVE_IPV6
case AF_INET6:
return (const u_char *) &su->sin6.sin6_addr;
-#endif /* HAVE_IPV6 */
}
return NULL;
}
@@ -585,11 +558,9 @@ sockunion_set(union sockunion *su, int family, const u_char *addr, size_t bytes)
case AF_INET:
memcpy(&su->sin.sin_addr.s_addr, addr, bytes);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
memcpy(&su->sin6.sin6_addr, addr, bytes);
break;
-#endif /* HAVE_IPV6 */
}
}
@@ -603,9 +574,7 @@ sockunion_getsockname (int fd)
{
struct sockaddr sa;
struct sockaddr_in sin;
-#ifdef HAVE_IPV6
struct sockaddr_in6 sin6;
-#endif /* HAVE_IPV6 */
char tmp_buffer[128];
} name;
union sockunion *su;
@@ -627,7 +596,6 @@ sockunion_getsockname (int fd)
memcpy (su, &name, sizeof (struct sockaddr_in));
return su;
}
-#ifdef HAVE_IPV6
if (name.sa.sa_family == AF_INET6)
{
su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion));
@@ -635,7 +603,6 @@ sockunion_getsockname (int fd)
sockunion_normalise_mapped (su);
return su;
}
-#endif /* HAVE_IPV6 */
return NULL;
}
@@ -649,9 +616,7 @@ sockunion_getpeername (int fd)
{
struct sockaddr sa;
struct sockaddr_in sin;
-#ifdef HAVE_IPV6
struct sockaddr_in6 sin6;
-#endif /* HAVE_IPV6 */
char tmp_buffer[128];
} name;
union sockunion *su;
@@ -672,7 +637,6 @@ sockunion_getpeername (int fd)
memcpy (su, &name, sizeof (struct sockaddr_in));
return su;
}
-#ifdef HAVE_IPV6
if (name.sa.sa_family == AF_INET6)
{
su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion));
@@ -680,7 +644,6 @@ sockunion_getpeername (int fd)
sockunion_normalise_mapped (su);
return su;
}
-#endif /* HAVE_IPV6 */
return NULL;
}
@@ -696,7 +659,6 @@ sockunion_print (const union sockunion *su)
case AF_INET:
printf ("%s\n", inet_ntoa (su->sin.sin_addr));
break;
-#ifdef HAVE_IPV6
case AF_INET6:
{
char buf [SU_ADDRSTRLEN];
@@ -705,7 +667,6 @@ sockunion_print (const union sockunion *su)
buf, sizeof (buf)));
}
break;
-#endif /* HAVE_IPV6 */
#ifdef AF_LINK
case AF_LINK:
@@ -723,7 +684,6 @@ sockunion_print (const union sockunion *su)
}
}
-#ifdef HAVE_IPV6
static int
in6addr_cmp (const struct in6_addr *addr1, const struct in6_addr *addr2)
{
@@ -742,7 +702,6 @@ in6addr_cmp (const struct in6_addr *addr1, const struct in6_addr *addr2)
}
return 0;
}
-#endif /* HAVE_IPV6 */
int
sockunion_cmp (const union sockunion *su1, const union sockunion *su2)
@@ -761,10 +720,8 @@ sockunion_cmp (const union sockunion *su1, const union sockunion *su2)
else
return -1;
}
-#ifdef HAVE_IPV6
if (su1->sa.sa_family == AF_INET6)
return in6addr_cmp (&su1->sin6.sin6_addr, &su2->sin6.sin6_addr);
-#endif /* HAVE_IPV6 */
return 0;
}
diff --git a/lib/sockunion.h b/lib/sockunion.h
index 3af3d78059..bed68e1ee1 100644
--- a/lib/sockunion.h
+++ b/lib/sockunion.h
@@ -47,11 +47,7 @@ enum connect_result
};
/* Default address family. */
-#ifdef HAVE_IPV6
#define AF_INET_UNION AF_INET6
-#else
-#define AF_INET_UNION AF_INET
-#endif
/* Sockunion address string length. Same as INET6_ADDRSTRLEN. */
#define SU_ADDRSTRLEN 46
diff --git a/lib/srcdest_table.c b/lib/srcdest_table.c
new file mode 100644
index 0000000000..dd148fa41d
--- /dev/null
+++ b/lib/srcdest_table.c
@@ -0,0 +1,312 @@
+/*
+ * SRC-DEST Routing Table
+ *
+ * Copyright (C) 2017 by David Lamparter & Christian Franke,
+ * Open Source Routing / NetDEF Inc.
+ *
+ * This file is part of FreeRangeRouting (FRR)
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FRR; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "srcdest_table.h"
+
+#include "memory.h"
+#include "prefix.h"
+#include "table.h"
+
+DEFINE_MTYPE_STATIC(LIB, ROUTE_SRC_NODE, "Route source node")
+
+/* ----- functions to manage rnodes _with_ srcdest table ----- */
+struct srcdest_rnode
+{
+ /* must be first in structure for casting to/from route_node */
+ ROUTE_NODE_FIELDS;
+
+ struct route_table *src_table;
+};
+
+static struct srcdest_rnode *
+srcdest_rnode_from_rnode (struct route_node *rn)
+{
+ assert (rnode_is_dstnode (rn));
+ return (struct srcdest_rnode *) rn;
+}
+
+static struct route_node *
+srcdest_rnode_to_rnode (struct srcdest_rnode *srn)
+{
+ return (struct route_node *) srn;
+}
+
+static struct route_node *
+srcdest_rnode_create (route_table_delegate_t *delegate,
+ struct route_table *table)
+{
+ struct srcdest_rnode *srn;
+ srn = XCALLOC (MTYPE_ROUTE_NODE, sizeof (struct srcdest_rnode));
+ return srcdest_rnode_to_rnode(srn);
+}
+
+static void
+srcdest_rnode_destroy (route_table_delegate_t *delegate,
+ struct route_table *table, struct route_node *rn)
+{
+ struct srcdest_rnode *srn = srcdest_rnode_from_rnode(rn);
+ struct route_table *src_table;
+
+ /* Clear route node's src_table here already, otherwise the
+ * deletion of the last node in the src_table will trigger
+ * another call to route_table_finish for the src_table.
+ *
+ * (Compare with srcdest_srcnode_destroy)
+ */
+ src_table = srn->src_table;
+ srn->src_table = NULL;
+ route_table_finish(src_table);
+ XFREE (MTYPE_ROUTE_NODE, rn);
+}
+
+route_table_delegate_t _srcdest_dstnode_delegate = {
+ .create_node = srcdest_rnode_create,
+ .destroy_node = srcdest_rnode_destroy
+};
+
+/* ----- functions to manage rnodes _in_ srcdest table ----- */
+
+/* node creation / deletion for srcdest source prefix nodes.
+ * the route_node isn't actually different from the normal route_node,
+ * but the cleanup is special to free the table (and possibly the
+ * destination prefix's route_node) */
+
+static struct route_node *
+srcdest_srcnode_create (route_table_delegate_t *delegate,
+ struct route_table *table)
+{
+ return XCALLOC (MTYPE_ROUTE_SRC_NODE, sizeof (struct route_node));
+}
+
+static void
+srcdest_srcnode_destroy (route_table_delegate_t *delegate,
+ struct route_table *table, struct route_node *rn)
+{
+ struct srcdest_rnode *srn;
+
+ XFREE (MTYPE_ROUTE_SRC_NODE, rn);
+
+ srn = table->info;
+ if (srn->src_table && route_table_count (srn->src_table) == 0)
+ {
+ /* deleting the route_table from inside destroy_node is ONLY
+ * permitted IF table->count is 0! see lib/table.c route_node_delete()
+ * for details */
+ route_table_finish (srn->src_table);
+ srn->src_table = NULL;
+
+ /* drop the ref we're holding in srcdest_node_get(). there might be
+ * non-srcdest routes, so the route_node may still exist. hence, it's
+ * important to clear src_table above. */
+ route_unlock_node (srcdest_rnode_to_rnode (srn));
+ }
+}
+
+route_table_delegate_t _srcdest_srcnode_delegate = {
+ .create_node = srcdest_srcnode_create,
+ .destroy_node = srcdest_srcnode_destroy
+};
+
+/* NB: read comments in code for refcounting before using! */
+static struct route_node *
+srcdest_srcnode_get (struct route_node *rn, struct prefix_ipv6 *src_p)
+{
+ struct srcdest_rnode *srn;
+
+ if (!src_p || src_p->prefixlen == 0)
+ return rn;
+
+ srn = srcdest_rnode_from_rnode (rn);
+ if (!srn->src_table)
+ {
+ /* this won't use srcdest_rnode, we're already on the source here */
+ srn->src_table = route_table_init_with_delegate (&_srcdest_srcnode_delegate);
+ srn->src_table->info = srn;
+
+ /* there is no route_unlock_node on the original rn here.
+ * The reference is kept for the src_table. */
+ }
+ else
+ {
+ /* only keep 1 reference for the src_table, makes the refcounting
+ * more similar to the non-srcdest case. Either way after return from
+ * function, the only reference held is the one on the return value.
+ *
+ * We can safely drop our reference here because src_table is holding
+ * another reference, so this won't free rn */
+ route_unlock_node (rn);
+ }
+
+ return route_node_get (srn->src_table, (struct prefix *)src_p);
+}
+
+static struct route_node *
+srcdest_srcnode_lookup (struct route_node *rn, struct prefix_ipv6 *src_p)
+{
+ struct srcdest_rnode *srn;
+
+ if (!rn || !src_p || src_p->prefixlen == 0)
+ return rn;
+
+ /* We got this rn from a lookup, so its refcnt was incremented. As we won't
+ * return return rn from any point beyond here, we should decrement its refcnt.
+ */
+ route_unlock_node (rn);
+
+ srn = srcdest_rnode_from_rnode (rn);
+ if (!srn->src_table)
+ return NULL;
+
+ return route_node_lookup (srn->src_table, (struct prefix *)src_p);
+}
+
+/* ----- exported functions ----- */
+
+struct route_table *
+srcdest_table_init(void)
+{
+ return route_table_init_with_delegate(&_srcdest_dstnode_delegate);
+}
+
+struct route_node *
+srcdest_route_next(struct route_node *rn)
+{
+ struct route_node *next, *parent;
+
+ /* For a non src-dest node, just return route_next */
+ if (!(rnode_is_dstnode(rn) || rnode_is_srcnode(rn)))
+ return route_next(rn);
+
+ if (rnode_is_dstnode(rn))
+ {
+ /* This means the route_node is part of the top hierarchy
+ * and refers to a destination prefix. */
+ struct srcdest_rnode *srn = srcdest_rnode_from_rnode(rn);
+
+ if (srn->src_table)
+ next = route_top(srn->src_table);
+ else
+ next = NULL;
+
+ if (next)
+ {
+ /* There is a source prefix. Return the node for it */
+ route_unlock_node(rn);
+ return next;
+ }
+ else
+ {
+ /* There is no source prefix, just continue as usual */
+ return route_next(rn);
+ }
+ }
+
+ /* This part handles the case of iterating source nodes. */
+ parent = route_lock_node(rn->table->info);
+ next = route_next(rn);
+
+ if (next)
+ {
+ /* There is another source node, continue in the source table */
+ route_unlock_node(parent);
+ return next;
+ }
+ else
+ {
+ /* The source table is complete, continue in the parent table */
+ return route_next(parent);
+ }
+}
+
+struct route_node *
+srcdest_rnode_get (struct route_table *table, union prefix46ptr dst_pu,
+ struct prefix_ipv6 *src_p)
+{
+ struct prefix_ipv6 *dst_p = dst_pu.p6;
+ struct route_node *rn;
+
+ rn = route_node_get (table, (struct prefix *) dst_p);
+ return srcdest_srcnode_get (rn, src_p);
+}
+
+struct route_node *
+srcdest_rnode_lookup (struct route_table *table, union prefix46ptr dst_pu,
+ struct prefix_ipv6 *src_p)
+{
+ struct prefix_ipv6 *dst_p = dst_pu.p6;
+ struct route_node *rn;
+ struct route_node *srn;
+
+ rn = route_node_lookup_maynull (table, (struct prefix *) dst_p);
+ srn = srcdest_srcnode_lookup (rn, src_p);
+
+ if (rn != NULL && rn == srn && !rn->info)
+ {
+ /* Match the behavior of route_node_lookup and don't return an
+ * empty route-node for a dest-route */
+ route_unlock_node(rn);
+ return NULL;
+ }
+ return srn;
+}
+
+void
+srcdest_rnode_prefixes (struct route_node *rn, struct prefix **p,
+ struct prefix **src_p)
+{
+ if (rnode_is_srcnode (rn))
+ {
+ struct route_node *dst_rn = rn->table->info;
+ if (p)
+ *p = &dst_rn->p;
+ if (src_p)
+ *src_p = &rn->p;
+ }
+ else
+ {
+ if (p)
+ *p = &rn->p;
+ if (src_p)
+ *src_p = NULL;
+ }
+}
+
+const char *
+srcdest_rnode2str (struct route_node *rn, char *str, int size)
+{
+ struct prefix *dst_p, *src_p;
+ char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN];
+
+ srcdest_rnode_prefixes(rn, &dst_p, &src_p);
+
+ snprintf(str, size, "%s%s%s",
+ prefix2str(dst_p, dst_buf, sizeof(dst_buf)),
+ (src_p && src_p->prefixlen) ? " from " : "",
+ (src_p && src_p->prefixlen) ? prefix2str(src_p, src_buf,
+ sizeof(src_buf))
+ : "");
+ return str;
+}
diff --git a/lib/srcdest_table.h b/lib/srcdest_table.h
new file mode 100644
index 0000000000..59111b5d17
--- /dev/null
+++ b/lib/srcdest_table.h
@@ -0,0 +1,101 @@
+/*
+ * SRC-DEST Routing Table
+ *
+ * Copyright (C) 2017 by David Lamparter & Christian Franke,
+ * Open Source Routing / NetDEF Inc.
+ *
+ * This file is part of FreeRangeRouting (FRR)
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FRR; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _ZEBRA_SRC_DEST_TABLE_H
+#define _ZEBRA_SRC_DEST_TABLE_H
+
+/* old/IPv4/non-srcdest:
+ * table -> route_node .info -> [obj]
+ *
+ * new/IPv6/srcdest:
+ * table -...-> srcdest_rnode [prefix = dest] .info -> [obj]
+ * .src_table ->
+ * srcdest table -...-> route_node [prefix = src] .info -> [obj]
+ *
+ * non-srcdest routes (src = ::/0) are treated just like before, their
+ * information being directly there in the info pointer.
+ *
+ * srcdest routes are found by looking up destination first, then looking
+ * up the source in the "src_table". src_table contains normal route_nodes,
+ * whose prefix is the _source_ prefix.
+ *
+ * NB: info can be NULL on the destination rnode, if there are only srcdest
+ * routes for a particular destination prefix.
+ */
+
+#include "prefix.h"
+#include "table.h"
+
+#define SRCDEST2STR_BUFFER (2*PREFIX2STR_BUFFER + sizeof(" from "))
+
+/* extended route node for IPv6 srcdest routing */
+struct srcdest_rnode;
+
+extern route_table_delegate_t _srcdest_dstnode_delegate;
+extern route_table_delegate_t _srcdest_srcnode_delegate;
+
+extern struct route_table *srcdest_table_init(void);
+extern struct route_node *srcdest_rnode_get(struct route_table *table,
+ union prefix46ptr dst_pu,
+ struct prefix_ipv6 *src_p);
+extern struct route_node *srcdest_rnode_lookup(struct route_table *table,
+ union prefix46ptr dst_pu,
+ struct prefix_ipv6 *src_p);
+extern void srcdest_rnode_prefixes (struct route_node *rn, struct prefix **p,
+ struct prefix **src_p);
+extern const char *srcdest_rnode2str(struct route_node *rn, char *str, int size);
+extern struct route_node *srcdest_route_next(struct route_node *rn);
+
+static inline int
+rnode_is_dstnode (struct route_node *rn)
+{
+ return rn->table->delegate == &_srcdest_dstnode_delegate;
+}
+
+static inline int
+rnode_is_srcnode (struct route_node *rn)
+{
+ return rn->table->delegate == &_srcdest_srcnode_delegate;
+}
+
+static inline struct route_table *
+srcdest_rnode_table (struct route_node *rn)
+{
+ if (rnode_is_srcnode (rn))
+ {
+ struct route_node *dst_rn = rn->table->info;
+ return dst_rn->table;
+ }
+ else
+ {
+ return rn->table;
+ }
+}
+static inline void *
+srcdest_rnode_table_info (struct route_node *rn)
+{
+ return srcdest_rnode_table(rn)->info;
+}
+
+#endif /* _ZEBRA_SRC_DEST_TABLE_H */
diff --git a/lib/table.c b/lib/table.c
index 5133ef6974..7f789dd3cd 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -28,7 +28,7 @@
#include "sockunion.h"
DEFINE_MTYPE( LIB, ROUTE_TABLE, "Route table")
-DEFINE_MTYPE_STATIC(LIB, ROUTE_NODE, "Route node")
+DEFINE_MTYPE( LIB, ROUTE_NODE, "Route node")
static void route_node_delete (struct route_node *);
static void route_table_free (struct route_table *);
@@ -78,6 +78,8 @@ route_node_set (struct route_table *table, const struct prefix *prefix)
static void
route_node_free (struct route_table *table, struct route_node *node)
{
+ if (table->cleanup)
+ table->cleanup(table, node);
table->delegate->destroy_node (table->delegate, table, node);
}
@@ -250,7 +252,6 @@ route_node_match_ipv4 (const struct route_table *table,
return route_node_match (table, (struct prefix *) &p);
}
-#ifdef HAVE_IPV6
struct route_node *
route_node_match_ipv6 (const struct route_table *table,
const struct in6_addr *addr)
@@ -264,7 +265,6 @@ route_node_match_ipv6 (const struct route_table *table,
return route_node_match (table, (struct prefix *) &p);
}
-#endif /* HAVE_IPV6 */
/* Lookup same prefix node. Return NULL when we can't find route. */
struct route_node *
@@ -288,6 +288,28 @@ route_node_lookup (const struct route_table *table, const struct prefix *p)
return NULL;
}
+/* Lookup same prefix node. Return NULL when we can't find route. */
+struct route_node *
+route_node_lookup_maynull (const struct route_table *table, const struct prefix *p)
+{
+ struct route_node *node;
+ u_char prefixlen = p->prefixlen;
+ const u_char *prefix = &p->u.prefix;
+
+ node = table->top;
+
+ while (node && node->p.prefixlen <= prefixlen &&
+ prefix_match (&node->p, p))
+ {
+ if (node->p.prefixlen == prefixlen)
+ return route_lock_node (node);
+
+ node = node->link[prefix_bit(prefix, node->p.prefixlen)];
+ }
+
+ return NULL;
+}
+
/* Add node to routing table. */
struct route_node *
route_node_get (struct route_table *const table, const struct prefix *p)
@@ -380,6 +402,14 @@ route_node_delete (struct route_node *node)
node->table->count--;
+ /* WARNING: FRAGILE CODE!
+ * route_node_free may have the side effect of free'ing the entire table.
+ * this is permitted only if table->count got decremented to zero above,
+ * because in that case parent will also be NULL, so that we won't try to
+ * delete a now-stale parent below.
+ *
+ * cf. srcdest_srcnode_destroy() in zebra/zebra_rib.c */
+
route_node_free (node->table, node);
/* If parent node is stub then delete it also. */
diff --git a/lib/table.h b/lib/table.h
index 78bf5da748..1691a8e20a 100644
--- a/lib/table.h
+++ b/lib/table.h
@@ -25,6 +25,7 @@
#include "memory.h"
DECLARE_MTYPE(ROUTE_TABLE)
+DECLARE_MTYPE(ROUTE_NODE)
/*
* Forward declarations.
@@ -61,6 +62,7 @@ struct route_table
* Delegate that performs certain functions for this table.
*/
route_table_delegate_t *delegate;
+ void (*cleanup)(struct route_table *, struct route_node *);
unsigned long count;
@@ -157,15 +159,15 @@ extern struct route_node *route_node_get (struct route_table *const,
const struct prefix *);
extern struct route_node *route_node_lookup (const struct route_table *,
const struct prefix *);
+extern struct route_node *route_node_lookup_maynull (const struct route_table *,
+ const struct prefix *);
extern struct route_node *route_lock_node (struct route_node *node);
extern struct route_node *route_node_match (const struct route_table *,
const struct prefix *);
extern struct route_node *route_node_match_ipv4 (const struct route_table *,
const struct in_addr *);
-#ifdef HAVE_IPV6
extern struct route_node *route_node_match_ipv6 (const struct route_table *,
const struct in6_addr *);
-#endif /* HAVE_IPV6 */
extern unsigned long route_table_count (const struct route_table *);
diff --git a/lib/thread.c b/lib/thread.c
index 5b8778b717..c1558a83e1 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -41,151 +41,16 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats")
#include <mach/mach_time.h>
#endif
-/* Recent absolute time of day */
-struct timeval recent_time;
/* Relative time, since startup */
-static struct timeval relative_time;
-
static struct hash *cpu_record = NULL;
-/* Adjust so that tv_usec is in the range [0,TIMER_SECOND_MICRO).
- And change negative values to 0. */
-static struct timeval
-timeval_adjust (struct timeval a)
-{
- while (a.tv_usec >= TIMER_SECOND_MICRO)
- {
- a.tv_usec -= TIMER_SECOND_MICRO;
- a.tv_sec++;
- }
-
- while (a.tv_usec < 0)
- {
- a.tv_usec += TIMER_SECOND_MICRO;
- a.tv_sec--;
- }
-
- if (a.tv_sec < 0)
- /* Change negative timeouts to 0. */
- a.tv_sec = a.tv_usec = 0;
-
- return a;
-}
-
-static struct timeval
-timeval_subtract (struct timeval a, struct timeval b)
-{
- struct timeval ret;
-
- ret.tv_usec = a.tv_usec - b.tv_usec;
- ret.tv_sec = a.tv_sec - b.tv_sec;
-
- return timeval_adjust (ret);
-}
-
-static long
-timeval_cmp (struct timeval a, struct timeval b)
-{
- return (a.tv_sec == b.tv_sec
- ? a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
-}
-
-unsigned long
+static unsigned long
timeval_elapsed (struct timeval a, struct timeval b)
{
return (((a.tv_sec - b.tv_sec) * TIMER_SECOND_MICRO)
+ (a.tv_usec - b.tv_usec));
}
-/* gettimeofday wrapper, to keep recent_time updated */
-static int
-quagga_gettimeofday (struct timeval *tv)
-{
- int ret;
-
- assert (tv);
-
- if (!(ret = gettimeofday (&recent_time, NULL)))
- {
- /* avoid copy if user passed recent_time pointer.. */
- if (tv != &recent_time)
- *tv = recent_time;
- return 0;
- }
- return ret;
-}
-
-static int
-quagga_get_relative (struct timeval *tv)
-{
- int ret;
-
-#ifdef HAVE_CLOCK_MONOTONIC
- {
- struct timespec tp;
- if (!(ret = clock_gettime (CLOCK_MONOTONIC, &tp)))
- {
- relative_time.tv_sec = tp.tv_sec;
- relative_time.tv_usec = tp.tv_nsec / 1000;
- }
- }
-#elif defined(__APPLE__)
- {
- uint64_t ticks;
- uint64_t useconds;
- static mach_timebase_info_data_t timebase_info;
-
- ticks = mach_absolute_time();
- if (timebase_info.denom == 0)
- mach_timebase_info(&timebase_info);
-
- useconds = ticks * timebase_info.numer / timebase_info.denom / 1000;
- relative_time.tv_sec = useconds / 1000000;
- relative_time.tv_usec = useconds % 1000000;
-
- return 0;
- }
-#else /* !HAVE_CLOCK_MONOTONIC && !__APPLE__ */
-#error no monotonic clock on this system
-#endif /* HAVE_CLOCK_MONOTONIC */
-
- if (tv)
- *tv = relative_time;
-
- return ret;
-}
-
-/* Exported Quagga timestamp function.
- * Modelled on POSIX clock_gettime.
- */
-int
-quagga_gettime (enum quagga_clkid clkid, struct timeval *tv)
-{
- switch (clkid)
- {
- case QUAGGA_CLK_MONOTONIC:
- return quagga_get_relative (tv);
- default:
- errno = EINVAL;
- return -1;
- }
-}
-
-time_t
-quagga_monotime (void)
-{
- struct timeval tv;
- quagga_get_relative(&tv);
- return tv.tv_sec;
-}
-
-/* Public export of recent_relative_time by value */
-struct timeval
-recent_relative_time (void)
-{
- return relative_time;
-}
-
static unsigned int
cpu_record_hash_key (struct cpu_thread_history *a)
{
@@ -221,8 +86,8 @@ static void
vty_out_cpu_thread_history(struct vty* vty,
struct cpu_thread_history *a)
{
- vty_out(vty, "%10ld.%03ld %9d %8ld %9ld %8ld %9ld",
- a->cpu.total/1000, a->cpu.total%1000, a->total_calls,
+ vty_out(vty, "%5d %10ld.%03ld %9d %8ld %9ld %8ld %9ld",
+ a->total_active, a->cpu.total/1000, a->cpu.total%1000, a->total_calls,
a->cpu.total/a->total_calls, a->cpu.max,
a->real.total/a->total_calls, a->real.max);
vty_out(vty, " %c%c%c%c%c%c %s%s",
@@ -247,6 +112,7 @@ cpu_record_hash_print(struct hash_backet *bucket,
if ( !(a->types & *filter) )
return;
vty_out_cpu_thread_history(vty,a);
+ totals->total_active += a->total_active;
totals->total_calls += a->total_calls;
totals->real.total += a->real.total;
if (totals->real.max < a->real.max)
@@ -268,7 +134,7 @@ cpu_record_print(struct vty *vty, thread_type filter)
vty_out(vty, "%21s %18s %18s%s",
"", "CPU (user+system):", "Real (wall-clock):", VTY_NEWLINE);
- vty_out(vty, " Runtime(ms) Invoked Avg uSec Max uSecs");
+ vty_out(vty, "Active Runtime(ms) Invoked Avg uSec Max uSecs");
vty_out(vty, " Avg uSec Max uSecs");
vty_out(vty, " Type Thread%s", VTY_NEWLINE);
hash_iterate(cpu_record,
@@ -287,15 +153,16 @@ DEFUN (show_thread_cpu,
"Thread CPU usage\n"
"Display filter (rwtexb)\n")
{
+ int idx_filter = 3;
int i = 0;
thread_type filter = (thread_type) -1U;
- if (argc > 0)
+ if (argc > 3)
{
filter = 0;
- while (argv[0][i] != '\0')
+ while (argv[idx_filter]->arg[i] != '\0')
{
- switch ( argv[0][i] )
+ switch ( argv[idx_filter]->arg[i] )
{
case 'r':
case 'R':
@@ -330,7 +197,7 @@ DEFUN (show_thread_cpu,
{
vty_out(vty, "Invalid filter \"%s\" specified,"
" must contain at least one of 'RWTEXB'%s",
- argv[0], VTY_NEWLINE);
+ argv[idx_filter]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
}
@@ -369,15 +236,16 @@ DEFUN (clear_thread_cpu,
"Thread CPU usage\n"
"Display filter (rwtexb)\n")
{
+ int idx_filter = 3;
int i = 0;
thread_type filter = (thread_type) -1U;
- if (argc > 0)
+ if (argc > 3)
{
filter = 0;
- while (argv[0][i] != '\0')
+ while (argv[idx_filter]->arg[i] != '\0')
{
- switch ( argv[0][i] )
+ switch ( argv[idx_filter]->arg[i] )
{
case 'r':
case 'R':
@@ -412,7 +280,7 @@ DEFUN (clear_thread_cpu,
{
vty_out(vty, "Invalid filter \"%s\" specified,"
" must contain at least one of 'RWTEXB'%s",
- argv[0], VTY_NEWLINE);
+ argv[idx_filter]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
}
@@ -421,17 +289,22 @@ DEFUN (clear_thread_cpu,
return CMD_SUCCESS;
}
+void
+thread_cmd_init (void)
+{
+ install_element (VIEW_NODE, &show_thread_cpu_cmd);
+ install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
+}
+
static int
thread_timer_cmp(void *a, void *b)
{
struct thread *thread_a = a;
struct thread *thread_b = b;
- long cmp = timeval_cmp(thread_a->u.sands, thread_b->u.sands);
-
- if (cmp < 0)
+ if (timercmp (&thread_a->u.sands, &thread_b->u.sands, <))
return -1;
- if (cmp > 0)
+ if (timercmp (&thread_a->u.sands, &thread_b->u.sands, >))
return 1;
return 0;
}
@@ -561,7 +434,9 @@ thread_add_unuse (struct thread_master *m, struct thread *thread)
assert (m != NULL && thread != NULL);
assert (thread->next == NULL);
assert (thread->prev == NULL);
- assert (thread->type == THREAD_UNUSED);
+
+ thread->type = THREAD_UNUSED;
+ thread->hist->total_active--;
thread_list_add (&m->unuse, thread);
}
@@ -659,12 +534,8 @@ thread_master_free (struct thread_master *m)
unsigned long
thread_timer_remain_second (struct thread *thread)
{
- quagga_get_relative (NULL);
-
- if (thread->u.sands.tv_sec - relative_time.tv_sec > 0)
- return thread->u.sands.tv_sec - relative_time.tv_sec;
- else
- return 0;
+ int64_t remain = monotime_until(&thread->u.sands, NULL) / 1000000LL;
+ return remain < 0 ? 0 : remain;
}
#define debugargdef const char *funcname, const char *schedfrom, int fromln
@@ -673,9 +544,9 @@ thread_timer_remain_second (struct thread *thread)
struct timeval
thread_timer_remain(struct thread *thread)
{
- quagga_get_relative(NULL);
-
- return timeval_subtract(thread->u.sands, relative_time);
+ struct timeval remain;
+ monotime_until(&thread->u.sands, &remain);
+ return remain;
}
/* Get new thread. */
@@ -684,6 +555,7 @@ thread_get (struct thread_master *m, u_char type,
int (*func) (struct thread *), void *arg, debugargdef)
{
struct thread *thread = thread_trim_head (&m->unuse);
+ struct cpu_thread_history tmp;
if (! thread)
{
@@ -693,11 +565,30 @@ thread_get (struct thread_master *m, u_char type,
thread->type = type;
thread->add_type = type;
thread->master = m;
- thread->func = func;
thread->arg = arg;
thread->index = -1;
thread->yield = THREAD_YIELD_TIME_SLOT; /* default */
+ /*
+ * So if the passed in funcname is not what we have
+ * stored that means the thread->hist needs to be
+ * updated. We keep the last one around in unused
+ * under the assumption that we are probably
+ * going to immediately allocate the same
+ * type of thread.
+ * This hopefully saves us some serious
+ * hash_get lookups.
+ */
+ if (thread->funcname != funcname ||
+ thread->func != func)
+ {
+ tmp.func = func;
+ tmp.funcname = funcname;
+ thread->hist = hash_get (cpu_record, &tmp,
+ (void * (*) (void *))cpu_record_hash_alloc);
+ }
+ thread->hist->total_active++;
+ thread->func = func;
thread->funcname = funcname;
thread->schedfrom = schedfrom;
thread->schedfrom_line = fromln;
@@ -828,7 +719,7 @@ funcname_thread_add_read_write (int dir, struct thread_master *m,
#else
if (FD_ISSET (fd, fdset))
{
- zlog (NULL, LOG_WARNING, "There is already %s fd [%d]", (dir = THREAD_READ) ? "read" : "write", fd);
+ zlog (NULL, LOG_WARNING, "There is already %s fd [%d]", (dir == THREAD_READ) ? "read" : "write", fd);
return NULL;
}
@@ -855,7 +746,6 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
{
struct thread *thread;
struct pqueue *queue;
- struct timeval alarm_time;
assert (m != NULL);
@@ -865,11 +755,8 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
queue = ((type == THREAD_TIMER) ? m->timer : m->background);
thread = thread_get (m, type, func, arg, debugargpass);
- /* Do we need jitter here? */
- quagga_get_relative (NULL);
- alarm_time.tv_sec = relative_time.tv_sec + time_relative->tv_sec;
- alarm_time.tv_usec = relative_time.tv_usec + time_relative->tv_usec;
- thread->u.sands = timeval_adjust(alarm_time);
+ monotime(&thread->u.sands);
+ timeradd(&thread->u.sands, time_relative, &thread->u.sands);
pqueue_enqueue(thread, queue);
return thread;
@@ -1054,7 +941,6 @@ thread_cancel (struct thread *thread)
assert(!"Thread should be either in queue or list or array!");
}
- thread->type = THREAD_UNUSED;
thread_add_unuse (thread->master, thread);
}
@@ -1077,7 +963,6 @@ thread_cancel_event (struct thread_master *m, void *arg)
{
ret++;
thread_list_delete (&m->event, t);
- t->type = THREAD_UNUSED;
thread_add_unuse (m, t);
}
}
@@ -1095,7 +980,6 @@ thread_cancel_event (struct thread_master *m, void *arg)
{
ret++;
thread_list_delete (&m->ready, t);
- t->type = THREAD_UNUSED;
thread_add_unuse (m, t);
}
}
@@ -1108,7 +992,7 @@ thread_timer_wait (struct pqueue *queue, struct timeval *timer_val)
if (queue->size)
{
struct thread *next_timer = queue->array[0];
- *timer_val = timeval_subtract (next_timer->u.sands, relative_time);
+ monotime_until(&next_timer->u.sands, timer_val);
return timer_val;
}
return NULL;
@@ -1119,7 +1003,6 @@ thread_run (struct thread_master *m, struct thread *thread,
struct thread *fetch)
{
*fetch = *thread;
- thread->type = THREAD_UNUSED;
thread_add_unuse (m, thread);
return fetch;
}
@@ -1237,7 +1120,7 @@ thread_timer_process (struct pqueue *queue, struct timeval *timenow)
while (queue->size)
{
thread = queue->array[0];
- if (timeval_cmp (*timenow, thread->u.sands) < 0)
+ if (timercmp (timenow, &thread->u.sands, <))
return ready;
pqueue_dequeue(queue);
thread->type = THREAD_READY;
@@ -1275,6 +1158,7 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
thread_fd_set readfd;
thread_fd_set writefd;
thread_fd_set exceptfd;
+ struct timeval now;
struct timeval timer_val = { .tv_sec = 0, .tv_usec = 0 };
struct timeval timer_val_bg;
struct timeval *timer_wait = &timer_val;
@@ -1311,15 +1195,20 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
/* Calculate select wait timer if nothing else to do */
if (m->ready.count == 0)
{
- quagga_get_relative (NULL);
timer_wait = thread_timer_wait (m->timer, &timer_val);
timer_wait_bg = thread_timer_wait (m->background, &timer_val_bg);
if (timer_wait_bg &&
- (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
+ (!timer_wait || (timercmp (timer_wait, timer_wait_bg, >))))
timer_wait = timer_wait_bg;
}
+ if (timer_wait && timer_wait->tv_sec < 0)
+ {
+ timerclear(&timer_val);
+ timer_wait = &timer_val;
+ }
+
num = fd_select (m, FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait);
/* Signals should get quick treatment */
@@ -1334,8 +1223,8 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
/* Check foreground timers. Historically, they have had higher
priority than I/O threads, so let's push them onto the ready
list in front of the I/O threads. */
- quagga_get_relative (NULL);
- thread_timer_process (m->timer, &relative_time);
+ monotime(&now);
+ thread_timer_process (m->timer, &now);
/* Got IO, process it */
if (num > 0)
@@ -1351,7 +1240,7 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
#endif
/* Background timer/events, lowest priority */
- thread_timer_process (m->background, &relative_time);
+ thread_timer_process (m->background, &now);
if ((thread = thread_trim_head (&m->ready)) != NULL)
return thread_run (m, thread, fetch);
@@ -1380,9 +1269,7 @@ thread_consumed_time (RUSAGE_T *now, RUSAGE_T *start, unsigned long *cputime)
int
thread_should_yield (struct thread *thread)
{
- quagga_get_relative (NULL);
- return (timeval_elapsed(relative_time, thread->real) >
- thread->yield);
+ return monotime_since(&thread->real, NULL) > (int64_t)thread->yield;
}
void
@@ -1394,17 +1281,8 @@ thread_set_yield_time (struct thread *thread, unsigned long yield_time)
void
thread_getrusage (RUSAGE_T *r)
{
- quagga_get_relative (NULL);
+ monotime(&r->real);
getrusage(RUSAGE_SELF, &(r->cpu));
- r->real = relative_time;
-
-#ifdef HAVE_CLOCK_MONOTONIC
- /* quagga_get_relative() only updates recent_time if gettimeofday
- * based, not when using CLOCK_MONOTONIC. As we export recent_time
- * and guarantee to update it before threads are run...
- */
- quagga_gettimeofday(&recent_time);
-#endif /* HAVE_CLOCK_MONOTONIC */
}
struct thread *thread_current = NULL;
@@ -1418,23 +1296,6 @@ thread_call (struct thread *thread)
unsigned long realtime, cputime;
RUSAGE_T before, after;
- /* Cache a pointer to the relevant cpu history thread, if the thread
- * does not have it yet.
- *
- * Callers submitting 'dummy threads' hence must take care that
- * thread->cpu is NULL
- */
- if (!thread->hist)
- {
- struct cpu_thread_history tmp;
-
- tmp.func = thread->func;
- tmp.funcname = thread->funcname;
-
- thread->hist = hash_get (cpu_record, &tmp,
- (void * (*) (void *))cpu_record_hash_alloc);
- }
-
GETRUSAGE (&before);
thread->real = before.real;
@@ -1479,18 +1340,22 @@ funcname_thread_execute (struct thread_master *m,
int val,
debugargdef)
{
- struct thread dummy;
+ struct cpu_thread_history tmp;
+ struct thread dummy;
memset (&dummy, 0, sizeof (struct thread));
dummy.type = THREAD_EVENT;
dummy.add_type = THREAD_EXECUTE;
dummy.master = NULL;
- dummy.func = func;
dummy.arg = arg;
dummy.u.val = val;
- dummy.funcname = funcname;
+ tmp.func = dummy.func = func;
+ tmp.funcname = dummy.funcname = funcname;
+ dummy.hist = hash_get (cpu_record, &tmp,
+ (void * (*) (void *))cpu_record_hash_alloc);
+
dummy.schedfrom = schedfrom;
dummy.schedfrom_line = fromln;
diff --git a/lib/thread.h b/lib/thread.h
index 3440a92999..49964e7743 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -23,6 +23,7 @@
#define _ZEBRA_THREAD_H
#include <zebra.h>
+#include "monotime.h"
struct rusage_t
{
@@ -115,6 +116,7 @@ struct cpu_thread_history
{
int (*func)(struct thread *);
unsigned int total_calls;
+ unsigned int total_active;
struct time_stats
{
unsigned long total, max;
@@ -238,21 +240,12 @@ extern void thread_call (struct thread *);
extern unsigned long thread_timer_remain_second (struct thread *);
extern struct timeval thread_timer_remain(struct thread*);
extern int thread_should_yield (struct thread *);
-extern unsigned long timeval_elapsed (struct timeval a, struct timeval b);
/* set yield time for thread */
extern void thread_set_yield_time (struct thread *, unsigned long);
/* Internal libfrr exports */
extern void thread_getrusage (RUSAGE_T *);
-extern struct cmd_element show_thread_cpu_cmd;
-extern struct cmd_element clear_thread_cpu_cmd;
-
-/* replacements for the system gettimeofday(), clock_gettime() and
- * time() functions, providing support for non-decrementing clock on
- * all systems, and fully monotonic on /some/ systems.
- */
-extern int quagga_gettime (enum quagga_clkid, struct timeval *);
-extern time_t quagga_monotime (void);
+extern void thread_cmd_init (void);
/* Returns elapsed real (wall clock) time. */
extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
@@ -262,8 +255,6 @@ extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
be used instead of calling gettimeofday if a recent value is sufficient.
This is guaranteed to be refreshed before a thread is called. */
extern struct timeval recent_time;
-/* Similar to recent_time, but a monotonically increasing time value */
-extern struct timeval recent_relative_time (void);
/* only for use in logging functions! */
extern struct thread *thread_current;
diff --git a/lib/vector.c b/lib/vector.c
index 03ad3171d6..e16fcf5315 100644
--- a/lib/vector.c
+++ b/lib/vector.c
@@ -25,7 +25,7 @@
#include "memory.h"
DEFINE_MTYPE_STATIC(LIB, VECTOR, "Vector")
-DEFINE_MTYPE( LIB, VECTOR_INDEX, "Vector index")
+DEFINE_MTYPE_STATIC(LIB, VECTOR_INDEX, "Vector index")
/* Initialize vector : allocate memory and return vector. */
vector
@@ -44,18 +44,6 @@ vector_init (unsigned int size)
}
void
-vector_only_wrapper_free (vector v)
-{
- XFREE (MTYPE_VECTOR, v);
-}
-
-void
-vector_only_index_free (void *index)
-{
- XFREE (MTYPE_VECTOR_INDEX, index);
-}
-
-void
vector_free (vector v)
{
XFREE (MTYPE_VECTOR_INDEX, v->index);
@@ -177,6 +165,24 @@ vector_unset (vector v, unsigned int i)
}
}
+void
+vector_unset_value (vector v, void *val)
+{
+ size_t i;
+
+ for (i = 0; i < v->active; i++)
+ if (v->index[i] == val)
+ {
+ v->index[i] = NULL;
+ break;
+ }
+
+ if (i + 1 == v->active)
+ do
+ v->active--;
+ while (i && v->index[--i] == NULL);
+}
+
/* Count the number of not emplty slot. */
unsigned int
vector_count (vector v)
diff --git a/lib/vector.h b/lib/vector.h
index d8f4c78608..f57f28bbd0 100644
--- a/lib/vector.h
+++ b/lib/vector.h
@@ -24,7 +24,6 @@
#define _ZEBRA_VECTOR_H
#include "memory.h"
-DECLARE_MTYPE(VECTOR_INDEX)
/* struct for vector */
struct _vector
@@ -54,9 +53,9 @@ extern int vector_empty_slot (vector v);
extern int vector_set (vector v, void *val);
extern int vector_set_index (vector v, unsigned int i, void *val);
extern void vector_unset (vector v, unsigned int i);
+extern void vector_unset_value (vector v, void *val);
+
extern unsigned int vector_count (vector v);
-extern void vector_only_wrapper_free (vector v);
-extern void vector_only_index_free (void *index);
extern void vector_free (vector v);
extern vector vector_copy (vector v);
diff --git a/lib/vrf.c b/lib/vrf.c
index 61b278dabf..ab7b43b078 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -480,20 +480,21 @@ DEFUN (vrf,
"Select a VRF to configure\n"
"VRF's name\n")
{
+ int idx_name = 1;
+ const char *vrfname = argv[idx_name]->arg;
struct vrf *vrfp;
- size_t sl;
- if ((sl = strlen(argv[0])) > VRF_NAMSIZ)
+ if (strlen(vrfname) > VRF_NAMSIZ)
{
vty_out (vty, "%% VRF name %s is invalid: length exceeds "
- "%d characters%s",
- argv[0], VRF_NAMSIZ, VTY_NEWLINE);
+ "%d characters%s",
+ vrfname, VRF_NAMSIZ, VTY_NEWLINE);
return CMD_WARNING;
}
- vrfp = vrf_get (VRF_UNKNOWN, argv[0]);
+ vrfp = vrf_get (VRF_UNKNOWN, vrfname);
- VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp);
+ VTY_PUSH_CONTEXT (VRF_NODE, vrfp);
return CMD_SUCCESS;
}
@@ -505,20 +506,22 @@ DEFUN_NOSH (no_vrf,
"Delete a pseudo VRF's configuration\n"
"VRF's name\n")
{
+ const char *vrfname = argv[2]->arg;
+
struct vrf *vrfp;
- vrfp = vrf_lookup_by_name (argv[0]);
+ vrfp = vrf_lookup_by_name (vrfname);
if (vrfp == NULL)
{
- vty_out (vty, "%% VRF %s does not exist%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% VRF %s does not exist%s", vrfname, VTY_NEWLINE);
return CMD_WARNING;
}
if (CHECK_FLAG (vrfp->status, VRF_ACTIVE))
{
vty_out (vty, "%% Only inactive VRFs can be deleted%s",
- VTY_NEWLINE);
+ VTY_NEWLINE);
return CMD_WARNING;
}
@@ -527,6 +530,14 @@ DEFUN_NOSH (no_vrf,
return CMD_SUCCESS;
}
+
+struct cmd_node vrf_node =
+{
+ VRF_NODE,
+ "%s(config-vrf)# ",
+ 1
+};
+
/*
* Debug CLI for vrf's
*/
@@ -579,3 +590,12 @@ vrf_install_commands (void)
install_element (CONFIG_NODE, &no_vrf_debug_cmd);
install_element (ENABLE_NODE, &no_vrf_debug_cmd);
}
+
+void
+vrf_cmd_init (int (*writefunc)(struct vty *vty))
+{
+ install_element (CONFIG_NODE, &vrf_cmd);
+ install_element (CONFIG_NODE, &no_vrf_cmd);
+ install_node (&vrf_node, writefunc);
+ install_default (VRF_NODE);
+}
diff --git a/lib/vrf.h b/lib/vrf.h
index c9e81bf669..f8bb07ef48 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -26,6 +26,7 @@
#include "openbsd-tree.h"
#include "linklist.h"
#include "qobj.h"
+#include "vty.h"
/* The default NS ID */
#define NS_DEFAULT 0
@@ -33,6 +34,7 @@
/* The default VRF ID */
#define VRF_DEFAULT 0
#define VRF_UNKNOWN UINT16_MAX
+#define VRF_ALL UINT16_MAX - 1
/* Pending: May need to refine this. */
#ifndef IFLA_VRF_MAX
@@ -52,11 +54,7 @@ enum {
/*
* The command strings
*/
-
-#define VRF_CMD_STR "vrf NAME"
#define VRF_CMD_HELP_STR "Specify the VRF\nThe VRF name\n"
-
-#define VRF_ALL_CMD_STR "vrf all"
#define VRF_ALL_CMD_HELP_STR "Specify the VRF\nAll VRFs\n"
/*
@@ -175,6 +173,8 @@ extern int vrf_bitmap_check (vrf_bitmap_t, vrf_id_t);
extern void vrf_init (void);
extern void vrf_terminate (void);
+extern void vrf_cmd_init (int (*writefunc)(struct vty *vty));
+
/*
* VRF utilities
*/
diff --git a/lib/vty.c b/lib/vty.c
index a39fe9f41b..0568351989 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
#include <zebra.h>
@@ -44,7 +44,7 @@ DEFINE_MTYPE_STATIC(LIB, VTY_OUT_BUF, "VTY output buffer")
DEFINE_MTYPE_STATIC(LIB, VTY_HIST, "VTY history")
/* Vty events */
-enum event
+enum event
{
VTY_SERV,
VTY_READ,
@@ -117,37 +117,37 @@ vty_out (struct vty *vty, const char *format, ...)
/* Initial buffer is not enough. */
if (len < 0 || len >= size)
- {
- while (1)
- {
- if (len > -1)
- size = len + 1;
- else
- size = size * 2;
-
- p = XREALLOC (MTYPE_VTY_OUT_BUF, p, size);
- if (! p)
- return -1;
-
- va_start (args, format);
- len = vsnprintf (p, size, format, args);
- va_end (args);
-
- if (len > -1 && len < size)
- break;
- }
- }
+ {
+ while (1)
+ {
+ if (len > -1)
+ size = len + 1;
+ else
+ size = size * 2;
+
+ p = XREALLOC (MTYPE_VTY_OUT_BUF, p, size);
+ if (! p)
+ return -1;
+
+ va_start (args, format);
+ len = vsnprintf (p, size, format, args);
+ va_end (args);
+
+ if (len > -1 && len < size)
+ break;
+ }
+ }
/* When initial buffer is enough to store all output. */
if (! p)
- p = buf;
+ p = buf;
/* Pointer p must point out buffer. */
buffer_put (vty->obuf, (u_char *) p, len);
/* If p is not different with buf, it is allocated buffer. */
if (p != buf)
- XFREE (MTYPE_VTY_OUT_BUF, p);
+ XFREE (MTYPE_VTY_OUT_BUF, p);
}
return len;
@@ -155,7 +155,7 @@ vty_out (struct vty *vty, const char *format, ...)
static int
vty_log_out (struct vty *vty, const char *level, const char *proto_str,
- const char *format, struct timestamp_control *ctl, va_list va)
+ const char *format, struct timestamp_control *ctl, va_list va)
{
int ret;
int len;
@@ -189,13 +189,13 @@ vty_log_out (struct vty *vty, const char *level, const char *proto_str,
if (write(vty->wfd, buf, len) < 0)
{
if (ERRNO_IO_RETRY(errno))
- /* Kernel buffer is full, probably too much debugging output, so just
- drop the data and ignore. */
- return -1;
+ /* Kernel buffer is full, probably too much debugging output, so just
+ drop the data and ignore. */
+ return -1;
/* Fatal I/O error. */
vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
zlog_warn("%s: write failed to vty client fd %d, closing: %s",
- __func__, vty->fd, safe_strerror(errno));
+ __func__, vty->fd, safe_strerror(errno));
buffer_reset(vty->obuf);
/* cannot call vty_close, because a parent routine may still try
to access the vty struct */
@@ -211,7 +211,7 @@ void
vty_time_print (struct vty *vty, int cr)
{
char buf[QUAGGA_TIMESTAMP_LEN];
-
+
if (quagga_timestamp(0, buf, sizeof(buf)) == 0)
{
zlog (NULL, LOG_INFO, "quagga_timestamp error");
@@ -236,20 +236,20 @@ vty_hello (struct vty *vty)
f = fopen (host.motdfile, "r");
if (f)
- {
- while (fgets (buf, sizeof (buf), f))
- {
- char *s;
- /* work backwards to ignore trailling isspace() */
- for (s = buf + strlen (buf); (s > buf) && isspace ((int)*(s - 1));
- s--);
- *s = '\0';
- vty_out (vty, "%s%s", buf, VTY_NEWLINE);
- }
- fclose (f);
- }
+ {
+ while (fgets (buf, sizeof (buf), f))
+ {
+ char *s;
+ /* work backwards to ignore trailling isspace() */
+ for (s = buf + strlen (buf); (s > buf) && isspace ((int)*(s - 1));
+ s--);
+ *s = '\0';
+ vty_out (vty, "%s%s", buf, VTY_NEWLINE);
+ }
+ fclose (f);
+ }
else
- vty_out (vty, "MOTD file not found%s", VTY_NEWLINE);
+ vty_out (vty, "MOTD file not found%s", VTY_NEWLINE);
}
else if (host.motd)
vty_out (vty, "%s", host.motd);
@@ -266,10 +266,10 @@ vty_prompt (struct vty *vty)
{
hostname = host.name;
if (!hostname)
- {
- uname (&names);
- hostname = names.nodename;
- }
+ {
+ uname (&names);
+ hostname = names.nodename;
+ }
vty_out (vty, cmd_prompt (vty->node), hostname);
}
}
@@ -322,7 +322,7 @@ vty_new ()
{
struct vty *new = XCALLOC (MTYPE_VTY, sizeof (struct vty));
- new->obuf = buffer_new(0); /* Use default buffer size. */
+ new->obuf = buffer_new(0); /* Use default buffer size. */
new->buf = XCALLOC (MTYPE_VTY, VTY_BUFSIZ);
new->error_buf = XCALLOC (MTYPE_VTY, VTY_BUFSIZ);
new->max = VTY_BUFSIZ;
@@ -343,19 +343,19 @@ vty_auth (struct vty *vty, char *buf)
{
case AUTH_NODE:
if (host.encrypt)
- passwd = host.password_encrypt;
+ passwd = host.password_encrypt;
else
- passwd = host.password;
+ passwd = host.password;
if (host.advanced)
- next_node = host.enable ? VIEW_NODE : ENABLE_NODE;
+ next_node = host.enable ? VIEW_NODE : ENABLE_NODE;
else
- next_node = VIEW_NODE;
+ next_node = VIEW_NODE;
break;
case AUTH_ENABLE_NODE:
if (host.encrypt)
- passwd = host.enable_encrypt;
+ passwd = host.enable_encrypt;
else
- passwd = host.enable;
+ passwd = host.enable;
next_node = ENABLE_NODE;
break;
}
@@ -363,9 +363,9 @@ vty_auth (struct vty *vty, char *buf)
if (passwd)
{
if (host.encrypt)
- fail = strcmp (crypt(buf, passwd), passwd);
+ fail = strcmp (crypt(buf, passwd), passwd);
else
- fail = strcmp (buf, passwd);
+ fail = strcmp (buf, passwd);
}
else
fail = 1;
@@ -373,26 +373,26 @@ vty_auth (struct vty *vty, char *buf)
if (! fail)
{
vty->fail = 0;
- vty->node = next_node; /* Success ! */
+ vty->node = next_node; /* Success ! */
}
else
{
vty->fail++;
if (vty->fail >= 3)
- {
- if (vty->node == AUTH_NODE)
- {
- vty_out (vty, "%% Bad passwords, too many failures!%s", VTY_NEWLINE);
- vty->status = VTY_CLOSE;
- }
- else
- {
- /* AUTH_ENABLE_NODE */
- vty->fail = 0;
- vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE);
+ {
+ if (vty->node == AUTH_NODE)
+ {
+ vty_out (vty, "%% Bad passwords, too many failures!%s", VTY_NEWLINE);
+ vty->status = VTY_CLOSE;
+ }
+ else
+ {
+ /* AUTH_ENABLE_NODE */
+ vty->fail = 0;
+ vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE);
vty->status = VTY_CLOSE;
- }
- }
+ }
+ }
}
}
@@ -419,7 +419,7 @@ vty_command (struct vty *vty, char *buf)
if (cp != NULL && *cp != '\0')
{
unsigned i;
- char vty_str[VTY_BUFSIZ];
+ char vty_str[VTY_BUFSIZ];
char prompt_str[VTY_BUFSIZ];
/* format the base vty info */
@@ -461,14 +461,14 @@ vty_command (struct vty *vty, char *buf)
protocolname = zlog_proto_names[zlog_default->protocol];
else
protocolname = zlog_proto_names[ZLOG_NONE];
-
+
#ifdef CONSUMED_TIME_CHECK
GETRUSAGE(&after);
if ((realtime = thread_consumed_time(&after, &before, &cputime)) >
- CONSUMED_TIME_CHECK)
+ CONSUMED_TIME_CHECK)
/* Warn about CPU hog that must be fixed. */
zlog_warn("SLOW COMMAND: command took %lums (cpu time %lums): %s",
- realtime/1000, cputime/1000, buf);
+ realtime/1000, cputime/1000, buf);
}
#endif /* CONSUMED_TIME_CHECK */
@@ -476,18 +476,18 @@ vty_command (struct vty *vty, char *buf)
switch (ret)
{
case CMD_WARNING:
- if (vty->type == VTY_FILE)
- vty_out (vty, "Warning...%s", VTY_NEWLINE);
- break;
+ if (vty->type == VTY_FILE)
+ vty_out (vty, "Warning...%s", VTY_NEWLINE);
+ break;
case CMD_ERR_AMBIGUOUS:
- vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);
- break;
+ vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);
+ break;
case CMD_ERR_NO_MATCH:
- vty_out (vty, "%% [%s] Unknown command: %s%s", protocolname, buf, VTY_NEWLINE);
- break;
+ vty_out (vty, "%% [%s] Unknown command: %s%s", protocolname, buf, VTY_NEWLINE);
+ break;
case CMD_ERR_INCOMPLETE:
- vty_out (vty, "%% Command incomplete.%s", VTY_NEWLINE);
- break;
+ vty_out (vty, "%% Command incomplete.%s", VTY_NEWLINE);
+ break;
}
cmd_free_strvec (vline);
@@ -685,7 +685,7 @@ vty_forward_word (struct vty *vty)
{
while (vty->cp != vty->length && vty->buf[vty->cp] != ' ')
vty_forward_char (vty);
-
+
while (vty->cp != vty->length && vty->buf[vty->cp] == ' ')
vty_forward_char (vty);
}
@@ -715,7 +715,7 @@ static void
vty_down_level (struct vty *vty)
{
vty_out (vty, "%s", VTY_NEWLINE);
- (*config_exit_cmd.func)(NULL, vty, 0, NULL);
+ cmd_exit (vty);
vty_prompt (vty);
vty->cp = 0;
}
@@ -742,6 +742,7 @@ vty_end_config (struct vty *vty)
case BGP_VPNV6_NODE:
case BGP_ENCAP_NODE:
case BGP_ENCAPV6_NODE:
+ case BGP_VRF_POLICY_NODE:
case BGP_VNC_DEFAULTS_NODE:
case BGP_VNC_NVE_GROUP_NODE:
case BGP_VNC_L2_GROUP_NODE:
@@ -791,14 +792,14 @@ vty_delete_char (struct vty *vty)
}
if (vty->cp == vty->length)
- return; /* completion need here? */
+ return; /* completion need here? */
size = vty->length - vty->cp;
vty->length--;
memmove (&vty->buf[vty->cp], &vty->buf[vty->cp + 1], size - 1);
vty->buf[vty->length] = '\0';
-
+
if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
return;
@@ -828,7 +829,7 @@ vty_kill_line (struct vty *vty)
int size;
size = vty->length - vty->cp;
-
+
if (size == 0)
return;
@@ -922,8 +923,8 @@ vty_complete_command (struct vty *vty)
if (isspace ((int) vty->buf[vty->length - 1]))
vector_set (vline, NULL);
- matched = cmd_complete_command_lib (vline, vty, &ret, 1);
-
+ matched = cmd_complete_command (vline, vty, &ret);
+
cmd_free_strvec (vline);
vty_out (vty, "%s", VTY_NEWLINE);
@@ -940,6 +941,14 @@ vty_complete_command (struct vty *vty)
vty_redraw_line (vty);
break;
case CMD_COMPLETE_FULL_MATCH:
+ if (!matched[0])
+ {
+ /* 2016-11-28 equinox -- need to debug, SEGV here */
+ vty_out (vty, "%% CLI BUG: FULL_MATCH with NULL str%s", VTY_NEWLINE);
+ vty_prompt (vty);
+ vty_redraw_line (vty);
+ break;
+ }
vty_prompt (vty);
vty_redraw_line (vty);
vty_backward_pure_word (vty);
@@ -953,17 +962,15 @@ vty_complete_command (struct vty *vty)
vty_backward_pure_word (vty);
vty_insert_word_overwrite (vty, matched[0]);
XFREE (MTYPE_TMP, matched[0]);
- vector_only_index_free (matched);
- return;
break;
case CMD_COMPLETE_LIST_MATCH:
for (i = 0; matched[i] != NULL; i++)
- {
- if (i != 0 && ((i % 6) == 0))
- vty_out (vty, "%s", VTY_NEWLINE);
- vty_out (vty, "%-10s ", matched[i]);
- XFREE (MTYPE_TMP, matched[i]);
- }
+ {
+ if (i != 0 && ((i % 6) == 0))
+ vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "%-10s ", matched[i]);
+ XFREE (MTYPE_TMP, matched[i]);
+ }
vty_out (vty, "%s", VTY_NEWLINE);
vty_prompt (vty);
@@ -977,18 +984,18 @@ vty_complete_command (struct vty *vty)
break;
}
if (matched)
- vector_only_index_free (matched);
+ XFREE (MTYPE_TMP, matched);
}
static void
vty_describe_fold (struct vty *vty, int cmd_width,
- unsigned int desc_width, struct cmd_token *token)
+ unsigned int desc_width, struct cmd_token *token)
{
char *buf;
const char *cmd, *p;
int pos;
- cmd = token->cmd[0] == '.' ? token->cmd + 1 : token->cmd;
+ cmd = token->text;
if (desc_width <= 0)
{
@@ -1037,7 +1044,7 @@ vty_describe_command (struct vty *vty)
vline = vector_init (1);
vector_set (vline, NULL);
}
- else
+ else
if (isspace ((int) vty->buf[vty->length - 1]))
vector_set (vline, NULL);
@@ -1056,24 +1063,22 @@ vty_describe_command (struct vty *vty)
vty_out (vty, "%% There is no matched command.%s", VTY_NEWLINE);
goto out;
break;
- }
+ }
/* Get width of command string. */
width = 0;
for (i = 0; i < vector_active (describe); i++)
if ((token = vector_slot (describe, i)) != NULL)
{
- unsigned int len;
+ unsigned int len;
- if (token->cmd[0] == '\0')
- continue;
+ if (token->text[0] == '\0')
+ continue;
- len = strlen (token->cmd);
- if (token->cmd[0] == '.')
- len--;
+ len = strlen (token->text);
- if (width < len)
- width = len;
+ if (width < len)
+ width = len;
}
/* Get width of description string. */
@@ -1083,45 +1088,45 @@ vty_describe_command (struct vty *vty)
for (i = 0; i < vector_active (describe); i++)
if ((token = vector_slot (describe, i)) != NULL)
{
- if (token->cmd[0] == '\0')
- continue;
-
- if (strcmp (token->cmd, command_cr) == 0)
- {
- token_cr = token;
- continue;
- }
-
- if (!token->desc)
- vty_out (vty, " %-s%s",
- token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
- VTY_NEWLINE);
- else if (desc_width >= strlen (token->desc))
- vty_out (vty, " %-*s %s%s", width,
- token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
- token->desc, VTY_NEWLINE);
- else
- vty_describe_fold (vty, width, desc_width, token);
+ if (token->text[0] == '\0')
+ continue;
+
+ if (strcmp (token->text, CMD_CR_TEXT) == 0)
+ {
+ token_cr = token;
+ continue;
+ }
+
+ if (!token->desc)
+ vty_out (vty, " %-s%s",
+ token->text,
+ VTY_NEWLINE);
+ else if (desc_width >= strlen (token->desc))
+ vty_out (vty, " %-*s %s%s", width,
+ token->text,
+ token->desc, VTY_NEWLINE);
+ else
+ vty_describe_fold (vty, width, desc_width, token);
#if 0
- vty_out (vty, " %-*s %s%s", width
- desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
- desc->str ? desc->str : "", VTY_NEWLINE);
+ vty_out (vty, " %-*s %s%s", width
+ desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
+ desc->str ? desc->str : "", VTY_NEWLINE);
#endif /* 0 */
}
if ((token = token_cr))
{
if (!token->desc)
- vty_out (vty, " %-s%s",
- token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
- VTY_NEWLINE);
+ vty_out (vty, " %-s%s",
+ token->text,
+ VTY_NEWLINE);
else if (desc_width >= strlen (token->desc))
- vty_out (vty, " %-*s %s%s", width,
- token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
- token->desc, VTY_NEWLINE);
+ vty_out (vty, " %-*s %s%s", width,
+ token->text,
+ token->desc, VTY_NEWLINE);
else
- vty_describe_fold (vty, width, desc_width, token);
+ vty_describe_fold (vty, width, desc_width, token);
}
out:
@@ -1232,41 +1237,41 @@ vty_telnet_option (struct vty *vty, unsigned char *buf, int nbytes)
for (i = 0; i < nbytes; i++)
{
switch (buf[i])
- {
- case IAC:
- vty_out (vty, "IAC ");
- break;
- case WILL:
- vty_out (vty, "WILL ");
- break;
- case WONT:
- vty_out (vty, "WONT ");
- break;
- case DO:
- vty_out (vty, "DO ");
- break;
- case DONT:
- vty_out (vty, "DONT ");
- break;
- case SB:
- vty_out (vty, "SB ");
- break;
- case SE:
- vty_out (vty, "SE ");
- break;
- case TELOPT_ECHO:
- vty_out (vty, "TELOPT_ECHO %s", VTY_NEWLINE);
- break;
- case TELOPT_SGA:
- vty_out (vty, "TELOPT_SGA %s", VTY_NEWLINE);
- break;
- case TELOPT_NAWS:
- vty_out (vty, "TELOPT_NAWS %s", VTY_NEWLINE);
- break;
- default:
- vty_out (vty, "%x ", buf[i]);
- break;
- }
+ {
+ case IAC:
+ vty_out (vty, "IAC ");
+ break;
+ case WILL:
+ vty_out (vty, "WILL ");
+ break;
+ case WONT:
+ vty_out (vty, "WONT ");
+ break;
+ case DO:
+ vty_out (vty, "DO ");
+ break;
+ case DONT:
+ vty_out (vty, "DONT ");
+ break;
+ case SB:
+ vty_out (vty, "SB ");
+ break;
+ case SE:
+ vty_out (vty, "SE ");
+ break;
+ case TELOPT_ECHO:
+ vty_out (vty, "TELOPT_ECHO %s", VTY_NEWLINE);
+ break;
+ case TELOPT_SGA:
+ vty_out (vty, "TELOPT_SGA %s", VTY_NEWLINE);
+ break;
+ case TELOPT_NAWS:
+ vty_out (vty, "TELOPT_NAWS %s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out (vty, "%x ", buf[i]);
+ break;
+ }
}
vty_out (vty, "%s", VTY_NEWLINE);
@@ -1279,42 +1284,42 @@ vty_telnet_option (struct vty *vty, unsigned char *buf, int nbytes)
vty->iac_sb_in_progress = 1;
return 0;
break;
- case SE:
+ case SE:
{
- if (!vty->iac_sb_in_progress)
- return 0;
-
- if ((vty->sb_len == 0) || (vty->sb_buf[0] == '\0'))
- {
- vty->iac_sb_in_progress = 0;
- return 0;
- }
- switch (vty->sb_buf[0])
- {
- case TELOPT_NAWS:
- if (vty->sb_len != TELNET_NAWS_SB_LEN)
- zlog_warn("RFC 1073 violation detected: telnet NAWS option "
- "should send %d characters, but we received %lu",
- TELNET_NAWS_SB_LEN, (u_long)vty->sb_len);
- else if (sizeof(vty->sb_buf) < TELNET_NAWS_SB_LEN)
- zlog_err("Bug detected: sizeof(vty->sb_buf) %lu < %d, "
- "too small to handle the telnet NAWS option",
- (u_long)sizeof(vty->sb_buf), TELNET_NAWS_SB_LEN);
- else
- {
- vty->width = ((vty->sb_buf[1] << 8)|vty->sb_buf[2]);
- vty->height = ((vty->sb_buf[3] << 8)|vty->sb_buf[4]);
+ if (!vty->iac_sb_in_progress)
+ return 0;
+
+ if ((vty->sb_len == 0) || (vty->sb_buf[0] == '\0'))
+ {
+ vty->iac_sb_in_progress = 0;
+ return 0;
+ }
+ switch (vty->sb_buf[0])
+ {
+ case TELOPT_NAWS:
+ if (vty->sb_len != TELNET_NAWS_SB_LEN)
+ zlog_warn("RFC 1073 violation detected: telnet NAWS option "
+ "should send %d characters, but we received %lu",
+ TELNET_NAWS_SB_LEN, (u_long)vty->sb_len);
+ else if (sizeof(vty->sb_buf) < TELNET_NAWS_SB_LEN)
+ zlog_err("Bug detected: sizeof(vty->sb_buf) %lu < %d, "
+ "too small to handle the telnet NAWS option",
+ (u_long)sizeof(vty->sb_buf), TELNET_NAWS_SB_LEN);
+ else
+ {
+ vty->width = ((vty->sb_buf[1] << 8)|vty->sb_buf[2]);
+ vty->height = ((vty->sb_buf[3] << 8)|vty->sb_buf[4]);
#ifdef TELNET_OPTION_DEBUG
- vty_out(vty, "TELNET NAWS window size negotiation completed: "
- "width %d, height %d%s",
- vty->width, vty->height, VTY_NEWLINE);
+ vty_out(vty, "TELNET NAWS window size negotiation completed: "
+ "width %d, height %d%s",
+ vty->width, vty->height, VTY_NEWLINE);
#endif
- }
- break;
- }
- vty->iac_sb_in_progress = 0;
- return 0;
- break;
+ }
+ break;
+ }
+ vty->iac_sb_in_progress = 0;
+ return 0;
+ break;
}
default:
break;
@@ -1339,7 +1344,7 @@ vty_execute (struct vty *vty)
default:
ret = vty_command (vty, vty->buf);
if (vty->type == VTY_TERM)
- vty_hist_add (vty);
+ vty_hist_add (vty);
break;
}
@@ -1409,187 +1414,187 @@ vty_read (struct thread *thread)
if ((nbytes = read (vty->fd, buf, VTY_READ_BUFSIZ)) <= 0)
{
if (nbytes < 0)
- {
- if (ERRNO_IO_RETRY(errno))
- {
- vty_event (VTY_READ, vty_sock, vty);
- return 0;
- }
- vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
- zlog_warn("%s: read error on vty client fd %d, closing: %s",
- __func__, vty->fd, safe_strerror(errno));
+ {
+ if (ERRNO_IO_RETRY(errno))
+ {
+ vty_event (VTY_READ, vty_sock, vty);
+ return 0;
+ }
+ vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
+ zlog_warn("%s: read error on vty client fd %d, closing: %s",
+ __func__, vty->fd, safe_strerror(errno));
buffer_reset(vty->obuf);
- }
+ }
vty->status = VTY_CLOSE;
}
- for (i = 0; i < nbytes; i++)
+ for (i = 0; i < nbytes; i++)
{
if (buf[i] == IAC)
- {
- if (!vty->iac)
- {
- vty->iac = 1;
- continue;
- }
- else
- {
- vty->iac = 0;
- }
- }
-
+ {
+ if (!vty->iac)
+ {
+ vty->iac = 1;
+ continue;
+ }
+ else
+ {
+ vty->iac = 0;
+ }
+ }
+
if (vty->iac_sb_in_progress && !vty->iac)
- {
- if (vty->sb_len < sizeof(vty->sb_buf))
- vty->sb_buf[vty->sb_len] = buf[i];
- vty->sb_len++;
- continue;
- }
+ {
+ if (vty->sb_len < sizeof(vty->sb_buf))
+ vty->sb_buf[vty->sb_len] = buf[i];
+ vty->sb_len++;
+ continue;
+ }
if (vty->iac)
- {
- /* In case of telnet command */
- int ret = 0;
- ret = vty_telnet_option (vty, buf + i, nbytes - i);
- vty->iac = 0;
- i += ret;
- continue;
- }
-
+ {
+ /* In case of telnet command */
+ int ret = 0;
+ ret = vty_telnet_option (vty, buf + i, nbytes - i);
+ vty->iac = 0;
+ i += ret;
+ continue;
+ }
+
if (vty->status == VTY_MORE)
- {
- switch (buf[i])
- {
- case CONTROL('C'):
- case 'q':
- case 'Q':
- vty_buffer_reset (vty);
- break;
+ {
+ switch (buf[i])
+ {
+ case CONTROL('C'):
+ case 'q':
+ case 'Q':
+ vty_buffer_reset (vty);
+ break;
#if 0 /* More line does not work for "show ip bgp". */
- case '\n':
- case '\r':
- vty->status = VTY_MORELINE;
- break;
+ case '\n':
+ case '\r':
+ vty->status = VTY_MORELINE;
+ break;
#endif
- default:
- break;
- }
- continue;
- }
+ default:
+ break;
+ }
+ continue;
+ }
/* Escape character. */
if (vty->escape == VTY_ESCAPE)
- {
- vty_escape_map (buf[i], vty);
- continue;
- }
+ {
+ vty_escape_map (buf[i], vty);
+ continue;
+ }
/* Pre-escape status. */
if (vty->escape == VTY_PRE_ESCAPE)
- {
- switch (buf[i])
- {
- case '[':
- vty->escape = VTY_ESCAPE;
- break;
- case 'b':
- vty_backward_word (vty);
- vty->escape = VTY_NORMAL;
- break;
- case 'f':
- vty_forward_word (vty);
- vty->escape = VTY_NORMAL;
- break;
- case 'd':
- vty_forward_kill_word (vty);
- vty->escape = VTY_NORMAL;
- break;
- case CONTROL('H'):
- case 0x7f:
- vty_backward_kill_word (vty);
- vty->escape = VTY_NORMAL;
- break;
- default:
- vty->escape = VTY_NORMAL;
- break;
- }
- continue;
- }
+ {
+ switch (buf[i])
+ {
+ case '[':
+ vty->escape = VTY_ESCAPE;
+ break;
+ case 'b':
+ vty_backward_word (vty);
+ vty->escape = VTY_NORMAL;
+ break;
+ case 'f':
+ vty_forward_word (vty);
+ vty->escape = VTY_NORMAL;
+ break;
+ case 'd':
+ vty_forward_kill_word (vty);
+ vty->escape = VTY_NORMAL;
+ break;
+ case CONTROL('H'):
+ case 0x7f:
+ vty_backward_kill_word (vty);
+ vty->escape = VTY_NORMAL;
+ break;
+ default:
+ vty->escape = VTY_NORMAL;
+ break;
+ }
+ continue;
+ }
switch (buf[i])
- {
- case CONTROL('A'):
- vty_beginning_of_line (vty);
- break;
- case CONTROL('B'):
- vty_backward_char (vty);
- break;
- case CONTROL('C'):
- vty_stop_input (vty);
- break;
- case CONTROL('D'):
- vty_delete_char (vty);
- break;
- case CONTROL('E'):
- vty_end_of_line (vty);
- break;
- case CONTROL('F'):
- vty_forward_char (vty);
- break;
- case CONTROL('H'):
- case 0x7f:
- vty_delete_backward_char (vty);
- break;
- case CONTROL('K'):
- vty_kill_line (vty);
- break;
- case CONTROL('N'):
- vty_next_line (vty);
- break;
- case CONTROL('P'):
- vty_previous_line (vty);
- break;
- case CONTROL('T'):
- vty_transpose_chars (vty);
- break;
- case CONTROL('U'):
- vty_kill_line_from_beginning (vty);
- break;
- case CONTROL('W'):
- vty_backward_kill_word (vty);
- break;
- case CONTROL('Z'):
- vty_end_config (vty);
- break;
- case '\n':
- case '\r':
- vty_out (vty, "%s", VTY_NEWLINE);
- vty_execute (vty);
- break;
- case '\t':
- vty_complete_command (vty);
- break;
- case '?':
- if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
- vty_self_insert (vty, buf[i]);
- else
- vty_describe_command (vty);
- break;
- case '\033':
- if (i + 1 < nbytes && buf[i + 1] == '[')
- {
- vty->escape = VTY_ESCAPE;
- i++;
- }
- else
- vty->escape = VTY_PRE_ESCAPE;
- break;
- default:
- if (buf[i] > 31 && buf[i] < 127)
- vty_self_insert (vty, buf[i]);
- break;
- }
+ {
+ case CONTROL('A'):
+ vty_beginning_of_line (vty);
+ break;
+ case CONTROL('B'):
+ vty_backward_char (vty);
+ break;
+ case CONTROL('C'):
+ vty_stop_input (vty);
+ break;
+ case CONTROL('D'):
+ vty_delete_char (vty);
+ break;
+ case CONTROL('E'):
+ vty_end_of_line (vty);
+ break;
+ case CONTROL('F'):
+ vty_forward_char (vty);
+ break;
+ case CONTROL('H'):
+ case 0x7f:
+ vty_delete_backward_char (vty);
+ break;
+ case CONTROL('K'):
+ vty_kill_line (vty);
+ break;
+ case CONTROL('N'):
+ vty_next_line (vty);
+ break;
+ case CONTROL('P'):
+ vty_previous_line (vty);
+ break;
+ case CONTROL('T'):
+ vty_transpose_chars (vty);
+ break;
+ case CONTROL('U'):
+ vty_kill_line_from_beginning (vty);
+ break;
+ case CONTROL('W'):
+ vty_backward_kill_word (vty);
+ break;
+ case CONTROL('Z'):
+ vty_end_config (vty);
+ break;
+ case '\n':
+ case '\r':
+ vty_out (vty, "%s", VTY_NEWLINE);
+ vty_execute (vty);
+ break;
+ case '\t':
+ vty_complete_command (vty);
+ break;
+ case '?':
+ if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
+ vty_self_insert (vty, buf[i]);
+ else
+ vty_describe_command (vty);
+ break;
+ case '\033':
+ if (i + 1 < nbytes && buf[i + 1] == '[')
+ {
+ vty->escape = VTY_ESCAPE;
+ i++;
+ }
+ else
+ vty->escape = VTY_PRE_ESCAPE;
+ break;
+ default:
+ if (buf[i] > 31 && buf[i] < 127)
+ vty_self_insert (vty, buf[i]);
+ break;
+ }
}
/* Check status. */
@@ -1629,36 +1634,36 @@ vty_flush (struct thread *thread)
flushrc = buffer_flush_available(vty->obuf, vty_sock);
else if (vty->status == VTY_MORELINE)
flushrc = buffer_flush_window(vty->obuf, vty_sock, vty->width,
- 1, erase, 0);
+ 1, erase, 0);
else
flushrc = buffer_flush_window(vty->obuf, vty_sock, vty->width,
- vty->lines >= 0 ? vty->lines :
- vty->height,
- erase, 0);
+ vty->lines >= 0 ? vty->lines :
+ vty->height,
+ erase, 0);
switch (flushrc)
{
case BUFFER_ERROR:
vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
zlog_warn("buffer_flush failed on vty client fd %d, closing",
- vty->fd);
+ vty->fd);
buffer_reset(vty->obuf);
vty_close(vty);
return 0;
case BUFFER_EMPTY:
if (vty->status == VTY_CLOSE)
- vty_close (vty);
+ vty_close (vty);
else
- {
- vty->status = VTY_NORMAL;
- if (vty->lines == 0)
- vty_event (VTY_READ, vty_sock, vty);
- }
+ {
+ vty->status = VTY_NORMAL;
+ if (vty->lines == 0)
+ vty_event (VTY_READ, vty_sock, vty);
+ }
break;
case BUFFER_PENDING:
/* There is more data waiting to be written. */
vty->status = VTY_MORE;
if (vty->lines == 0)
- vty_event (VTY_WRITE, vty_sock, vty);
+ vty_event (VTY_WRITE, vty_sock, vty);
break;
}
@@ -1711,9 +1716,9 @@ vty_create (int vty_sock, union sockunion *su)
if (no_password_check)
{
if (host.advanced)
- vty->node = ENABLE_NODE;
+ vty->node = ENABLE_NODE;
else
- vty->node = VIEW_NODE;
+ vty->node = VIEW_NODE;
}
if (host.lines >= 0)
vty->lines = host.lines;
@@ -1722,12 +1727,12 @@ vty_create (int vty_sock, union sockunion *su)
{
/* Vty is not available if password isn't set. */
if (host.password == NULL && host.password_encrypt == NULL)
- {
- vty_out (vty, "Vty password is not set.%s", VTY_NEWLINE);
- vty->status = VTY_CLOSE;
- vty_close (vty);
- return NULL;
- }
+ {
+ vty_out (vty, "Vty password is not set.%s", VTY_NEWLINE);
+ vty->status = VTY_CLOSE;
+ vty_close (vty);
+ return NULL;
+ }
}
/* Say hello to the world. */
@@ -1848,54 +1853,51 @@ vty_accept (struct thread *thread)
if (p.family == AF_INET && vty_accesslist_name)
{
if ((acl = access_list_lookup (AFI_IP, vty_accesslist_name)) &&
- (access_list_apply (acl, &p) == FILTER_DENY))
- {
- zlog (NULL, LOG_INFO, "Vty connection refused from %s",
- sockunion2str (&su, buf, SU_ADDRSTRLEN));
- close (vty_sock);
-
- /* continue accepting connections */
- vty_event (VTY_SERV, accept_sock, NULL);
-
- return 0;
- }
- }
-
-#ifdef HAVE_IPV6
+ (access_list_apply (acl, &p) == FILTER_DENY))
+ {
+ zlog (NULL, LOG_INFO, "Vty connection refused from %s",
+ sockunion2str (&su, buf, SU_ADDRSTRLEN));
+ close (vty_sock);
+
+ /* continue accepting connections */
+ vty_event (VTY_SERV, accept_sock, NULL);
+
+ return 0;
+ }
+ }
+
/* VTY's ipv6 accesslist apply. */
if (p.family == AF_INET6 && vty_ipv6_accesslist_name)
{
if ((acl = access_list_lookup (AFI_IP6, vty_ipv6_accesslist_name)) &&
- (access_list_apply (acl, &p) == FILTER_DENY))
- {
- zlog (NULL, LOG_INFO, "Vty connection refused from %s",
- sockunion2str (&su, buf, SU_ADDRSTRLEN));
- close (vty_sock);
-
- /* continue accepting connections */
- vty_event (VTY_SERV, accept_sock, NULL);
-
- return 0;
- }
- }
-#endif /* HAVE_IPV6 */
-
+ (access_list_apply (acl, &p) == FILTER_DENY))
+ {
+ zlog (NULL, LOG_INFO, "Vty connection refused from %s",
+ sockunion2str (&su, buf, SU_ADDRSTRLEN));
+ close (vty_sock);
+
+ /* continue accepting connections */
+ vty_event (VTY_SERV, accept_sock, NULL);
+
+ return 0;
+ }
+ }
+
on = 1;
- ret = setsockopt (vty_sock, IPPROTO_TCP, TCP_NODELAY,
- (char *) &on, sizeof (on));
+ ret = setsockopt (vty_sock, IPPROTO_TCP, TCP_NODELAY,
+ (char *) &on, sizeof (on));
if (ret < 0)
- zlog (NULL, LOG_INFO, "can't set sockopt to vty_sock : %s",
- safe_strerror (errno));
+ zlog (NULL, LOG_INFO, "can't set sockopt to vty_sock : %s",
+ safe_strerror (errno));
zlog (NULL, LOG_INFO, "Vty connection from %s",
- sockunion2str (&su, buf, SU_ADDRSTRLEN));
+ sockunion2str (&su, buf, SU_ADDRSTRLEN));
vty_create (vty_sock, &su);
return 0;
}
-#ifdef HAVE_IPV6
static void
vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
{
@@ -1926,15 +1928,13 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
do
{
if (ainfo->ai_family != AF_INET
-#ifdef HAVE_IPV6
- && ainfo->ai_family != AF_INET6
-#endif /* HAVE_IPV6 */
- )
- continue;
+ && ainfo->ai_family != AF_INET6
+ )
+ continue;
sock = socket (ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
if (sock < 0)
- continue;
+ continue;
sockopt_v6only (ainfo->ai_family, sock);
sockopt_reuseaddr (sock);
@@ -1943,17 +1943,17 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
ret = bind (sock, ainfo->ai_addr, ainfo->ai_addrlen);
if (ret < 0)
- {
- close (sock); /* Avoid sd leak. */
- continue;
- }
+ {
+ close (sock); /* Avoid sd leak. */
+ continue;
+ }
ret = listen (sock, 3);
- if (ret < 0)
- {
- close (sock); /* Avoid sd leak. */
- continue;
- }
+ if (ret < 0)
+ {
+ close (sock); /* Avoid sd leak. */
+ continue;
+ }
vty_event (VTY_SERV, sock, NULL);
}
@@ -1961,76 +1961,6 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
freeaddrinfo (ainfo_save);
}
-#else /* HAVE_IPV6 */
-
-/* Make vty server socket. */
-static void
-vty_serv_sock_family (const char* addr, unsigned short port, int family)
-{
- int ret;
- union sockunion su;
- int accept_sock;
- void* naddr=NULL;
-
- memset (&su, 0, sizeof (union sockunion));
- su.sa.sa_family = family;
- if(addr)
- switch(family)
- {
- case AF_INET:
- naddr=&su.sin.sin_addr;
- break;
-#ifdef HAVE_IPV6
- case AF_INET6:
- naddr=&su.sin6.sin6_addr;
- break;
-#endif
- }
-
- if(naddr)
- switch(inet_pton(family,addr,naddr))
- {
- case -1:
- zlog_err("bad address %s",addr);
- naddr=NULL;
- break;
- case 0:
- zlog_err("error translating address %s: %s",addr,safe_strerror(errno));
- naddr=NULL;
- }
-
- /* Make new socket. */
- accept_sock = sockunion_stream_socket (&su);
- if (accept_sock < 0)
- return;
-
- /* This is server, so reuse address. */
- sockopt_reuseaddr (accept_sock);
- sockopt_reuseport (accept_sock);
- set_cloexec (accept_sock);
-
- /* Bind socket to universal address and given port. */
- ret = sockunion_bind (accept_sock, &su, port, naddr);
- if (ret < 0)
- {
- zlog_warn("can't bind socket");
- close (accept_sock); /* Avoid sd leak. */
- return;
- }
-
- /* Listen socket under queue 3. */
- ret = listen (accept_sock, 3);
- if (ret < 0)
- {
- zlog (NULL, LOG_WARNING, "can't listen socket");
- close (accept_sock); /* Avoid sd leak. */
- return;
- }
-
- /* Add vty server event. */
- vty_event (VTY_SERV, accept_sock, NULL);
-}
-#endif /* HAVE_IPV6 */
#ifdef VTYSH
/* For sockaddr_un. */
@@ -2045,7 +1975,7 @@ vty_serv_un (const char *path)
struct sockaddr_un serv;
mode_t old_mask;
struct zprivs_ids_t ids;
-
+
/* First of all, unlink existing socket */
unlink (path);
@@ -2076,7 +2006,7 @@ vty_serv_un (const char *path)
if (ret < 0)
{
zlog_err("Cannot bind path %s: %s", path, safe_strerror(errno));
- close (sock); /* Avoid sd leak. */
+ close (sock); /* Avoid sd leak. */
return;
}
@@ -2084,7 +2014,7 @@ vty_serv_un (const char *path)
if (ret < 0)
{
zlog_err("listen(fd %d) failed: %s", sock, safe_strerror(errno));
- close (sock); /* Avoid sd leak. */
+ close (sock); /* Avoid sd leak. */
return;
}
@@ -2118,7 +2048,7 @@ vtysh_accept (struct thread *thread)
int client_len;
struct sockaddr_un client;
struct vty *vty;
-
+
accept_sock = THREAD_FD (thread);
vty_event (VTYSH_SERV, accept_sock, NULL);
@@ -2127,7 +2057,7 @@ vtysh_accept (struct thread *thread)
client_len = sizeof (struct sockaddr_un);
sock = accept (accept_sock, (struct sockaddr *) &client,
- (socklen_t *) &client_len);
+ (socklen_t *) &client_len);
if (sock < 0)
{
@@ -2198,16 +2128,16 @@ vtysh_read (struct thread *thread)
if ((nbytes = read (sock, buf, VTY_READ_BUFSIZ)) <= 0)
{
if (nbytes < 0)
- {
- if (ERRNO_IO_RETRY(errno))
- {
- vty_event (VTYSH_READ, sock, vty);
- return 0;
- }
- vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
- zlog_warn("%s: read failed on vtysh client fd %d, closing: %s",
- __func__, sock, safe_strerror(errno));
- }
+ {
+ if (ERRNO_IO_RETRY(errno))
+ {
+ vty_event (VTYSH_READ, sock, vty);
+ return 0;
+ }
+ vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
+ zlog_warn("%s: read failed on vtysh client fd %d, closing: %s",
+ __func__, sock, safe_strerror(errno));
+ }
buffer_reset(vty->obuf);
vty_close (vty);
#ifdef VTYSH_DEBUG
@@ -2285,14 +2215,7 @@ vty_serv_sock (const char *addr, unsigned short port, const char *path)
{
/* If port is set to 0, do not listen on TCP/IP at all! */
if (port)
- {
-
-#ifdef HAVE_IPV6
- vty_serv_sock_addrinfo (addr, port);
-#else /* ! HAVE_IPV6 */
- vty_serv_sock_family (addr,port, AF_INET);
-#endif /* HAVE_IPV6 */
- }
+ vty_serv_sock_addrinfo (addr, port);
#ifdef VTYSH
vty_serv_un (path);
@@ -2307,6 +2230,7 @@ void
vty_close (struct vty *vty)
{
int i;
+ bool was_stdio = false;
/* Cancel threads.*/
if (vty->t_read)
@@ -2341,7 +2265,7 @@ vty_close (struct vty *vty)
close (vty->wfd);
}
else
- vty_stdio_reset ();
+ was_stdio = true;
if (vty->buf)
XFREE (MTYPE_VTY, vty->buf);
@@ -2354,6 +2278,9 @@ vty_close (struct vty *vty)
/* OK free vty. */
XFREE (MTYPE_VTY, vty);
+
+ if (was_stdio)
+ vty_stdio_reset ();
}
/* When time out occur output message then close connection. */
@@ -2395,26 +2322,31 @@ vty_read_file (FILE *confp)
vty->fd = STDIN_FILENO;
vty->type = VTY_FILE;
vty->node = CONFIG_NODE;
-
+
/* Execute configuration file */
ret = config_from_file (vty, confp, &line_num);
/* Flush any previous errors before printing messages below */
buffer_flush_all (vty->obuf, vty->fd);
- if ( !((ret == CMD_SUCCESS) || (ret == CMD_ERR_NOTHING_TODO)) )
+ if ( !((ret == CMD_SUCCESS) || (ret == CMD_ERR_NOTHING_TODO)) )
{
+ const char *message = NULL;
switch (ret)
{
case CMD_ERR_AMBIGUOUS:
- fprintf (stderr, "*** Error reading config: Ambiguous command.\n");
+ message = "*** Error reading config: Ambiguous command.";
break;
case CMD_ERR_NO_MATCH:
- fprintf (stderr, "*** Error reading config: There is no such command.\n");
+ message = "*** Error reading config: There is no such command.";
break;
}
- fprintf (stderr, "*** Error occured processing line %u, below:\n%s\n",
- line_num, vty->error_buf);
+ fprintf (stderr, "%s\n", message);
+ zlog_err ("%s", message);
+ fprintf (stderr, "*** Error occurred processing line %u, below:\n%s\n",
+ line_num, vty->error_buf);
+ zlog_err ("*** Error occurred processing line %u, below:\n%s",
+ line_num, vty->error_buf);
}
vty_close (vty);
@@ -2429,7 +2361,7 @@ vty_use_backup_config (char *fullpath)
int tmp, sav;
int c;
char buffer[512];
-
+
fullpath_sav = malloc (strlen (fullpath) + strlen (CONF_BACKUP_EXT) + 1);
strcpy (fullpath_sav, fullpath);
strcat (fullpath_sav, CONF_BACKUP_EXT);
@@ -2441,7 +2373,7 @@ vty_use_backup_config (char *fullpath)
fullpath_tmp = malloc (strlen (fullpath) + 8);
sprintf (fullpath_tmp, "%s.XXXXXX", fullpath);
-
+
/* Open file to configuration write. */
tmp = mkstemp (fullpath_tmp);
if (tmp < 0)
@@ -2459,21 +2391,21 @@ vty_use_backup_config (char *fullpath)
free (fullpath_tmp);
return NULL;
}
-
+
while((c = read (sav, buffer, 512)) > 0)
{
if (write (tmp, buffer, c) <= 0)
- {
- free (fullpath_sav);
- free (fullpath_tmp);
- close (sav);
- close (tmp);
- return NULL;
- }
+ {
+ free (fullpath_sav);
+ free (fullpath_tmp);
+ close (sav);
+ close (tmp);
+ return NULL;
+ }
}
close (sav);
close (tmp);
-
+
if (chmod(fullpath_tmp, CONFIGFILE_MASK) != 0)
{
unlink (fullpath_tmp);
@@ -2481,12 +2413,12 @@ vty_use_backup_config (char *fullpath)
free (fullpath_tmp);
return NULL;
}
-
+
if (link (fullpath_tmp, fullpath) == 0)
ret = fopen (fullpath, "r");
unlink (fullpath_tmp);
-
+
free (fullpath_sav);
free (fullpath_tmp);
return ret;
@@ -2508,12 +2440,12 @@ vty_read_config (char *config_file,
if (! IS_DIRECTORY_SEP (config_file[0]))
{
if (getcwd (cwd, MAXPATHLEN) == NULL)
- {
- fprintf (stderr, "Failure to determine Current Working Directory %d!\n", errno);
- exit (1);
- }
- tmp = XMALLOC (MTYPE_TMP,
- strlen (cwd) + strlen (config_file) + 2);
+ {
+ fprintf (stderr, "Failure to determine Current Working Directory %d!\n", errno);
+ exit (1);
+ }
+ tmp = XMALLOC (MTYPE_TMP,
+ strlen (cwd) + strlen (config_file) + 2);
sprintf (tmp, "%s/%s", cwd, config_file);
fullpath = tmp;
}
@@ -2526,14 +2458,14 @@ vty_read_config (char *config_file,
{
fprintf (stderr, "%s: failed to open configuration file %s: %s\n",
__func__, fullpath, safe_strerror (errno));
-
+
confp = vty_use_backup_config (fullpath);
if (confp)
fprintf (stderr, "WARNING: using backup configuration file!\n");
else
{
- fprintf (stderr, "can't open configuration file [%s]\n",
- config_file);
+ fprintf (stderr, "can't open configuration file [%s]\n",
+ config_file);
exit(1);
}
}
@@ -2565,7 +2497,7 @@ vty_read_config (char *config_file,
{
ret = stat (integrate_default, &conf_stat);
if (ret >= 0)
- goto tmp_free_and_out;
+ goto tmp_free_and_out;
}
#endif /* VTYSH */
confp = fopen (config_default_dir, "r");
@@ -2573,7 +2505,7 @@ vty_read_config (char *config_file,
{
fprintf (stderr, "%s: failed to open configuration file %s: %s\n",
__func__, config_default_dir, safe_strerror (errno));
-
+
confp = vty_use_backup_config (config_default_dir);
if (confp)
{
@@ -2583,10 +2515,10 @@ vty_read_config (char *config_file,
else
{
fprintf (stderr, "can't open configuration file [%s]\n",
- config_default_dir);
- goto tmp_free_and_out;
+ config_default_dir);
+ goto tmp_free_and_out;
}
- }
+ }
else
fullpath = config_default_dir;
}
@@ -2605,23 +2537,23 @@ tmp_free_and_out:
/* Small utility function which output log to the VTY. */
void
vty_log (const char *level, const char *proto_str,
- const char *format, struct timestamp_control *ctl, va_list va)
+ const char *format, struct timestamp_control *ctl, va_list va)
{
unsigned int i;
struct vty *vty;
-
+
if (!vtyvec)
return;
for (i = 0; i < vector_active (vtyvec); i++)
if ((vty = vector_slot (vtyvec, i)) != NULL)
if (vty->monitor)
- {
- va_list ac;
- va_copy(ac, va);
- vty_log_out (vty, level, proto_str, format, ctl, ac);
- va_end(ac);
- }
+ {
+ va_list ac;
+ va_copy(ac, va);
+ vty_log_out (vty, level, proto_str, format, ctl, ac);
+ va_end(ac);
+ }
}
/* Async-signal-safe version of vty_log for fixed strings. */
@@ -2635,7 +2567,7 @@ vty_log_fixed (char *buf, size_t len)
/* vty may not have been initialised */
if (!vtyvec)
return;
-
+
iov[0].iov_base = buf;
iov[0].iov_len = len;
iov[1].iov_base = crlf;
@@ -2645,13 +2577,13 @@ vty_log_fixed (char *buf, size_t len)
{
struct vty *vty;
if (((vty = vector_slot (vtyvec, i)) != NULL) && vty->monitor)
- /* N.B. We don't care about the return code, since process is
- most likely just about to die anyway. */
- if (writev(vty->wfd, iov, 2) == -1)
- {
- fprintf(stderr, "Failure to writev: %d\n", errno);
- exit(-1);
- }
+ /* N.B. We don't care about the return code, since process is
+ most likely just about to die anyway. */
+ if (writev(vty->wfd, iov, 2) == -1)
+ {
+ fprintf(stderr, "Failure to writev: %d\n", errno);
+ exit(-1);
+ }
}
}
@@ -2718,28 +2650,28 @@ vty_event (enum event event, int sock, struct vty *vty)
/* Time out treatment. */
if (vty->v_timeout)
- {
- if (vty->t_timeout)
- thread_cancel (vty->t_timeout);
- vty->t_timeout =
- thread_add_timer (vty_master, vty_timeout, vty, vty->v_timeout);
- }
+ {
+ if (vty->t_timeout)
+ thread_cancel (vty->t_timeout);
+ vty->t_timeout =
+ thread_add_timer (vty_master, vty_timeout, vty, vty->v_timeout);
+ }
break;
case VTY_WRITE:
if (! vty->t_write)
- vty->t_write = thread_add_write (vty_master, vty_flush, vty, sock);
+ vty->t_write = thread_add_write (vty_master, vty_flush, vty, sock);
break;
case VTY_TIMEOUT_RESET:
if (vty->t_timeout)
- {
- thread_cancel (vty->t_timeout);
- vty->t_timeout = NULL;
- }
+ {
+ thread_cancel (vty->t_timeout);
+ vty->t_timeout = NULL;
+ }
if (vty->v_timeout)
- {
- vty->t_timeout =
- thread_add_timer (vty_master, vty_timeout, vty, vty->v_timeout);
- }
+ {
+ vty->t_timeout =
+ thread_add_timer (vty_master, vty_timeout, vty, vty->v_timeout);
+ }
break;
}
}
@@ -2755,8 +2687,8 @@ DEFUN (config_who,
for (i = 0; i < vector_active (vtyvec); i++)
if ((v = vector_slot (vtyvec, i)) != NULL)
vty_out (vty, "%svty[%d] connected from %s.%s",
- v->config ? "*" : " ",
- i, v->address, VTY_NEWLINE);
+ v->config ? "*" : " ",
+ i, v->address, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -2797,21 +2729,24 @@ exec_timeout (struct vty *vty, const char *min_str, const char *sec_str)
DEFUN (exec_timeout_min,
exec_timeout_min_cmd,
- "exec-timeout <0-35791>",
+ "exec-timeout (0-35791)",
"Set timeout value\n"
"Timeout value in minutes\n")
{
- return exec_timeout (vty, argv[0], NULL);
+ int idx_number = 1;
+ return exec_timeout (vty, argv[idx_number]->arg, NULL);
}
DEFUN (exec_timeout_sec,
exec_timeout_sec_cmd,
- "exec-timeout <0-35791> <0-2147483>",
+ "exec-timeout (0-35791) (0-2147483)",
"Set the EXEC timeout\n"
"Timeout in minutes\n"
"Timeout in seconds\n")
{
- return exec_timeout (vty, argv[0], argv[1]);
+ int idx_number = 1;
+ int idx_number_2 = 2;
+ return exec_timeout (vty, argv[idx_number]->arg, argv[idx_number_2]->arg);
}
DEFUN (no_exec_timeout,
@@ -2830,10 +2765,11 @@ DEFUN (vty_access_class,
"Filter connections based on an IP access list\n"
"IP access list\n")
{
+ int idx_word = 1;
if (vty_accesslist_name)
XFREE(MTYPE_VTY, vty_accesslist_name);
- vty_accesslist_name = XSTRDUP(MTYPE_VTY, argv[0]);
+ vty_accesslist_name = XSTRDUP(MTYPE_VTY, argv[idx_word]->arg);
return CMD_SUCCESS;
}
@@ -2846,10 +2782,12 @@ DEFUN (no_vty_access_class,
"Filter connections based on an IP access list\n"
"IP access list\n")
{
- if (! vty_accesslist_name || (argc && strcmp(vty_accesslist_name, argv[0])))
+ int idx_word = 2;
+ const char *accesslist = (argc == 3) ? argv[idx_word]->arg : NULL;
+ if (! vty_accesslist_name || (argc == 3 && strcmp(vty_accesslist_name, accesslist)))
{
vty_out (vty, "Access-class is not currently applied to vty%s",
- VTY_NEWLINE);
+ VTY_NEWLINE);
return CMD_WARNING;
}
@@ -2860,7 +2798,6 @@ DEFUN (no_vty_access_class,
return CMD_SUCCESS;
}
-#ifdef HAVE_IPV6
/* Set vty access class. */
DEFUN (vty_ipv6_access_class,
vty_ipv6_access_class_cmd,
@@ -2869,10 +2806,11 @@ DEFUN (vty_ipv6_access_class,
"Filter connections based on an IP access list\n"
"IPv6 access list\n")
{
+ int idx_word = 2;
if (vty_ipv6_accesslist_name)
XFREE(MTYPE_VTY, vty_ipv6_accesslist_name);
- vty_ipv6_accesslist_name = XSTRDUP(MTYPE_VTY, argv[0]);
+ vty_ipv6_accesslist_name = XSTRDUP(MTYPE_VTY, argv[idx_word]->arg);
return CMD_SUCCESS;
}
@@ -2886,11 +2824,14 @@ DEFUN (no_vty_ipv6_access_class,
"Filter connections based on an IP access list\n"
"IPv6 access list\n")
{
+ int idx_word = 3;
+ const char *accesslist = (argc == 4) ? argv[idx_word]->arg : NULL;
+
if (! vty_ipv6_accesslist_name ||
- (argc && strcmp(vty_ipv6_accesslist_name, argv[0])))
+ (argc == 4 && strcmp(vty_ipv6_accesslist_name, accesslist)))
{
vty_out (vty, "IPv6 access-class is not currently applied to vty%s",
- VTY_NEWLINE);
+ VTY_NEWLINE);
return CMD_WARNING;
}
@@ -2900,7 +2841,6 @@ DEFUN (no_vty_ipv6_access_class,
return CMD_SUCCESS;
}
-#endif /* HAVE_IPV6 */
/* vty login. */
DEFUN (vty_login,
@@ -2964,12 +2904,16 @@ DEFUN (terminal_no_monitor,
return CMD_SUCCESS;
}
-ALIAS (terminal_no_monitor,
+DEFUN (no_terminal_monitor,
no_terminal_monitor_cmd,
"no terminal monitor",
NO_STR
"Set terminal line parameters\n"
"Copy debug output to the current terminal line\n")
+{
+ return terminal_no_monitor (self, vty, argc, argv);
+}
+
DEFUN (show_history,
show_history_cmd,
@@ -2982,13 +2926,13 @@ DEFUN (show_history,
for (index = vty->hindex + 1; index != vty->hindex;)
{
if (index == VTY_MAXHIST)
- {
- index = 0;
- continue;
- }
+ {
+ index = 0;
+ continue;
+ }
if (vty->hist[index] != NULL)
- vty_out (vty, " %s%s", vty->hist[index], VTY_NEWLINE);
+ vty_out (vty, " %s%s", vty->hist[index], VTY_NEWLINE);
index++;
}
@@ -3015,17 +2959,17 @@ vty_config_write (struct vty *vty)
if (vty_accesslist_name)
vty_out (vty, " access-class %s%s",
- vty_accesslist_name, VTY_NEWLINE);
+ vty_accesslist_name, VTY_NEWLINE);
if (vty_ipv6_accesslist_name)
vty_out (vty, " ipv6 access-class %s%s",
- vty_ipv6_accesslist_name, VTY_NEWLINE);
+ vty_ipv6_accesslist_name, VTY_NEWLINE);
/* exec-timeout */
if (vty_timeout_val != VTY_TIMEOUT_DEFAULT)
- vty_out (vty, " exec-timeout %ld %ld%s",
- vty_timeout_val / 60,
- vty_timeout_val % 60, VTY_NEWLINE);
+ vty_out (vty, " exec-timeout %ld %ld%s",
+ vty_timeout_val / 60,
+ vty_timeout_val % 60, VTY_NEWLINE);
/* login */
if (no_password_check)
@@ -3033,7 +2977,7 @@ vty_config_write (struct vty *vty)
if (do_log_commands)
vty_out (vty, "log commands%s", VTY_NEWLINE);
-
+
vty_out (vty, "!%s", VTY_NEWLINE);
return CMD_SUCCESS;
@@ -3057,16 +3001,16 @@ vty_reset ()
for (i = 0; i < vector_active (vtyvec); i++)
if ((vty = vector_slot (vtyvec, i)) != NULL)
{
- buffer_reset (vty->obuf);
- vty->status = VTY_CLOSE;
- vty_close (vty);
+ buffer_reset (vty->obuf);
+ vty->status = VTY_CLOSE;
+ vty_close (vty);
}
for (i = 0; i < vector_active (Vvty_serv_thread); i++)
if ((vty_serv_thread = vector_slot (Vvty_serv_thread, i)) != NULL)
{
- thread_cancel (vty_serv_thread);
- vector_slot (Vvty_serv_thread, i) = NULL;
+ thread_cancel (vty_serv_thread);
+ vector_slot (Vvty_serv_thread, i) = NULL;
close (i);
}
@@ -3101,15 +3045,15 @@ vty_save_cwd (void)
* Hence not worrying about it too much.
*/
if (!chdir (SYSCONFDIR))
- {
- fprintf(stderr, "Failure to chdir to %s, errno: %d\n", SYSCONFDIR, errno);
- exit(-1);
- }
+ {
+ fprintf(stderr, "Failure to chdir to %s, errno: %d\n", SYSCONFDIR, errno);
+ exit(-1);
+ }
if (getcwd (cwd, MAXPATHLEN) == NULL)
- {
- fprintf(stderr, "Failure to getcwd, errno: %d\n", errno);
- exit(-1);
- }
+ {
+ fprintf(stderr, "Failure to getcwd, errno: %d\n", errno);
+ exit(-1);
+ }
}
vty_cwd = XMALLOC (MTYPE_TMP, strlen (cwd) + 1);
@@ -3178,10 +3122,8 @@ vty_init (struct thread_master *master_thread)
install_element (VTY_NODE, &no_vty_access_class_cmd);
install_element (VTY_NODE, &vty_login_cmd);
install_element (VTY_NODE, &no_vty_login_cmd);
-#ifdef HAVE_IPV6
install_element (VTY_NODE, &vty_ipv6_access_class_cmd);
install_element (VTY_NODE, &no_vty_ipv6_access_class_cmd);
-#endif /* HAVE_IPV6 */
}
void
diff --git a/lib/vty.h b/lib/vty.h
index 80b6d3eb2a..f3be18a660 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -29,14 +29,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#define VTY_BUFSIZ 4096
#define VTY_MAXHIST 20
-#if defined(VTY_DEPRECATE_INDEX) && defined(__GNUC__) && \
- (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && \
- !defined(__ICC)
-#define INDEX_WARNING __attribute__((deprecated))
-#else
-#define INDEX_WARNING
-#endif
-
/* VTY struct. */
struct vty
{
@@ -82,10 +74,6 @@ struct vty
/* History insert end point */
int hindex;
- /* For current referencing point of interface, route-map,
- access-list etc... */
- void *index INDEX_WARNING;
-
/* qobj object ID (replacement for "index") */
uint64_t qobj_index;
@@ -139,32 +127,23 @@ struct vty
char address[SU_ADDRSTRLEN];
};
-#undef INDEX_WARNING
-
static inline void vty_push_context(struct vty *vty,
- int node, uint64_t id, void *idx)
+ int node, uint64_t id)
{
vty->node = node;
vty->qobj_index = id;
-#if defined(VTY_DEPRECATE_INDEX) && defined(__GNUC__) && \
- (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- vty->index = idx;
-#pragma GCC diagnostic pop
-#else
- vty->index = idx;
-#endif
}
+/* note: VTY_PUSH_CONTEXT(..., NULL) doesn't work, since it will try to
+ * dereference "NULL->qobj_node.nid" */
#define VTY_PUSH_CONTEXT(nodeval, ptr) \
- vty_push_context(vty, nodeval, QOBJ_ID(ptr), NULL)
-#define VTY_PUSH_CONTEXT_COMPAT(nodeval, ptr) \
- vty_push_context(vty, nodeval, QOBJ_ID(ptr), ptr)
+ vty_push_context(vty, nodeval, QOBJ_ID_0SAFE(ptr))
+#define VTY_PUSH_CONTEXT_NULL(nodeval) \
+ vty_push_context(vty, nodeval, 0ULL)
#define VTY_PUSH_CONTEXT_SUB(nodeval, ptr) do { \
vty->node = nodeval; \
/* qobj_index stays untouched */ \
- vty->qobj_index_sub = QOBJ_ID(ptr); \
+ vty->qobj_index_sub = QOBJ_ID_0SAFE(ptr); \
} while (0)
/* can return NULL if context is invalid! */
diff --git a/lib/wheel.c b/lib/wheel.c
new file mode 100644
index 0000000000..fe53dea299
--- /dev/null
+++ b/lib/wheel.c
@@ -0,0 +1,164 @@
+/*
+ * Timer Wheel
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#include "zebra.h"
+#include "linklist.h"
+#include "thread.h"
+#include "memory.h"
+#include "wheel.h"
+#include "log.h"
+
+DEFINE_MTYPE_STATIC(LIB, TIMER_WHEEL, "Timer Wheel")
+DEFINE_MTYPE_STATIC(LIB, TIMER_WHEEL_LIST, "Timer Wheel Slot List")
+
+static int debug_timer_wheel = 0;
+
+static int
+wheel_timer_thread (struct thread *t)
+{
+ struct listnode *node, *nextnode;
+ unsigned long long curr_slot;
+ unsigned int slots_to_skip = 1;
+ struct timer_wheel *wheel;
+ void *data;
+
+ wheel = THREAD_ARG(t);
+ THREAD_OFF(wheel->timer);
+
+ wheel->curr_slot += wheel->slots_to_skip;
+
+ curr_slot = wheel->curr_slot % wheel->slots;
+
+ if (debug_timer_wheel)
+ zlog_debug ("%s: Wheel Slot: %lld(%lld) count: %d",
+ __PRETTY_FUNCTION__,
+ wheel->curr_slot,
+ curr_slot, listcount(wheel->wheel_slot_lists[curr_slot]));
+
+ for (ALL_LIST_ELEMENTS (wheel->wheel_slot_lists[curr_slot], node, nextnode, data))
+ (*wheel->slot_run)(data);
+
+ while (list_isempty(wheel->wheel_slot_lists[(curr_slot + slots_to_skip) % wheel->slots]) &&
+ (curr_slot + slots_to_skip ) % wheel->slots != curr_slot)
+ slots_to_skip++;
+
+ wheel->slots_to_skip = slots_to_skip;
+ THREAD_TIMER_MSEC_ON (wheel->master, wheel->timer,
+ wheel_timer_thread, wheel,
+ wheel->nexttime * slots_to_skip);
+
+ return 0;
+}
+
+struct timer_wheel *
+wheel_init (struct thread_master *master, int period, size_t slots,
+ unsigned int (*slot_key) (void *),
+ void (*slot_run) (void *))
+{
+ struct timer_wheel *wheel;
+ size_t i;
+
+ wheel = XCALLOC(MTYPE_TIMER_WHEEL, sizeof (struct timer_wheel));
+
+ wheel->slot_key = slot_key;
+ wheel->slot_run = slot_run;
+
+ wheel->period = period;
+ wheel->slots = slots;
+ wheel->curr_slot = 0;
+ wheel->master = master;
+ wheel->nexttime = period / slots;
+
+ wheel->wheel_slot_lists = XCALLOC(MTYPE_TIMER_WHEEL_LIST,
+ slots * sizeof (struct listnode *));
+ for (i = 0; i < slots; i++)
+ wheel->wheel_slot_lists[i] = list_new ();
+
+ THREAD_TIMER_MSEC_ON (wheel->master, wheel->timer,
+ wheel_timer_thread, wheel,
+ wheel->nexttime);
+
+ return wheel;
+}
+
+void
+wheel_delete (struct timer_wheel *wheel)
+{
+ int i;
+
+ for (i = 0; i < wheel->slots; i++)
+ {
+ list_delete(wheel->wheel_slot_lists[i]);
+ }
+
+ THREAD_OFF(wheel->timer);
+ XFREE(MTYPE_TIMER_WHEEL_LIST, wheel->wheel_slot_lists);
+ XFREE(MTYPE_TIMER_WHEEL, wheel);
+}
+
+int
+wheel_stop (struct timer_wheel *wheel)
+{
+ THREAD_OFF(wheel->timer);
+ return 0;
+}
+
+int
+wheel_start (struct timer_wheel *wheel)
+{
+ if (!wheel->timer)
+ THREAD_TIMER_MSEC_ON (wheel->master, wheel->timer,
+ wheel_timer_thread, wheel,
+ wheel->nexttime);
+
+ return 0;
+}
+
+int
+wheel_add_item (struct timer_wheel *wheel, void *item)
+{
+ long long slot;
+
+ slot = (*wheel->slot_key)(item);
+
+ if (debug_timer_wheel)
+ zlog_debug ("%s: Inserting %p: %lld %lld",
+ __PRETTY_FUNCTION__, item,
+ slot, slot % wheel->slots);
+ listnode_add (wheel->wheel_slot_lists[slot % wheel->slots], item);
+
+ return 0;
+}
+
+int
+wheel_remove_item (struct timer_wheel *wheel, void *item)
+{
+ long long slot;
+
+ slot = (*wheel->slot_key)(item);
+
+ if (debug_timer_wheel)
+ zlog_debug ("%s: Removing %p: %lld %lld",
+ __PRETTY_FUNCTION__, item,
+ slot, slot % wheel->slots);
+ listnode_delete (wheel->wheel_slot_lists[slot % wheel->slots], item);
+
+ return 0;
+}
diff --git a/lib/wheel.h b/lib/wheel.h
new file mode 100644
index 0000000000..79d21e124b
--- /dev/null
+++ b/lib/wheel.h
@@ -0,0 +1,118 @@
+/*
+ * Timer Wheel
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#ifndef __WHEEL_H__
+#define __WHEEL_H__
+
+struct timer_wheel
+{
+ struct thread_master *master;
+ int slots;
+ long long curr_slot;
+ unsigned int period;
+ unsigned int nexttime;
+ unsigned int slots_to_skip;
+
+ struct list **wheel_slot_lists;
+ struct thread *timer;
+ /*
+ * Key to determine what slot the item belongs in
+ */
+ unsigned int (*slot_key) (void *);
+
+ void (*slot_run) (void *);
+};
+
+/*
+ * Creates a timer wheel
+ *
+ * master - Thread master structure for the process
+ * period - The Time in seconds that the timer wheel will
+ * take before it starts issuing commands again
+ * for items in each slot
+ * slots - The number of slots to have in this particular
+ * timer wheel
+ * slot_key - A hashing function of some sort that will allow
+ * the timer wheel to put items into individual slots
+ * slot_run - The function to run over each item in a particular slot
+ *
+ * Creates a timer wheel that will wake up 'slots' times over the entire
+ * wheel. Each time the timer wheel wakes up it will iterate through
+ * and run the slot_run function for each item stored in that particular
+ * slot.
+ *
+ * The timer code is 'intelligent' in that it notices if anything is
+ * in a particular slot and can schedule the next timer to skip
+ * the empty slot.
+ *
+ * The general purpose of a timer wheel is to reduce events in a system.
+ * A perfect example of usage for this is say hello packets that need
+ * to be sent out to all your neighbors. Suppose a large routing protocol
+ * has to send keepalive packets every Y seconds to each of it's peers.
+ * At scale we can have a very large number of peers, X.
+ * This means that we will have X timing events every Y seconds.
+ * If you replace these events with a timer wheel that has Z slots
+ * you will have at most Y/Z timer events if each slot has a work item
+ * in it.
+ *
+ * When X is large the number of events in a system can quickly escalate
+ * and cause significant amount of time handling thread events instead
+ * of running your code.
+ */
+struct timer_wheel *wheel_init (struct thread_master *master, int period, size_t slots,
+ unsigned int (*slot_key) (void *),
+ void (*slot_run) (void *));
+
+/*
+ * Delete the specified timer wheel created
+ */
+void wheel_delete (struct timer_wheel *);
+
+/*
+ * Pause the Wheel from running
+ */
+int wheel_stop (struct timer_wheel *wheel);
+
+/*
+ * Start the wheel running again
+ */
+int wheel_start (struct timer_wheel *wheel);
+
+/*
+ * wheel - The Timer wheel being modified
+ * item - The generic data structure that will be handed
+ * to the slot_run function.
+ *
+ * Add item to a slot setup by the slot_key,
+ * possibly change next time pop.
+ */
+int wheel_add_item (struct timer_wheel *wheel, void *item);
+
+/*
+ * wheel - The Timer wheel being modified.
+ * item - The item to remove from one of the slots in
+ * the timer wheel.
+ *
+ * Remove a item to a slot setup by the slot_key,
+ * possibly change next time pop.
+ */
+int wheel_remove_item (struct timer_wheel *wheel, void *item);
+
+#endif
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 549bb2360a..51017b34ea 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -222,6 +222,12 @@ DEFUN (show_work_queues,
return CMD_SUCCESS;
}
+void
+workqueue_cmd_init (void)
+{
+ install_element (VIEW_NODE, &show_work_queues_cmd);
+}
+
/* 'plug' a queue: Stop it from being scheduled,
* ie: prevent the queue from draining.
*/
diff --git a/lib/workqueue.h b/lib/workqueue.h
index eaf8574907..548f96d8b0 100644
--- a/lib/workqueue.h
+++ b/lib/workqueue.h
@@ -129,5 +129,7 @@ bool work_queue_is_scheduled (struct work_queue *);
/* Helpers, exported for thread.c and command.c */
extern int work_queue_run (struct thread *);
-extern struct cmd_element show_work_queues_cmd;
+
+extern void workqueue_cmd_init (void);
+
#endif /* _QUAGGA_WORK_QUEUE_H */
diff --git a/lib/zclient.c b/lib/zclient.c
index 440de3635f..cea4b098fc 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -786,7 +786,6 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
return zclient_send_message(zclient);
}
-#ifdef HAVE_IPV6
int
zapi_ipv4_route_ipv6_nexthop (u_char cmd, struct zclient *zclient,
struct prefix_ipv4 *p, struct zapi_ipv6 *api)
@@ -855,12 +854,15 @@ zapi_ipv4_route_ipv6_nexthop (u_char cmd, struct zclient *zclient,
int
zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
- struct zapi_ipv6 *api)
+ struct prefix_ipv6 *src_p, struct zapi_ipv6 *api)
{
int i;
int psize;
struct stream *s;
+ /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL */
+ assert (!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p);
+
/* Reset stream. */
s = zclient->obuf;
stream_reset (s);
@@ -879,6 +881,13 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
stream_putc (s, p->prefixlen);
stream_write (s, (u_char *)&p->prefix, psize);
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_SRCPFX))
+ {
+ psize = PSIZE (src_p->prefixlen);
+ stream_putc (s, src_p->prefixlen);
+ stream_write (s, (u_char *)&src_p->prefix, psize);
+ }
+
/* Nexthop, ifindex, distance and metric information. */
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
{
@@ -918,7 +927,6 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
return zclient_send_message(zclient);
}
-#endif /* HAVE_IPV6 */
/*
* send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
@@ -1138,11 +1146,15 @@ struct interface *
zebra_interface_link_params_read (struct stream *s)
{
struct if_link_params *iflp;
- uint32_t ifindex = stream_getl (s);
+ ifindex_t ifindex;
+
+ assert (s);
+
+ ifindex = stream_getl (s);
struct interface *ifp = if_lookup_by_index (ifindex);
- if (ifp == NULL || s == NULL)
+ if (ifp == NULL)
{
zlog_err ("%s: unknown ifindex %u, shouldn't happen",
__func__, ifindex);
@@ -1628,6 +1640,7 @@ zclient_read (struct thread *thread)
case ZEBRA_REDISTRIBUTE_IPV6_DEL:
if (zclient->redistribute_route_ipv6_del)
(*zclient->redistribute_route_ipv6_del) (command, zclient, length, vrf_id);
+ break;
case ZEBRA_INTERFACE_LINK_PARAMS:
if (zclient->interface_link_params)
(*zclient->interface_link_params) (command, zclient, length);
diff --git a/lib/zclient.h b/lib/zclient.h
index 4312cdc83c..89fc865c78 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -37,6 +37,62 @@
/* Zebra header size. */
#define ZEBRA_HEADER_SIZE 8
+/* Zebra message types. */
+typedef enum {
+ ZEBRA_INTERFACE_ADD,
+ ZEBRA_INTERFACE_DELETE,
+ ZEBRA_INTERFACE_ADDRESS_ADD,
+ ZEBRA_INTERFACE_ADDRESS_DELETE,
+ ZEBRA_INTERFACE_UP,
+ ZEBRA_INTERFACE_DOWN,
+ ZEBRA_IPV4_ROUTE_ADD,
+ ZEBRA_IPV4_ROUTE_DELETE,
+ ZEBRA_IPV6_ROUTE_ADD,
+ ZEBRA_IPV6_ROUTE_DELETE,
+ ZEBRA_REDISTRIBUTE_ADD,
+ ZEBRA_REDISTRIBUTE_DELETE,
+ ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
+ ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
+ ZEBRA_ROUTER_ID_ADD,
+ ZEBRA_ROUTER_ID_DELETE,
+ ZEBRA_ROUTER_ID_UPDATE,
+ ZEBRA_HELLO,
+ ZEBRA_NEXTHOP_REGISTER,
+ ZEBRA_NEXTHOP_UNREGISTER,
+ ZEBRA_NEXTHOP_UPDATE,
+ ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
+ ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
+ ZEBRA_INTERFACE_BFD_DEST_UPDATE,
+ ZEBRA_IMPORT_ROUTE_REGISTER,
+ ZEBRA_IMPORT_ROUTE_UNREGISTER,
+ ZEBRA_IMPORT_CHECK_UPDATE,
+ ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD,
+ ZEBRA_BFD_DEST_REGISTER,
+ ZEBRA_BFD_DEST_DEREGISTER,
+ ZEBRA_BFD_DEST_UPDATE,
+ ZEBRA_BFD_DEST_REPLAY,
+ ZEBRA_REDISTRIBUTE_IPV4_ADD,
+ ZEBRA_REDISTRIBUTE_IPV4_DEL,
+ ZEBRA_REDISTRIBUTE_IPV6_ADD,
+ ZEBRA_REDISTRIBUTE_IPV6_DEL,
+ ZEBRA_VRF_UNREGISTER,
+ ZEBRA_VRF_ADD,
+ ZEBRA_VRF_DELETE,
+ ZEBRA_INTERFACE_VRF_UPDATE,
+ ZEBRA_BFD_CLIENT_REGISTER,
+ ZEBRA_INTERFACE_ENABLE_RADV,
+ ZEBRA_INTERFACE_DISABLE_RADV,
+ ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB,
+ ZEBRA_INTERFACE_LINK_PARAMS,
+ ZEBRA_MPLS_LABELS_ADD,
+ ZEBRA_MPLS_LABELS_DELETE,
+ ZEBRA_IPV4_NEXTHOP_ADD,
+ ZEBRA_IPV4_NEXTHOP_DELETE,
+ ZEBRA_IPV6_NEXTHOP_ADD,
+ ZEBRA_IPV6_NEXTHOP_DELETE,
+ ZEBRA_IPMR_ROUTE_STATS,
+} zebra_message_types_t;
+
struct redist_proto
{
u_char enabled;
@@ -114,6 +170,7 @@ struct zclient
#define ZAPI_MESSAGE_METRIC 0x08
#define ZAPI_MESSAGE_TAG 0x10
#define ZAPI_MESSAGE_MTU 0x20
+#define ZAPI_MESSAGE_SRCPFX 0x40
/* Zserv protocol message header */
struct zserv_header
@@ -214,7 +271,6 @@ extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *,
extern struct interface *zebra_interface_link_params_read (struct stream *);
extern size_t zebra_interface_link_params_write (struct stream *,
struct interface *);
-#ifdef HAVE_IPV6
/* IPv6 prefix add and delete function prototype. */
struct zapi_ipv6
@@ -246,9 +302,9 @@ struct zapi_ipv6
};
extern int zapi_ipv6_route (u_char cmd, struct zclient *zclient,
- struct prefix_ipv6 *p, struct zapi_ipv6 *api);
+ struct prefix_ipv6 *p, struct prefix_ipv6 *src_p,
+ struct zapi_ipv6 *api);
extern int zapi_ipv4_route_ipv6_nexthop (u_char, struct zclient *,
struct prefix_ipv4 *, struct zapi_ipv6 *);
-#endif /* HAVE_IPV6 */
#endif /* _ZEBRA_ZCLIENT_H */
diff --git a/lib/zebra.h b/lib/zebra.h
index 420f237176..19a26b5230 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -352,61 +352,6 @@ struct in_pktinfo
/* default zebra TCP port for zclient */
#define ZEBRA_PORT 2600
-/* Zebra message types. */
-typedef enum {
- ZEBRA_INTERFACE_ADD,
- ZEBRA_INTERFACE_DELETE,
- ZEBRA_INTERFACE_ADDRESS_ADD,
- ZEBRA_INTERFACE_ADDRESS_DELETE,
- ZEBRA_INTERFACE_UP,
- ZEBRA_INTERFACE_DOWN,
- ZEBRA_IPV4_ROUTE_ADD,
- ZEBRA_IPV4_ROUTE_DELETE,
- ZEBRA_IPV6_ROUTE_ADD,
- ZEBRA_IPV6_ROUTE_DELETE,
- ZEBRA_REDISTRIBUTE_ADD,
- ZEBRA_REDISTRIBUTE_DELETE,
- ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
- ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
- ZEBRA_ROUTER_ID_ADD,
- ZEBRA_ROUTER_ID_DELETE,
- ZEBRA_ROUTER_ID_UPDATE,
- ZEBRA_HELLO,
- ZEBRA_NEXTHOP_REGISTER,
- ZEBRA_NEXTHOP_UNREGISTER,
- ZEBRA_NEXTHOP_UPDATE,
- ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
- ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
- ZEBRA_INTERFACE_BFD_DEST_UPDATE,
- ZEBRA_IMPORT_ROUTE_REGISTER,
- ZEBRA_IMPORT_ROUTE_UNREGISTER,
- ZEBRA_IMPORT_CHECK_UPDATE,
- ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD,
- ZEBRA_BFD_DEST_REGISTER,
- ZEBRA_BFD_DEST_DEREGISTER,
- ZEBRA_BFD_DEST_UPDATE,
- ZEBRA_BFD_DEST_REPLAY,
- ZEBRA_REDISTRIBUTE_IPV4_ADD,
- ZEBRA_REDISTRIBUTE_IPV4_DEL,
- ZEBRA_REDISTRIBUTE_IPV6_ADD,
- ZEBRA_REDISTRIBUTE_IPV6_DEL,
- ZEBRA_VRF_UNREGISTER,
- ZEBRA_VRF_ADD,
- ZEBRA_VRF_DELETE,
- ZEBRA_INTERFACE_VRF_UPDATE,
- ZEBRA_BFD_CLIENT_REGISTER,
- ZEBRA_INTERFACE_ENABLE_RADV,
- ZEBRA_INTERFACE_DISABLE_RADV,
- ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB,
- ZEBRA_INTERFACE_LINK_PARAMS,
- ZEBRA_MPLS_LABELS_ADD,
- ZEBRA_MPLS_LABELS_DELETE,
- ZEBRA_IPV4_NEXTHOP_ADD,
- ZEBRA_IPV4_NEXTHOP_DELETE,
- ZEBRA_IPV6_NEXTHOP_ADD,
- ZEBRA_IPV6_NEXTHOP_DELETE,
-} zebra_message_types_t;
-
/* Marker value used in new Zserv, in the byte location corresponding
* the command value in the old zserv header. To allow old and new
* Zserv headers to be distinguished from each other.
@@ -435,13 +380,7 @@ extern int proto_redistnum(int afi, const char *s);
extern const char *zserv_command_string (unsigned int command);
-/* Error codes of zebra. */
-#define ZEBRA_ERR_NOERROR 0
-#define ZEBRA_ERR_RTEXIST -1
-#define ZEBRA_ERR_RTUNREACH -2
-#define ZEBRA_ERR_EPERM -3
-#define ZEBRA_ERR_RTNOEXIST -4
-#define ZEBRA_ERR_KERNEL -5
+#define strmatch(a,b) (!strcmp((a), (b)))
/* Zebra message flags */
#define ZEBRA_FLAG_INTERNAL 0x01
@@ -469,10 +408,41 @@ typedef enum {
/* Subsequent Address Family Identifier. */
#define SAFI_UNICAST 1
#define SAFI_MULTICAST 2
-#define SAFI_RESERVED_3 3
-#define SAFI_MPLS_VPN 4
-#define SAFI_ENCAP 7 /* per IANA */
-#define SAFI_MAX 8
+#define SAFI_MPLS_VPN 3
+#define SAFI_RESERVED_4 4
+#define SAFI_ENCAP 5
+#define SAFI_RESERVED_5 5
+#define SAFI_MAX 6
+
+#define IANA_SAFI_RESERVED 0
+#define IANA_SAFI_UNICAST 1
+#define IANA_SAFI_MULTICAST 2
+#define IANA_SAFI_ENCAP 7
+#define IANA_SAFI_MPLS_VPN 128
+
+/*
+ * The above AFI and SAFI definitions are for internal use. The protocol
+ * definitions (IANA values) as for example used in BGP protocol packets
+ * are defined below and these will get mapped to/from the internal values
+ * in the appropriate places.
+ * The rationale is that the protocol (IANA) values may be sparse and are
+ * not optimal for use in data-structure sizing.
+ * Note: Only useful (i.e., supported) values are defined below.
+ */
+typedef enum {
+ IANA_AFI_RESERVED = 0,
+ IANA_AFI_IPV4 = 1,
+ IANA_AFI_IPV6 = 2,
+ IANA_AFI_L2VPN = 25,
+ IANA_AFI_IPMR = 128,
+ IANA_AFI_IP6MR = 129
+} iana_afi_t;
+
+#define IANA_SAFI_RESERVED 0
+#define IANA_SAFI_UNICAST 1
+#define IANA_SAFI_MULTICAST 2
+#define IANA_SAFI_ENCAP 7
+#define IANA_SAFI_MPLS_VPN 128
/* Default Administrative Distance of each protocol. */
#define ZEBRA_KERNEL_DISTANCE_DEFAULT 0
@@ -506,4 +476,48 @@ typedef uint32_t route_tag_t;
#define ROUTE_TAG_MAX UINT32_MAX
#define ROUTE_TAG_PRI PRIu32
+static inline afi_t afi_iana2int (iana_afi_t afi)
+{
+ if (afi == IANA_AFI_IPV4)
+ return AFI_IP;
+ if (afi == IANA_AFI_IPV6)
+ return AFI_IP6;
+ return AFI_MAX;
+}
+
+static inline iana_afi_t afi_int2iana (afi_t afi)
+{
+ if (afi == AFI_IP)
+ return IANA_AFI_IPV4;
+ if (afi == AFI_IP6)
+ return IANA_AFI_IPV6;
+ return IANA_AFI_RESERVED;
+}
+
+static inline safi_t safi_iana2int (safi_t safi)
+{
+ if (safi == IANA_SAFI_UNICAST)
+ return SAFI_UNICAST;
+ if (safi == IANA_SAFI_MULTICAST)
+ return SAFI_MULTICAST;
+ if (safi == IANA_SAFI_MPLS_VPN)
+ return SAFI_MPLS_VPN;
+ if (safi == IANA_SAFI_ENCAP)
+ return SAFI_ENCAP;
+ return SAFI_MAX;
+}
+
+static inline safi_t safi_int2iana (safi_t safi)
+{
+ if (safi == SAFI_UNICAST)
+ return IANA_SAFI_UNICAST;
+ if (safi == SAFI_MULTICAST)
+ return IANA_SAFI_MULTICAST;
+ if (safi == SAFI_MPLS_VPN)
+ return IANA_SAFI_MPLS_VPN;
+ if (safi == SAFI_ENCAP)
+ return IANA_SAFI_ENCAP;
+ return IANA_SAFI_RESERVED;
+}
+
#endif /* _ZEBRA_H */
diff --git a/m4/ax_compare_version.m4 b/m4/ax_compare_version.m4
new file mode 100644
index 0000000000..74dc0fdd9a
--- /dev/null
+++ b/m4/ax_compare_version.m4
@@ -0,0 +1,177 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_compare_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+# This macro compares two version strings. Due to the various number of
+# minor-version numbers that can exist, and the fact that string
+# comparisons are not compatible with numeric comparisons, this is not
+# necessarily trivial to do in a autoconf script. This macro makes doing
+# these comparisons easy.
+#
+# The six basic comparisons are available, as well as checking equality
+# limited to a certain number of minor-version levels.
+#
+# The operator OP determines what type of comparison to do, and can be one
+# of:
+#
+# eq - equal (test A == B)
+# ne - not equal (test A != B)
+# le - less than or equal (test A <= B)
+# ge - greater than or equal (test A >= B)
+# lt - less than (test A < B)
+# gt - greater than (test A > B)
+#
+# Additionally, the eq and ne operator can have a number after it to limit
+# the test to that number of minor versions.
+#
+# eq0 - equal up to the length of the shorter version
+# ne0 - not equal up to the length of the shorter version
+# eqN - equal up to N sub-version levels
+# neN - not equal up to N sub-version levels
+#
+# When the condition is true, shell commands ACTION-IF-TRUE are run,
+# otherwise shell commands ACTION-IF-FALSE are run. The environment
+# variable 'ax_compare_version' is always set to either 'true' or 'false'
+# as well.
+#
+# Examples:
+#
+# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
+#
+# would both be true.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
+#
+# would both be false.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
+#
+# would be true because it is only comparing two minor versions.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
+#
+# would be true because it is only comparing the lesser number of minor
+# versions of the two values.
+#
+# Note: The characters that separate the version numbers do not matter. An
+# empty string is the same as version 0. OP is evaluated by autoconf, not
+# configure, so must be a string, not a variable.
+#
+# The author would like to acknowledge Guido Draheim whose advice about
+# the m4_case and m4_ifvaln functions make this macro only include the
+# portions necessary to perform the specific comparison specified by the
+# OP argument in the final configure script.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 11
+
+dnl #########################################################################
+AC_DEFUN([AX_COMPARE_VERSION], [
+ AC_REQUIRE([AC_PROG_AWK])
+
+ # Used to indicate true or false condition
+ ax_compare_version=false
+
+ # Convert the two version strings to be compared into a format that
+ # allows a simple string comparison. The end result is that a version
+ # string of the form 1.12.5-r617 will be converted to the form
+ # 0001001200050617. In other words, each number is zero padded to four
+ # digits, and non digits are removed.
+ AS_VAR_PUSHDEF([A],[ax_compare_version_A])
+ A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ AS_VAR_PUSHDEF([B],[ax_compare_version_B])
+ B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
+ dnl # then the first line is used to determine if the condition is true.
+ dnl # The sed right after the echo is to remove any indented white space.
+ m4_case(m4_tolower($2),
+ [lt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [gt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [le],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],
+ [ge],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],[
+ dnl Split the operator from the subversion count if present.
+ m4_bmatch(m4_substr($2,2),
+ [0],[
+ # A count of zero means use the length of the shorter version.
+ # Determine the number of characters in A and B.
+ ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
+ ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
+
+ # Set A to no more than B's length and B to no more than A's length.
+ A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
+ ],
+ [[0-9]+],[
+ # A count greater than zero means use only that many subversions
+ A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ ],
+ [.+],[
+ AC_WARNING(
+ [illegal OP numeric parameter: $2])
+ ],[])
+
+ # Pad zeros at end of numbers to make same length.
+ ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
+ B="$B`echo $A | sed 's/./0/g'`"
+ A="$ax_compare_version_tmp_A"
+
+ # Check for equality or inequality as necessary.
+ m4_case(m4_tolower(m4_substr($2,0,2)),
+ [eq],[
+ test "x$A" = "x$B" && ax_compare_version=true
+ ],
+ [ne],[
+ test "x$A" != "x$B" && ax_compare_version=true
+ ],[
+ AC_WARNING([illegal OP parameter: $2])
+ ])
+ ])
+
+ AS_VAR_POPDEF([A])dnl
+ AS_VAR_POPDEF([B])dnl
+
+ dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
+ if test "$ax_compare_version" = "true" ; then
+ m4_ifvaln([$4],[$4],[:])dnl
+ m4_ifvaln([$5],[else $5])dnl
+ fi
+]) dnl AX_COMPARE_VERSION
diff --git a/m4/ax_prog_perl_modules.m4 b/m4/ax_prog_perl_modules.m4
new file mode 100644
index 0000000000..11a326c930
--- /dev/null
+++ b/m4/ax_prog_perl_modules.m4
@@ -0,0 +1,77 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_prog_perl_modules.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PROG_PERL_MODULES([MODULES], [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+# Checks to see if the given perl modules are available. If true the shell
+# commands in ACTION-IF-TRUE are executed. If not the shell commands in
+# ACTION-IF-FALSE are run. Note if $PERL is not set (for example by
+# calling AC_CHECK_PROG, or AC_PATH_PROG), AC_CHECK_PROG(PERL, perl, perl)
+# will be run.
+#
+# MODULES is a space separated list of module names. To check for a
+# minimum version of a module, append the version number to the module
+# name, separated by an equals sign.
+#
+# Example:
+#
+# AX_PROG_PERL_MODULES( Text::Wrap Net::LDAP=1.0.3, ,
+# AC_MSG_WARN(Need some Perl modules)
+#
+# LICENSE
+#
+# Copyright (c) 2009 Dean Povey <povey@wedgetail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 7
+
+AU_ALIAS([AC_PROG_PERL_MODULES], [AX_PROG_PERL_MODULES])
+AC_DEFUN([AX_PROG_PERL_MODULES],[dnl
+
+m4_define([ax_perl_modules])
+m4_foreach([ax_perl_module], m4_split(m4_normalize([$1])),
+ [
+ m4_append([ax_perl_modules],
+ [']m4_bpatsubst(ax_perl_module,=,[ ])[' ])
+ ])
+
+# Make sure we have perl
+if test -z "$PERL"; then
+AC_CHECK_PROG(PERL,perl,perl)
+fi
+
+if test "x$PERL" != x; then
+ ax_perl_modules_failed=0
+ for ax_perl_module in ax_perl_modules; do
+ AC_MSG_CHECKING(for perl module $ax_perl_module)
+
+ # Would be nice to log result here, but can't rely on autoconf internals
+ $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1
+ if test $? -ne 0; then
+ AC_MSG_RESULT(no);
+ ax_perl_modules_failed=1
+ else
+ AC_MSG_RESULT(ok);
+ fi
+ done
+
+ # Run optional shell commands
+ if test "$ax_perl_modules_failed" = 0; then
+ :
+ $2
+ else
+ :
+ $3
+ fi
+else
+ AC_MSG_WARN(could not find perl)
+fi])dnl
diff --git a/m4/pkg.m4 b/m4/pkg.m4
new file mode 100644
index 0000000000..c5b26b52e6
--- /dev/null
+++ b/m4/pkg.m4
@@ -0,0 +1,214 @@
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+# serial 1 (pkg-config-0.24)
+#
+# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists. Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+# only at the first occurence in configure.ac, so if the first place
+# it's called might be skipped (such as if it is within an "if", you
+# have to call PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes ],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])# PKG_CHECK_MODULES
+
+
+# PKG_INSTALLDIR(DIRECTORY)
+# -------------------------
+# Substitutes the variable pkgconfigdir as the location where a module
+# should install pkg-config .pc files. By default the directory is
+# $libdir/pkgconfig, but the default can be changed by passing
+# DIRECTORY. The user can override through the --with-pkgconfigdir
+# parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+]) dnl PKG_INSTALLDIR
+
+
+# PKG_NOARCH_INSTALLDIR(DIRECTORY)
+# -------------------------
+# Substitutes the variable noarch_pkgconfigdir as the location where a
+# module should install arch-independent pkg-config .pc files. By
+# default the directory is $datadir/pkgconfig, but the default can be
+# changed by passing DIRECTORY. The user can override through the
+# --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+]) dnl PKG_NOARCH_INSTALLDIR
+
+
+# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# -------------------------------------------
+# Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])# PKG_CHECK_VAR
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index f75a35fa50..2e31535d24 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -433,7 +433,7 @@ ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
else
{
summary->type = route->type;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &summary->changed);
+ monotime(&summary->changed);
}
summary->path.router_bits = route->path.router_bits;
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index bbab8598b8..198526a0eb 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -388,7 +388,7 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec)
{
- result = timeval_elapsed (recent_relative_time (), oa->ts_spf);
+ result = monotime_since(&oa->ts_spf, NULL);
if (result/TIMER_SECOND_MICRO > 0)
{
vty_out (vty, "SPF last executed %ld.%lds ago%s",
@@ -435,25 +435,32 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
DEFUN (area_range,
area_range_cmd,
- "area A.B.C.D range X:X::X:X/M",
- "OSPF area parameters\n"
- OSPF6_AREA_ID_STR
+ "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
+ "OSPF6 area ID as a decimal value\n"
"Configured address range\n"
"Specify IPv6 prefix\n"
- )
+ "Advertise\n"
+ "Do not advertise\n"
+ "User specified metric for this range\n"
+ "Advertised metric for this range\n")
{
+ int idx_ipv4 = 1;
+ int idx_ipv6_prefixlen = 3;
+ int idx_type = 4;
int ret;
struct ospf6_area *oa;
struct prefix prefix;
struct ospf6_route *range;
u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
- OSPF6_CMD_AREA_GET (argv[0], oa);
+ OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa);
- ret = str2prefix (argv[1], &prefix);
+ ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &prefix);
if (ret != 1 || prefix.family != AF_INET6)
{
- vty_out (vty, "Malformed argument: %s%s", argv[1], VNL);
+ vty_out (vty, "Malformed argument: %s%s", argv[idx_ipv6_prefixlen]->arg, VNL);
return CMD_SUCCESS;
}
@@ -467,26 +474,26 @@ DEFUN (area_range,
range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
}
- if (argc > 2)
+ if (argc > idx_type)
{
- if (strcmp (argv[2], "not-advertise") == 0)
+ if (strmatch (argv[idx_type]->text, "not-advertise"))
{
SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
}
- else if (strcmp (argv[2], "advertise") == 0)
+ else if (strmatch (argv[idx_type]->text, "advertise"))
{
UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
}
else
{
- VTY_GET_INTEGER_RANGE ("cost", cost, argv[2], 0, OSPF_LS_INFINITY);
+ VTY_GET_INTEGER_RANGE ("cost", cost, argv[5]->arg, 0, OSPF_LS_INFINITY);
UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
}
}
range->path.u.cost_config = cost;
- zlog_debug ("%s: for prefix %s, flag = %x\n", __func__, argv[1], range->flag);
+ zlog_debug ("%s: for prefix %s, flag = %x\n", __func__, argv[idx_ipv6_prefixlen]->arg, range->flag);
if (range->rnode == NULL)
{
ospf6_route_add (range, oa->range_table);
@@ -501,64 +508,39 @@ DEFUN (area_range,
return CMD_SUCCESS;
}
-ALIAS (area_range,
- area_range_advertise_cmd,
- "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
- "OSPF area parameters\n"
- OSPF6_AREA_ID_STR
- "Configured address range\n"
- "Specify IPv6 prefix\n"
- )
-
-ALIAS (area_range,
- area_range_cost_cmd,
- "area (A.B.C.D|<0-4294967295>) range X:X::X:X/M cost <0-16777215>",
- "OSPF area parameters\n"
- OSPF6_AREA_ID_STR
- "Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n"
- "User specified metric for this range\n"
- "Advertised metric for this range\n")
-
-ALIAS (area_range,
- area_range_advertise_cost_cmd,
- "area (A.B.C.D|<0-4294967295>) range X:X::X:X/M advertise cost <0-16777215>",
- "OSPF area parameters\n"
- OSPF6_AREA_ID_STR
- "Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n"
- "User specified metric for this range\n"
- "Advertised metric for this range\n")
-
DEFUN (no_area_range,
no_area_range_cmd,
- "no area A.B.C.D range X:X::X:X/M",
+ "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
NO_STR
- "OSPF area parameters\n"
- OSPF6_AREA_ID_STR
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
+ "OSPF6 area ID as a decimal value\n"
"Configured address range\n"
- "Specify IPv6 prefix\n")
+ "Specify IPv6 prefix\n"
+ "Advertise\n"
+ "Do not advertise\n"
+ "User specified metric for this range\n"
+ "Advertised metric for this range\n")
{
+ int idx_ipv4 = 2;
int ret;
struct ospf6_area *oa;
struct prefix prefix;
struct ospf6_route *range, *route;
- OSPF6_CMD_AREA_GET (argv[0], oa);
- argc--;
- argv++;
+ OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa);
- ret = str2prefix (argv[0], &prefix);
+ ret = str2prefix (argv[idx_ipv4]->arg, &prefix);
if (ret != 1 || prefix.family != AF_INET6)
{
- vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
+ vty_out (vty, "Malformed argument: %s%s", argv[idx_ipv4]->arg, VNL);
return CMD_SUCCESS;
}
range = ospf6_route_lookup (&prefix, oa->range_table);
if (range == NULL)
{
- vty_out (vty, "Range %s does not exists.%s", argv[0], VNL);
+ vty_out (vty, "Range %s does not exists.%s", argv[idx_ipv4]->arg, VNL);
return CMD_SUCCESS;
}
@@ -580,36 +562,8 @@ DEFUN (no_area_range,
return CMD_SUCCESS;
}
-ALIAS (no_area_range,
- no_area_range_advertise_cmd,
- "no area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
- NO_STR
- "OSPF area parameters\n"
- OSPF6_AREA_ID_STR
- "Configured address range\n"
- "Specify IPv6 prefix\n")
-ALIAS (no_area_range,
- no_area_range_cost_cmd,
- "no area (A.B.C.D|<0-4294967295>) range X:X::X:X/M cost <0-16777215>",
- NO_STR
- "OSPF area parameters\n"
- OSPF6_AREA_ID_STR
- "Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n"
- "User specified metric for this range\n"
- "Advertised metric for this range\n")
-ALIAS (no_area_range,
- no_area_range_advertise_cost_cmd,
- "no area (A.B.C.D|<0-4294967295>) range X:X::X:X/M advertise cost <0-16777215>",
- NO_STR
- "OSPF area parameters\n"
- OSPF6_AREA_ID_STR
- "Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n"
- "User specified metric for this range\n"
- "Advertised metric for this range\n")
void
ospf6_area_config_write (struct vty *vty)
@@ -664,30 +618,30 @@ ospf6_area_config_write (struct vty *vty)
DEFUN (area_filter_list,
area_filter_list_cmd,
- "area A.B.C.D filter-list prefix WORD (in|out)",
- "OSPFv6 area parameters\n"
- "OSPFv6 area ID in IP address format\n"
- "Filter networks between OSPFv6 areas\n"
- "Filter prefixes between OSPFv6 areas\n"
+ "area A.B.C.D filter-list prefix WORD <in|out>",
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
+ "Filter networks between OSPF6 areas\n"
+ "Filter prefixes between OSPF6 areas\n"
"Name of an IPv6 prefix-list\n"
"Filter networks sent to this area\n"
"Filter networks sent from this area\n")
{
+ int idx_ipv4 = 1;
+ int idx_word = 4;
struct ospf6_area *area;
struct prefix_list *plist;
- OSPF6_CMD_AREA_GET (argv[0], area);
- argc--;
- argv++;
+ OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, area);
- plist = prefix_list_lookup (AFI_IP6, argv[0]);
- if (strncmp (argv[1], "in", 2) == 0)
+ plist = prefix_list_lookup (AFI_IP6, argv[idx_ipv4]->arg);
+ if (strncmp (argv[idx_word]->arg, "in", 2) == 0)
{
PREFIX_LIST_IN (area) = plist;
if (PREFIX_NAME_IN (area))
free (PREFIX_NAME_IN (area));
- PREFIX_NAME_IN (area) = strdup (argv[0]);
+ PREFIX_NAME_IN (area) = strdup (argv[idx_ipv4]->arg);
ospf6_abr_reimport (area);
}
else
@@ -696,7 +650,7 @@ DEFUN (area_filter_list,
if (PREFIX_NAME_OUT (area))
free (PREFIX_NAME_OUT (area));
- PREFIX_NAME_OUT (area) = strdup (argv[0]);
+ PREFIX_NAME_OUT (area) = strdup (argv[idx_ipv4]->arg);
ospf6_abr_enable_area (area);
}
@@ -705,26 +659,26 @@ DEFUN (area_filter_list,
DEFUN (no_area_filter_list,
no_area_filter_list_cmd,
- "no area A.B.C.D filter-list prefix WORD (in|out)",
+ "no area A.B.C.D filter-list prefix WORD <in|out>",
NO_STR
- "OSPFv6 area parameters\n"
- "OSPFv6 area ID in IP address format\n"
- "Filter networks between OSPFv6 areas\n"
- "Filter prefixes between OSPFv6 areas\n"
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
+ "Filter networks between OSPF6 areas\n"
+ "Filter prefixes between OSPF6 areas\n"
"Name of an IPv6 prefix-list\n"
"Filter networks sent to this area\n"
"Filter networks sent from this area\n")
{
+ int idx_ipv4 = 2;
+ int idx_word = 5;
struct ospf6_area *area;
- OSPF6_CMD_AREA_GET (argv[0], area);
- argc--;
- argv++;
+ OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, area);
- if (strncmp (argv[1], "in", 2) == 0)
+ if (strncmp (argv[idx_word]->arg, "in", 2) == 0)
{
if (PREFIX_NAME_IN (area))
- if (strcmp (PREFIX_NAME_IN (area), argv[0]) != 0)
+ if (strcmp (PREFIX_NAME_IN (area), argv[idx_ipv4]->arg) != 0)
return CMD_SUCCESS;
PREFIX_LIST_IN (area) = NULL;
@@ -737,7 +691,7 @@ DEFUN (no_area_filter_list,
else
{
if (PREFIX_NAME_OUT (area))
- if (strcmp (PREFIX_NAME_OUT (area), argv[0]) != 0)
+ if (strcmp (PREFIX_NAME_OUT (area), argv[idx_ipv4]->arg) != 0)
return CMD_SUCCESS;
PREFIX_LIST_OUT (area) = NULL;
@@ -754,24 +708,26 @@ DEFUN (no_area_filter_list,
DEFUN (area_import_list,
area_import_list_cmd,
"area A.B.C.D import-list NAME",
- "OSPFv6 area parameters\n"
- "OSPFv6 area ID in IP address format\n"
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
"Set the filter for networks from other areas announced to the specified one\n"
"Name of the acess-list\n")
{
+ int idx_ipv4 = 1;
+ int idx_name = 3;
struct ospf6_area *area;
struct access_list *list;
- OSPF6_CMD_AREA_GET(argv[0], area);
+ OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
- list = access_list_lookup (AFI_IP6, argv[1]);
+ list = access_list_lookup (AFI_IP6, argv[idx_name]->arg);
IMPORT_LIST (area) = list;
if (IMPORT_NAME (area))
free (IMPORT_NAME (area));
- IMPORT_NAME (area) = strdup (argv[1]);
+ IMPORT_NAME (area) = strdup (argv[idx_name]->arg);
ospf6_abr_reimport (area);
return CMD_SUCCESS;
@@ -780,14 +736,16 @@ DEFUN (area_import_list,
DEFUN (no_area_import_list,
no_area_import_list_cmd,
"no area A.B.C.D import-list NAME",
- "OSPFv6 area parameters\n"
- "OSPFv6 area ID in IP address format\n"
+ NO_STR
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
"Unset the filter for networks announced to other areas\n"
- "NAme of the access-list\n")
+ "Name of the access-list\n")
{
+ int idx_ipv4 = 2;
struct ospf6_area *area;
- OSPF6_CMD_AREA_GET(argv[0], area);
+ OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
IMPORT_LIST (area) = 0;
@@ -803,24 +761,26 @@ DEFUN (no_area_import_list,
DEFUN (area_export_list,
area_export_list_cmd,
"area A.B.C.D export-list NAME",
- "OSPFv6 area parameters\n"
- "OSPFv6 area ID in IP address format\n"
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
"Set the filter for networks announced to other areas\n"
"Name of the acess-list\n")
{
+ int idx_ipv4 = 1;
+ int idx_name = 3;
struct ospf6_area *area;
struct access_list *list;
- OSPF6_CMD_AREA_GET(argv[0], area);
+ OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
- list = access_list_lookup (AFI_IP6, argv[1]);
+ list = access_list_lookup (AFI_IP6, argv[idx_name]->arg);
EXPORT_LIST (area) = list;
if (EXPORT_NAME (area))
free (EXPORT_NAME (area));
- EXPORT_NAME (area) = strdup (argv[1]);
+ EXPORT_NAME (area) = strdup (argv[idx_name]->arg);
ospf6_abr_enable_area (area);
return CMD_SUCCESS;
@@ -829,14 +789,16 @@ DEFUN (area_export_list,
DEFUN (no_area_export_list,
no_area_export_list_cmd,
"no area A.B.C.D export-list NAME",
- "OSPFv6 area parameters\n"
- "OSPFv6 area ID in IP address format\n"
+ NO_STR
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
"Unset the filter for networks announced to other areas\n"
"Name of the access-list\n")
{
+ int idx_ipv4 = 2;
struct ospf6_area *area;
- OSPF6_CMD_AREA_GET(argv[0], area);
+ OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
EXPORT_LIST (area) = 0;
@@ -895,6 +857,7 @@ DEFUN (show_ipv6_ospf6_area_spf_tree,
"Shortest Path First caculation\n"
"Show SPF tree\n")
{
+ int idx_ipv4 = 4;
u_int32_t area_id;
struct ospf6_area *oa;
struct ospf6_vertex *root;
@@ -905,15 +868,15 @@ DEFUN (show_ipv6_ospf6_area_spf_tree,
ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
- if (inet_pton (AF_INET, argv[0], &area_id) != 1)
+ if (inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
{
- vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
+ vty_out (vty, "Malformed Area-ID: %s%s", argv[idx_ipv4]->arg, VNL);
return CMD_SUCCESS;
}
oa = ospf6_area_lookup (area_id, ospf6);
if (oa == NULL)
{
- vty_out (vty, "No such Area: %s%s", argv[0], VNL);
+ vty_out (vty, "No such Area: %s%s", argv[idx_ipv4]->arg, VNL);
return CMD_SUCCESS;
}
@@ -936,10 +899,14 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
SHOW_STR
IP6_STR
OSPF6_STR
- "Shortest Path First caculation\n"
+ "Shortest Path First calculation\n"
"Show SPF tree\n"
- "Specify root's router-id to calculate another router's SPF tree\n")
+ "Specify root's router-id to calculate another router's SPF tree\n"
+ "OSPF6 area parameters\n"
+ OSPF6_AREA_ID_STR)
{
+ int idx_ipv4 = 5;
+ int idx_ipv4_2 = 7;
u_int32_t area_id;
struct ospf6_area *oa;
struct ospf6_vertex *root;
@@ -951,18 +918,18 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
OSPF6_CMD_CHECK_RUNNING ();
- inet_pton (AF_INET, argv[0], &router_id);
+ inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id);
ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
- if (inet_pton (AF_INET, argv[1], &area_id) != 1)
+ if (inet_pton (AF_INET, argv[idx_ipv4_2]->arg, &area_id) != 1)
{
- vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VNL);
+ vty_out (vty, "Malformed Area-ID: %s%s", argv[idx_ipv4_2]->arg, VNL);
return CMD_SUCCESS;
}
oa = ospf6_area_lookup (area_id, ospf6);
if (oa == NULL)
{
- vty_out (vty, "No such Area: %s%s", argv[1], VNL);
+ vty_out (vty, "No such Area: %s%s", argv[idx_ipv4_2]->arg, VNL);
return CMD_SUCCESS;
}
@@ -992,15 +959,16 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
DEFUN (ospf6_area_stub,
ospf6_area_stub_cmd,
- "area (A.B.C.D|<0-4294967295>) stub",
+ "area <A.B.C.D|(0-4294967295)> stub",
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
"OSPF6 area ID as a decimal value\n"
"Configure OSPF6 area as stub\n")
{
+ int idx_ipv4_number = 1;
struct ospf6_area *area;
- OSPF6_CMD_AREA_GET(argv[0], area);
+ OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
if (!ospf6_area_stub_set (ospf6, area))
{
@@ -1016,16 +984,17 @@ DEFUN (ospf6_area_stub,
DEFUN (ospf6_area_stub_no_summary,
ospf6_area_stub_no_summary_cmd,
- "area (A.B.C.D|<0-4294967295>) stub no-summary",
+ "area <A.B.C.D|(0-4294967295)> stub no-summary",
"OSPF6 stub parameters\n"
"OSPF6 area ID in IP address format\n"
"OSPF6 area ID as a decimal value\n"
"Configure OSPF6 area as stub\n"
"Do not inject inter-area routes into stub\n")
{
+ int idx_ipv4_number = 1;
struct ospf6_area *area;
- OSPF6_CMD_AREA_GET(argv[0], area);
+ OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
if (!ospf6_area_stub_set (ospf6, area))
{
@@ -1041,16 +1010,17 @@ DEFUN (ospf6_area_stub_no_summary,
DEFUN (no_ospf6_area_stub,
no_ospf6_area_stub_cmd,
- "no area (A.B.C.D|<0-4294967295>) stub",
+ "no area <A.B.C.D|(0-4294967295)> stub",
NO_STR
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
"OSPF6 area ID as a decimal value\n"
"Configure OSPF6 area as stub\n")
{
+ int idx_ipv4_number = 2;
struct ospf6_area *area;
- OSPF6_CMD_AREA_GET(argv[0], area);
+ OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
ospf6_area_stub_unset (ospf6, area);
ospf6_area_no_summary_unset (ospf6, area);
@@ -1060,7 +1030,7 @@ DEFUN (no_ospf6_area_stub,
DEFUN (no_ospf6_area_stub_no_summary,
no_ospf6_area_stub_no_summary_cmd,
- "no area (A.B.C.D|<0-4294967295>) stub no-summary",
+ "no area <A.B.C.D|(0-4294967295)> stub no-summary",
NO_STR
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
@@ -1068,9 +1038,10 @@ DEFUN (no_ospf6_area_stub_no_summary,
"Configure OSPF6 area as stub\n"
"Do not inject inter-area routes into area\n")
{
+ int idx_ipv4_number = 2;
struct ospf6_area *area;
- OSPF6_CMD_AREA_GET(argv[0], area);
+ OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
ospf6_area_stub_unset (ospf6, area);
ospf6_area_no_summary_unset (ospf6, area);
@@ -1086,13 +1057,7 @@ ospf6_area_init (void)
install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
install_element (OSPF6_NODE, &area_range_cmd);
- install_element (OSPF6_NODE, &area_range_advertise_cmd);
- install_element (OSPF6_NODE, &area_range_cost_cmd);
- install_element (OSPF6_NODE, &area_range_advertise_cost_cmd);
install_element (OSPF6_NODE, &no_area_range_cmd);
- install_element (OSPF6_NODE, &no_area_range_advertise_cmd);
- install_element (OSPF6_NODE, &no_area_range_cost_cmd);
- install_element (OSPF6_NODE, &no_area_range_advertise_cost_cmd);
install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd);
install_element (OSPF6_NODE, &ospf6_area_stub_cmd);
install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd);
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 7c59dece79..643519e3fa 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -96,7 +96,7 @@ ospf6_as_external_lsa_originate (struct ospf6_route *route)
if (info->tag)
SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
else
- UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
+ UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
/* Set metric */
OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
@@ -688,13 +688,13 @@ DEFUN (ospf6_redistribute,
ospf6_redistribute_cmd,
"redistribute " FRR_REDIST_STR_OSPF6D,
"Redistribute\n"
- FRR_REDIST_HELP_STR_OSPF6D
- )
+ FRR_REDIST_HELP_STR_OSPF6D)
{
int type;
- type = proto_redistnum(AFI_IP6, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
+ char *proto = argv[argc - 1]->text;
+ type = proto_redistnum(AFI_IP6, proto);
+ if (type < 0)
return CMD_WARNING;
ospf6_asbr_redistribute_unset (type);
@@ -708,33 +708,38 @@ DEFUN (ospf6_redistribute_routemap,
"Redistribute\n"
FRR_REDIST_HELP_STR_OSPF6D
"Route map reference\n"
- "Route map name\n"
- )
+ "Route map name\n")
{
+ int idx_protocol = 1;
+ int idx_word = 3;
int type;
- type = proto_redistnum(AFI_IP6, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
+ char *proto = argv[idx_protocol]->text;
+ type = proto_redistnum(AFI_IP6, proto);
+ if (type < 0)
return CMD_WARNING;
ospf6_asbr_redistribute_unset (type);
- ospf6_asbr_routemap_set (type, argv[1]);
+ ospf6_asbr_routemap_set (type, argv[idx_word]->arg);
ospf6_asbr_redistribute_set (type);
return CMD_SUCCESS;
}
DEFUN (no_ospf6_redistribute,
no_ospf6_redistribute_cmd,
- "no redistribute " FRR_REDIST_STR_OSPF6D,
+ "no redistribute " FRR_REDIST_STR_OSPF6D " [route-map WORD]",
NO_STR
"Redistribute\n"
FRR_REDIST_HELP_STR_OSPF6D
- )
+ "Route map reference\n"
+ "Route map name\n")
{
+ int idx_protocol = 2;
int type;
- type = proto_redistnum(AFI_IP6, argv[0]);
- if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
+ char *proto = argv[idx_protocol]->text;
+ type = proto_redistnum(AFI_IP6, proto);
+ if (type < 0)
return CMD_WARNING;
ospf6_asbr_redistribute_unset (type);
@@ -742,15 +747,6 @@ DEFUN (no_ospf6_redistribute,
return CMD_SUCCESS;
}
-ALIAS (no_ospf6_redistribute,
- no_ospf6_redistribute_route_map_cmd,
- "no redistribute " FRR_REDIST_STR_OSPF6D " route-map WORD",
- NO_STR
- "Redistribute\n"
- FRR_REDIST_HELP_STR_OSPF6D
- "Route map reference\n"
- "Route map name\n")
-
int
ospf6_redistribute_config_write (struct vty *vty)
{
@@ -1099,173 +1095,39 @@ route_map_command_status (struct vty *vty, int ret)
return CMD_WARNING;
}
-/* add "match address" */
-DEFUN (ospf6_routemap_match_address_prefixlist,
- ospf6_routemap_match_address_prefixlist_cmd,
- "match ipv6 address prefix-list WORD",
- "Match values\n"
- IPV6_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IPv6 prefix-list name\n")
-{
- int ret = route_map_add_match ((struct route_map_index *) vty->index,
- "ipv6 address prefix-list", argv[0]);
- return route_map_command_status (vty, ret);
-}
-
-/* delete "match address" */
-DEFUN (ospf6_routemap_no_match_address_prefixlist,
- ospf6_routemap_no_match_address_prefixlist_cmd,
- "no match ipv6 address prefix-list WORD",
- NO_STR
- "Match values\n"
- IPV6_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IPv6 prefix-list name\n")
-{
- int ret = route_map_delete_match ((struct route_map_index *) vty->index,
- "ipv6 address prefix-list", argv[0]);
- return route_map_command_status (vty, ret);
-}
-
-/* "match interface" */
-DEFUN (ospf6_routemap_match_interface,
- ospf6_routemap_match_interface_cmd,
- "match interface WORD",
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-{
- return route_map_add_match ((struct route_map_index *) vty->index,
- "interface", argv[0]);
-}
-
-/* "no match interface WORD" */
-DEFUN (ospf6_routemap_no_match_interface,
- ospf6_routemap_no_match_interface_cmd,
- "no match interface",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n")
-{
- int ret = route_map_delete_match ((struct route_map_index *) vty->index,
- "interface", (argc == 0) ? NULL : argv[0]);
- return route_map_command_status (vty, ret);
-}
-
-ALIAS (ospf6_routemap_no_match_interface,
- ospf6_routemap_no_match_interface_val_cmd,
- "no match interface WORD",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-
-/* add "match tag" */
-DEFUN (ospf6_routemap_match_tag,
- ospf6_routemap_match_tag_cmd,
- "match tag <1-4294967295>",
- MATCH_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
-{
- int ret = route_map_add_match ((struct route_map_index *) vty->index,
- "tag", argv[0]);
- return route_map_command_status (vty, ret);
-}
-
-/* delete "match tag" */
-DEFUN (ospf6_routemap_no_match_tag,
- ospf6_routemap_no_match_tag_cmd,
- "no match tag",
- NO_STR
- MATCH_STR
- "Tag value for routing protocol\n")
-{
- int ret = route_map_delete_match ((struct route_map_index *) vty->index,
- "tag", argc ? argv[0] : NULL);
- return route_map_command_status (vty, ret);
-}
-
-ALIAS (ospf6_routemap_no_match_tag,
- ospf6_routemap_no_match_tag_val_cmd,
- "no match tag <1-4294967295>",
- NO_STR
- MATCH_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
-
/* add "set metric-type" */
DEFUN (ospf6_routemap_set_metric_type,
ospf6_routemap_set_metric_type_cmd,
- "set metric-type (type-1|type-2)",
+ "set metric-type <type-1|type-2>",
"Set value\n"
"Type of metric\n"
"OSPF6 external type 1 metric\n"
"OSPF6 external type 2 metric\n")
{
- int ret = route_map_add_set ((struct route_map_index *) vty->index,
- "metric-type", argv[0]);
+ VTY_DECLVAR_CONTEXT(route_map_index, route_map_index);
+ int idx_external = 2;
+ int ret = route_map_add_set (route_map_index,
+ "metric-type", argv[idx_external]->arg);
return route_map_command_status (vty, ret);
}
/* delete "set metric-type" */
DEFUN (ospf6_routemap_no_set_metric_type,
ospf6_routemap_no_set_metric_type_cmd,
- "no set metric-type (type-1|type-2)",
+ "no set metric-type <type-1|type-2>",
NO_STR
"Set value\n"
"Type of metric\n"
"OSPF6 external type 1 metric\n"
"OSPF6 external type 2 metric\n")
{
- int ret = route_map_delete_set ((struct route_map_index *) vty->index,
- "metric-type", argv[0]);
- return route_map_command_status (vty, ret);
-}
-
-/* add "set metric" */
-DEFUN (set_metric,
- set_metric_cmd,
- "set metric <0-4294967295>",
- "Set value\n"
- "Metric value\n"
- "Metric value\n")
-{
- int ret = route_map_add_set ((struct route_map_index *) vty->index,
- "metric", argv[0]);
- return route_map_command_status (vty, ret);
-}
-
-/* delete "set metric" */
-DEFUN (no_set_metric,
- no_set_metric_cmd,
- "no set metric",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n")
-{
- int ret = 0;
-
- if (argc == 0)
- ret = route_map_delete_set ((struct route_map_index *) vty->index,
- "metric", NULL);
- else
- ret = route_map_delete_set ((struct route_map_index *) vty->index,
- "metric", argv[0]);
+ VTY_DECLVAR_CONTEXT(route_map_index, route_map_index);
+ int idx_external = 3;
+ int ret = route_map_delete_set (route_map_index,
+ "metric-type", argv[idx_external]->arg);
return route_map_command_status (vty, ret);
}
-ALIAS (no_set_metric,
- no_set_metric_val_cmd,
- "no set metric <0-4294967295>",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n"
- "Metric value\n")
-
/* add "set forwarding-address" */
DEFUN (ospf6_routemap_set_forwarding,
ospf6_routemap_set_forwarding_cmd,
@@ -1274,8 +1136,10 @@ DEFUN (ospf6_routemap_set_forwarding,
"Forwarding Address\n"
"IPv6 Address\n")
{
- int ret = route_map_add_set ((struct route_map_index *) vty->index,
- "forwarding-address", argv[0]);
+ VTY_DECLVAR_CONTEXT(route_map_index, route_map_index);
+ int idx_ipv6 = 2;
+ int ret = route_map_add_set (route_map_index,
+ "forwarding-address", argv[idx_ipv6]->arg);
return route_map_command_status (vty, ret);
}
@@ -1288,45 +1152,13 @@ DEFUN (ospf6_routemap_no_set_forwarding,
"Forwarding Address\n"
"IPv6 Address\n")
{
- int ret = route_map_delete_set ((struct route_map_index *) vty->index,
- "forwarding-address", argv[0]);
- return route_map_command_status (vty, ret);
-}
-
-/* add "set tag" */
-DEFUN (ospf6_routemap_set_tag,
- ospf6_routemap_set_tag_cmd,
- "set tag <1-4294967295>",
- "Set value\n"
- "Tag value for routing protocol\n"
- "Tag value\n")
-{
- int ret = route_map_add_set ((struct route_map_index *) vty->index,
- "tag", argv[0]);
- return route_map_command_status (vty, ret);
-}
-
-/* delete "set tag" */
-DEFUN (ospf6_routemap_no_set_tag,
- ospf6_routemap_no_set_tag_cmd,
- "no set tag",
- NO_STR
- "Set value\n"
- "Tag value for routing protocol\n")
-{
- int ret = route_map_delete_set ((struct route_map_index *) vty->index,
- "tag", argc ? argv[0] : NULL);
+ VTY_DECLVAR_CONTEXT(route_map_index, route_map_index);
+ int idx_ipv6 = 3;
+ int ret = route_map_delete_set (route_map_index,
+ "forwarding-address", argv[idx_ipv6]->arg);
return route_map_command_status (vty, ret);
}
-ALIAS (ospf6_routemap_no_set_tag,
- ospf6_routemap_no_set_tag_val_cmd,
- "no set tag <1-4294967295>",
- NO_STR
- "Set value\n"
- "Tag value for routing protocol\n"
- "Tag value\n")
-
static void
ospf6_routemap_init (void)
{
@@ -1335,6 +1167,9 @@ ospf6_routemap_init (void)
route_map_add_hook (ospf6_asbr_routemap_update);
route_map_delete_hook (ospf6_asbr_routemap_update);
+ route_map_set_metric_hook (generic_set_add);
+ route_map_no_set_metric_hook (generic_set_delete);
+
route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
route_map_install_match (&ospf6_routemap_rule_match_interface_cmd);
route_map_install_match (&ospf6_routemap_rule_match_tag_cmd);
@@ -1344,37 +1179,13 @@ ospf6_routemap_init (void)
route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
route_map_install_set (&ospf6_routemap_rule_set_tag_cmd);
- /* Match address prefix-list */
- install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
- install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
-
- /* Match interface */
- install_element (RMAP_NODE, &ospf6_routemap_match_interface_cmd);
- install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_cmd);
- install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_val_cmd);
-
- /* Match tag */
- install_element (RMAP_NODE, &ospf6_routemap_match_tag_cmd);
- install_element (RMAP_NODE, &ospf6_routemap_no_match_tag_cmd);
- install_element (RMAP_NODE, &ospf6_routemap_no_match_tag_val_cmd);
-
/* ASE Metric Type (e.g. Type-1/Type-2) */
install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
/* ASE Metric */
- install_element (RMAP_NODE, &set_metric_cmd);
- install_element (RMAP_NODE, &no_set_metric_cmd);
- install_element (RMAP_NODE, &no_set_metric_val_cmd);
-
- /* Forwarding address */
install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
-
- /* Tag */
- install_element (RMAP_NODE, &ospf6_routemap_set_tag_cmd);
- install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_cmd);
- install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_val_cmd);
}
@@ -1529,7 +1340,6 @@ ospf6_asbr_init (void)
install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
- install_element (OSPF6_NODE, &no_ospf6_redistribute_route_map_cmd);
}
void
@@ -1593,5 +1403,3 @@ install_element_ospf6_debug_asbr ()
install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
}
-
-
diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c
index f9bb6f0031..fed5021208 100644
--- a/ospf6d/ospf6_bfd.c
+++ b/ospf6d/ospf6_bfd.c
@@ -245,7 +245,7 @@ ospf6_bfd_interface_dest_update (int command, struct zclient *zclient,
old_status = bfd_info->status;
bfd_info->status = status;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv);
+ monotime(&tv);
bfd_info->last_update = tv.tv_sec;
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
@@ -328,10 +328,8 @@ DEFUN (ipv6_ospf6_bfd,
"Enables BFD support\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -346,7 +344,7 @@ DEFUN (ipv6_ospf6_bfd,
DEFUN (ipv6_ospf6_bfd_param,
ipv6_ospf6_bfd_param_cmd,
- "ipv6 ospf6 bfd " BFD_CMD_DETECT_MULT_RANGE BFD_CMD_MIN_RX_RANGE BFD_CMD_MIN_TX_RANGE,
+ "ipv6 ospf6 bfd (2-255) (50-60000) (50-60000)",
IP6_STR
OSPF6_STR
"Enables BFD support\n"
@@ -354,14 +352,16 @@ DEFUN (ipv6_ospf6_bfd_param,
"Required min receive interval\n"
"Desired min transmit interval\n")
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 5;
struct ospf6_interface *oi;
- struct interface *ifp;
u_int32_t rx_val;
u_int32_t tx_val;
u_int8_t dm_val;
int ret;
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -369,7 +369,7 @@ DEFUN (ipv6_ospf6_bfd_param,
oi = ospf6_interface_create (ifp);
assert (oi);
- if ((ret = bfd_validate_param (vty, argv[0], argv[1], argv[2], &dm_val,
+ if ((ret = bfd_validate_param (vty, argv[idx_number]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg, &dm_val,
&rx_val, &tx_val)) != CMD_SUCCESS)
return ret;
@@ -387,10 +387,8 @@ DEFUN (no_ipv6_ospf6_bfd,
"Disables BFD support\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c
index 14c16c0241..6ac93d8984 100644
--- a/ospf6d/ospf6_flood.c
+++ b/ospf6d/ospf6_flood.c
@@ -224,7 +224,7 @@ ospf6_install_lsa (struct ospf6_lsa *lsa)
ospf6_flood_clear (old);
}
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
if (! OSPF6_LSA_IS_MAXAGE (lsa))
lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec);
@@ -862,7 +862,7 @@ ospf6_receive_lsa (struct ospf6_neighbor *from,
if (old)
{
struct timeval now, res;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timersub (&now, &old->installed, &res);
time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec/1000);
if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival)
@@ -875,7 +875,7 @@ ospf6_receive_lsa (struct ospf6_neighbor *from,
}
}
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
+ monotime(&new->received);
if (is_debug)
zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 65fff1b16c..8998799cf6 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -46,6 +46,7 @@
#include "ospf6_bfd.h"
DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
+DEFINE_QOBJ_TYPE(ospf6_interface)
unsigned char conf_debug_ospf6_interface = 0;
@@ -212,6 +213,8 @@ ospf6_interface_create (struct interface *ifp)
oi->ifmtu = iobuflen;
}
+ QOBJ_REG (oi, ospf6_interface);
+
oi->lsupdate_list = ospf6_lsdb_create (oi);
oi->lsack_list = ospf6_lsdb_create (oi);
oi->lsdb = ospf6_lsdb_create (oi);
@@ -238,6 +241,8 @@ ospf6_interface_delete (struct ospf6_interface *oi)
struct listnode *node, *nnode;
struct ospf6_neighbor *on;
+ QOBJ_UNREG (oi);
+
for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
ospf6_neighbor_delete (on);
@@ -956,7 +961,7 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
vty_out (vty, " Number of I/F scoped LSAs is %u%s",
oi->lsdb->count, VNL);
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timerclear (&res);
if (oi->thread_send_lsupdate)
@@ -988,23 +993,23 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
/* show interface */
DEFUN (show_ipv6_ospf6_interface,
show_ipv6_ospf6_interface_ifname_cmd,
- "show ipv6 ospf6 interface IFNAME",
+ "show ipv6 ospf6 interface [IFNAME]",
SHOW_STR
IP6_STR
OSPF6_STR
INTERFACE_STR
- IFNAME_STR
- )
+ IFNAME_STR)
{
+ int idx_ifname = 4;
struct interface *ifp;
struct listnode *i;
- if (argc)
+ if (argc == 5)
{
- ifp = if_lookup_by_name (argv[0]);
+ ifp = if_lookup_by_name (argv[idx_ifname]->arg);
if (ifp == NULL)
{
- vty_out (vty, "No such Interface: %s%s", argv[0],
+ vty_out (vty, "No such Interface: %s%s", argv[idx_ifname]->arg,
VNL);
return CMD_WARNING;
}
@@ -1019,88 +1024,58 @@ DEFUN (show_ipv6_ospf6_interface,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_interface,
- show_ipv6_ospf6_interface_cmd,
- "show ipv6 ospf6 interface",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- INTERFACE_STR
- )
-
DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
show_ipv6_ospf6_interface_ifname_prefix_cmd,
- "show ipv6 ospf6 interface IFNAME prefix",
+ "show ipv6 ospf6 interface IFNAME prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
SHOW_STR
IP6_STR
OSPF6_STR
INTERFACE_STR
IFNAME_STR
"Display connected prefixes to advertise\n"
- )
+ OSPF6_ROUTE_ADDRESS_STR
+ OSPF6_ROUTE_PREFIX_STR
+ OSPF6_ROUTE_MATCH_STR
+ "Display details of the prefixes\n")
{
+ int idx_ifname = 4;
+ int idx_prefix = 6;
struct interface *ifp;
struct ospf6_interface *oi;
- ifp = if_lookup_by_name (argv[0]);
+ ifp = if_lookup_by_name (argv[idx_ifname]->arg);
if (ifp == NULL)
{
- vty_out (vty, "No such Interface: %s%s", argv[0], VNL);
+ vty_out (vty, "No such Interface: %s%s", argv[idx_ifname]->arg, VNL);
return CMD_WARNING;
}
oi = ifp->info;
if (oi == NULL)
{
- vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[0], VNL);
+ vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[idx_ifname]->arg, VNL);
return CMD_WARNING;
}
- argc--;
- argv++;
- ospf6_route_table_show (vty, argc, argv, oi->route_connected);
+ ospf6_route_table_show (vty, idx_prefix, argc, argv, oi->route_connected);
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_interface_ifname_prefix,
- show_ipv6_ospf6_interface_ifname_prefix_detail_cmd,
- "show ipv6 ospf6 interface IFNAME prefix (X:X::X:X|X:X::X:X/M|detail)",
+DEFUN (show_ipv6_ospf6_interface_prefix,
+ show_ipv6_ospf6_interface_prefix_cmd,
+ "show ipv6 ospf6 interface prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
SHOW_STR
IP6_STR
OSPF6_STR
INTERFACE_STR
- IFNAME_STR
"Display connected prefixes to advertise\n"
OSPF6_ROUTE_ADDRESS_STR
OSPF6_ROUTE_PREFIX_STR
- "Display details of the prefixes\n"
- )
-
-ALIAS (show_ipv6_ospf6_interface_ifname_prefix,
- show_ipv6_ospf6_interface_ifname_prefix_match_cmd,
- "show ipv6 ospf6 interface IFNAME prefix X:X::X:X/M (match|detail)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- INTERFACE_STR
- IFNAME_STR
- "Display connected prefixes to advertise\n"
- OSPF6_ROUTE_PREFIX_STR
OSPF6_ROUTE_MATCH_STR
- "Display details of the prefixes\n"
- )
-
-DEFUN (show_ipv6_ospf6_interface_prefix,
- show_ipv6_ospf6_interface_prefix_cmd,
- "show ipv6 ospf6 interface prefix",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- INTERFACE_STR
- "Display connected prefixes to advertise\n"
- )
+ "Display details of the prefixes\n")
{
+ int idx_prefix = 5;
struct listnode *i;
struct ospf6_interface *oi;
struct interface *ifp;
@@ -1111,56 +1086,29 @@ DEFUN (show_ipv6_ospf6_interface_prefix,
if (oi == NULL)
continue;
- ospf6_route_table_show (vty, argc, argv, oi->route_connected);
+ ospf6_route_table_show (vty, idx_prefix, argc, argv, oi->route_connected);
}
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_interface_prefix,
- show_ipv6_ospf6_interface_prefix_detail_cmd,
- "show ipv6 ospf6 interface prefix (X:X::X:X|X:X::X:X/M|detail)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- INTERFACE_STR
- "Display connected prefixes to advertise\n"
- OSPF6_ROUTE_ADDRESS_STR
- OSPF6_ROUTE_PREFIX_STR
- "Display details of the prefixes\n"
- )
-
-ALIAS (show_ipv6_ospf6_interface_prefix,
- show_ipv6_ospf6_interface_prefix_match_cmd,
- "show ipv6 ospf6 interface prefix X:X::X:X/M (match|detail)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- INTERFACE_STR
- "Display connected prefixes to advertise\n"
- OSPF6_ROUTE_PREFIX_STR
- OSPF6_ROUTE_MATCH_STR
- "Display details of the prefixes\n"
- )
-
-
/* interface variable set command */
DEFUN (ipv6_ospf6_ifmtu,
ipv6_ospf6_ifmtu_cmd,
- "ipv6 ospf6 ifmtu <1-65535>",
+ "ipv6 ospf6 ifmtu (1-65535)",
IP6_STR
OSPF6_STR
"Interface MTU\n"
"OSPFv3 Interface MTU\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
struct ospf6_interface *oi;
- struct interface *ifp;
unsigned int ifmtu, iobuflen;
struct listnode *node, *nnode;
struct ospf6_neighbor *on;
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1168,7 +1116,7 @@ DEFUN (ipv6_ospf6_ifmtu,
oi = ospf6_interface_create (ifp);
assert (oi);
- ifmtu = strtol (argv[0], NULL, 10);
+ ifmtu = strtol (argv[idx_number]->arg, NULL, 10);
if (oi->ifmtu == ifmtu)
return CMD_SUCCESS;
@@ -1214,13 +1162,12 @@ DEFUN (no_ipv6_ospf6_ifmtu,
"Interface MTU\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
unsigned int iobuflen;
struct listnode *node, *nnode;
struct ospf6_neighbor *on;
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1255,18 +1202,18 @@ DEFUN (no_ipv6_ospf6_ifmtu,
DEFUN (ipv6_ospf6_cost,
ipv6_ospf6_cost_cmd,
- "ipv6 ospf6 cost <1-65535>",
+ "ipv6 ospf6 cost (1-65535)",
IP6_STR
OSPF6_STR
"Interface cost\n"
"Outgoing metric of this interface\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
struct ospf6_interface *oi;
- struct interface *ifp;
unsigned long int lcost;
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1274,7 +1221,7 @@ DEFUN (ipv6_ospf6_cost,
oi = ospf6_interface_create (ifp);
assert (oi);
- lcost = strtol (argv[0], NULL, 10);
+ lcost = strtol (argv[idx_number]->arg, NULL, 10);
if (lcost > UINT32_MAX)
{
@@ -1302,10 +1249,8 @@ DEFUN (no_ipv6_ospf6_cost,
"Calculate interface cost from bandwidth\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1322,18 +1267,19 @@ DEFUN (no_ipv6_ospf6_cost,
DEFUN (auto_cost_reference_bandwidth,
auto_cost_reference_bandwidth_cmd,
- "auto-cost reference-bandwidth <1-4294967>",
+ "auto-cost reference-bandwidth (1-4294967)",
"Calculate OSPF interface cost according to bandwidth\n"
"Use reference bandwidth method to assign OSPF cost\n"
"The reference bandwidth in terms of Mbits per second\n")
{
- struct ospf6 *o = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, o);
+ int idx_number = 2;
struct ospf6_area *oa;
struct ospf6_interface *oi;
struct listnode *i, *j;
u_int32_t refbw;
- refbw = strtol (argv[0], NULL, 10);
+ refbw = strtol (argv[idx_number]->arg, NULL, 10);
if (refbw < 1 || refbw > 4294967)
{
vty_out (vty, "reference-bandwidth value is invalid%s", VTY_NEWLINE);
@@ -1354,12 +1300,13 @@ DEFUN (auto_cost_reference_bandwidth,
DEFUN (no_auto_cost_reference_bandwidth,
no_auto_cost_reference_bandwidth_cmd,
- "no auto-cost reference-bandwidth",
+ "no auto-cost reference-bandwidth [(1-4294967)]",
NO_STR
"Calculate OSPF interface cost according to bandwidth\n"
- "Use reference bandwidth method to assign OSPF cost\n")
+ "Use reference bandwidth method to assign OSPF cost\n"
+ "The reference bandwidth in terms of Mbits per second\n")
{
- struct ospf6 *o = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, o);
struct ospf6_area *oa;
struct ospf6_interface *oi;
struct listnode *i, *j;
@@ -1375,27 +1322,19 @@ DEFUN (no_auto_cost_reference_bandwidth,
return CMD_SUCCESS;
}
-ALIAS (no_auto_cost_reference_bandwidth,
- no_auto_cost_reference_bandwidth_val_cmd,
- "no auto-cost reference-bandwidth <1-4294967>",
- NO_STR
- "Calculate OSPF interface cost according to bandwidth\n"
- "Use reference bandwidth method to assign OSPF cost\n"
- "The reference bandwidth in terms of Mbits per second\n")
DEFUN (ipv6_ospf6_hellointerval,
ipv6_ospf6_hellointerval_cmd,
- "ipv6 ospf6 hello-interval <1-65535>",
+ "ipv6 ospf6 hello-interval (1-65535)",
IP6_STR
OSPF6_STR
- "Interval time of Hello packets\n"
+ "Time between HELLO packets\n"
SECONDS_STR
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1403,24 +1342,23 @@ DEFUN (ipv6_ospf6_hellointerval,
oi = ospf6_interface_create (ifp);
assert (oi);
- oi->hello_interval = strtol (argv[0], NULL, 10);
+ oi->hello_interval = strtol (argv[idx_number]->arg, NULL, 10);
return CMD_SUCCESS;
}
/* interface variable set command */
DEFUN (ipv6_ospf6_deadinterval,
ipv6_ospf6_deadinterval_cmd,
- "ipv6 ospf6 dead-interval <1-65535>",
+ "ipv6 ospf6 dead-interval (1-65535)",
IP6_STR
OSPF6_STR
"Interval time after which a neighbor is declared down\n"
SECONDS_STR
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1428,24 +1366,22 @@ DEFUN (ipv6_ospf6_deadinterval,
oi = ospf6_interface_create (ifp);
assert (oi);
- oi->dead_interval = strtol (argv[0], NULL, 10);
+ oi->dead_interval = strtol (argv[idx_number]->arg, NULL, 10);
return CMD_SUCCESS;
}
/* interface variable set command */
DEFUN (ipv6_ospf6_transmitdelay,
ipv6_ospf6_transmitdelay_cmd,
- "ipv6 ospf6 transmit-delay <1-3600>",
+ "ipv6 ospf6 transmit-delay (1-3600)",
IP6_STR
OSPF6_STR
- "Transmit delay of this interface\n"
- SECONDS_STR
- )
+ "Link state transmit delay\n"
+ SECONDS_STR)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1453,24 +1389,23 @@ DEFUN (ipv6_ospf6_transmitdelay,
oi = ospf6_interface_create (ifp);
assert (oi);
- oi->transdelay = strtol (argv[0], NULL, 10);
+ oi->transdelay = strtol (argv[idx_number]->arg, NULL, 10);
return CMD_SUCCESS;
}
/* interface variable set command */
DEFUN (ipv6_ospf6_retransmitinterval,
ipv6_ospf6_retransmitinterval_cmd,
- "ipv6 ospf6 retransmit-interval <1-65535>",
+ "ipv6 ospf6 retransmit-interval (1-65535)",
IP6_STR
OSPF6_STR
"Time between retransmitting lost link state advertisements\n"
SECONDS_STR
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1478,24 +1413,23 @@ DEFUN (ipv6_ospf6_retransmitinterval,
oi = ospf6_interface_create (ifp);
assert (oi);
- oi->rxmt_interval = strtol (argv[0], NULL, 10);
+ oi->rxmt_interval = strtol (argv[idx_number]->arg, NULL, 10);
return CMD_SUCCESS;
}
/* interface variable set command */
DEFUN (ipv6_ospf6_priority,
ipv6_ospf6_priority_cmd,
- "ipv6 ospf6 priority <0-255>",
+ "ipv6 ospf6 priority (0-255)",
IP6_STR
OSPF6_STR
"Router priority\n"
"Priority value\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1503,7 +1437,7 @@ DEFUN (ipv6_ospf6_priority,
oi = ospf6_interface_create (ifp);
assert (oi);
- oi->priority = strtol (argv[0], NULL, 10);
+ oi->priority = strtol (argv[idx_number]->arg, NULL, 10);
if (oi->area &&
(oi->state == OSPF6_INTERFACE_DROTHER ||
@@ -1516,17 +1450,16 @@ DEFUN (ipv6_ospf6_priority,
DEFUN (ipv6_ospf6_instance,
ipv6_ospf6_instance_cmd,
- "ipv6 ospf6 instance-id <0-255>",
+ "ipv6 ospf6 instance-id (0-255)",
IP6_STR
OSPF6_STR
"Instance ID for this interface\n"
"Instance ID value\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *)vty->index;
assert (ifp);
oi = (struct ospf6_interface *)ifp->info;
@@ -1534,7 +1467,7 @@ DEFUN (ipv6_ospf6_instance,
oi = ospf6_interface_create (ifp);
assert (oi);
- oi->instance_id = strtol (argv[0], NULL, 10);
+ oi->instance_id = strtol (argv[idx_number]->arg, NULL, 10);
return CMD_SUCCESS;
}
@@ -1543,15 +1476,14 @@ DEFUN (ipv6_ospf6_passive,
"ipv6 ospf6 passive",
IP6_STR
OSPF6_STR
- "passive interface, No adjacency will be formed on this interface\n"
+ "Passive interface; no adjacency will be formed on this interface\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
struct listnode *node, *nnode;
struct ospf6_neighbor *on;
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1580,10 +1512,8 @@ DEFUN (no_ipv6_ospf6_passive,
"passive interface: No Adjacency will be formed on this I/F\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1604,13 +1534,11 @@ DEFUN (ipv6_ospf6_mtu_ignore,
"ipv6 ospf6 mtu-ignore",
IP6_STR
OSPF6_STR
- "Ignore MTU mismatch on this interface\n"
+ "Disable MTU mismatch detection on this interface\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1629,13 +1557,11 @@ DEFUN (no_ipv6_ospf6_mtu_ignore,
NO_STR
IP6_STR
OSPF6_STR
- "Ignore MTU mismatch on this interface\n"
+ "Disable MTU mismatch detection on this interface\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1658,10 +1584,9 @@ DEFUN (ipv6_ospf6_advertise_prefix_list,
"Prefix list name\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_word = 4;
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1671,7 +1596,7 @@ DEFUN (ipv6_ospf6_advertise_prefix_list,
if (oi->plist_name)
XFREE (MTYPE_CFG_PLIST_NAME, oi->plist_name);
- oi->plist_name = XSTRDUP (MTYPE_CFG_PLIST_NAME, argv[0]);
+ oi->plist_name = XSTRDUP (MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg);
ospf6_interface_connected_route_update (oi->interface);
@@ -1699,10 +1624,8 @@ DEFUN (no_ipv6_ospf6_advertise_prefix_list,
"Filter prefix using prefix-list\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1734,18 +1657,17 @@ DEFUN (no_ipv6_ospf6_advertise_prefix_list,
DEFUN (ipv6_ospf6_network,
ipv6_ospf6_network_cmd,
- "ipv6 ospf6 network (broadcast|point-to-point)",
+ "ipv6 ospf6 network <broadcast|point-to-point>",
IP6_STR
OSPF6_STR
- "Network Type\n"
- "Specify OSPFv6 broadcast network\n"
+ "Network type\n"
+ "Specify OSPF6 broadcast network\n"
"Specify OSPF6 point-to-point network\n"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_network = 3;
struct ospf6_interface *oi;
- struct interface *ifp;
-
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1754,14 +1676,14 @@ DEFUN (ipv6_ospf6_network,
}
assert (oi);
- if (strncmp (argv[0], "b", 1) == 0)
+ if (strncmp (argv[idx_network]->arg, "b", 1) == 0)
{
if (oi->type == OSPF_IFTYPE_BROADCAST)
return CMD_SUCCESS;
oi->type = OSPF_IFTYPE_BROADCAST;
}
- else if (strncmp (argv[0], "point-to-p", 10) == 0)
+ else if (strncmp (argv[idx_network]->arg, "point-to-p", 10) == 0)
{
if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
return CMD_SUCCESS;
@@ -1782,15 +1704,14 @@ DEFUN (no_ipv6_ospf6_network,
NO_STR
IP6_STR
OSPF6_STR
- "Network Type\n"
+ "Network type\n"
"Default to whatever interface type system specifies"
)
{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
- struct interface *ifp;
int type;
- ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
@@ -1898,20 +1819,12 @@ ospf6_interface_init (void)
{
/* Install interface node. */
install_node (&interface_node, config_write_ospf6_interface);
+ if_cmd_init ();
- install_element (VIEW_NODE, &show_ipv6_ospf6_interface_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd);
- install_element (CONFIG_NODE, &interface_cmd);
- install_default (INTERFACE_NODE);
- install_element (INTERFACE_NODE, &interface_desc_cmd);
- install_element (INTERFACE_NODE, &no_interface_desc_cmd);
install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
@@ -1938,7 +1851,6 @@ ospf6_interface_init (void)
/* reference bandwidth commands */
install_element (OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
install_element (OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
- install_element (OSPF6_NODE, &no_auto_cost_reference_bandwidth_val_cmd);
}
/* Clear the specified interface structure */
@@ -1974,19 +1886,20 @@ DEFUN (clear_ipv6_ospf6_interface,
IFNAME_STR
)
{
+ int idx_ifname = 4;
struct interface *ifp;
struct listnode *node;
- if (argc == 0) /* Clear all the ospfv3 interfaces. */
+ if (argc == 4) /* Clear all the ospfv3 interfaces. */
{
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
ospf6_interface_clear (vty, ifp);
}
else /* Interface name is specified. */
{
- if ((ifp = if_lookup_by_name (argv[0])) == NULL)
+ if ((ifp = if_lookup_by_name (argv[idx_ifname]->arg)) == NULL)
{
- vty_out (vty, "No such Interface: %s%s", argv[0], VNL);
+ vty_out (vty, "No such Interface: %s%s", argv[idx_ifname]->arg, VNL);
return CMD_WARNING;
}
ospf6_interface_clear (vty, ifp);
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index 3e09bfb930..179477a634 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -22,6 +22,7 @@
#ifndef OSPF6_INTERFACE_H
#define OSPF6_INTERFACE_H
+#include "qobj.h"
#include "if.h"
/* Debug option */
@@ -116,7 +117,10 @@ struct ospf6_interface
/* BFD information */
void *bfd_info;
+
+ QOBJ_FIELDS
};
+DECLARE_QOBJ_TYPE(ospf6_interface)
/* interface state */
#define OSPF6_INTERFACE_NONE 0
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 5b92212daa..d93406fb68 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -1485,11 +1485,11 @@ ospf6_brouter_debug_print (struct ospf6_route *brouter)
ospf6_linkstate_prefix2str (&brouter->prefix, destination,
sizeof (destination));
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timersub (&now, &brouter->installed, &res);
timerstring (&res, installed, sizeof (installed));
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timersub (&now, &brouter->changed, &res);
timerstring (&res, changed, sizeof (changed));
@@ -1730,8 +1730,9 @@ DEFUN (debug_ospf6_brouter_router,
"Specify border-router's router-id\n"
)
{
+ int idx_ipv4 = 4;
u_int32_t router_id;
- inet_pton (AF_INET, argv[0], &router_id);
+ inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id);
OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
return CMD_SUCCESS;
}
@@ -1760,8 +1761,9 @@ DEFUN (debug_ospf6_brouter_area,
"Specify Area-ID\n"
)
{
+ int idx_ipv4 = 4;
u_int32_t area_id;
- inet_pton (AF_INET, argv[0], &area_id);
+ inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id);
OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
return CMD_SUCCESS;
}
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index 35e5a91544..bea153c928 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -207,9 +207,7 @@ ospf6_lsa_age_set (struct ospf6_lsa *lsa)
assert (lsa && lsa->header);
- if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &now) < 0)
- zlog_warn ("LSA: quagga_gettime failed, may fail LSA AGEs: %s",
- safe_strerror (errno));
+ monotime(&now);
lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age);
lsa->birth.tv_usec = now.tv_usec;
@@ -230,9 +228,7 @@ ospf6_lsa_age_current (struct ospf6_lsa *lsa)
assert (lsa->header);
/* current time */
- if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &now) < 0)
- zlog_warn ("LSA: quagga_gettime failed, may fail LSA AGEs: %s",
- safe_strerror (errno));
+ monotime(&now);
if (ntohs (lsa->header->age) >= OSPF_LSA_MAXAGE)
{
@@ -513,7 +509,7 @@ ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
inet_ntop (AF_INET, &lsa->header->adv_router,
adv_router, sizeof (adv_router));
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timersub (&now, &lsa->installed, &res);
timerstring (&res, duration, sizeof (duration));
@@ -818,26 +814,35 @@ ospf6_lsa_handler_name (struct ospf6_lsa_handler *h)
DEFUN (debug_ospf6_lsa_type,
debug_ospf6_lsa_hex_cmd,
- "debug ospf6 lsa (router|network|inter-prefix|inter-router|as-external|link|intra-prefix|unknown)",
+ "debug ospf6 lsa <router|network|inter-prefix|inter-router|as-external|link|intra-prefix|unknown> [<originate|examine|flooding>]",
DEBUG_STR
OSPF6_STR
"Debug Link State Advertisements (LSAs)\n"
- "Specify LS type as Hexadecimal\n"
- )
-{
+ "Display Router LSAs\n"
+ "Display Network LSAs\n"
+ "Display Inter-Area-Prefix LSAs\n"
+ "Display Inter-Router LSAs\n"
+ "Display As-External LSAs\n"
+ "Display Link LSAs\n"
+ "Display Intra-Area-Prefix LSAs\n"
+ "Display LSAs of unknown origin\n"
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
+{
+ int idx_lsa = 3;
+ int idx_type = 4;
unsigned int i;
struct ospf6_lsa_handler *handler = NULL;
- assert (argc);
-
for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
{
handler = vector_slot (ospf6_lsa_handler_vector, i);
if (handler == NULL)
continue;
- if (strncmp (argv[0], ospf6_lsa_handler_name(handler), strlen(argv[0])) == 0)
+ if (strncmp (argv[idx_lsa]->arg, ospf6_lsa_handler_name(handler), strlen(argv[idx_lsa]->arg)) == 0)
break;
- if (! strcasecmp (argv[0], handler->name))
+ if (! strcasecmp (argv[idx_lsa]->arg, handler->name))
break;
handler = NULL;
}
@@ -845,13 +850,13 @@ DEFUN (debug_ospf6_lsa_type,
if (handler == NULL)
handler = &unknown_handler;
- if (argc >= 2)
+ if (argc == 5)
{
- if (! strcmp (argv[1], "originate"))
+ if (! strcmp (argv[idx_type]->text, "originate"))
SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE);
- if (! strcmp (argv[1], "examine"))
+ else if (! strcmp (argv[idx_type]->text, "examine"))
SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN);
- if (! strcmp (argv[1], "flooding"))
+ else if (! strcmp (argv[idx_type]->text, "flooding"))
SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD);
}
else
@@ -860,51 +865,51 @@ DEFUN (debug_ospf6_lsa_type,
return CMD_SUCCESS;
}
-ALIAS (debug_ospf6_lsa_type,
- debug_ospf6_lsa_hex_detail_cmd,
- "debug ospf6 lsa (router|network|inter-prefix|inter-router|as-external|link|intra-prefix|unknown) (originate|examine|flooding)",
- DEBUG_STR
- OSPF6_STR
- "Debug Link State Advertisements (LSAs)\n"
- "Specify LS type as Hexadecimal\n"
- )
-
DEFUN (no_debug_ospf6_lsa_type,
no_debug_ospf6_lsa_hex_cmd,
- "no debug ospf6 lsa (router|network|inter-prefix|inter-router|as-external|link|intra-prefix|unknown)",
+ "no debug ospf6 lsa <router|network|inter-prefix|inter-router|as-external|link|intra-prefix|unknown> [<originate|examine|flooding>]",
NO_STR
DEBUG_STR
OSPF6_STR
"Debug Link State Advertisements (LSAs)\n"
- "Specify LS type as Hexadecimal\n"
- )
-{
+ "Display Router LSAs\n"
+ "Display Network LSAs\n"
+ "Display Inter-Area-Prefix LSAs\n"
+ "Display Inter-Router LSAs\n"
+ "Display As-External LSAs\n"
+ "Display Link LSAs\n"
+ "Display Intra-Area-Prefix LSAs\n"
+ "Display LSAs of unknown origin\n"
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
+{
+ int idx_lsa = 4;
+ int idx_type = 5;
u_int i;
struct ospf6_lsa_handler *handler = NULL;
- assert (argc);
-
for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
{
handler = vector_slot (ospf6_lsa_handler_vector, i);
if (handler == NULL)
continue;
- if (strncmp (argv[0], ospf6_lsa_handler_name(handler), strlen(argv[0])) == 0)
+ if (strncmp (argv[idx_lsa]->arg, ospf6_lsa_handler_name(handler), strlen(argv[idx_lsa]->arg)) == 0)
break;
- if (! strcasecmp (argv[0], handler->name))
+ if (! strcasecmp (argv[idx_lsa]->arg, handler->name))
break;
}
if (handler == NULL)
return CMD_SUCCESS;
- if (argc >= 2)
+ if (argc == 6)
{
- if (! strcmp (argv[1], "originate"))
+ if (! strcmp (argv[idx_type]->text, "originate"))
UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE);
- if (! strcmp (argv[1], "examine"))
+ if (! strcmp (argv[idx_type]->text, "examine"))
UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN);
- if (! strcmp (argv[1], "flooding"))
+ if (! strcmp (argv[idx_type]->text, "flooding"))
UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD);
}
else
@@ -913,27 +918,14 @@ DEFUN (no_debug_ospf6_lsa_type,
return CMD_SUCCESS;
}
-ALIAS (no_debug_ospf6_lsa_type,
- no_debug_ospf6_lsa_hex_detail_cmd,
- "no debug ospf6 lsa (router|network|inter-prefix|inter-router|as-external|link|intra-prefix) (originate|examine|flooding)",
- NO_STR
- DEBUG_STR
- OSPF6_STR
- "Debug Link State Advertisements (LSAs)\n"
- "Specify LS type as Hexadecimal\n"
- )
void
install_element_ospf6_debug_lsa (void)
{
install_element (ENABLE_NODE, &debug_ospf6_lsa_hex_cmd);
- install_element (ENABLE_NODE, &debug_ospf6_lsa_hex_detail_cmd);
install_element (ENABLE_NODE, &no_debug_ospf6_lsa_hex_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf6_lsa_hex_detail_cmd);
install_element (CONFIG_NODE, &debug_ospf6_lsa_hex_cmd);
- install_element (CONFIG_NODE, &debug_ospf6_lsa_hex_detail_cmd);
install_element (CONFIG_NODE, &no_debug_ospf6_lsa_hex_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf6_lsa_hex_detail_cmd);
}
int
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index b0e94288b4..578b39a641 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -1817,10 +1817,7 @@ ospf6_dbdesc_send (struct thread *thread)
if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) &&
(on->dbdesc_seqnum == 0))
{
- struct timeval tv;
- if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv) < 0)
- tv.tv_sec = 1;
- on->dbdesc_seqnum = tv.tv_sec;
+ on->dbdesc_seqnum = monotime(NULL);
}
dbdesc->options[0] = on->ospf6_if->area->options[0];
@@ -2340,7 +2337,7 @@ ospf6_lsack_send_interface (struct thread *thread)
/* Commands */
DEFUN (debug_ospf6_message,
debug_ospf6_message_cmd,
- "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
+ "debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv>]",
DEBUG_STR
OSPF6_STR
"Debug OSPFv3 message\n"
@@ -2351,35 +2348,36 @@ DEFUN (debug_ospf6_message,
"Debug Link State Update message\n"
"Debug Link State Acknowledgement message\n"
"Debug All message\n"
- )
+ "Debug only sending message\n"
+ "Debug only receiving message\n")
{
+ int idx_packet = 3;
+ int idx_send_recv = 4;
unsigned char level = 0;
int type = 0;
int i;
- assert (argc > 0);
-
/* check type */
- if (! strncmp (argv[0], "u", 1))
+ if (! strncmp (argv[idx_packet]->arg, "u", 1))
type = OSPF6_MESSAGE_TYPE_UNKNOWN;
- else if (! strncmp (argv[0], "h", 1))
+ else if (! strncmp (argv[idx_packet]->arg, "h", 1))
type = OSPF6_MESSAGE_TYPE_HELLO;
- else if (! strncmp (argv[0], "d", 1))
+ else if (! strncmp (argv[idx_packet]->arg, "d", 1))
type = OSPF6_MESSAGE_TYPE_DBDESC;
- else if (! strncmp (argv[0], "lsr", 3))
+ else if (! strncmp (argv[idx_packet]->arg, "lsr", 3))
type = OSPF6_MESSAGE_TYPE_LSREQ;
- else if (! strncmp (argv[0], "lsu", 3))
+ else if (! strncmp (argv[idx_packet]->arg, "lsu", 3))
type = OSPF6_MESSAGE_TYPE_LSUPDATE;
- else if (! strncmp (argv[0], "lsa", 3))
+ else if (! strncmp (argv[idx_packet]->arg, "lsa", 3))
type = OSPF6_MESSAGE_TYPE_LSACK;
- else if (! strncmp (argv[0], "a", 1))
+ else if (! strncmp (argv[idx_packet]->arg, "a", 1))
type = OSPF6_MESSAGE_TYPE_ALL;
- if (argc == 1)
+ if (argc == 4)
level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
- else if (! strncmp (argv[1], "s", 1))
+ else if (! strncmp (argv[idx_send_recv]->arg, "s", 1))
level = OSPF6_DEBUG_MESSAGE_SEND;
- else if (! strncmp (argv[1], "r", 1))
+ else if (! strncmp (argv[idx_send_recv]->arg, "r", 1))
level = OSPF6_DEBUG_MESSAGE_RECV;
if (type == OSPF6_MESSAGE_TYPE_ALL)
@@ -2393,27 +2391,9 @@ DEFUN (debug_ospf6_message,
return CMD_SUCCESS;
}
-ALIAS (debug_ospf6_message,
- debug_ospf6_message_sendrecv_cmd,
- "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 message\n"
- "Debug Unknown message\n"
- "Debug Hello message\n"
- "Debug Database Description message\n"
- "Debug Link State Request message\n"
- "Debug Link State Update message\n"
- "Debug Link State Acknowledgement message\n"
- "Debug All message\n"
- "Debug only sending message\n"
- "Debug only receiving message\n"
- )
-
-
DEFUN (no_debug_ospf6_message,
no_debug_ospf6_message_cmd,
- "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
+ "no debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv>]",
NO_STR
DEBUG_STR
OSPF6_STR
@@ -2425,35 +2405,36 @@ DEFUN (no_debug_ospf6_message,
"Debug Link State Update message\n"
"Debug Link State Acknowledgement message\n"
"Debug All message\n"
- )
+ "Debug only sending message\n"
+ "Debug only receiving message\n")
{
+ int idx_packet = 4;
+ int idx_send_recv = 5;
unsigned char level = 0;
int type = 0;
int i;
- assert (argc > 0);
-
/* check type */
- if (! strncmp (argv[0], "u", 1))
+ if (! strncmp (argv[idx_packet]->arg, "u", 1))
type = OSPF6_MESSAGE_TYPE_UNKNOWN;
- else if (! strncmp (argv[0], "h", 1))
+ else if (! strncmp (argv[idx_packet]->arg, "h", 1))
type = OSPF6_MESSAGE_TYPE_HELLO;
- else if (! strncmp (argv[0], "d", 1))
+ else if (! strncmp (argv[idx_packet]->arg, "d", 1))
type = OSPF6_MESSAGE_TYPE_DBDESC;
- else if (! strncmp (argv[0], "lsr", 3))
+ else if (! strncmp (argv[idx_packet]->arg, "lsr", 3))
type = OSPF6_MESSAGE_TYPE_LSREQ;
- else if (! strncmp (argv[0], "lsu", 3))
+ else if (! strncmp (argv[idx_packet]->arg, "lsu", 3))
type = OSPF6_MESSAGE_TYPE_LSUPDATE;
- else if (! strncmp (argv[0], "lsa", 3))
+ else if (! strncmp (argv[idx_packet]->arg, "lsa", 3))
type = OSPF6_MESSAGE_TYPE_LSACK;
- else if (! strncmp (argv[0], "a", 1))
+ else if (! strncmp (argv[idx_packet]->arg, "a", 1))
type = OSPF6_MESSAGE_TYPE_ALL;
- if (argc == 1)
+ if (argc == 5)
level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
- else if (! strncmp (argv[1], "s", 1))
+ else if (! strncmp (argv[idx_send_recv]->arg, "s", 1))
level = OSPF6_DEBUG_MESSAGE_SEND;
- else if (! strncmp (argv[1], "r", 1))
+ else if (! strncmp (argv[idx_send_recv]->arg, "r", 1))
level = OSPF6_DEBUG_MESSAGE_RECV;
if (type == OSPF6_MESSAGE_TYPE_ALL)
@@ -2467,24 +2448,6 @@ DEFUN (no_debug_ospf6_message,
return CMD_SUCCESS;
}
-ALIAS (no_debug_ospf6_message,
- no_debug_ospf6_message_sendrecv_cmd,
- "no debug ospf6 message "
- "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
- NO_STR
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 message\n"
- "Debug Unknown message\n"
- "Debug Hello message\n"
- "Debug Database Description message\n"
- "Debug Link State Request message\n"
- "Debug Link State Update message\n"
- "Debug Link State Acknowledgement message\n"
- "Debug All message\n"
- "Debug only sending message\n"
- "Debug only receiving message\n"
- )
int
config_write_ospf6_debug_message (struct vty *vty)
@@ -2549,12 +2512,8 @@ install_element_ospf6_debug_message (void)
{
install_element (ENABLE_NODE, &debug_ospf6_message_cmd);
install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd);
- install_element (ENABLE_NODE, &debug_ospf6_message_sendrecv_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf6_message_sendrecv_cmd);
install_element (CONFIG_NODE, &debug_ospf6_message_cmd);
install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd);
- install_element (CONFIG_NODE, &debug_ospf6_message_sendrecv_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf6_message_sendrecv_cmd);
}
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index bb265274f5..ec79a1552b 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -97,7 +97,7 @@ ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
on->ospf6_if = oi;
on->state = OSPF6_NEIGHBOR_DOWN;
on->state_change = 0;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
+ monotime(&on->last_changed);
on->router_id = router_id;
on->summary_list = ospf6_lsdb_create (on);
@@ -163,7 +163,7 @@ ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int e
return;
on->state_change++;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
+ monotime(&on->last_changed);
/* log */
if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
@@ -633,7 +633,7 @@ ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
{
char router_id[16];
char duration[16];
- struct timeval now, res;
+ struct timeval res;
char nstate[16];
char deadtime[16];
long h, m, s;
@@ -645,13 +645,11 @@ ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
}
#endif /*HAVE_GETNAMEINFO*/
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
-
/* Dead time */
h = m = s = 0;
if (on->inactivity_timer)
{
- s = on->inactivity_timer->u.sands.tv_sec - recent_relative_time().tv_sec;
+ s = monotime_until(&on->inactivity_timer->u.sands, NULL) / 1000000LL;
h = s / 3600;
s -= h * 3600;
m = s / 60;
@@ -673,7 +671,7 @@ ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
}
/* Duration */
- timersub (&now, &on->last_changed, &res);
+ monotime_since(&on->last_changed, &res);
timerstring (&res, duration, sizeof (duration));
/*
@@ -682,7 +680,7 @@ ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
"I/F", "State", VNL);
*/
- vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
+ vty_out (vty, "%-15s %3d %11s %8s/%-12s %11s %s[%s]%s",
router_id, on->priority, deadtime,
ospf6_neighbor_state_str[on->state], nstate, duration,
on->ospf6_if->interface->name,
@@ -707,11 +705,11 @@ ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timersub (&now, &on->last_changed, &res);
timerstring (&res, duration, sizeof (duration));
- vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
+ vty_out (vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]%s",
router_id, ospf6_neighbor_state_str[on->state],
duration, drouter, bdrouter, on->ospf6_if->interface->name,
ospf6_interface_state_str[on->ospf6_if->state],
@@ -731,7 +729,7 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timersub (&now, &on->last_changed, &res);
timerstring (&res, duration, sizeof (duration));
@@ -829,13 +827,15 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
DEFUN (show_ipv6_ospf6_neighbor,
show_ipv6_ospf6_neighbor_cmd,
- "show ipv6 ospf6 neighbor",
+ "show ipv6 ospf6 neighbor [<detail|drchoice>]",
SHOW_STR
IP6_STR
OSPF6_STR
"Neighbor list\n"
- )
+ "Display details\n"
+ "Display DR choices\n")
{
+ int idx_type = 4;
struct ospf6_neighbor *on;
struct ospf6_interface *oi;
struct ospf6_area *oa;
@@ -845,20 +845,20 @@ DEFUN (show_ipv6_ospf6_neighbor,
OSPF6_CMD_CHECK_RUNNING ();
showfunc = ospf6_neighbor_show;
- if (argc)
+ if (argc == 5)
{
- if (! strncmp (argv[0], "de", 2))
+ if (! strncmp (argv[idx_type]->arg, "de", 2))
showfunc = ospf6_neighbor_show_detail;
- else if (! strncmp (argv[0], "dr", 2))
+ else if (! strncmp (argv[idx_type]->arg, "dr", 2))
showfunc = ospf6_neighbor_show_drchoice;
}
if (showfunc == ospf6_neighbor_show)
- vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
+ vty_out (vty, "%-15s %3s %11s %8s/%-12s %11s %s[%s]%s",
"Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
"I/F", "State", VNL);
else if (showfunc == ospf6_neighbor_show_drchoice)
- vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
+ vty_out (vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]%s",
"RouterID", "State", "Duration", "DR", "BDR", "I/F",
"State", VNL);
@@ -870,16 +870,6 @@ DEFUN (show_ipv6_ospf6_neighbor,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_neighbor,
- show_ipv6_ospf6_neighbor_detail_cmd,
- "show ipv6 ospf6 neighbor (detail|drchoice)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- "Neighbor list\n"
- "Display details\n"
- "Display DR choices\n"
- )
DEFUN (show_ipv6_ospf6_neighbor_one,
show_ipv6_ospf6_neighbor_one_cmd,
@@ -891,6 +881,7 @@ DEFUN (show_ipv6_ospf6_neighbor_one,
"Specify Router-ID as IPv4 address notation\n"
)
{
+ int idx_ipv4 = 4;
struct ospf6_neighbor *on;
struct ospf6_interface *oi;
struct ospf6_area *oa;
@@ -901,9 +892,9 @@ DEFUN (show_ipv6_ospf6_neighbor_one,
OSPF6_CMD_CHECK_RUNNING ();
showfunc = ospf6_neighbor_show_detail;
- if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
+ if ((inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1)
{
- vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
+ vty_out (vty, "Router-ID is not parsable: %s%s", argv[idx_ipv4]->arg,
VNL);
return CMD_SUCCESS;
}
@@ -920,23 +911,26 @@ void
ospf6_neighbor_init (void)
{
install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd);
}
DEFUN (debug_ospf6_neighbor,
debug_ospf6_neighbor_cmd,
- "debug ospf6 neighbor",
+ "debug ospf6 neighbor [<state|event>]",
DEBUG_STR
OSPF6_STR
"Debug OSPFv3 Neighbor\n"
- )
+ "Debug OSPFv3 Neighbor State Change\n"
+ "Debug OSPFv3 Neighbor Event\n")
{
+ int idx_type = 3;
unsigned char level = 0;
- if (argc)
+
+ if (argc == 4)
{
- if (! strncmp (argv[0], "s", 1))
+ if (! strncmp (argv[idx_type]->arg, "s", 1))
level = OSPF6_DEBUG_NEIGHBOR_STATE;
- if (! strncmp (argv[0], "e", 1))
+ else if (! strncmp (argv[idx_type]->arg, "e", 1))
level = OSPF6_DEBUG_NEIGHBOR_EVENT;
}
else
@@ -946,31 +940,25 @@ DEFUN (debug_ospf6_neighbor,
return CMD_SUCCESS;
}
-ALIAS (debug_ospf6_neighbor,
- debug_ospf6_neighbor_detail_cmd,
- "debug ospf6 neighbor (state|event)",
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 Neighbor\n"
- "Debug OSPFv3 Neighbor State Change\n"
- "Debug OSPFv3 Neighbor Event\n"
- )
DEFUN (no_debug_ospf6_neighbor,
no_debug_ospf6_neighbor_cmd,
- "no debug ospf6 neighbor",
+ "no debug ospf6 neighbor [<state|event>]",
NO_STR
DEBUG_STR
OSPF6_STR
"Debug OSPFv3 Neighbor\n"
- )
+ "Debug OSPFv3 Neighbor State Change\n"
+ "Debug OSPFv3 Neighbor Event\n")
{
+ int idx_type = 4;
unsigned char level = 0;
- if (argc)
+
+ if (argc == 5)
{
- if (! strncmp (argv[0], "s", 1))
+ if (! strncmp (argv[idx_type]->arg, "s", 1))
level = OSPF6_DEBUG_NEIGHBOR_STATE;
- if (! strncmp (argv[0], "e", 1))
+ if (! strncmp (argv[idx_type]->arg, "e", 1))
level = OSPF6_DEBUG_NEIGHBOR_EVENT;
}
else
@@ -980,16 +968,6 @@ DEFUN (no_debug_ospf6_neighbor,
return CMD_SUCCESS;
}
-ALIAS (no_debug_ospf6_neighbor,
- no_debug_ospf6_neighbor_detail_cmd,
- "no debug ospf6 neighbor (state|event)",
- NO_STR
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 Neighbor\n"
- "Debug OSPFv3 Neighbor State Change\n"
- "Debug OSPFv3 Neighbor Event\n"
- )
DEFUN (no_debug_ospf6,
no_debug_ospf6_cmd,
@@ -1052,14 +1030,10 @@ void
install_element_ospf6_debug_neighbor (void)
{
install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd);
- install_element (ENABLE_NODE, &debug_ospf6_neighbor_detail_cmd);
install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_detail_cmd);
install_element (ENABLE_NODE, &no_debug_ospf6_cmd);
install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd);
- install_element (CONFIG_NODE, &debug_ospf6_neighbor_detail_cmd);
install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_detail_cmd);
install_element (CONFIG_NODE, &no_debug_ospf6_cmd);
}
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index 5172eee48d..29956c61a0 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -600,7 +600,7 @@ ospf6_route_add (struct ospf6_route *route,
else if (IS_OSPF6_DEBUG_ROUTE (TABLE))
zlog_debug ("%s: route add: %s", ospf6_route_table_name (table), buf);
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
node = route_node_get (table->table, &route->prefix);
route->rnode = node;
@@ -1020,7 +1020,7 @@ ospf6_route_show (struct vty *vty, struct ospf6_route *route)
struct listnode *node;
struct ospf6_nexthop *nh;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timersub (&now, &route->changed, &res);
timerstring (&res, duration, sizeof (duration));
@@ -1068,7 +1068,7 @@ ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route)
struct listnode *node;
struct ospf6_nexthop *nh;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
/* destination */
if (route->type == OSPF6_DEST_TYPE_LINKSTATE)
@@ -1298,7 +1298,7 @@ ospf6_route_show_table (struct vty *vty, int detail,
}
int
-ospf6_route_table_show (struct vty *vty, int argc, const char *argv[],
+ospf6_route_table_show (struct vty *vty, int argc_start, int argc, struct cmd_token **argv,
struct ospf6_route_table *table)
{
int summary = 0;
@@ -1312,60 +1312,60 @@ ospf6_route_table_show (struct vty *vty, int argc, const char *argv[],
memset (&prefix, 0, sizeof (struct prefix));
- for (i = 0; i < argc; i++)
+ for (i = argc_start; i < argc; i++)
{
- if (! strcmp (argv[i], "summary"))
+ if (! strcmp (argv[i]->arg, "summary"))
{
summary++;
continue;
}
- if (! strcmp (argv[i], "intra-area"))
+ if (! strcmp (argv[i]->arg, "intra-area"))
{
type = OSPF6_PATH_TYPE_INTRA;
continue;
}
- if (! strcmp (argv[i], "inter-area"))
+ if (! strcmp (argv[i]->arg, "inter-area"))
{
type = OSPF6_PATH_TYPE_INTER;
continue;
}
- if (! strcmp (argv[i], "external-1"))
+ if (! strcmp (argv[i]->arg, "external-1"))
{
type = OSPF6_PATH_TYPE_EXTERNAL1;
continue;
}
- if (! strcmp (argv[i], "external-2"))
+ if (! strcmp (argv[i]->arg, "external-2"))
{
type = OSPF6_PATH_TYPE_EXTERNAL2;
continue;
}
- if (! strcmp (argv[i], "detail"))
+ if (! strcmp (argv[i]->arg, "detail"))
{
detail++;
continue;
}
- if (! strcmp (argv[i], "match"))
+ if (! strcmp (argv[i]->arg, "match"))
{
match++;
continue;
}
- ret = str2prefix (argv[i], &prefix);
+ ret = str2prefix (argv[i]->arg, &prefix);
if (ret == 1 && prefix.family == AF_INET6)
{
isprefix++;
- if (strchr (argv[i], '/'))
+ if (strchr (argv[i]->arg, '/'))
slash++;
continue;
}
- vty_out (vty, "Malformed argument: %s%s", argv[i], VNL);
+ vty_out (vty, "Malformed argument: %s%s", argv[i]->arg, VNL);
return CMD_SUCCESS;
}
@@ -1473,7 +1473,8 @@ ospf6_linkstate_show_table (struct vty *vty, int detail,
}
int
-ospf6_linkstate_table_show (struct vty *vty, int argc, const char *argv[],
+ospf6_linkstate_table_show (struct vty *vty, int idx_ipv4, int argc,
+ struct cmd_token **argv,
struct ospf6_route_table *table)
{
int detail = 0;
@@ -1486,9 +1487,9 @@ ospf6_linkstate_table_show (struct vty *vty, int argc, const char *argv[],
memset (&id, 0, sizeof (struct prefix));
memset (&prefix, 0, sizeof (struct prefix));
- for (i = 0; i < argc; i++)
+ for (i = idx_ipv4; i < argc; i++)
{
- if (! strcmp (argv[i], "detail"))
+ if (! strcmp (argv[i]->arg, "detail"))
{
detail++;
continue;
@@ -1496,29 +1497,29 @@ ospf6_linkstate_table_show (struct vty *vty, int argc, const char *argv[],
if (! is_router)
{
- ret = str2prefix (argv[i], &router);
+ ret = str2prefix (argv[i]->arg, &router);
if (ret == 1 && router.family == AF_INET)
{
is_router++;
continue;
}
- vty_out (vty, "Malformed argument: %s%s", argv[i], VNL);
+ vty_out (vty, "Malformed argument: %s%s", argv[i]->arg, VNL);
return CMD_SUCCESS;
}
if (! is_id)
{
- ret = str2prefix (argv[i], &id);
+ ret = str2prefix (argv[i]->arg, &id);
if (ret == 1 && id.family == AF_INET)
{
is_id++;
continue;
}
- vty_out (vty, "Malformed argument: %s%s", argv[i], VNL);
+ vty_out (vty, "Malformed argument: %s%s", argv[i]->arg, VNL);
return CMD_SUCCESS;
}
- vty_out (vty, "Malformed argument: %s%s", argv[i], VNL);
+ vty_out (vty, "Malformed argument: %s%s", argv[i]->arg, VNL);
return CMD_SUCCESS;
}
@@ -1563,25 +1564,26 @@ ospf6_brouter_show (struct vty *vty, struct ospf6_route *route)
DEFUN (debug_ospf6_route,
debug_ospf6_route_cmd,
- "debug ospf6 route (table|intra-area|inter-area|memory)",
+ "debug ospf6 route <table|intra-area|inter-area|memory>",
DEBUG_STR
OSPF6_STR
+ "Debug routes\n"
"Debug route table calculation\n"
- "Debug detail\n"
"Debug intra-area route calculation\n"
"Debug inter-area route calculation\n"
"Debug route memory use\n"
)
{
+ int idx_type = 3;
unsigned char level = 0;
- if (! strncmp (argv[0], "table", 5))
+ if (! strncmp (argv[idx_type]->arg, "table", 5))
level = OSPF6_DEBUG_ROUTE_TABLE;
- else if (! strncmp (argv[0], "intra", 5))
+ else if (! strncmp (argv[idx_type]->arg, "intra", 5))
level = OSPF6_DEBUG_ROUTE_INTRA;
- else if (! strncmp (argv[0], "inter", 5))
+ else if (! strncmp (argv[idx_type]->arg, "inter", 5))
level = OSPF6_DEBUG_ROUTE_INTER;
- else if (! strncmp (argv[0], "memor", 5))
+ else if (! strncmp (argv[idx_type]->arg, "memor", 5))
level = OSPF6_DEBUG_ROUTE_MEMORY;
OSPF6_DEBUG_ROUTE_ON (level);
return CMD_SUCCESS;
@@ -1589,23 +1591,26 @@ DEFUN (debug_ospf6_route,
DEFUN (no_debug_ospf6_route,
no_debug_ospf6_route_cmd,
- "no debug ospf6 route (table|intra-area|inter-area|memory)",
+ "no debug ospf6 route <table|intra-area|inter-area|memory>",
NO_STR
DEBUG_STR
OSPF6_STR
+ "Debug routes\n"
"Debug route table calculation\n"
"Debug intra-area route calculation\n"
+ "Debug inter-area route calculation\n"
"Debug route memory use\n")
{
+ int idx_type = 4;
unsigned char level = 0;
- if (! strncmp (argv[0], "table", 5))
+ if (! strncmp (argv[idx_type]->arg, "table", 5))
level = OSPF6_DEBUG_ROUTE_TABLE;
- else if (! strncmp (argv[0], "intra", 5))
+ else if (! strncmp (argv[idx_type]->arg, "intra", 5))
level = OSPF6_DEBUG_ROUTE_INTRA;
- else if (! strncmp (argv[0], "inter", 5))
+ else if (! strncmp (argv[idx_type]->arg, "inter", 5))
level = OSPF6_DEBUG_ROUTE_INTER;
- else if (! strncmp (argv[0], "memor", 5))
+ else if (! strncmp (argv[idx_type]->arg, "memor", 5))
level = OSPF6_DEBUG_ROUTE_MEMORY;
OSPF6_DEBUG_ROUTE_OFF (level);
return CMD_SUCCESS;
diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h
index 7ecc066602..8b973d28ff 100644
--- a/ospf6d/ospf6_route.h
+++ b/ospf6d/ospf6_route.h
@@ -22,6 +22,8 @@
#ifndef OSPF6_ROUTE_H
#define OSPF6_ROUTE_H
+#include "command.h"
+
#define OSPF6_MULTI_PATH_LIMIT 4
/* Debug option */
@@ -329,10 +331,10 @@ extern void ospf6_route_dump (struct ospf6_route_table *table);
extern void ospf6_route_show (struct vty *vty, struct ospf6_route *route);
extern void ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route);
-extern int ospf6_route_table_show (struct vty *, int, const char *[],
+extern int ospf6_route_table_show (struct vty *, int, int, struct cmd_token **,
struct ospf6_route_table *);
-extern int ospf6_linkstate_table_show (struct vty *vty, int argc,
- const char *argv[],
+extern int ospf6_linkstate_table_show (struct vty *vty, int idx_ipv4, int argc,
+ struct cmd_token **argv,
struct ospf6_route_table *table);
extern void ospf6_brouter_show_header (struct vty *vty);
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index 7e977499cf..333ce5588e 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -603,7 +603,7 @@ ospf6_spf_calculation_thread (struct thread *t)
ospf6->t_spf_calc = NULL;
/* execute SPF calculation */
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &start);
+ monotime(&start);
if (ospf6_is_router_abr (ospf6))
ospf6_abr_range_reset_cost (ospf6);
@@ -644,7 +644,7 @@ ospf6_spf_calculation_thread (struct thread *t)
if (ospf6_is_router_abr (ospf6))
ospf6_abr_defaults_to_stub (ospf6);
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &end);
+ monotime(&end);
timersub (&end, &start, &runtime);
ospf6->ts_spf_duration = runtime;
@@ -670,7 +670,6 @@ void
ospf6_spf_schedule (struct ospf6 *ospf6, unsigned int reason)
{
unsigned long delay, elapsed, ht;
- struct timeval now, result;
ospf6_set_spf_reason(ospf6, reason);
@@ -694,11 +693,7 @@ ospf6_spf_schedule (struct ospf6 *ospf6, unsigned int reason)
return;
}
- /* XXX Monotic timers: we only care about relative time here. */
- now = recent_relative_time ();
- timersub (&now, &ospf6->ts_spf, &result);
-
- elapsed = (result.tv_sec * 1000) + (result.tv_usec / 1000);
+ elapsed = monotime_since(&ospf6->ts_spf, NULL) / 1000LL;
ht = ospf6->spf_holdtime * ospf6->spf_hold_multiplier;
if (ht > ospf6->spf_max_holdtime)
@@ -866,7 +861,7 @@ ospf6_timers_spf_set (struct vty *vty, unsigned int delay,
unsigned int hold,
unsigned int max)
{
- struct ospf6 *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, ospf);
ospf->spf_delay = delay;
ospf->spf_holdtime = hold;
@@ -877,7 +872,7 @@ ospf6_timers_spf_set (struct vty *vty, unsigned int delay,
DEFUN (ospf6_timers_throttle_spf,
ospf6_timers_throttle_spf_cmd,
- "timers throttle spf <0-600000> <0-600000> <0-600000>",
+ "timers throttle spf (0-600000) (0-600000) (0-600000)",
"Adjust routing timers\n"
"Throttling adaptive timer\n"
"OSPF6 SPF timers\n"
@@ -885,28 +880,28 @@ DEFUN (ospf6_timers_throttle_spf,
"Initial hold time (msec) between consecutive SPF calculations\n"
"Maximum hold time (msec)\n")
{
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 5;
unsigned int delay, hold, max;
- if (argc != 3)
- {
- vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- VTY_GET_INTEGER_RANGE ("SPF delay timer", delay, argv[0], 0, 600000);
- VTY_GET_INTEGER_RANGE ("SPF hold timer", hold, argv[1], 0, 600000);
- VTY_GET_INTEGER_RANGE ("SPF max-hold timer", max, argv[2], 0, 600000);
+ VTY_GET_INTEGER_RANGE ("SPF delay timer", delay, argv[idx_number]->arg, 0, 600000);
+ VTY_GET_INTEGER_RANGE ("SPF hold timer", hold, argv[idx_number_2]->arg, 0, 600000);
+ VTY_GET_INTEGER_RANGE ("SPF max-hold timer", max, argv[idx_number_3]->arg, 0, 600000);
return ospf6_timers_spf_set (vty, delay, hold, max);
}
DEFUN (no_ospf6_timers_throttle_spf,
no_ospf6_timers_throttle_spf_cmd,
- "no timers throttle spf",
+ "no timers throttle spf [(0-600000) (0-600000) (0-600000)]",
NO_STR
"Adjust routing timers\n"
"Throttling adaptive timer\n"
- "OSPF6 SPF timers\n")
+ "OSPF6 SPF timers\n"
+ "Delay (msec) from first change received till SPF calculation\n"
+ "Initial hold time (msec) between consecutive SPF calculations\n"
+ "Maximum hold time (msec)\n")
{
return ospf6_timers_spf_set (vty,
OSPF_SPF_DELAY_DEFAULT,
@@ -914,16 +909,6 @@ DEFUN (no_ospf6_timers_throttle_spf,
OSPF_SPF_MAX_HOLDTIME_DEFAULT);
}
-ALIAS (no_ospf6_timers_throttle_spf,
- no_ospf6_timers_throttle_spf_val_cmd,
- "no timers throttle spf <0-600000> <0-600000> <0-600000>",
- NO_STR
- "Adjust routing timers\n"
- "Throttling adaptive timer\n"
- "OSPF6 SPF timers\n"
- "Delay (msec) from first change received till SPF calculation\n"
- "Initial hold time (msec) between consecutive SPF calculations\n"
- "Maximum hold time (msec)\n")
int
config_write_ospf6_debug_spf (struct vty *vty)
@@ -972,5 +957,4 @@ ospf6_spf_init (void)
{
install_element (OSPF6_NODE, &ospf6_timers_throttle_spf_cmd);
install_element (OSPF6_NODE, &no_ospf6_timers_throttle_spf_cmd);
- install_element (OSPF6_NODE, &no_ospf6_timers_throttle_spf_val_cmd);
}
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 3d632b644e..92111c73fc 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -49,6 +49,8 @@
#include "ospf6_spf.h"
#include "ospf6d.h"
+DEFINE_QOBJ_TYPE(ospf6)
+
/* global ospf6d variable */
struct ospf6 *ospf6;
@@ -122,7 +124,7 @@ ospf6_create (void)
o = XCALLOC (MTYPE_OSPF6_TOP, sizeof (struct ospf6));
/* initialize */
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &o->starttime);
+ monotime(&o->starttime);
o->area_list = list_new ();
o->area_list->cmp = ospf6_area_cmp;
o->lsdb = ospf6_lsdb_create (o);
@@ -159,6 +161,7 @@ ospf6_create (void)
/* Enable "log-adjacency-changes" */
SET_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
+ QOBJ_REG (o, ospf6);
return o;
}
@@ -169,6 +172,7 @@ ospf6_delete (struct ospf6 *o)
struct listnode *node, *nnode;
struct ospf6_area *oa;
+ QOBJ_UNREG (o);
ospf6_disable (ospf6);
for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
@@ -294,8 +298,7 @@ DEFUN (router_ospf6,
ospf6 = ospf6_create ();
/* set current ospf point. */
- vty->node = OSPF6_NODE;
- vty->index = ospf6;
+ VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
return CMD_SUCCESS;
}
@@ -305,19 +308,11 @@ DEFUN (no_router_ospf6,
no_router_ospf6_cmd,
"no router ospf6",
NO_STR
- OSPF6_ROUTER_STR)
+ ROUTER_STR
+ OSPF6_STR)
{
- if (ospf6 == NULL)
- vty_out (vty, "OSPFv3 is not configured%s", VNL);
- else
- {
- ospf6_delete (ospf6);
- ospf6 = NULL;
- }
-
/* return to config node . */
- vty->node = CONFIG_NODE;
- vty->index = NULL;
+ VTY_PUSH_CONTEXT_NULL(CONFIG_NODE);
return CMD_SUCCESS;
}
@@ -329,16 +324,15 @@ DEFUN (ospf6_router_id,
"Configure OSPF Router-ID\n"
V4NOTATION_STR)
{
+ VTY_DECLVAR_CONTEXT(ospf6, o);
+ int idx_ipv4 = 1;
int ret;
u_int32_t router_id;
- struct ospf6 *o;
-
- o = (struct ospf6 *) vty->index;
- ret = inet_pton (AF_INET, argv[0], &router_id);
+ ret = inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id);
if (ret == 0)
{
- vty_out (vty, "malformed OSPF Router-ID: %s%s", argv[0], VNL);
+ vty_out (vty, "malformed OSPF Router-ID: %s%s", argv[idx_ipv4]->arg, VNL);
return CMD_SUCCESS;
}
@@ -354,7 +348,7 @@ DEFUN (ospf6_log_adjacency_changes,
"log-adjacency-changes",
"Log changes in adjacency state\n")
{
- struct ospf6 *ospf6 = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
@@ -367,7 +361,7 @@ DEFUN (ospf6_log_adjacency_changes_detail,
"Log changes in adjacency state\n"
"Log all state changes\n")
{
- struct ospf6 *ospf6 = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
@@ -380,7 +374,7 @@ DEFUN (no_ospf6_log_adjacency_changes,
NO_STR
"Log changes in adjacency state\n")
{
- struct ospf6 *ospf6 = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
@@ -394,7 +388,7 @@ DEFUN (no_ospf6_log_adjacency_changes_detail,
"Log changes in adjacency state\n"
"Log all state changes\n")
{
- struct ospf6 *ospf6 = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
@@ -403,26 +397,17 @@ DEFUN (no_ospf6_log_adjacency_changes_detail,
DEFUN (ospf6_timers_lsa,
ospf6_timers_lsa_cmd,
- "timers lsa min-arrival <0-600000>",
+ "timers lsa min-arrival (0-600000)",
"Adjust routing timers\n"
"OSPF6 LSA timers\n"
"Minimum delay in receiving new version of a LSA\n"
"Delay in milliseconds\n")
{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf);
+ int idx_number = 3;
unsigned int minarrival;
- struct ospf6 *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
-
- if (argc != 1)
- {
- vty_out (vty, "Insufficient number of arguments%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]);
+ VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[idx_number]->arg);
ospf->lsa_minarrival = minarrival;
return CMD_SUCCESS;
@@ -430,21 +415,20 @@ DEFUN (ospf6_timers_lsa,
DEFUN (no_ospf6_timers_lsa,
no_ospf6_timers_lsa_cmd,
- "no timers lsa min-arrival",
+ "no timers lsa min-arrival [(0-600000)]",
NO_STR
"Adjust routing timers\n"
"OSPF6 LSA timers\n"
- "Minimum delay in receiving new version of a LSA\n")
+ "Minimum delay in receiving new version of a LSA\n"
+ "Delay in milliseconds\n")
{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf);
+ int idx_number = 4;
unsigned int minarrival;
- struct ospf6 *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
- if (argc)
+ if (argc == 5)
{
- VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]);
+ VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[idx_number]->arg);
if (ospf->lsa_minarrival != minarrival ||
minarrival == OSPF_MIN_LS_ARRIVAL)
@@ -456,36 +440,28 @@ DEFUN (no_ospf6_timers_lsa,
return CMD_SUCCESS;
}
-ALIAS (no_ospf6_timers_lsa,
- no_ospf6_timers_lsa_val_cmd,
- "no timers lsa min-arrival <0-600000>",
- NO_STR
- "Adjust routing timers\n"
- "OSPF6 LSA timers\n"
- "Minimum delay in receiving new version of a LSA\n"
- "Delay in milliseconds\n")
DEFUN (ospf6_distance,
ospf6_distance_cmd,
- "distance <1-255>",
+ "distance (1-255)",
"Administrative distance\n"
"OSPF6 Administrative distance\n")
{
- struct ospf6 *o = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, o);
- o->distance_all = atoi (argv[0]);
+ o->distance_all = atoi (argv[1]->arg);
return CMD_SUCCESS;
}
DEFUN (no_ospf6_distance,
no_ospf6_distance_cmd,
- "no distance <1-255>",
+ "no distance (1-255)",
NO_STR
"Administrative distance\n"
"OSPF6 Administrative distance\n")
{
- struct ospf6 *o = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, o);
o->distance_all = 0;
@@ -494,7 +470,7 @@ DEFUN (no_ospf6_distance,
DEFUN (ospf6_distance_ospf6,
ospf6_distance_ospf6_cmd,
- "distance ospf6 {intra-area <1-255>|inter-area <1-255>|external <1-255>}",
+ "distance ospf6 <intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)>",
"Administrative distance\n"
"OSPF6 distance\n"
"Intra-area routes\n"
@@ -502,35 +478,68 @@ DEFUN (ospf6_distance_ospf6,
"Inter-area routes\n"
"Distance for inter-area routes\n"
"External routes\n"
+ "Distance for external routes\n"
+ "Intra-area routes\n"
+ "Distance for intra-area routes\n"
+ "Inter-area routes\n"
+ "Distance for inter-area routes\n"
+ "External routes\n"
+ "Distance for external routes\n"
+ "Intra-area routes\n"
+ "Distance for intra-area routes\n"
+ "Inter-area routes\n"
+ "Distance for inter-area routes\n"
+ "External routes\n"
"Distance for external routes\n")
{
- struct ospf6 *o = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, o);
- if (argc < 3) /* should not happen */
+ char *intra, *inter, *external;
+ intra = inter = external = NULL;
+
+ int idx = 0;
+ if (argv_find (argv, argc, "intra-area", &idx))
+ intra = argv[++idx]->arg;
+ if (argv_find (argv, argc, "intra-area", &idx))
+ {
+ vty_out (vty, "%% Cannot specify intra-area distance twice%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ idx = 0;
+ if (argv_find (argv, argc, "inter-area", &idx))
+ inter = argv[++idx]->arg;
+ if (argv_find (argv, argc, "inter-area", &idx))
+ {
+ vty_out (vty, "%% Cannot specify inter-area distance twice%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ idx = 0;
+ if (argv_find (argv, argc, "external", &idx))
+ external = argv[++idx]->arg;
+ if (argv_find (argv, argc, "external", &idx))
+ {
+ vty_out (vty, "%% Cannot specify external distance twice%s", VTY_NEWLINE);
return CMD_WARNING;
+ }
- if (!argv[0] && !argv[1] && !argv[2])
- {
- vty_out(vty, "%% Command incomplete. (Arguments required)%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (argv[0] != NULL)
- o->distance_intra = atoi (argv[0]);
+ if (intra)
+ o->distance_intra = atoi (intra);
- if (argv[1] != NULL)
- o->distance_inter = atoi (argv[1]);
+ if (inter)
+ o->distance_inter = atoi (inter);
- if (argv[2] != NULL)
- o->distance_external = atoi (argv[2]);
+ if (external)
+ o->distance_external = atoi (external);
return CMD_SUCCESS;
}
DEFUN (no_ospf6_distance_ospf6,
no_ospf6_distance_ospf6_cmd,
- "no distance ospf6 {intra-area <1-255>|inter-area <1-255>|external <1-255>}",
+ "no distance ospf6 [<intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)>]",
NO_STR
"Administrative distance\n"
"OSPF6 distance\n"
@@ -539,63 +548,107 @@ DEFUN (no_ospf6_distance_ospf6,
"Inter-area routes\n"
"Distance for inter-area routes\n"
"External routes\n"
+ "Distance for external routes\n"
+ "Intra-area routes\n"
+ "Distance for intra-area routes\n"
+ "Inter-area routes\n"
+ "Distance for inter-area routes\n"
+ "External routes\n"
+ "Distance for external routes\n"
+ "Intra-area routes\n"
+ "Distance for intra-area routes\n"
+ "Inter-area routes\n"
+ "Distance for inter-area routes\n"
+ "External routes\n"
"Distance for external routes\n")
{
- struct ospf6 *o = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf6, o);
+
+ char *intra, *inter, *external;
+ intra = inter = external = NULL;
+ if (argc == 3)
+ {
+ /* If no arguments are given, clear all distance information */
+ o->distance_intra = 0;
+ o->distance_inter = 0;
+ o->distance_external = 0;
+ return CMD_SUCCESS;
+ }
+
+ int idx = 0;
+ if (argv_find (argv, argc, "intra-area", &idx))
+ intra = argv[++idx]->arg;
+ if (argv_find (argv, argc, "intra-area", &idx))
+ {
+ vty_out (vty, "%% Cannot specify intra-area distance twice%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ idx = 0;
+ if (argv_find (argv, argc, "inter-area", &idx))
+ inter = argv[++idx]->arg;
+ if (argv_find (argv, argc, "inter-area", &idx))
+ {
+ vty_out (vty, "%% Cannot specify inter-area distance twice%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ idx = 0;
+ if (argv_find (argv, argc, "external", &idx))
+ external = argv[++idx]->arg;
+ if (argv_find (argv, argc, "external", &idx))
+ {
+ vty_out (vty, "%% Cannot specify external distance twice%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
if (argc < 3) /* should not happen */
return CMD_WARNING;
- if (argv[0] != NULL)
+ if (intra)
o->distance_intra = 0;
- if (argv[1] != NULL)
+ if (inter)
o->distance_inter = 0;
- if (argv[2] != NULL)
+ if (external)
o->distance_external = 0;
- if (argv[0] || argv[1] || argv[2])
- return CMD_SUCCESS;
-
- /* If no arguments are given, clear all distance information */
- o->distance_intra = 0;
- o->distance_inter = 0;
- o->distance_external = 0;
-
return CMD_SUCCESS;
}
+#if 0
DEFUN (ospf6_distance_source,
ospf6_distance_source_cmd,
- "distance <1-255> X:X::X:X/M [WORD]",
+ "distance (1-255) X:X::X:X/M [WORD]",
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n"
"Access list name\n")
{
- struct ospf6 *o = vty->index;
-
- ospf6_distance_set (vty, o, argv[0], argv[1], argc == 3 ? argv[2] : NULL);
+ VTY_DECLVAR_CONTEXT(ospf6, o);
+ char *alname = (argc == 4) ? argv[3]->arg : NULL;
+ ospf6_distance_set (vty, o, argv[1]->arg, argv[2]->arg, alname);
return CMD_SUCCESS;
}
DEFUN (no_ospf6_distance_source,
no_ospf6_distance_source_cmd,
- "no distance <1-255> X:X::X:X/M [WORD]",
+ "no distance (1-255) X:X::X:X/M [WORD]",
NO_STR
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n"
"Access list name\n")
{
- struct ospf6 *o = vty->index;
-
- ospf6_distance_unset (vty, o, argv[0], argv[1], argc == 3 ? argv[2] : NULL);
+ VTY_DECLVAR_CONTEXT(ospf6, o);
+ char *alname = (argc == 5) ? argv[4]->arg : NULL;
+ ospf6_distance_unset (vty, o, argv[2]->arg, argv[3]->arg, alname);
return CMD_SUCCESS;
}
+#endif
DEFUN (ospf6_interface_area,
ospf6_interface_area_cmd,
@@ -606,16 +659,16 @@ DEFUN (ospf6_interface_area,
"OSPF6 area ID in IPv4 address notation\n"
)
{
- struct ospf6 *o;
+ VTY_DECLVAR_CONTEXT(ospf6, o);
+ int idx_ifname = 1;
+ int idx_ipv4 = 3;
struct ospf6_area *oa;
struct ospf6_interface *oi;
struct interface *ifp;
u_int32_t area_id;
- o = (struct ospf6 *) vty->index;
-
/* find/create ospf6 interface */
- ifp = if_get_by_name (argv[0]);
+ ifp = if_get_by_name (argv[idx_ifname]->arg);
oi = (struct ospf6_interface *) ifp->info;
if (oi == NULL)
oi = ospf6_interface_create (ifp);
@@ -627,9 +680,9 @@ DEFUN (ospf6_interface_area,
}
/* parse Area-ID */
- if (inet_pton (AF_INET, argv[1], &area_id) != 1)
+ if (inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
{
- vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
+ vty_out (vty, "Invalid Area-ID: %s%s", argv[idx_ipv4]->arg, VNL);
return CMD_SUCCESS;
}
@@ -668,15 +721,17 @@ DEFUN (no_ospf6_interface_area,
"OSPF6 area ID in IPv4 address notation\n"
)
{
+ int idx_ifname = 2;
+ int idx_ipv4 = 4;
struct ospf6_interface *oi;
struct ospf6_area *oa;
struct interface *ifp;
u_int32_t area_id;
- ifp = if_lookup_by_name (argv[0]);
+ ifp = if_lookup_by_name (argv[idx_ifname]->arg);
if (ifp == NULL)
{
- vty_out (vty, "No such interface %s%s", argv[0], VNL);
+ vty_out (vty, "No such interface %s%s", argv[idx_ifname]->arg, VNL);
return CMD_SUCCESS;
}
@@ -688,16 +743,16 @@ DEFUN (no_ospf6_interface_area,
}
/* parse Area-ID */
- if (inet_pton (AF_INET, argv[1], &area_id) != 1)
+ if (inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
{
- vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
+ vty_out (vty, "Invalid Area-ID: %s%s", argv[idx_ipv4]->arg, VNL);
return CMD_SUCCESS;
}
/* Verify Area */
if (oi->area == NULL)
{
- vty_out (vty, "No such Area-ID: %s%s", argv[1], VNL);
+ vty_out (vty, "No such Area-ID: %s%s", argv[idx_ipv4]->arg, VNL);
return CMD_SUCCESS;
}
@@ -773,9 +828,10 @@ DEFUN (no_ospf6_stub_router_admin,
return CMD_SUCCESS;
}
+#if 0
DEFUN (ospf6_stub_router_startup,
ospf6_stub_router_startup_cmd,
- "stub-router on-startup <5-86400>",
+ "stub-router on-startup (5-86400)",
"Make router a stub router\n"
"Advertise inability to be a transit router\n"
"Automatically advertise as stub-router on startup of OSPF6\n"
@@ -798,7 +854,7 @@ DEFUN (no_ospf6_stub_router_startup,
DEFUN (ospf6_stub_router_shutdown,
ospf6_stub_router_shutdown_cmd,
- "stub-router on-shutdown <5-86400>",
+ "stub-router on-shutdown (5-86400)",
"Make router a stub router\n"
"Advertise inability to be a transit router\n"
"Automatically advertise as stub-router before shutdown\n"
@@ -818,6 +874,7 @@ DEFUN (no_ospf6_stub_router_shutdown,
{
return CMD_SUCCESS;
}
+#endif
static void
ospf6_show (struct vty *vty, struct ospf6 *o)
@@ -834,7 +891,7 @@ ospf6_show (struct vty *vty, struct ospf6 *o)
router_id, VNL);
/* running time */
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timersub (&now, &o->starttime, &running);
timerstring (&running, duration, sizeof (duration));
vty_out (vty, " Running %s%s", duration, VNL);
@@ -913,56 +970,40 @@ DEFUN (show_ipv6_ospf6,
DEFUN (show_ipv6_ospf6_route,
show_ipv6_ospf6_route_cmd,
- "show ipv6 ospf6 route",
+ "show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>]",
SHOW_STR
IP6_STR
OSPF6_STR
ROUTE_STR
- )
+ "Display Intra-Area routes\n"
+ "Display Inter-Area routes\n"
+ "Display Type-1 External routes\n"
+ "Display Type-2 External routes\n"
+ "Specify IPv6 address\n"
+ "Specify IPv6 prefix\n"
+ "Detailed information\n"
+ "Summary of route table\n")
{
OSPF6_CMD_CHECK_RUNNING ();
- ospf6_route_table_show (vty, argc, argv, ospf6->route_table);
+ ospf6_route_table_show (vty, 4, argc, argv, ospf6->route_table);
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_route,
- show_ipv6_ospf6_route_detail_cmd,
- "show ipv6 ospf6 route (X:X::X:X|X:X::X:X/M|detail|summary)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- ROUTE_STR
- "Specify IPv6 address\n"
- "Specify IPv6 prefix\n"
- "Detailed information\n"
- "Summary of route table\n"
- )
-
DEFUN (show_ipv6_ospf6_route_match,
show_ipv6_ospf6_route_match_cmd,
- "show ipv6 ospf6 route X:X::X:X/M match",
+ "show ipv6 ospf6 route X:X::X:X/M <match|longer>",
SHOW_STR
IP6_STR
OSPF6_STR
ROUTE_STR
"Specify IPv6 prefix\n"
"Display routes which match the specified route\n"
- )
+ "Display routes longer than the specified route\n")
{
- const char *sargv[CMD_ARGC_MAX];
- int i, sargc;
-
OSPF6_CMD_CHECK_RUNNING ();
- /* copy argv to sargv and then append "match" */
- for (i = 0; i < argc; i++)
- sargv[i] = argv[i];
- sargc = argc;
- sargv[sargc++] = "match";
- sargv[sargc] = NULL;
-
- ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
+ ospf6_route_table_show (vty, 4, argc, argv, ospf6->route_table);
return CMD_SUCCESS;
}
@@ -978,62 +1019,17 @@ DEFUN (show_ipv6_ospf6_route_match_detail,
"Detailed information\n"
)
{
- const char *sargv[CMD_ARGC_MAX];
- int i, sargc;
-
- /* copy argv to sargv and then append "match" and "detail" */
- for (i = 0; i < argc; i++)
- sargv[i] = argv[i];
- sargc = argc;
- sargv[sargc++] = "match";
- sargv[sargc++] = "detail";
- sargv[sargc] = NULL;
-
OSPF6_CMD_CHECK_RUNNING ();
- ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
+ ospf6_route_table_show (vty, 4, argc, argv, ospf6->route_table);
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_route_match,
- show_ipv6_ospf6_route_longer_cmd,
- "show ipv6 ospf6 route X:X::X:X/M longer",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- ROUTE_STR
- "Specify IPv6 prefix\n"
- "Display routes longer than the specified route\n"
- )
-
-DEFUN (show_ipv6_ospf6_route_match_detail,
- show_ipv6_ospf6_route_longer_detail_cmd,
- "show ipv6 ospf6 route X:X::X:X/M longer detail",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- ROUTE_STR
- "Specify IPv6 prefix\n"
- "Display routes longer than the specified route\n"
- "Detailed information\n"
- );
-ALIAS (show_ipv6_ospf6_route,
- show_ipv6_ospf6_route_type_cmd,
- "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- ROUTE_STR
- "Display Intra-Area routes\n"
- "Display Inter-Area routes\n"
- "Display Type-1 External routes\n"
- "Display Type-2 External routes\n"
- )
DEFUN (show_ipv6_ospf6_route_type_detail,
show_ipv6_ospf6_route_type_detail_cmd,
- "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2) detail",
+ "show ipv6 ospf6 route <intra-area|inter-area|external-1|external-2> detail",
SHOW_STR
IP6_STR
OSPF6_STR
@@ -1045,19 +1041,9 @@ DEFUN (show_ipv6_ospf6_route_type_detail,
"Detailed information\n"
)
{
- const char *sargv[CMD_ARGC_MAX];
- int i, sargc;
-
- /* copy argv to sargv and then append "detail" */
- for (i = 0; i < argc; i++)
- sargv[i] = argv[i];
- sargc = argc;
- sargv[sargc++] = "detail";
- sargv[sargc] = NULL;
-
OSPF6_CMD_CHECK_RUNNING ();
- ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
+ ospf6_route_table_show (vty, 4, argc, argv, ospf6->route_table);
return CMD_SUCCESS;
}
@@ -1118,7 +1104,7 @@ config_write_ospf6 (struct vty *vty)
struct ospf6_area *oa;
struct ospf6_interface *oi;
- /* OSPFv6 configuration. */
+ /* OSPFv3 configuration. */
if (ospf6 == NULL)
return CMD_SUCCESS;
@@ -1183,12 +1169,8 @@ ospf6_top_init (void)
install_element (CONFIG_NODE, &no_router_ospf6_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_route_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_route_detail_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_detail_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
install_default (OSPF6_NODE);
@@ -1201,18 +1183,18 @@ ospf6_top_init (void)
/* LSA timers commands */
install_element (OSPF6_NODE, &ospf6_timers_lsa_cmd);
install_element (OSPF6_NODE, &no_ospf6_timers_lsa_cmd);
- install_element (OSPF6_NODE, &no_ospf6_timers_lsa_val_cmd);
install_element (OSPF6_NODE, &ospf6_interface_area_cmd);
install_element (OSPF6_NODE, &no_ospf6_interface_area_cmd);
install_element (OSPF6_NODE, &ospf6_stub_router_admin_cmd);
install_element (OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
- /* For a later time
+ /* For a later time */
+#if 0
install_element (OSPF6_NODE, &ospf6_stub_router_startup_cmd);
install_element (OSPF6_NODE, &no_ospf6_stub_router_startup_cmd);
install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd);
install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd);
- */
+#endif
install_element (OSPF6_NODE, &ospf6_distance_cmd);
install_element (OSPF6_NODE, &no_ospf6_distance_cmd);
@@ -1223,5 +1205,3 @@ ospf6_top_init (void)
install_element (OSPF6_NODE, &no_ospf6_distance_source_cmd);
#endif
}
-
-
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index 8985eeaa28..42a4d12483 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -22,6 +22,7 @@
#ifndef OSPF6_TOP_H
#define OSPF6_TOP_H
+#include "qobj.h"
#include "routemap.h"
/* OSPFv3 top level data structure */
@@ -93,7 +94,10 @@ struct ospf6
u_char distance_external;
struct route_table *distance_table;
+
+ QOBJ_FIELDS
};
+DECLARE_QOBJ_TYPE(ospf6)
#define OSPF6_DISABLED 0x01
#define OSPF6_STUB_ROUTER 0x02
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 3e4042d65d..76bee9cf55 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -217,7 +217,7 @@ ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
struct stream *s;
struct zapi_ipv6 api;
unsigned long ifindex;
- struct prefix_ipv6 p;
+ struct prefix_ipv6 p, src_p;
struct in6_addr *nexthop;
if (ospf6 == NULL)
@@ -240,6 +240,18 @@ ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s));
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
+ {
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ }
+
+ if (src_p.prefixlen)
+ /* we completely ignore srcdest routes for now. */
+ return 0;
+
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
@@ -325,30 +337,6 @@ DEFUN (show_zebra,
return CMD_SUCCESS;
}
-DEFUN (router_zebra,
- router_zebra_cmd,
- "router zebra",
- "Enable a routing process\n"
- "Make connection to zebra daemon\n")
-{
- vty->node = ZEBRA_NODE;
- zclient->enable = 1;
- zclient_start (zclient);
- return CMD_SUCCESS;
-}
-
-DEFUN (no_router_zebra,
- no_router_zebra_cmd,
- "no router zebra",
- NO_STR
- "Configure routing process\n"
- "Disable connection to zebra daemon\n")
-{
- zclient->enable = 0;
- zclient_stop (zclient);
- return CMD_SUCCESS;
-}
-
/* Zebra configuration write function. */
static int
config_write_ospf6_zebra (struct vty *vty)
@@ -487,9 +475,9 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request)
api.distance = ospf6_distance_apply (dest, request);
if (type == REM)
- ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, &api);
+ ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api);
else
- ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, &api);
+ ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api);
if (ret < 0)
zlog_err ("zapi_ipv6_route() %s failed: %s",
@@ -551,7 +539,7 @@ ospf6_zebra_add_discard (struct ospf6_route *request)
dest = (struct prefix_ipv6 *) &request->prefix;
- zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, &api);
+ zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api);
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
zlog_debug ("Zebra: Route add discard %s/%d",
@@ -596,7 +584,7 @@ ospf6_zebra_delete_discard (struct ospf6_route *request)
dest = (struct prefix_ipv6 *) &request->prefix;
- zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, &api);
+ zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api);
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
zlog_debug ("Zebra: Route delete discard %s/%d",
@@ -850,9 +838,6 @@ ospf6_zebra_init (struct thread_master *master)
/* Install command element for zebra node. */
install_element (VIEW_NODE, &show_zebra_cmd);
- install_element (CONFIG_NODE, &router_zebra_cmd);
- install_element (CONFIG_NODE, &no_router_zebra_cmd);
-
install_default (ZEBRA_NODE);
install_element (ZEBRA_NODE, &redistribute_ospf6_cmd);
install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd);
@@ -864,7 +849,7 @@ ospf6_zebra_init (struct thread_master *master)
DEFUN (debug_ospf6_zebra_sendrecv,
debug_ospf6_zebra_sendrecv_cmd,
- "debug ospf6 zebra (send|recv)",
+ "debug ospf6 zebra [<send|recv>]",
DEBUG_STR
OSPF6_STR
"Debug connection between zebra\n"
@@ -872,13 +857,14 @@ DEFUN (debug_ospf6_zebra_sendrecv,
"Debug Receiving zebra\n"
)
{
+ int idx_send_recv = 3;
unsigned char level = 0;
- if (argc)
+ if (argc == 4)
{
- if (! strncmp (argv[0], "s", 1))
+ if (strmatch(argv[idx_send_recv]->text, "send"))
level = OSPF6_DEBUG_ZEBRA_SEND;
- else if (! strncmp (argv[0], "r", 1))
+ else if (strmatch(argv[idx_send_recv]->text, "recv"))
level = OSPF6_DEBUG_ZEBRA_RECV;
}
else
@@ -888,18 +874,9 @@ DEFUN (debug_ospf6_zebra_sendrecv,
return CMD_SUCCESS;
}
-ALIAS (debug_ospf6_zebra_sendrecv,
- debug_ospf6_zebra_cmd,
- "debug ospf6 zebra",
- DEBUG_STR
- OSPF6_STR
- "Debug connection between zebra\n"
- )
-
-
DEFUN (no_debug_ospf6_zebra_sendrecv,
no_debug_ospf6_zebra_sendrecv_cmd,
- "no debug ospf6 zebra (send|recv)",
+ "no debug ospf6 zebra [<send|recv>]",
NO_STR
DEBUG_STR
OSPF6_STR
@@ -908,13 +885,14 @@ DEFUN (no_debug_ospf6_zebra_sendrecv,
"Debug Receiving zebra\n"
)
{
+ int idx_send_recv = 4;
unsigned char level = 0;
- if (argc)
+ if (argc == 5)
{
- if (! strncmp (argv[0], "s", 1))
+ if (strmatch(argv[idx_send_recv]->text, "send"))
level = OSPF6_DEBUG_ZEBRA_SEND;
- else if (! strncmp (argv[0], "r", 1))
+ else if (strmatch(argv[idx_send_recv]->text, "recv"))
level = OSPF6_DEBUG_ZEBRA_RECV;
}
else
@@ -924,14 +902,6 @@ DEFUN (no_debug_ospf6_zebra_sendrecv,
return CMD_SUCCESS;
}
-ALIAS (no_debug_ospf6_zebra_sendrecv,
- no_debug_ospf6_zebra_cmd,
- "no debug ospf6 zebra",
- NO_STR
- DEBUG_STR
- OSPF6_STR
- "Debug connection between zebra\n"
- )
int
config_write_ospf6_debug_zebra (struct vty *vty)
@@ -951,12 +921,8 @@ config_write_ospf6_debug_zebra (struct vty *vty)
void
install_element_ospf6_debug_zebra (void)
{
- install_element (ENABLE_NODE, &debug_ospf6_zebra_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf6_zebra_cmd);
install_element (ENABLE_NODE, &debug_ospf6_zebra_sendrecv_cmd);
install_element (ENABLE_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
- install_element (CONFIG_NODE, &debug_ospf6_zebra_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf6_zebra_cmd);
install_element (CONFIG_NODE, &debug_ospf6_zebra_sendrecv_cmd);
install_element (CONFIG_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
}
diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c
index 76874f6d1d..2aaed5fcbf 100644
--- a/ospf6d/ospf6d.c
+++ b/ospf6d/ospf6d.c
@@ -84,7 +84,8 @@ DEFUN (show_version_ospf6,
show_version_ospf6_cmd,
"show version ospf6",
SHOW_STR
- "Displays ospf6d version\n"
+ "Display version\n"
+ "Display ospf6d version\n"
)
{
vty_out (vty, "Zebra OSPF6d Version: %s%s",
@@ -126,54 +127,61 @@ config_write_ospf6_debug (struct vty *vty)
"%s AS Scoped Link State Database%s%s"
static int
-parse_show_level (int argc, const char *argv[])
+parse_show_level (int idx_level, int argc, struct cmd_token **argv)
{
- int level = 0;
- if (argc)
+ int level = OSPF6_LSDB_SHOW_LEVEL_NORMAL;
+
+ if (argc > idx_level)
{
- if (! strncmp (argv[0], "de", 2))
+ if (strmatch (argv[idx_level]->text, "detail"))
level = OSPF6_LSDB_SHOW_LEVEL_DETAIL;
- else if (! strncmp (argv[0], "du", 2))
+ else if (strmatch (argv[idx_level]->text, "dump"))
level = OSPF6_LSDB_SHOW_LEVEL_DUMP;
- else if (! strncmp (argv[0], "in", 2))
+ else if (strmatch (argv[idx_level]->text, "internal"))
level = OSPF6_LSDB_SHOW_LEVEL_INTERNAL;
}
- else
- level = OSPF6_LSDB_SHOW_LEVEL_NORMAL;
+
return level;
}
static u_int16_t
-parse_type_spec (int argc, const char *argv[])
+parse_type_spec (int idx_lsa, int argc, struct cmd_token **argv)
{
u_int16_t type = 0;
- assert (argc);
- if (! strcmp (argv[0], "router"))
- type = htons (OSPF6_LSTYPE_ROUTER);
- else if (! strcmp (argv[0], "network"))
- type = htons (OSPF6_LSTYPE_NETWORK);
- else if (! strcmp (argv[0], "as-external"))
- type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
- else if (! strcmp (argv[0], "intra-prefix"))
- type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
- else if (! strcmp (argv[0], "inter-router"))
- type = htons (OSPF6_LSTYPE_INTER_ROUTER);
- else if (! strcmp (argv[0], "inter-prefix"))
- type = htons (OSPF6_LSTYPE_INTER_PREFIX);
- else if (! strcmp (argv[0], "link"))
- type = htons (OSPF6_LSTYPE_LINK);
+
+ if (argc > idx_lsa)
+ {
+ if (strmatch (argv[0]->text, "router"))
+ type = htons (OSPF6_LSTYPE_ROUTER);
+ else if (strmatch (argv[0]->text, "network"))
+ type = htons (OSPF6_LSTYPE_NETWORK);
+ else if (strmatch (argv[0]->text, "as-external"))
+ type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
+ else if (strmatch (argv[0]->text, "intra-prefix"))
+ type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
+ else if (strmatch (argv[0]->text, "inter-router"))
+ type = htons (OSPF6_LSTYPE_INTER_ROUTER);
+ else if (strmatch (argv[0]->text, "inter-prefix"))
+ type = htons (OSPF6_LSTYPE_INTER_PREFIX);
+ else if (strmatch (argv[0]->text, "link"))
+ type = htons (OSPF6_LSTYPE_LINK);
+ }
+
return type;
}
DEFUN (show_ipv6_ospf6_database,
show_ipv6_ospf6_database_cmd,
- "show ipv6 ospf6 database",
+ "show ipv6 ospf6 database [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
"Display Link state database\n"
- )
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_level = 4;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -182,7 +190,7 @@ DEFUN (show_ipv6_ospf6_database,
OSPF6_CMD_CHECK_RUNNING ();
- level = parse_show_level (argc, argv);
+ level = parse_show_level (idx_level, argc, argv);
for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
{
@@ -207,23 +215,9 @@ DEFUN (show_ipv6_ospf6_database,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database,
- show_ipv6_ospf6_database_detail_cmd,
- "show ipv6 ospf6 database (detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
DEFUN (show_ipv6_ospf6_database_type,
show_ipv6_ospf6_database_type_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix)",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -237,8 +231,13 @@ DEFUN (show_ipv6_ospf6_database_type,
"Display Type-7 LSAs\n"
"Display Link LSAs\n"
"Display Intra-Area-Prefix LSAs\n"
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n"
)
{
+ int idx_lsa = 4;
+ int idx_level = 5;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -248,10 +247,8 @@ DEFUN (show_ipv6_ospf6_database_type,
OSPF6_CMD_CHECK_RUNNING ();
- type = parse_type_spec (argc, argv);
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ type = parse_type_spec (idx_lsa, argc, argv);
+ level = parse_show_level (idx_level, argc, argv);
switch (OSPF6_LSA_SCOPE (type))
{
@@ -289,41 +286,22 @@ DEFUN (show_ipv6_ospf6_database_type,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_type,
- show_ipv6_ospf6_database_type_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
DEFUN (show_ipv6_ospf6_database_id,
show_ipv6_ospf6_database_id_cmd,
- "show ipv6 ospf6 database * A.B.C.D",
+ "show ipv6 ospf6 database <*|linkstate-id> A.B.C.D [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
"Display Link state database\n"
"Any Link state Type\n"
+ "Search by Link state ID\n"
"Specify Link state ID as IPv4 address notation\n"
- )
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_ipv4 = 4;
+ int idx_level = 6;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -333,16 +311,10 @@ DEFUN (show_ipv6_ospf6_database_id,
OSPF6_CMD_CHECK_RUNNING ();
- if ((inet_pton (AF_INET, argv[0], &id)) != 1)
- {
- vty_out (vty, "Link State ID is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
+ if (argv[idx_ipv4]->type == IPV4_TKN)
+ inet_pton (AF_INET, argv[idx_ipv4]->arg, &id);
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ level = parse_show_level (idx_level, argc, argv);
for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
{
@@ -367,59 +339,23 @@ DEFUN (show_ipv6_ospf6_database_id,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_id,
- show_ipv6_ospf6_database_id_detail_cmd,
- "show ipv6 ospf6 database * A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Any Link state Type\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
-ALIAS (show_ipv6_ospf6_database_id,
- show_ipv6_ospf6_database_linkstate_id_cmd,
- "show ipv6 ospf6 database linkstate-id A.B.C.D",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Search by Link state ID\n"
- "Specify Link state ID as IPv4 address notation\n"
- )
-
-ALIAS (show_ipv6_ospf6_database_id,
- show_ipv6_ospf6_database_linkstate_id_detail_cmd,
- "show ipv6 ospf6 database linkstate-id A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Search by Link state ID\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
DEFUN (show_ipv6_ospf6_database_router,
show_ipv6_ospf6_database_router_cmd,
- "show ipv6 ospf6 database * * A.B.C.D",
+ "show ipv6 ospf6 database <*|adv-router> * A.B.C.D <detail|dump|internal>",
SHOW_STR
IPV6_STR
OSPF6_STR
"Display Link state database\n"
"Any Link state Type\n"
+ "Search by Advertising Router\n"
"Any Link state ID\n"
"Specify Advertising Router as IPv4 address notation\n"
- )
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_ipv4 = 6;
+ int idx_level = 7;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -428,17 +364,8 @@ DEFUN (show_ipv6_ospf6_database_router,
u_int32_t adv_router = 0;
OSPF6_CMD_CHECK_RUNNING ();
-
- if ((inet_pton (AF_INET, argv[0], &adv_router)) != 1)
- {
- vty_out (vty, "Advertising Router is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ inet_pton (AF_INET, argv[idx_ipv4]->arg, &adv_router);
+ level = parse_show_level (idx_level, argc, argv);
for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
{
@@ -463,53 +390,9 @@ DEFUN (show_ipv6_ospf6_database_router,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_router,
- show_ipv6_ospf6_database_router_detail_cmd,
- "show ipv6 ospf6 database * * A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Any Link state Type\n"
- "Any Link state ID\n"
- "Specify Advertising Router as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
-ALIAS (show_ipv6_ospf6_database_router,
- show_ipv6_ospf6_database_adv_router_cmd,
- "show ipv6 ospf6 database adv-router A.B.C.D",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Search by Advertising Router\n"
- "Specify Advertising Router as IPv4 address notation\n"
- )
-
-ALIAS (show_ipv6_ospf6_database_router,
- show_ipv6_ospf6_database_adv_router_detail_cmd,
- "show ipv6 ospf6 database adv-router A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Search by Advertising Router\n"
- "Specify Advertising Router as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
DEFUN (show_ipv6_ospf6_database_type_id,
show_ipv6_ospf6_database_type_id_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) A.B.C.D",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> [linkstate-id] A.B.C.D [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -523,9 +406,16 @@ DEFUN (show_ipv6_ospf6_database_type_id,
"Display Type-7 LSAs\n"
"Display Link LSAs\n"
"Display Intra-Area-Prefix LSAs\n"
+ "Search by Link state ID\n"
"Specify Link state ID as IPv4 address notation\n"
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n"
)
{
+ int idx_lsa = 4;
+ int idx_ipv4 = 6;
+ int idx_level = 7;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -536,20 +426,9 @@ DEFUN (show_ipv6_ospf6_database_type_id,
OSPF6_CMD_CHECK_RUNNING ();
- type = parse_type_spec (argc, argv);
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &id)) != 1)
- {
- vty_out (vty, "Link state ID is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ type = parse_type_spec (idx_lsa, argc, argv);
+ inet_pton (AF_INET, argv[idx_ipv4]->arg, &id);
+ level = parse_show_level (idx_level, argc, argv);
switch (OSPF6_LSA_SCOPE (type))
{
@@ -587,84 +466,9 @@ DEFUN (show_ipv6_ospf6_database_type_id,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_type_id,
- show_ipv6_ospf6_database_type_id_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
-ALIAS (show_ipv6_ospf6_database_type_id,
- show_ipv6_ospf6_database_type_linkstate_id_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) linkstate-id A.B.C.D",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Search by Link state ID\n"
- "Specify Link state ID as IPv4 address notation\n"
- )
-
-ALIAS (show_ipv6_ospf6_database_type_id,
- show_ipv6_ospf6_database_type_linkstate_id_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) linkstate-id A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Search by Link state ID\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
DEFUN (show_ipv6_ospf6_database_type_router,
show_ipv6_ospf6_database_type_router_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) * A.B.C.D",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> <*|adv-router> A.B.C.D [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -679,9 +483,16 @@ DEFUN (show_ipv6_ospf6_database_type_router,
"Display Link LSAs\n"
"Display Intra-Area-Prefix LSAs\n"
"Any Link state ID\n"
+ "Search by Advertising Router\n"
"Specify Advertising Router as IPv4 address notation\n"
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n"
)
{
+ int idx_lsa = 4;
+ int idx_ipv4 = 6;
+ int idx_level = 7;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -692,20 +503,9 @@ DEFUN (show_ipv6_ospf6_database_type_router,
OSPF6_CMD_CHECK_RUNNING ();
- type = parse_type_spec (argc, argv);
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &adv_router)) != 1)
- {
- vty_out (vty, "Advertising Router is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ type = parse_type_spec (idx_lsa, argc, argv);
+ inet_pton (AF_INET, argv[idx_ipv4]->arg, &adv_router);
+ level = parse_show_level (idx_level, argc, argv);
switch (OSPF6_LSA_SCOPE (type))
{
@@ -743,83 +543,10 @@ DEFUN (show_ipv6_ospf6_database_type_router,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_type_router,
- show_ipv6_ospf6_database_type_router_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) * A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Any Link state ID\n"
- "Specify Advertising Router as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
-ALIAS (show_ipv6_ospf6_database_type_router,
- show_ipv6_ospf6_database_type_adv_router_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) adv-router A.B.C.D",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Search by Advertising Router\n"
- "Specify Advertising Router as IPv4 address notation\n"
- )
-
-ALIAS (show_ipv6_ospf6_database_type_router,
- show_ipv6_ospf6_database_type_adv_router_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) adv-router A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Search by Advertising Router\n"
- "Specify Advertising Router as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
DEFUN (show_ipv6_ospf6_database_id_router,
show_ipv6_ospf6_database_id_router_cmd,
- "show ipv6 ospf6 database * A.B.C.D A.B.C.D",
+ "show ipv6 ospf6 database * A.B.C.D A.B.C.D [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -827,8 +554,14 @@ DEFUN (show_ipv6_ospf6_database_id_router,
"Any Link state Type\n"
"Specify Link state ID as IPv4 address notation\n"
"Specify Advertising Router as IPv4 address notation\n"
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n"
)
{
+ int idx_ls_id = 5;
+ int idx_adv_rtr = 6;
+ int idx_level = 7;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -838,27 +571,9 @@ DEFUN (show_ipv6_ospf6_database_id_router,
u_int32_t adv_router = 0;
OSPF6_CMD_CHECK_RUNNING ();
-
- if ((inet_pton (AF_INET, argv[0], &id)) != 1)
- {
- vty_out (vty, "Link state ID is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &adv_router)) != 1)
- {
- vty_out (vty, "Advertising Router is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ inet_pton (AF_INET, argv[idx_ls_id]->arg, &id);
+ inet_pton (AF_INET, argv[idx_adv_rtr]->arg, &adv_router);
+ level = parse_show_level (idx_level, argc, argv);
for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
{
@@ -883,25 +598,10 @@ DEFUN (show_ipv6_ospf6_database_id_router,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_id_router,
- show_ipv6_ospf6_database_id_router_detail_cmd,
- "show ipv6 ospf6 database * A.B.C.D A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Any Link state Type\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Specify Advertising Router as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
show_ipv6_ospf6_database_adv_router_linkstate_id_cmd,
- "show ipv6 ospf6 database adv-router A.B.C.D linkstate-id A.B.C.D",
+ "show ipv6 ospf6 database adv-router A.B.C.D linkstate-id A.B.C.D [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -910,8 +610,13 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
"Specify Advertising Router as IPv4 address notation\n"
"Search by Link state ID\n"
"Specify Link state ID as IPv4 address notation\n"
- )
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_adv_rtr = 5;
+ int idx_ls_id = 7;
+ int idx_level = 8;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -921,27 +626,9 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
u_int32_t adv_router = 0;
OSPF6_CMD_CHECK_RUNNING ();
-
- if ((inet_pton (AF_INET, argv[0], &adv_router)) != 1)
- {
- vty_out (vty, "Advertising Router is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &id)) != 1)
- {
- vty_out (vty, "Link state ID is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ inet_pton (AF_INET, argv[idx_adv_rtr]->arg, &adv_router);
+ inet_pton (AF_INET, argv[idx_ls_id]->arg, &id);
+ level = parse_show_level (idx_level, argc, argv);
for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
{
@@ -966,28 +653,9 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_adv_router_linkstate_id,
- show_ipv6_ospf6_database_adv_router_linkstate_id_detail_cmd,
- "show ipv6 ospf6 database adv-router A.B.C.D linkstate-id A.B.C.D "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Search by Advertising Router\n"
- "Specify Advertising Router as IPv4 address notation\n"
- "Search by Link state ID\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
DEFUN (show_ipv6_ospf6_database_type_id_router,
show_ipv6_ospf6_database_type_id_router_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) A.B.C.D A.B.C.D",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> A.B.C.D A.B.C.D [<dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -1003,8 +671,13 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
"Display Intra-Area-Prefix LSAs\n"
"Specify Link state ID as IPv4 address notation\n"
"Specify Advertising Router as IPv4 address notation\n"
- )
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_lsa = 4;
+ int idx_ls_id = 5;
+ int idx_adv_rtr = 6;
+ int idx_level = 7;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -1016,30 +689,10 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
OSPF6_CMD_CHECK_RUNNING ();
- type = parse_type_spec (argc, argv);
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &id)) != 1)
- {
- vty_out (vty, "Link state ID is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &adv_router)) != 1)
- {
- vty_out (vty, "Advertising Router is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ type = parse_type_spec (idx_lsa, argc, argv);
+ inet_pton (AF_INET, argv[idx_ls_id]->arg, &id);
+ inet_pton (AF_INET, argv[idx_adv_rtr]->arg, &adv_router);
+ level = parse_show_level (idx_level, argc, argv);
switch (OSPF6_LSA_SCOPE (type))
{
@@ -1077,37 +730,10 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_type_id_router,
- show_ipv6_ospf6_database_type_id_router_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) A.B.C.D A.B.C.D "
- "(dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Specify Advertising Router as IPv4 address notation\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
show_ipv6_ospf6_database_type_adv_router_linkstate_id_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) "
- "adv-router A.B.C.D linkstate-id A.B.C.D",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> adv-router A.B.C.D linkstate-id A.B.C.D [<dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -1125,8 +751,13 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
"Specify Advertising Router as IPv4 address notation\n"
"Search by Link state ID\n"
"Specify Link state ID as IPv4 address notation\n"
- )
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_lsa = 4;
+ int idx_adv_rtr = 6;
+ int idx_ls_id = 8;
+ int idx_level = 9;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -1138,30 +769,10 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
OSPF6_CMD_CHECK_RUNNING ();
- type = parse_type_spec (argc, argv);
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &adv_router)) != 1)
- {
- vty_out (vty, "Advertising Router is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &id)) != 1)
- {
- vty_out (vty, "Link state ID is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ type = parse_type_spec (idx_lsa, argc, argv);
+ inet_pton (AF_INET, argv[idx_adv_rtr]->arg, &adv_router);
+ inet_pton (AF_INET, argv[idx_ls_id]->arg, &id);
+ level = parse_show_level (idx_level, argc, argv);
switch (OSPF6_LSA_SCOPE (type))
{
@@ -1199,43 +810,19 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
- show_ipv6_ospf6_database_type_adv_router_linkstate_id_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) "
- "adv-router A.B.C.D linkstate-id A.B.C.D "
- "(dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Search by Advertising Router\n"
- "Specify Advertising Router as IPv4 address notation\n"
- "Search by Link state ID\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
DEFUN (show_ipv6_ospf6_database_self_originated,
show_ipv6_ospf6_database_self_originated_cmd,
- "show ipv6 ospf6 database self-originated",
+ "show ipv6 ospf6 database self-originated [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
+ "Display Link state database\n"
"Display Self-originated LSAs\n"
- )
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_level = 5;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -1244,9 +831,7 @@ DEFUN (show_ipv6_ospf6_database_self_originated,
u_int32_t adv_router = 0;
OSPF6_CMD_CHECK_RUNNING ();
-
- level = parse_show_level (argc, argv);
-
+ level = parse_show_level (idx_level, argc, argv);
adv_router = o->router_id;
for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
@@ -1272,24 +857,10 @@ DEFUN (show_ipv6_ospf6_database_self_originated,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_self_originated,
- show_ipv6_ospf6_database_self_originated_detail_cmd,
- "show ipv6 ospf6 database self-originated "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Self-originated LSAs\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
DEFUN (show_ipv6_ospf6_database_type_self_originated,
show_ipv6_ospf6_database_type_self_originated_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) self-originated",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> self-originated [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -1304,8 +875,12 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
"Display Link LSAs\n"
"Display Intra-Area-Prefix LSAs\n"
"Display Self-originated LSAs\n"
- )
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_lsa = 4;
+ int idx_level = 6;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -1316,10 +891,8 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
OSPF6_CMD_CHECK_RUNNING ();
- type = parse_type_spec (argc, argv);
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
+ type = parse_type_spec (idx_lsa, argc, argv);
+ level = parse_show_level (idx_level, argc, argv);
adv_router = o->router_id;
@@ -1359,37 +932,9 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_type_self_originated,
- show_ipv6_ospf6_database_type_self_originated_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) self-originated "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Display Self-originated LSAs\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
show_ipv6_ospf6_database_type_self_originated_linkstate_id_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) self-originated "
- "linkstate-id A.B.C.D",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> self-originated linkstate-id A.B.C.D [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -1406,8 +951,13 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
"Display Self-originated LSAs\n"
"Search by Link state ID\n"
"Specify Link state ID as IPv4 address notation\n"
- )
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_lsa = 4;
+ int idx_ls_id = 7;
+ int idx_level = 8;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -1419,21 +969,9 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
OSPF6_CMD_CHECK_RUNNING ();
- type = parse_type_spec (argc, argv);
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &id)) != 1)
- {
- vty_out (vty, "Link State ID is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
-
+ type = parse_type_spec (idx_lsa, argc, argv);
+ inet_pton (AF_INET, argv[idx_ls_id]->arg, &id);
+ level = parse_show_level (idx_level, argc, argv);
adv_router = o->router_id;
switch (OSPF6_LSA_SCOPE (type))
@@ -1472,38 +1010,9 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
- show_ipv6_ospf6_database_type_self_originated_linkstate_id_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) self-originated "
- "linkstate-id A.B.C.D (detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Display Self-originated LSAs\n"
- "Search by Link state ID\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
show_ipv6_ospf6_database_type_id_self_originated_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) A.B.C.D self-originated",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> A.B.C.D self-originated [<detail|dump|internal>]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -1519,8 +1028,13 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
"Display Intra-Area-Prefix LSAs\n"
"Specify Link state ID as IPv4 address notation\n"
"Display Self-originated LSAs\n"
- )
+ "Display details of LSAs\n"
+ "Dump LSAs\n"
+ "Display LSA's internal information\n")
{
+ int idx_lsa = 4;
+ int idx_ls_id = 5;
+ int idx_level = 7;
int level;
struct listnode *i, *j;
struct ospf6 *o = ospf6;
@@ -1532,21 +1046,9 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
OSPF6_CMD_CHECK_RUNNING ();
- type = parse_type_spec (argc, argv);
- argc--;
- argv++;
-
- if ((inet_pton (AF_INET, argv[0], &id)) != 1)
- {
- vty_out (vty, "Link State ID is not parsable: %s%s",
- argv[0], VNL);
- return CMD_SUCCESS;
- }
-
- argc--;
- argv++;
- level = parse_show_level (argc, argv);
-
+ type = parse_type_spec (idx_lsa, argc, argv);
+ inet_pton (AF_INET, argv[idx_ls_id]->arg, &id);
+ level = parse_show_level (idx_level, argc, argv);
adv_router = o->router_id;
switch (OSPF6_LSA_SCOPE (type))
@@ -1585,109 +1087,74 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_database_type_id_self_originated,
- show_ipv6_ospf6_database_type_id_self_originated_detail_cmd,
- "show ipv6 ospf6 database "
- "(router|network|inter-prefix|inter-router|as-external|"
- "group-membership|type-7|link|intra-prefix) A.B.C.D self-originated "
- "(detail|dump|internal)",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- "Display Link state database\n"
- "Display Router LSAs\n"
- "Display Network LSAs\n"
- "Display Inter-Area-Prefix LSAs\n"
- "Display Inter-Area-Router LSAs\n"
- "Display As-External LSAs\n"
- "Display Group-Membership LSAs\n"
- "Display Type-7 LSAs\n"
- "Display Link LSAs\n"
- "Display Intra-Area-Prefix LSAs\n"
- "Display Self-originated LSAs\n"
- "Search by Link state ID\n"
- "Specify Link state ID as IPv4 address notation\n"
- "Display details of LSAs\n"
- "Dump LSAs\n"
- "Display LSA's internal information\n"
- )
-
-
DEFUN (show_ipv6_ospf6_border_routers,
show_ipv6_ospf6_border_routers_cmd,
- "show ipv6 ospf6 border-routers",
+ "show ipv6 ospf6 border-routers [<A.B.C.D|detail>]",
SHOW_STR
IP6_STR
OSPF6_STR
"Display routing table for ABR and ASBR\n"
- )
+ "Router ID\n"
+ "Show detailed output\n")
{
+ int idx_ipv4 = 4;
u_int32_t adv_router;
- void (*showfunc) (struct vty *, struct ospf6_route *);
struct ospf6_route *ro;
struct prefix prefix;
OSPF6_CMD_CHECK_RUNNING ();
- if (argc && ! strcmp ("detail", argv[0]))
+ if (argc == 5)
{
- showfunc = ospf6_route_show_detail;
- argc--;
- argv++;
- }
- else
- showfunc = ospf6_brouter_show;
-
- if (argc)
- {
- if ((inet_pton (AF_INET, argv[0], &adv_router)) != 1)
+ if (strmatch (argv[idx_ipv4]->text, "detail"))
{
- vty_out (vty, "Router ID is not parsable: %s%s", argv[0], VNL);
- return CMD_SUCCESS;
+ for (ro = ospf6_route_head (ospf6->brouter_table); ro;
+ ro = ospf6_route_next (ro))
+ ospf6_route_show_detail (vty, ro);
}
-
- ospf6_linkstate_prefix (adv_router, 0, &prefix);
- ro = ospf6_route_lookup (&prefix, ospf6->brouter_table);
- if (!ro)
+ else
{
- vty_out (vty, "No Route found for Router ID: %s%s", argv[0], VNL);
+ inet_pton (AF_INET, argv[idx_ipv4]->arg, &adv_router);
+
+ ospf6_linkstate_prefix (adv_router, 0, &prefix);
+ ro = ospf6_route_lookup (&prefix, ospf6->brouter_table);
+ if (!ro)
+ {
+ vty_out (vty, "No Route found for Router ID: %s%s", argv[4]->arg, VNL);
+ return CMD_SUCCESS;
+ }
+
+ ospf6_route_show_detail (vty, ro);
return CMD_SUCCESS;
}
-
- ospf6_route_show_detail (vty, ro);
- return CMD_SUCCESS;
}
+ else
+ {
+ ospf6_brouter_show_header (vty);
- if (showfunc == ospf6_brouter_show)
- ospf6_brouter_show_header (vty);
-
- for (ro = ospf6_route_head (ospf6->brouter_table); ro;
- ro = ospf6_route_next (ro))
- (*showfunc) (vty, ro);
+ for (ro = ospf6_route_head (ospf6->brouter_table); ro;
+ ro = ospf6_route_next (ro))
+ ospf6_brouter_show (vty, ro);
+ }
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_border_routers,
- show_ipv6_ospf6_border_routers_detail_cmd,
- "show ipv6 ospf6 border-routers (A.B.C.D|detail)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- "Display routing table for ABR and ASBR\n"
- "Specify Router-ID\n"
- "Display Detail\n"
- )
DEFUN (show_ipv6_ospf6_linkstate,
show_ipv6_ospf6_linkstate_cmd,
- "show ipv6 ospf6 linkstate",
+ "show ipv6 ospf6 linkstate <router A.B.C.D|network A.B.C.D A.B.C.D>",
SHOW_STR
IP6_STR
OSPF6_STR
"Display linkstate routing table\n"
- )
+ "Display Router Entry\n"
+ "Specify Router ID as IPv4 address notation\n"
+ "Display Network Entry\n"
+ "Specify Router ID as IPv4 address notation\n"
+ "Specify Link state ID as IPv4 address notation\n")
{
+ int idx_ipv4 = 4;
struct listnode *node;
struct ospf6_area *oa;
@@ -1697,35 +1164,14 @@ DEFUN (show_ipv6_ospf6_linkstate,
{
vty_out (vty, "%s SPF Result in Area %s%s%s",
VNL, oa->name, VNL, VNL);
- ospf6_linkstate_table_show (vty, argc, argv, oa->spf_table);
+ ospf6_linkstate_table_show (vty, idx_ipv4, argc, argv, oa->spf_table);
}
vty_out (vty, "%s", VNL);
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_ospf6_linkstate,
- show_ipv6_ospf6_linkstate_router_cmd,
- "show ipv6 ospf6 linkstate router A.B.C.D",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- "Display linkstate routing table\n"
- "Display Router Entry\n"
- "Specify Router ID as IPv4 address notation\n"
- )
-ALIAS (show_ipv6_ospf6_linkstate,
- show_ipv6_ospf6_linkstate_network_cmd,
- "show ipv6 ospf6 linkstate network A.B.C.D A.B.C.D",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- "Display linkstate routing table\n"
- "Display Network Entry\n"
- "Specify Router ID as IPv4 address notation\n"
- "Specify Link state ID as IPv4 address notation\n"
- )
DEFUN (show_ipv6_ospf6_linkstate_detail,
show_ipv6_ospf6_linkstate_detail_cmd,
@@ -1734,27 +1180,19 @@ DEFUN (show_ipv6_ospf6_linkstate_detail,
IP6_STR
OSPF6_STR
"Display linkstate routing table\n"
- )
+ "Display detailed information\n")
{
- const char *sargv[CMD_ARGC_MAX];
- int i, sargc;
+ int idx_detail = 4;
struct listnode *node;
struct ospf6_area *oa;
OSPF6_CMD_CHECK_RUNNING ();
- /* copy argv to sargv and then append "detail" */
- for (i = 0; i < argc; i++)
- sargv[i] = argv[i];
- sargc = argc;
- sargv[sargc++] = "detail";
- sargv[sargc] = NULL;
-
for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
{
vty_out (vty, "%s SPF Result in Area %s%s%s",
VNL, oa->name, VNL, VNL);
- ospf6_linkstate_table_show (vty, sargc, sargv, oa->spf_table);
+ ospf6_linkstate_table_show (vty, idx_detail, argc, argv, oa->spf_table);
}
vty_out (vty, "%s", VNL);
@@ -1801,52 +1239,24 @@ ospf6_init (void)
install_element (VIEW_NODE, &show_version_ospf6_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_border_routers_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_border_routers_detail_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_router_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_network_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_detail_cmd);
-#define INSTALL(n,c) \
- install_element (n ## _NODE, &show_ipv6_ospf6_ ## c)
-
- INSTALL (VIEW, database_cmd);
- INSTALL (VIEW, database_detail_cmd);
- INSTALL (VIEW, database_type_cmd);
- INSTALL (VIEW, database_type_detail_cmd);
- INSTALL (VIEW, database_id_cmd);
- INSTALL (VIEW, database_id_detail_cmd);
- INSTALL (VIEW, database_linkstate_id_cmd);
- INSTALL (VIEW, database_linkstate_id_detail_cmd);
- INSTALL (VIEW, database_router_cmd);
- INSTALL (VIEW, database_router_detail_cmd);
- INSTALL (VIEW, database_adv_router_cmd);
- INSTALL (VIEW, database_adv_router_detail_cmd);
- INSTALL (VIEW, database_type_id_cmd);
- INSTALL (VIEW, database_type_id_detail_cmd);
- INSTALL (VIEW, database_type_linkstate_id_cmd);
- INSTALL (VIEW, database_type_linkstate_id_detail_cmd);
- INSTALL (VIEW, database_type_router_cmd);
- INSTALL (VIEW, database_type_router_detail_cmd);
- INSTALL (VIEW, database_type_adv_router_cmd);
- INSTALL (VIEW, database_type_adv_router_detail_cmd);
- INSTALL (VIEW, database_adv_router_linkstate_id_cmd);
- INSTALL (VIEW, database_adv_router_linkstate_id_detail_cmd);
- INSTALL (VIEW, database_id_router_cmd);
- INSTALL (VIEW, database_id_router_detail_cmd);
- INSTALL (VIEW, database_type_id_router_cmd);
- INSTALL (VIEW, database_type_id_router_detail_cmd);
- INSTALL (VIEW, database_type_adv_router_linkstate_id_cmd);
- INSTALL (VIEW, database_type_adv_router_linkstate_id_detail_cmd);
- INSTALL (VIEW, database_self_originated_cmd);
- INSTALL (VIEW, database_self_originated_detail_cmd);
- INSTALL (VIEW, database_type_self_originated_cmd);
- INSTALL (VIEW, database_type_self_originated_detail_cmd);
- INSTALL (VIEW, database_type_id_self_originated_cmd);
- INSTALL (VIEW, database_type_id_self_originated_detail_cmd);
- INSTALL (VIEW, database_type_self_originated_linkstate_id_cmd);
- INSTALL (VIEW, database_type_self_originated_linkstate_id_detail_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_id_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_router_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_router_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_adv_router_linkstate_id_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_id_router_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_router_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_adv_router_linkstate_id_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_self_originated_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_self_originated_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_self_originated_cmd);
+ install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_self_originated_linkstate_id_cmd);
/* Make ospf protocol socket. */
ospf6_serv_sock ();
diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h
index b41e8ff001..f0bc022749 100644
--- a/ospf6d/ospf6d.h
+++ b/ospf6d/ospf6d.h
@@ -58,21 +58,6 @@ extern struct thread_master *master;
#define OSPF6_NEIGHBOR(x) ((struct ospf6_neighbor *) (x))
/* operation on timeval structure */
-#ifndef timerclear
-#define timerclear(a) (a)->tv_sec = (tvp)->tv_usec = 0
-#endif /*timerclear*/
-#ifndef timersub
-#define timersub(a, b, res) \
- do { \
- (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
- (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
- if ((res)->tv_usec < 0) \
- { \
- (res)->tv_sec--; \
- (res)->tv_usec += 1000000; \
- } \
- } while (0)
-#endif /*timersub*/
#define timerstring(tv, buf, size) \
do { \
if ((tv)->tv_sec / 60 / 60 / 24) \
@@ -87,15 +72,6 @@ extern struct thread_master *master;
(tv)->tv_sec / 60LL % 60, \
(tv)->tv_sec % 60LL); \
} while (0)
-#define timerstring_local(tv, buf, size) \
- do { \
- int ret; \
- struct tm *tm; \
- tm = localtime (&(tv)->tv_sec); \
- ret = strftime (buf, size, "%Y/%m/%d %H:%M:%S", tm); \
- if (ret == 0) \
- zlog_warn ("strftime error"); \
- } while (0)
#define threadtimer_string(now, t, buf, size) \
do { \
diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c
index fe40b10171..b063f317e2 100644
--- a/ospfd/ospf_ase.c
+++ b/ospfd/ospf_ase.c
@@ -649,7 +649,7 @@ ospf_ase_calculate_timer (struct thread *t)
{
ospf->ase_calc = 0;
- quagga_gettime(QUAGGA_CLK_MONOTONIC, &start_time);
+ monotime(&start_time);
/* Calculate external route for each AS-external-LSA */
LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
@@ -681,7 +681,7 @@ ospf_ase_calculate_timer (struct thread *t)
ospf->old_external_route = ospf->new_external_route;
ospf->new_external_route = route_table_init ();
- quagga_gettime(QUAGGA_CLK_MONOTONIC, &stop_time);
+ monotime(&stop_time);
zlog_info ("SPF Processing Time(usecs): External Routes: %lld\n",
(stop_time.tv_sec - start_time.tv_sec)*1000000LL+
diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c
index 9ad8508510..74bc38220b 100644
--- a/ospfd/ospf_bfd.c
+++ b/ospfd/ospf_bfd.c
@@ -249,7 +249,7 @@ ospf_bfd_interface_dest_update (int command, struct zclient *zclient,
old_status = bfd_info->status;
bfd_info->status = status;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv);
+ monotime(&tv);
bfd_info->last_update = tv.tv_sec;
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
@@ -368,7 +368,7 @@ DEFUN (ip_ospf_bfd,
"OSPF interface commands\n"
"Enables BFD support\n")
{
- struct interface *ifp = (struct interface *) vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf_if_params *params;
struct bfd_info *bfd_info;
@@ -385,7 +385,7 @@ DEFUN (ip_ospf_bfd,
DEFUN (ip_ospf_bfd_param,
ip_ospf_bfd_param_cmd,
- "ip ospf bfd " BFD_CMD_DETECT_MULT_RANGE BFD_CMD_MIN_RX_RANGE BFD_CMD_MIN_TX_RANGE,
+ "ip ospf bfd (2-255) (50-60000) (50-60000)",
"IP Information\n"
"OSPF interface commands\n"
"Enables BFD support\n"
@@ -393,7 +393,10 @@ DEFUN (ip_ospf_bfd_param,
"Required min receive interval\n"
"Desired min transmit interval\n")
{
- struct interface *ifp = (struct interface *) vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 5;
u_int32_t rx_val;
u_int32_t tx_val;
u_int8_t dm_val;
@@ -401,7 +404,7 @@ DEFUN (ip_ospf_bfd_param,
assert (ifp);
- if ((ret = bfd_validate_param (vty, argv[0], argv[1], argv[2], &dm_val,
+ if ((ret = bfd_validate_param (vty, argv[idx_number]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg, &dm_val,
&rx_val, &tx_val)) != CMD_SUCCESS)
return ret;
@@ -412,13 +415,16 @@ DEFUN (ip_ospf_bfd_param,
DEFUN (no_ip_ospf_bfd,
no_ip_ospf_bfd_cmd,
- "no ip ospf bfd",
+ "no ip ospf bfd [(2-255) (50-60000) (50-60000)]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
- "Disables BFD support\n")
+ "Disables BFD support\n"
+ "Detect Multiplier\n"
+ "Required min receive interval\n"
+ "Desired min transmit interval\n")
{
- struct interface *ifp = (struct interface *)vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf_if_params *params;
assert (ifp);
@@ -433,17 +439,6 @@ DEFUN (no_ip_ospf_bfd,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_bfd,
- no_ip_ospf_bfd_param_cmd,
- "no ip ospf bfd " BFD_CMD_DETECT_MULT_RANGE BFD_CMD_MIN_RX_RANGE BFD_CMD_MIN_TX_RANGE,
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Enables BFD support\n"
- "Detect Multiplier\n"
- "Required min receive interval\n"
- "Desired min transmit interval\n")
-
void
ospf_bfd_init(void)
{
@@ -457,5 +452,4 @@ ospf_bfd_init(void)
install_element (INTERFACE_NODE, &ip_ospf_bfd_cmd);
install_element (INTERFACE_NODE, &ip_ospf_bfd_param_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_bfd_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_bfd_param_cmd);
}
diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c
index 5535261195..21b2855499 100644
--- a/ospfd/ospf_dump.c
+++ b/ospfd/ospf_dump.c
@@ -22,6 +22,7 @@
#include <zebra.h>
+#include "monotime.h"
#include "linklist.h"
#include "thread.h"
#include "prefix.h"
@@ -234,8 +235,8 @@ ospf_timer_dump (struct thread *t, char *buf, size_t size)
struct timeval result;
if (!t)
return "inactive";
-
- result = tv_sub (t->u.sands, recent_relative_time());
+
+ monotime_until (&t->u.sands, &result);
return ospf_timeval_dump (&result, buf, size);
}
@@ -633,54 +634,69 @@ ospf_packet_dump (struct stream *s)
stream_set_getp (s, gp);
}
-
-/*
- [no] debug ospf [<1-65535>] packet (hello|dd|ls-request|ls-update|ls-ack|all)
- [send|recv [detail]]
-*/
-static int
-debug_ospf_packet_common (struct vty *vty, int arg_base, int argc,
- const char **argv)
+DEFUN (debug_ospf_packet,
+ debug_ospf_packet_cmd,
+ "debug ospf [(1-65535)] packet <hello|dd|ls-request|ls-update|ls-ack|all> [<send [detail]|recv [detail]|detail>]",
+ DEBUG_STR
+ OSPF_STR
+ "Instance ID\n"
+ "OSPF packets\n"
+ "OSPF Hello\n"
+ "OSPF Database Description\n"
+ "OSPF Link State Request\n"
+ "OSPF Link State Update\n"
+ "OSPF Link State Acknowledgment\n"
+ "OSPF all packets\n"
+ "Packet sent\n"
+ "Detail Information\n"
+ "Packet received\n"
+ "Detail Information\n"
+ "Detail Information\n")
{
+ int inst = (argv[2]->type == RANGE_TKN) ? 1 : 0;
+ int detail = strmatch (argv[argc - 1]->text, "detail");
+ int send = strmatch (argv[argc - (1+detail)]->text, "send");
+ int recv = strmatch (argv[argc - (1+detail)]->text, "recv");
+ char *packet = argv[3 + inst]->text;
+
+ if (inst) // user passed instance ID
+ {
+ if (!ospf_lookup_instance (strtoul (argv[2]->arg, NULL, 10)))
+ return CMD_SUCCESS;
+ }
+
int type = 0;
int flag = 0;
int i;
- assert (argc > arg_base + 0);
-
/* Check packet type. */
- if (strncmp (argv[arg_base + 0], "h", 1) == 0)
+ if (strmatch (packet, "hello"))
type = OSPF_DEBUG_HELLO;
- else if (strncmp (argv[arg_base + 0], "d", 1) == 0)
+ else if (strmatch (packet, "dd"))
type = OSPF_DEBUG_DB_DESC;
- else if (strncmp (argv[arg_base + 0], "ls-r", 4) == 0)
+ else if (strmatch (packet, "ls-request"))
type = OSPF_DEBUG_LS_REQ;
- else if (strncmp (argv[arg_base + 0], "ls-u", 4) == 0)
+ else if (strmatch (packet, "ls-update"))
type = OSPF_DEBUG_LS_UPD;
- else if (strncmp (argv[arg_base + 0], "ls-a", 4) == 0)
+ else if (strmatch (packet, "ls-ack"))
type = OSPF_DEBUG_LS_ACK;
- else if (strncmp (argv[arg_base + 0], "a", 1) == 0)
+ else if (strmatch (packet, "all"))
type = OSPF_DEBUG_ALL;
- /* Default, both send and recv. */
- if (argc == arg_base + 1)
- flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV;
-
- /* send or recv. */
- if (argc >= arg_base + 2)
- {
- if (strncmp (argv[arg_base + 1], "s", 1) == 0)
- flag = OSPF_DEBUG_SEND;
- else if (strncmp (argv[arg_base + 1], "r", 1) == 0)
- flag = OSPF_DEBUG_RECV;
- else if (strncmp (argv[arg_base + 1], "d", 1) == 0)
- flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL;
- }
-
- /* detail. */
- if (argc == arg_base + 3)
- if (strncmp (argv[arg_base + 2], "d", 1) == 0)
- flag |= OSPF_DEBUG_DETAIL;
+ /* Cases:
+ * (none) = send + recv
+ * detail = send + recv + detail
+ * recv = recv
+ * send = send
+ * recv detail = recv + detail
+ * send detail = send + detail
+ */
+ if (!send && !recv)
+ send = recv = 1;
+
+ flag |= (send) ? OSPF_DEBUG_SEND : 0;
+ flag |= (recv) ? OSPF_DEBUG_RECV : 0;
+ flag |= (detail) ? OSPF_DEBUG_DETAIL : 0;
for (i = 0; i < 5; i++)
if (type & (0x01 << i))
@@ -694,43 +710,13 @@ debug_ospf_packet_common (struct vty *vty, int arg_base, int argc,
return CMD_SUCCESS;
}
-DEFUN (debug_ospf_packet,
- debug_ospf_packet_all_cmd,
- "debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)",
+DEFUN (no_debug_ospf_packet,
+ no_debug_ospf_packet_cmd,
+ "no debug ospf [(1-65535)] packet <hello|dd|ls-request|ls-update|ls-ack|all> [<send [detail]|recv [detail]|detail>]",
+ NO_STR
DEBUG_STR
OSPF_STR
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n")
-{
- return (debug_ospf_packet_common(vty, 0, argc, argv));
-}
-
-ALIAS (debug_ospf_packet,
- debug_ospf_packet_send_recv_cmd,
- "debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)",
- "Debugging functions\n"
- "OSPF information\n"
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n"
- "Packet sent\n"
- "Packet received\n"
- "Detail information\n")
-
-ALIAS (debug_ospf_packet,
- debug_ospf_packet_send_recv_detail_cmd,
- "debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) (detail|)",
- "Debugging functions\n"
- "OSPF information\n"
+ "Instance ID\n"
"OSPF packets\n"
"OSPF Hello\n"
"OSPF Database Description\n"
@@ -739,109 +725,55 @@ ALIAS (debug_ospf_packet,
"OSPF Link State Acknowledgment\n"
"OSPF all packets\n"
"Packet sent\n"
+ "Detail Information\n"
"Packet received\n"
+ "Detail Information\n"
"Detail Information\n")
-
-DEFUN (debug_ospf_instance_packet,
- debug_ospf_instance_packet_all_cmd,
- "debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all)",
- DEBUG_STR
- OSPF_STR
- "Instance ID\n"
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n")
{
- u_short instance = 0;
-
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
- if (!ospf_lookup_instance (instance))
- return CMD_SUCCESS;
-
- return (debug_ospf_packet_common(vty, 1, argc, argv));
-}
-
-ALIAS (debug_ospf_instance_packet,
- debug_ospf_instance_packet_send_recv_cmd,
- "debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)",
- "Debugging functions\n"
- "OSPF information\n"
- "Instance ID\n"
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n"
- "Packet sent\n"
- "Packet received\n"
- "Detail information\n")
+ int inst = (argv[3]->type == RANGE_TKN) ? 1 : 0;
+ int detail = strmatch (argv[argc - 1]->text, "detail");
+ int send = strmatch (argv[argc - (1+detail)]->text, "send");
+ int recv = strmatch (argv[argc - (1+detail)]->text, "recv");
+ char *packet = argv[4 + inst]->text;
-ALIAS (debug_ospf_instance_packet,
- debug_ospf_instance_packet_send_recv_detail_cmd,
- "debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) (detail|)",
- "Debugging functions\n"
- "OSPF information\n"
- "Instance ID\n"
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n"
- "Packet sent\n"
- "Packet received\n"
- "Detail Information\n")
+ if (inst) // user passed instance ID
+ {
+ if (!ospf_lookup_instance (strtoul (argv[3]->arg, NULL, 10)))
+ return CMD_SUCCESS;
+ }
-static int
-no_debug_ospf_packet_common (struct vty *vty, int arg_base, int argc,
- const char **argv)
-{
int type = 0;
int flag = 0;
int i;
- assert (argc > arg_base + 0);
-
/* Check packet type. */
- if (strncmp (argv[arg_base + 0], "h", 1) == 0)
+ if (strmatch (packet, "hello"))
type = OSPF_DEBUG_HELLO;
- else if (strncmp (argv[arg_base + 0], "d", 1) == 0)
+ else if (strmatch (packet, "dd"))
type = OSPF_DEBUG_DB_DESC;
- else if (strncmp (argv[arg_base + 0], "ls-r", 4) == 0)
+ else if (strmatch (packet, "ls-request"))
type = OSPF_DEBUG_LS_REQ;
- else if (strncmp (argv[arg_base + 0], "ls-u", 4) == 0)
+ else if (strmatch (packet, "ls-update"))
type = OSPF_DEBUG_LS_UPD;
- else if (strncmp (argv[arg_base + 0], "ls-a", 4) == 0)
+ else if (strmatch (packet, "ls-ack"))
type = OSPF_DEBUG_LS_ACK;
- else if (strncmp (argv[arg_base + 0], "a", 1) == 0)
+ else if (strmatch (packet, "all"))
type = OSPF_DEBUG_ALL;
- /* Default, both send and recv. */
- if (argc == arg_base + 1)
- flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL ;
-
- /* send or recv. */
- if (argc == arg_base + 2)
- {
- if (strncmp (argv[arg_base + 1], "s", 1) == 0)
- flag = OSPF_DEBUG_SEND | OSPF_DEBUG_DETAIL;
- else if (strncmp (argv[arg_base + 1], "r", 1) == 0)
- flag = OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL;
- else if (strncmp (argv[arg_base + 1], "d", 1) == 0)
- flag = OSPF_DEBUG_DETAIL | OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL;
- }
-
- /* detail. */
- if (argc == arg_base + 3)
- if (strncmp (argv[arg_base + 2], "d", 1) == 0)
- flag = OSPF_DEBUG_DETAIL;
+ /* Cases:
+ * (none) = send + recv
+ * detail = send + recv + detail
+ * recv = recv
+ * send = send
+ * recv detail = recv + detail
+ * send detail = send + detail
+ */
+ if (!send && !recv)
+ send = recv = 1;
+
+ flag |= (send) ? OSPF_DEBUG_SEND : 0;
+ flag |= (recv) ? OSPF_DEBUG_RECV : 0;
+ flag |= (detail) ? OSPF_DEBUG_DETAIL : 0;
for (i = 0; i < 5; i++)
if (type & (0x01 << i))
@@ -862,132 +794,37 @@ no_debug_ospf_packet_common (struct vty *vty, int arg_base, int argc,
return CMD_SUCCESS;
}
-DEFUN (no_debug_ospf_packet,
- no_debug_ospf_packet_all_cmd,
- "no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)",
- NO_STR
- DEBUG_STR
- OSPF_STR
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n")
-{
- return no_debug_ospf_packet_common(vty, 0, argc, argv);
-}
-
-ALIAS (no_debug_ospf_packet,
- no_debug_ospf_packet_send_recv_cmd,
- "no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)",
- NO_STR
- "Debugging functions\n"
- "OSPF information\n"
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n"
- "Packet sent\n"
- "Packet received\n"
- "Detail Information\n")
-
-ALIAS (no_debug_ospf_packet,
- no_debug_ospf_packet_send_recv_detail_cmd,
- "no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) (detail|)",
- NO_STR
- "Debugging functions\n"
- "OSPF information\n"
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n"
- "Packet sent\n"
- "Packet received\n"
- "Detail Information\n")
-
-DEFUN (no_debug_ospf_instance_packet,
- no_debug_ospf_instance_packet_all_cmd,
- "no debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all)",
- NO_STR
+DEFUN (debug_ospf_ism,
+ debug_ospf_ism_cmd,
+ "debug ospf [(1-65535)] ism [<status|events|timers>]",
DEBUG_STR
OSPF_STR
"Instance ID\n"
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n")
+ "OSPF Interface State Machine\n"
+ "ISM Status Information\n"
+ "ISM Event Information\n"
+ "ISM TImer Information\n")
{
- u_short instance = 0;
-
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
- if (!ospf_lookup_instance (instance))
- return CMD_SUCCESS;
-
- return (no_debug_ospf_packet_common(vty, 1, argc, argv));
-}
-
-ALIAS (no_debug_ospf_instance_packet,
- no_debug_ospf_instance_packet_send_recv_cmd,
- "no debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)",
- NO_STR
- "Debugging functions\n"
- "OSPF information\n"
- "Instance ID\n"
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n"
- "Packet sent\n"
- "Packet received\n"
- "Detail Information\n")
-
-ALIAS (no_debug_ospf_instance_packet,
- no_debug_ospf_instance_packet_send_recv_detail_cmd,
- "no debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) (detail|)",
- NO_STR
- "Debugging functions\n"
- "OSPF information\n"
- "Instance ID\n"
- "OSPF packets\n"
- "OSPF Hello\n"
- "OSPF Database Description\n"
- "OSPF Link State Request\n"
- "OSPF Link State Update\n"
- "OSPF Link State Acknowledgment\n"
- "OSPF all packets\n"
- "Packet sent\n"
- "Packet received\n"
- "Detail Information\n")
+ int inst = (argv[2]->type == RANGE_TKN);
+ char *dbgparam = (argc == 4 + inst) ? argv[argc - 1]->text : NULL;
+ if (inst) // user passed instance ID
+ {
+ if (!ospf_lookup_instance (strtoul (argv[2]->arg, NULL, 10)))
+ return CMD_SUCCESS;
+ }
-static int
-debug_ospf_ism_common (struct vty *vty, int arg_base, int argc, const char **argv)
-{
if (vty->node == CONFIG_NODE)
{
- if (argc == arg_base + 0)
+ if (!dbgparam)
DEBUG_ON (ism, ISM);
- else if (argc == arg_base + 1)
+ else
{
- if (strncmp (argv[arg_base + 0], "s", 1) == 0)
+ if (strmatch (dbgparam, "status"))
DEBUG_ON (ism, ISM_STATUS);
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
+ else if (strmatch (dbgparam, "events"))
DEBUG_ON (ism, ISM_EVENTS);
- else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
+ else if (strmatch (dbgparam, "timers"))
DEBUG_ON (ism, ISM_TIMERS);
}
@@ -995,159 +832,77 @@ debug_ospf_ism_common (struct vty *vty, int arg_base, int argc, const char **arg
}
/* ENABLE_NODE. */
- if (argc == arg_base + 0)
+ if (!dbgparam)
TERM_DEBUG_ON (ism, ISM);
- else if (argc == arg_base + 1)
+ else
{
- if (strncmp (argv[arg_base + 0], "s", 1) == 0)
- TERM_DEBUG_ON (ism, ISM_STATUS);
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
- TERM_DEBUG_ON (ism, ISM_EVENTS);
- else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
- TERM_DEBUG_ON (ism, ISM_TIMERS);
+ if (strmatch (dbgparam, "status"))
+ TERM_DEBUG_ON (ism, ISM_STATUS);
+ else if (strmatch (dbgparam, "events"))
+ TERM_DEBUG_ON (ism, ISM_EVENTS);
+ else if (strmatch (dbgparam, "timers"))
+ TERM_DEBUG_ON (ism, ISM_TIMERS);
}
return CMD_SUCCESS;
}
-DEFUN (debug_ospf_ism,
- debug_ospf_ism_cmd,
- "debug ospf ism",
- DEBUG_STR
- OSPF_STR
- "OSPF Interface State Machine\n")
-{
- return debug_ospf_ism_common(vty, 0, argc, argv);
-}
-
-ALIAS (debug_ospf_ism,
- debug_ospf_ism_sub_cmd,
- "debug ospf ism (status|events|timers)",
+DEFUN (no_debug_ospf_ism,
+ no_debug_ospf_ism_cmd,
+ "no debug ospf [(1-65535)] ism [<status|events|timers>]",
+ NO_STR
DEBUG_STR
OSPF_STR
+ "Instance ID\n"
"OSPF Interface State Machine\n"
"ISM Status Information\n"
"ISM Event Information\n"
"ISM TImer Information\n")
-
-DEFUN (debug_ospf_instance_ism,
- debug_ospf_instance_ism_cmd,
- "debug ospf <1-65535> ism",
- DEBUG_STR
- OSPF_STR
- "Instance ID\n"
- "OSPF Interface State Machine\n")
{
- u_short instance = 0;
-
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
- if (!ospf_lookup_instance (instance))
- return CMD_SUCCESS;
+ int inst = (argv[3]->type == RANGE_TKN);
+ char *dbgparam = (argc == 5 + inst) ? argv[argc - 1]->text : NULL;
- return debug_ospf_ism_common(vty, 1, argc, argv);
-}
-
-ALIAS (debug_ospf_instance_ism,
- debug_ospf_instance_ism_sub_cmd,
- "debug ospf <1-65535> ism (status|events|timers)",
- DEBUG_STR
- OSPF_STR
- "Instance ID\n"
- "OSPF Interface State Machine\n"
- "ISM Status Information\n"
- "ISM Event Information\n"
- "ISM TImer Information\n")
+ if (inst) // user passed instance ID
+ {
+ if (!ospf_lookup_instance (strtoul (argv[3]->arg, NULL, 10)))
+ return CMD_SUCCESS;
+ }
-static int
-no_debug_ospf_ism_common(struct vty *vty, int arg_base, int argc,
- const char **argv)
-{
if (vty->node == CONFIG_NODE)
{
- if (argc == arg_base + 0)
+ if (!dbgparam)
DEBUG_OFF (ism, ISM);
- else if (argc == arg_base + 1)
+ else
{
- if (strncmp (argv[arg_base + 0], "s", 1) == 0)
+ if (strmatch (dbgparam, "status"))
DEBUG_OFF (ism, ISM_STATUS);
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
+ else if (strmatch (dbgparam, "events"))
DEBUG_OFF (ism, ISM_EVENTS);
- else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
+ else if (strmatch (dbgparam, "timers"))
DEBUG_OFF (ism, ISM_TIMERS);
}
+
return CMD_SUCCESS;
}
/* ENABLE_NODE. */
- if (argc == arg_base + 0)
+ if (!dbgparam)
TERM_DEBUG_OFF (ism, ISM);
- else if (argc == arg_base + 1)
+ else
{
- if (strncmp (argv[arg_base + 0], "s", 1) == 0)
- TERM_DEBUG_OFF (ism, ISM_STATUS);
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
- TERM_DEBUG_OFF (ism, ISM_EVENTS);
- else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
- TERM_DEBUG_OFF (ism, ISM_TIMERS);
+ if (strmatch (dbgparam, "status"))
+ TERM_DEBUG_OFF (ism, ISM_STATUS);
+ else if (strmatch (dbgparam, "events"))
+ TERM_DEBUG_OFF (ism, ISM_EVENTS);
+ else if (strmatch (dbgparam, "timers"))
+ TERM_DEBUG_OFF (ism, ISM_TIMERS);
}
return CMD_SUCCESS;
}
-DEFUN (no_debug_ospf_ism,
- no_debug_ospf_ism_cmd,
- "no debug ospf ism",
- NO_STR
- DEBUG_STR
- OSPF_STR
- "OSPF Interface State Machine")
-{
- return no_debug_ospf_ism_common(vty, 0, argc, argv);
-}
-
-ALIAS (no_debug_ospf_ism,
- no_debug_ospf_ism_sub_cmd,
- "no debug ospf ism (status|events|timers)",
- NO_STR
- "Debugging functions\n"
- "OSPF information\n"
- "OSPF Interface State Machine\n"
- "ISM Status Information\n"
- "ISM Event Information\n"
- "ISM Timer Information\n")
-
-DEFUN (no_debug_ospf_instance_ism,
- no_debug_ospf_instance_ism_cmd,
- "no debug ospf <1-65535> ism",
- NO_STR
- DEBUG_STR
- OSPF_STR
- "Instance ID\n"
- "OSPF Interface State Machine")
-{
- u_short instance = 0;
-
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
- if (!ospf_lookup_instance (instance))
- return CMD_SUCCESS;
-
- return no_debug_ospf_ism_common(vty, 1, argc, argv);
-}
-
-ALIAS (no_debug_ospf_instance_ism,
- no_debug_ospf_instance_ism_sub_cmd,
- "no debug ospf <1-65535> ism (status|events|timers)",
- NO_STR
- "Debugging functions\n"
- "OSPF information\n"
- "Instance ID\n"
- "OSPF Interface State Machine\n"
- "ISM Status Information\n"
- "ISM Event Information\n"
- "ISM Timer Information\n")
-
static int
-debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **argv)
+debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv)
{
if (vty->node == CONFIG_NODE)
{
@@ -1155,11 +910,11 @@ debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **arg
DEBUG_ON (nsm, NSM);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "s", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "status"))
DEBUG_ON (nsm, NSM_STATUS);
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "events"))
DEBUG_ON (nsm, NSM_EVENTS);
- else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "timers"))
DEBUG_ON (nsm, NSM_TIMERS);
}
@@ -1171,11 +926,11 @@ debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **arg
TERM_DEBUG_ON (nsm, NSM);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "s", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "status"))
TERM_DEBUG_ON (nsm, NSM_STATUS);
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "events"))
TERM_DEBUG_ON (nsm, NSM_EVENTS);
- else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "timers"))
TERM_DEBUG_ON (nsm, NSM_TIMERS);
}
@@ -1184,66 +939,54 @@ debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **arg
DEFUN (debug_ospf_nsm,
debug_ospf_nsm_cmd,
- "debug ospf nsm",
- DEBUG_STR
- OSPF_STR
- "OSPF Neighbor State Machine\n")
-{
- return debug_ospf_nsm_common (vty, 0, argc, argv);
-}
-
-ALIAS (debug_ospf_nsm,
- debug_ospf_nsm_sub_cmd,
- "debug ospf nsm (status|events|timers)",
+ "debug ospf nsm [<status|events|timers>]",
DEBUG_STR
OSPF_STR
"OSPF Neighbor State Machine\n"
"NSM Status Information\n"
"NSM Event Information\n"
"NSM Timer Information\n")
+{
+ return debug_ospf_nsm_common (vty, 3, argc, argv);
+}
DEFUN (debug_ospf_instance_nsm,
debug_ospf_instance_nsm_cmd,
- "debug ospf <1-65535> nsm",
+ "debug ospf (1-65535) nsm [<status|events|timers>]",
DEBUG_STR
OSPF_STR
"Instance ID\n"
- "OSPF Neighbor State Machine\n")
+ "OSPF Neighbor State Machine\n"
+ "NSM Status Information\n"
+ "NSM Event Information\n"
+ "NSM Timer Information\n")
{
+ int idx_number = 2;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
- return debug_ospf_nsm_common (vty, 1, argc, argv);
+ return debug_ospf_nsm_common (vty, 4, argc, argv);
}
-ALIAS (debug_ospf_instance_nsm,
- debug_ospf_instance_nsm_sub_cmd,
- "debug ospf <1-65535> nsm (status|events|timers)",
- DEBUG_STR
- OSPF_STR
- "Instance ID\n"
- "OSPF Neighbor State Machine\n"
- "NSM Status Information\n"
- "NSM Event Information\n"
- "NSM Timer Information\n")
static int
-no_debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **argv)
+no_debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv)
{
+ /* XXX qlyoung */
if (vty->node == CONFIG_NODE)
{
if (argc == arg_base + 0)
DEBUG_OFF (nsm, NSM);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "s", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "status"))
DEBUG_OFF (nsm, NSM_STATUS);
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "events"))
DEBUG_OFF (nsm, NSM_EVENTS);
- else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "timers"))
DEBUG_OFF (nsm, NSM_TIMERS);
}
@@ -1255,11 +998,11 @@ no_debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **
TERM_DEBUG_OFF (nsm, NSM);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "s", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "status"))
TERM_DEBUG_OFF (nsm, NSM_STATUS);
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "events"))
TERM_DEBUG_OFF (nsm, NSM_EVENTS);
- else if (strncmp (argv[arg_base + 0], "t", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "timers"))
TERM_DEBUG_OFF (nsm, NSM_TIMERS);
}
@@ -1268,59 +1011,44 @@ no_debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **
DEFUN (no_debug_ospf_nsm,
no_debug_ospf_nsm_cmd,
- "no debug ospf nsm",
+ "no debug ospf nsm [<status|events|timers>]",
NO_STR
DEBUG_STR
OSPF_STR
- "OSPF Neighbor State Machine")
-{
- return no_debug_ospf_nsm_common(vty, 0, argc, argv);
-}
-
-ALIAS (no_debug_ospf_nsm,
- no_debug_ospf_nsm_sub_cmd,
- "no debug ospf nsm (status|events|timers)",
- NO_STR
- "Debugging functions\n"
- "OSPF information\n"
- "OSPF Interface State Machine\n"
+ "OSPF Neighbor State Machine\n"
"NSM Status Information\n"
"NSM Event Information\n"
"NSM Timer Information\n")
+{
+ return no_debug_ospf_nsm_common(vty, 4, argc, argv);
+}
+
DEFUN (no_debug_ospf_instance_nsm,
no_debug_ospf_instance_nsm_cmd,
- "no debug ospf <1-65535> nsm",
+ "no debug ospf (1-65535) nsm [<status|events|timers>]",
NO_STR
DEBUG_STR
OSPF_STR
"Instance ID\n"
- "OSPF Neighbor State Machine")
+ "OSPF Neighbor State Machine\n"
+ "NSM Status Information\n"
+ "NSM Event Information\n"
+ "NSM Timer Information\n")
{
+ int idx_number = 3;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
- return no_debug_ospf_nsm_common(vty, 1, argc, argv);
+ return no_debug_ospf_nsm_common(vty, 5, argc, argv);
}
-ALIAS (no_debug_ospf_instance_nsm,
- no_debug_ospf_instance_nsm_sub_cmd,
- "no debug ospf <1-65535> nsm (status|events|timers)",
- NO_STR
- "Debugging functions\n"
- "OSPF information\n"
- "Instance ID\n"
- "OSPF Interface State Machine\n"
- "NSM Status Information\n"
- "NSM Event Information\n"
- "NSM Timer Information\n")
-
static int
-debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **argv)
+debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv)
{
if (vty->node == CONFIG_NODE)
{
@@ -1328,13 +1056,13 @@ debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **arg
DEBUG_ON (lsa, LSA);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "g", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "generate"))
DEBUG_ON (lsa, LSA_GENERATE);
- else if (strncmp (argv[arg_base + 0], "f", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "flooding"))
DEBUG_ON (lsa, LSA_FLOODING);
- else if (strncmp (argv[arg_base + 0], "i", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "install"))
DEBUG_ON (lsa, LSA_INSTALL);
- else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "refresh"))
DEBUG_ON (lsa, LSA_REFRESH);
}
@@ -1346,13 +1074,13 @@ debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **arg
TERM_DEBUG_ON (lsa, LSA);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "g", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "generate"))
TERM_DEBUG_ON (lsa, LSA_GENERATE);
- else if (strncmp (argv[arg_base + 0], "f", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "flooding"))
TERM_DEBUG_ON (lsa, LSA_FLOODING);
- else if (strncmp (argv[arg_base + 0], "i", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "install"))
TERM_DEBUG_ON (lsa, LSA_INSTALL);
- else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "refresh"))
TERM_DEBUG_ON (lsa, LSA_REFRESH);
}
@@ -1361,17 +1089,7 @@ debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **arg
DEFUN (debug_ospf_lsa,
debug_ospf_lsa_cmd,
- "debug ospf lsa",
- DEBUG_STR
- OSPF_STR
- "OSPF Link State Advertisement\n")
-{
- return debug_ospf_lsa_common(vty, 0, argc, argv);
-}
-
-ALIAS (debug_ospf_lsa,
- debug_ospf_lsa_sub_cmd,
- "debug ospf lsa (generate|flooding|install|refresh)",
+ "debug ospf lsa [<generate|flooding|install|refresh>]",
DEBUG_STR
OSPF_STR
"OSPF Link State Advertisement\n"
@@ -1379,38 +1097,35 @@ ALIAS (debug_ospf_lsa,
"LSA Flooding\n"
"LSA Install/Delete\n"
"LSA Refresh\n")
+{
+ return debug_ospf_lsa_common(vty, 3, argc, argv);
+}
DEFUN (debug_ospf_instance_lsa,
debug_ospf_instance_lsa_cmd,
- "debug ospf <1-65535> lsa",
+ "debug ospf (1-65535) lsa [<generate|flooding|install|refresh>]",
DEBUG_STR
OSPF_STR
"Instance ID\n"
- "OSPF Link State Advertisement\n")
+ "OSPF Link State Advertisement\n"
+ "LSA Generation\n"
+ "LSA Flooding\n"
+ "LSA Install/Delete\n"
+ "LSA Refresh\n")
{
+ int idx_number = 2;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
- return debug_ospf_lsa_common(vty, 1, argc, argv);
+ return debug_ospf_lsa_common(vty, 4, argc, argv);
}
-ALIAS (debug_ospf_instance_lsa,
- debug_ospf_instance_lsa_sub_cmd,
- "debug ospf <1-65535> lsa (generate|flooding|install|refresh)",
- DEBUG_STR
- OSPF_STR
- "Instance ID\n"
- "OSPF Link State Advertisement\n"
- "LSA Generation\n"
- "LSA Flooding\n"
- "LSA Install/Delete\n"
- "LSA Refresh\n")
static int
-no_debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **argv)
+no_debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv)
{
if (vty->node == CONFIG_NODE)
{
@@ -1418,13 +1133,13 @@ no_debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **
DEBUG_OFF (lsa, LSA);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "g", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "generate"))
DEBUG_OFF (lsa, LSA_GENERATE);
- else if (strncmp (argv[arg_base + 0], "f", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "flooding"))
DEBUG_OFF (lsa, LSA_FLOODING);
- else if (strncmp (argv[arg_base + 0], "i", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "install"))
DEBUG_OFF (lsa, LSA_INSTALL);
- else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "refresh"))
DEBUG_OFF (lsa, LSA_REFRESH);
}
@@ -1436,13 +1151,13 @@ no_debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **
TERM_DEBUG_OFF (lsa, LSA);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "g", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "generate"))
TERM_DEBUG_OFF (lsa, LSA_GENERATE);
- else if (strncmp (argv[arg_base + 0], "f", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "flooding"))
TERM_DEBUG_OFF (lsa, LSA_FLOODING);
- else if (strncmp (argv[arg_base + 0], "i", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "install"))
TERM_DEBUG_OFF (lsa, LSA_INSTALL);
- else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "refresh"))
TERM_DEBUG_OFF (lsa, LSA_REFRESH);
}
@@ -1451,18 +1166,7 @@ no_debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **
DEFUN (no_debug_ospf_lsa,
no_debug_ospf_lsa_cmd,
- "no debug ospf lsa",
- NO_STR
- DEBUG_STR
- OSPF_STR
- "OSPF Link State Advertisement\n")
-{
- return no_debug_ospf_lsa_common (vty, 0, argc, argv);
-}
-
-ALIAS (no_debug_ospf_lsa,
- no_debug_ospf_lsa_sub_cmd,
- "no debug ospf lsa (generate|flooding|install|refresh)",
+ "no debug ospf lsa [<generate|flooding|install|refresh>]",
NO_STR
DEBUG_STR
OSPF_STR
@@ -1471,41 +1175,36 @@ ALIAS (no_debug_ospf_lsa,
"LSA Flooding\n"
"LSA Install/Delete\n"
"LSA Refres\n")
+{
+ return no_debug_ospf_lsa_common (vty, 4, argc, argv);
+}
DEFUN (no_debug_ospf_instance_lsa,
no_debug_ospf_instance_lsa_cmd,
- "no debug ospf <1-65535> lsa",
+ "no debug ospf (1-65535) lsa [<generate|flooding|install|refresh>]",
NO_STR
DEBUG_STR
OSPF_STR
"Instance ID\n"
- "OSPF Link State Advertisement\n")
+ "OSPF Link State Advertisement\n"
+ "LSA Generation\n"
+ "LSA Flooding\n"
+ "LSA Install/Delete\n"
+ "LSA Refres\n")
{
+ int idx_number = 3;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
- return no_debug_ospf_lsa_common (vty, 1, argc, argv);
+ return no_debug_ospf_lsa_common (vty, 5, argc, argv);
}
-ALIAS (no_debug_ospf_instance_lsa,
- no_debug_ospf_instance_lsa_sub_cmd,
- "no debug ospf <1-65535> lsa (generate|flooding|install|refresh)",
- NO_STR
- DEBUG_STR
- OSPF_STR
- "Instance ID\n"
- "OSPF Link State Advertisement\n"
- "LSA Generation\n"
- "LSA Flooding\n"
- "LSA Install/Delete\n"
- "LSA Refres\n")
-
static int
-debug_ospf_zebra_common (struct vty *vty, int arg_base, int argc, const char **argv)
+debug_ospf_zebra_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv)
{
if (vty->node == CONFIG_NODE)
{
@@ -1513,9 +1212,9 @@ debug_ospf_zebra_common (struct vty *vty, int arg_base, int argc, const char **a
DEBUG_ON (zebra, ZEBRA);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "i", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "interface"))
DEBUG_ON (zebra, ZEBRA_INTERFACE);
- else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "redistribute"))
DEBUG_ON (zebra, ZEBRA_REDISTRIBUTE);
}
@@ -1527,9 +1226,9 @@ debug_ospf_zebra_common (struct vty *vty, int arg_base, int argc, const char **a
TERM_DEBUG_ON (zebra, ZEBRA);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "i", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "interface"))
TERM_DEBUG_ON (zebra, ZEBRA_INTERFACE);
- else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "redistribute"))
TERM_DEBUG_ON (zebra, ZEBRA_REDISTRIBUTE);
}
@@ -1538,53 +1237,40 @@ debug_ospf_zebra_common (struct vty *vty, int arg_base, int argc, const char **a
DEFUN (debug_ospf_zebra,
debug_ospf_zebra_cmd,
- "debug ospf zebra",
- DEBUG_STR
- OSPF_STR
- "OSPF Zebra information\n")
-{
- return debug_ospf_zebra_common(vty, 0, argc, argv);
-}
-
-ALIAS (debug_ospf_zebra,
- debug_ospf_zebra_sub_cmd,
- "debug ospf zebra (interface|redistribute)",
+ "debug ospf zebra [<interface|redistribute>]",
DEBUG_STR
OSPF_STR
"OSPF Zebra information\n"
"Zebra interface\n"
"Zebra redistribute\n")
+{
+ return debug_ospf_zebra_common(vty, 3, argc, argv);
+}
DEFUN (debug_ospf_instance_zebra,
debug_ospf_instance_zebra_cmd,
- "debug ospf <1-65535> zebra",
+ "debug ospf (1-65535) zebra [<interface|redistribute>]",
DEBUG_STR
OSPF_STR
"Instance ID\n"
- "OSPF Zebra information\n")
+ "OSPF Zebra information\n"
+ "Zebra interface\n"
+ "Zebra redistribute\n")
{
+ int idx_number = 2;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
- return debug_ospf_zebra_common(vty, 1, argc, argv);
+ return debug_ospf_zebra_common(vty, 4, argc, argv);
}
-ALIAS (debug_ospf_instance_zebra,
- debug_ospf_instance_zebra_sub_cmd,
- "debug ospf <1-65535> zebra (interface|redistribute)",
- DEBUG_STR
- OSPF_STR
- "Instance ID\n"
- "OSPF Zebra information\n"
- "Zebra interface\n"
- "Zebra redistribute\n")
static int
no_debug_ospf_zebra_common(struct vty *vty, int arg_base, int argc,
- const char **argv)
+ struct cmd_token **argv)
{
if (vty->node == CONFIG_NODE)
{
@@ -1592,9 +1278,9 @@ no_debug_ospf_zebra_common(struct vty *vty, int arg_base, int argc,
DEBUG_OFF (zebra, ZEBRA);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "i", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "interface"))
DEBUG_OFF (zebra, ZEBRA_INTERFACE);
- else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "redistribute"))
DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE);
}
@@ -1606,9 +1292,9 @@ no_debug_ospf_zebra_common(struct vty *vty, int arg_base, int argc,
TERM_DEBUG_OFF (zebra, ZEBRA);
else if (argc == arg_base + 1)
{
- if (strncmp (argv[arg_base + 0], "i", 1) == 0)
+ if (strmatch(argv[arg_base]->text, "interface"))
TERM_DEBUG_OFF (zebra, ZEBRA_INTERFACE);
- else if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ else if (strmatch(argv[arg_base]->text, "redistribute"))
TERM_DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE);
}
@@ -1617,53 +1303,38 @@ no_debug_ospf_zebra_common(struct vty *vty, int arg_base, int argc,
DEFUN (no_debug_ospf_zebra,
no_debug_ospf_zebra_cmd,
- "no debug ospf zebra",
- NO_STR
- DEBUG_STR
- OSPF_STR
- "OSPF Zebra information\n")
-{
- return no_debug_ospf_zebra_common(vty, 0, argc, argv);
-}
-
-ALIAS (no_debug_ospf_zebra,
- no_debug_ospf_zebra_sub_cmd,
- "no debug ospf zebra (interface|redistribute)",
+ "no debug ospf zebra [<interface|redistribute>]",
NO_STR
DEBUG_STR
OSPF_STR
"OSPF Zebra information\n"
"Zebra interface\n"
"Zebra redistribute\n")
+{
+ return no_debug_ospf_zebra_common(vty, 4, argc, argv);
+}
DEFUN (no_debug_ospf_instance_zebra,
no_debug_ospf_instance_zebra_cmd,
- "no debug ospf <1-65535> zebra",
+ "no debug ospf (1-65535) zebra [<interface|redistribute>]",
NO_STR
DEBUG_STR
OSPF_STR
"Instance ID\n"
- "OSPF Zebra information\n")
+ "OSPF Zebra information\n"
+ "Zebra interface\n"
+ "Zebra redistribute\n")
{
+ int idx_number = 3;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
- return no_debug_ospf_zebra_common(vty, 1, argc, argv);
+ return no_debug_ospf_zebra_common(vty, 5, argc, argv);
}
-ALIAS (no_debug_ospf_instance_zebra,
- no_debug_ospf_instance_zebra_sub_cmd,
- "no debug ospf <1-65535> zebra (interface|redistribute)",
- NO_STR
- DEBUG_STR
- OSPF_STR
- "Instance ID\n"
- "OSPF Zebra information\n"
- "Zebra interface\n"
- "Zebra redistribute\n")
DEFUN (debug_ospf_event,
@@ -1695,15 +1366,16 @@ DEFUN (no_debug_ospf_event,
DEFUN (debug_ospf_instance_event,
debug_ospf_instance_event_cmd,
- "debug ospf <1-65535> event",
+ "debug ospf (1-65535) event",
DEBUG_STR
OSPF_STR
"Instance ID\n"
"OSPF event information\n")
{
+ int idx_number = 2;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
@@ -1715,16 +1387,17 @@ DEFUN (debug_ospf_instance_event,
DEFUN (no_debug_ospf_instance_event,
no_debug_ospf_instance_event_cmd,
- "no debug ospf <1-65535> event",
+ "no debug ospf (1-65535) event",
NO_STR
DEBUG_STR
OSPF_STR
"Instance ID\n"
"OSPF event information\n")
{
+ int idx_number = 3;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
@@ -1763,15 +1436,16 @@ DEFUN (no_debug_ospf_nssa,
DEFUN (debug_ospf_instance_nssa,
debug_ospf_instance_nssa_cmd,
- "debug ospf <1-65535> nssa",
+ "debug ospf (1-65535) nssa",
DEBUG_STR
OSPF_STR
"Instance ID\n"
"OSPF nssa information\n")
{
+ int idx_number = 2;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
@@ -1783,16 +1457,17 @@ DEFUN (debug_ospf_instance_nssa,
DEFUN (no_debug_ospf_instance_nssa,
no_debug_ospf_instance_nssa_cmd,
- "no debug ospf <1-65535> nssa",
+ "no debug ospf (1-65535) nssa",
NO_STR
DEBUG_STR
OSPF_STR
"Instance ID\n"
"OSPF nssa information\n")
{
+ int idx_number = 3;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if (!ospf_lookup_instance (instance))
return CMD_SUCCESS;
@@ -2004,16 +1679,17 @@ DEFUN (show_debugging_ospf,
DEFUN (show_debugging_ospf_instance,
show_debugging_ospf_instance_cmd,
- "show debugging ospf <1-65535>",
+ "show debugging ospf (1-65535)",
SHOW_STR
DEBUG_STR
OSPF_STR
"Instance ID\n")
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance (instance)) == NULL )
return CMD_SUCCESS;
@@ -2166,116 +1842,62 @@ debug_init ()
install_node (&debug_node, config_write_debug);
install_element (ENABLE_NODE, &show_debugging_ospf_cmd);
- install_element (ENABLE_NODE, &debug_ospf_packet_send_recv_detail_cmd);
- install_element (ENABLE_NODE, &debug_ospf_packet_send_recv_cmd);
- install_element (ENABLE_NODE, &debug_ospf_packet_all_cmd);
- install_element (ENABLE_NODE, &debug_ospf_ism_sub_cmd);
install_element (ENABLE_NODE, &debug_ospf_ism_cmd);
- install_element (ENABLE_NODE, &debug_ospf_nsm_sub_cmd);
install_element (ENABLE_NODE, &debug_ospf_nsm_cmd);
- install_element (ENABLE_NODE, &debug_ospf_lsa_sub_cmd);
install_element (ENABLE_NODE, &debug_ospf_lsa_cmd);
- install_element (ENABLE_NODE, &debug_ospf_zebra_sub_cmd);
install_element (ENABLE_NODE, &debug_ospf_zebra_cmd);
install_element (ENABLE_NODE, &debug_ospf_event_cmd);
install_element (ENABLE_NODE, &debug_ospf_nssa_cmd);
install_element (ENABLE_NODE, &debug_ospf_te_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_packet_send_recv_detail_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_packet_send_recv_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_packet_all_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_ism_sub_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_ism_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_nsm_sub_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_nsm_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_lsa_sub_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_lsa_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_zebra_sub_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_zebra_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_event_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_nssa_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_te_cmd);
install_element (ENABLE_NODE, &show_debugging_ospf_instance_cmd);
- install_element (ENABLE_NODE, &debug_ospf_instance_packet_send_recv_detail_cmd);
- install_element (ENABLE_NODE, &debug_ospf_instance_packet_send_recv_cmd);
- install_element (ENABLE_NODE, &debug_ospf_instance_packet_all_cmd);
- install_element (ENABLE_NODE, &debug_ospf_instance_ism_sub_cmd);
- install_element (ENABLE_NODE, &debug_ospf_instance_ism_cmd);
- install_element (ENABLE_NODE, &debug_ospf_instance_nsm_sub_cmd);
+ install_element (ENABLE_NODE, &debug_ospf_packet_cmd);
+ install_element (ENABLE_NODE, &no_debug_ospf_packet_cmd);
+
install_element (ENABLE_NODE, &debug_ospf_instance_nsm_cmd);
- install_element (ENABLE_NODE, &debug_ospf_instance_lsa_sub_cmd);
install_element (ENABLE_NODE, &debug_ospf_instance_lsa_cmd);
- install_element (ENABLE_NODE, &debug_ospf_instance_zebra_sub_cmd);
install_element (ENABLE_NODE, &debug_ospf_instance_zebra_cmd);
install_element (ENABLE_NODE, &debug_ospf_instance_event_cmd);
install_element (ENABLE_NODE, &debug_ospf_instance_nssa_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_instance_packet_send_recv_detail_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_instance_packet_send_recv_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_instance_packet_all_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_instance_ism_sub_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_instance_ism_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_instance_nsm_sub_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_instance_nsm_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_instance_lsa_sub_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_instance_lsa_cmd);
- install_element (ENABLE_NODE, &no_debug_ospf_instance_zebra_sub_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_instance_zebra_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_instance_event_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_instance_nssa_cmd);
install_element (ENABLE_NODE, &no_debug_ospf_cmd);
- install_element (CONFIG_NODE, &debug_ospf_packet_send_recv_detail_cmd);
- install_element (CONFIG_NODE, &debug_ospf_packet_send_recv_cmd);
- install_element (CONFIG_NODE, &debug_ospf_packet_all_cmd);
- install_element (CONFIG_NODE, &debug_ospf_ism_sub_cmd);
+ install_element (CONFIG_NODE, &debug_ospf_packet_cmd);
+ install_element (CONFIG_NODE, &no_debug_ospf_packet_cmd);
install_element (CONFIG_NODE, &debug_ospf_ism_cmd);
- install_element (CONFIG_NODE, &debug_ospf_nsm_sub_cmd);
+ install_element (CONFIG_NODE, &no_debug_ospf_ism_cmd);
+
install_element (CONFIG_NODE, &debug_ospf_nsm_cmd);
- install_element (CONFIG_NODE, &debug_ospf_lsa_sub_cmd);
install_element (CONFIG_NODE, &debug_ospf_lsa_cmd);
- install_element (CONFIG_NODE, &debug_ospf_zebra_sub_cmd);
install_element (CONFIG_NODE, &debug_ospf_zebra_cmd);
install_element (CONFIG_NODE, &debug_ospf_event_cmd);
install_element (CONFIG_NODE, &debug_ospf_nssa_cmd);
install_element (CONFIG_NODE, &debug_ospf_te_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_packet_send_recv_detail_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_packet_send_recv_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_packet_all_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_ism_sub_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_ism_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_nsm_sub_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_nsm_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_lsa_sub_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_lsa_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_zebra_sub_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_zebra_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_event_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_nssa_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_te_cmd);
- install_element (CONFIG_NODE, &debug_ospf_instance_packet_send_recv_detail_cmd);
- install_element (CONFIG_NODE, &debug_ospf_instance_packet_send_recv_cmd);
- install_element (CONFIG_NODE, &debug_ospf_instance_packet_all_cmd);
- install_element (CONFIG_NODE, &debug_ospf_instance_ism_sub_cmd);
- install_element (CONFIG_NODE, &debug_ospf_instance_ism_cmd);
- install_element (CONFIG_NODE, &debug_ospf_instance_nsm_sub_cmd);
install_element (CONFIG_NODE, &debug_ospf_instance_nsm_cmd);
- install_element (CONFIG_NODE, &debug_ospf_instance_lsa_sub_cmd);
install_element (CONFIG_NODE, &debug_ospf_instance_lsa_cmd);
- install_element (CONFIG_NODE, &debug_ospf_instance_zebra_sub_cmd);
install_element (CONFIG_NODE, &debug_ospf_instance_zebra_cmd);
install_element (CONFIG_NODE, &debug_ospf_instance_event_cmd);
install_element (CONFIG_NODE, &debug_ospf_instance_nssa_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_instance_packet_send_recv_detail_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_instance_packet_send_recv_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_instance_packet_all_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_instance_ism_sub_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_instance_ism_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_instance_nsm_sub_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_instance_nsm_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_instance_lsa_sub_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_instance_lsa_cmd);
- install_element (CONFIG_NODE, &no_debug_ospf_instance_zebra_sub_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_instance_zebra_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_instance_event_cmd);
install_element (CONFIG_NODE, &no_debug_ospf_instance_nssa_cmd);
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index 7f83ddeaae..417a7aa8d2 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -22,6 +22,7 @@
#include <zebra.h>
+#include "monotime.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
@@ -277,8 +278,8 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr,
"while local one is initial instance.");
; /* Accept this LSA for quick LSDB resynchronization. */
}
- else if (tv_cmp (tv_sub (recent_relative_time (), current->tv_recv),
- msec2tv (ospf->min_ls_arrival)) < 0)
+ else if (monotime_since (&current->tv_recv, NULL)
+ < ospf->min_ls_arrival * 1000LL)
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("LSA[Flooding]: LSA is received recently.");
@@ -969,7 +970,7 @@ ospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf_area *area)
more time for the ACK to be received and avoid
retransmissions */
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
- lsa->tv_recv = recent_relative_time ();
+ monotime(&lsa->tv_recv);
lsa->tv_orig = lsa->tv_recv;
ospf_flood_through_area (area, NULL, lsa);
ospf_lsa_maxage (area->ospf, lsa);
@@ -982,7 +983,7 @@ ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa)
more time for the ACK to be received and avoid
retransmissions */
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
- lsa->tv_recv = recent_relative_time ();
+ monotime(&lsa->tv_recv);
lsa->tv_orig = lsa->tv_recv;
ospf_flood_through_as (ospf, NULL, lsa);
ospf_lsa_maxage (ospf, lsa);
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 8440765579..936ec69666 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -51,6 +51,7 @@
#include "ospfd/ospf_snmp.h"
#endif /* HAVE_SNMP */
+DEFINE_QOBJ_TYPE(ospf_interface)
int
ospf_if_get_output_cost (struct ospf_interface *oi)
@@ -246,7 +247,8 @@ ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p)
ospf_opaque_type9_lsa_init (oi);
oi->ospf = ospf;
-
+ QOBJ_REG (oi, ospf_interface);
+
return oi;
}
@@ -307,6 +309,8 @@ ospf_if_free (struct ospf_interface *oi)
ospf_opaque_type9_lsa_term (oi);
+ QOBJ_UNREG (oi);
+
/* Free Pseudo Neighbour */
ospf_nbr_delete (oi->nbr_self);
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index 7a74288bff..bd51bbf422 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -23,6 +23,7 @@
#ifndef _ZEBRA_OSPF_INTERFACE_H
#define _ZEBRA_OSPF_INTERFACE_H
+#include "qobj.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_spf.h"
@@ -228,7 +229,10 @@ struct ospf_interface
u_int32_t state_change; /* Number of status change. */
u_int32_t full_nbrs;
+
+ QOBJ_FIELDS
};
+DECLARE_QOBJ_TYPE(ospf_interface)
/* Prototypes. */
extern char *ospf_if_name (struct ospf_interface *);
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 916d4d01c9..cf9943893a 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -22,6 +22,7 @@
#include <zebra.h>
+#include "monotime.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
@@ -63,40 +64,6 @@ get_metric (u_char *metric)
struct timeval
-tv_adjust (struct timeval a)
-{
- while (a.tv_usec >= 1000000)
- {
- a.tv_usec -= 1000000;
- a.tv_sec++;
- }
-
- while (a.tv_usec < 0)
- {
- a.tv_usec += 1000000;
- a.tv_sec--;
- }
-
- return a;
-}
-
-int
-tv_ceil (struct timeval a)
-{
- a = tv_adjust (a);
-
- return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
-}
-
-int
-tv_floor (struct timeval a)
-{
- a = tv_adjust (a);
-
- return a.tv_sec;
-}
-
-struct timeval
int2tv (int a)
{
struct timeval ret;
@@ -115,50 +82,22 @@ msec2tv (int a)
ret.tv_sec = a/1000;
ret.tv_usec = (a%1000) * 1000;
- return tv_adjust (ret);
-}
-
-struct timeval
-tv_add (struct timeval a, struct timeval b)
-{
- struct timeval ret;
-
- ret.tv_sec = a.tv_sec + b.tv_sec;
- ret.tv_usec = a.tv_usec + b.tv_usec;
-
- return tv_adjust (ret);
-}
-
-struct timeval
-tv_sub (struct timeval a, struct timeval b)
-{
- struct timeval ret;
-
- ret.tv_sec = a.tv_sec - b.tv_sec;
- ret.tv_usec = a.tv_usec - b.tv_usec;
-
- return tv_adjust (ret);
-}
-
-int
-tv_cmp (struct timeval a, struct timeval b)
-{
- return (a.tv_sec == b.tv_sec ?
- a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
+ return ret;
}
int
ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
{
- struct timeval delta, now;
+ struct timeval delta;
int delay = 0;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
- delta = tv_sub (now, lsa->tv_orig);
-
- if (tv_cmp (delta, msec2tv (OSPF_MIN_LS_INTERVAL)) < 0)
+ if (monotime_since (&lsa->tv_orig, &delta) < OSPF_MIN_LS_INTERVAL * 1000LL)
{
- delay = tv_ceil (tv_sub (msec2tv (OSPF_MIN_LS_INTERVAL), delta));
+ struct timeval minv = msec2tv (OSPF_MIN_LS_INTERVAL);
+ timersub (&minv, &delta, &minv);
+
+ /* TBD: remove padding to full sec, return timeval instead */
+ delay = minv.tv_sec + !!minv.tv_usec;
if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
@@ -174,12 +113,10 @@ ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
int
get_age (struct ospf_lsa *lsa)
{
- int age;
-
- age = ntohs (lsa->data->ls_age)
- + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
+ struct timeval rel;
- return age;
+ monotime_since (&lsa->tv_recv, &rel);
+ return ntohs (lsa->data->ls_age) + rel.tv_sec;
}
@@ -228,7 +165,7 @@ ospf_lsa_new ()
new->flags = 0;
new->lock = 1;
new->retransmit_counter = 0;
- new->tv_recv = recent_relative_time ();
+ monotime(&new->tv_recv);
new->tv_orig = new->tv_recv;
new->refresh_list = -1;
@@ -3701,8 +3638,8 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
*/
delay = (random() % (max_delay - min_delay)) + min_delay;
- current_index = ospf->lsa_refresh_queue.index + (quagga_monotime ()
- - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
+ current_index = ospf->lsa_refresh_queue.index + (monotime(NULL)
+ - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
% (OSPF_LSA_REFRESHER_SLOTS);
@@ -3765,7 +3702,7 @@ ospf_lsa_refresh_walker (struct thread *t)
modulus. */
ospf->lsa_refresh_queue.index =
((unsigned long)(ospf->lsa_refresh_queue.index +
- (quagga_monotime () - ospf->lsa_refresher_started)
+ (monotime(NULL) - ospf->lsa_refresher_started)
/ OSPF_LSA_REFRESHER_GRANULARITY))
% OSPF_LSA_REFRESHER_SLOTS;
@@ -3806,7 +3743,7 @@ ospf_lsa_refresh_walker (struct thread *t)
ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
ospf, ospf->lsa_refresh_interval);
- ospf->lsa_refresher_started = quagga_monotime ();
+ ospf->lsa_refresher_started = monotime(NULL);
for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
{
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index 28ecc9d4d6..8b9a0d4c49 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -227,14 +227,8 @@ struct as_external_lsa
/* Prototypes. */
/* XXX: Eek, time functions, similar are in lib/thread.c */
-extern struct timeval tv_adjust (struct timeval);
-extern int tv_ceil (struct timeval);
-extern int tv_floor (struct timeval);
extern struct timeval int2tv (int);
extern struct timeval msec2tv (int);
-extern struct timeval tv_add (struct timeval, struct timeval);
-extern struct timeval tv_sub (struct timeval, struct timeval);
-extern int tv_cmp (struct timeval, struct timeval);
extern int get_age (struct ospf_lsa *);
extern u_int16_t ospf_lsa_checksum (struct lsa_header *);
diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c
index c6b55b0746..ccb82bf8fe 100644
--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -33,6 +33,7 @@
#include "stream.h"
#include "table.h"
#include "log.h"
+#include "command.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@@ -629,10 +630,10 @@ nsm_notice_state_change (struct ospf_neighbor *nbr, int next_state, int event)
/* Advance in NSM */
if (next_state > nbr->state)
- nbr->ts_last_progress = recent_relative_time ();
+ monotime(&nbr->ts_last_progress);
else /* regression in NSM */
{
- nbr->ts_last_regress = recent_relative_time ();
+ monotime(&nbr->ts_last_regress);
nbr->last_regress_str = ospf_nsm_event_str [event];
}
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 33980b35c6..56efa2ebd6 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -769,10 +769,7 @@ DEFUN (capability_opaque,
"Enable specific OSPF feature\n"
"Opaque LSA\n")
{
- struct ospf *ospf = (struct ospf *) vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
/* Turn on the "master switch" of opaque-lsa capability. */
if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
@@ -786,11 +783,14 @@ DEFUN (capability_opaque,
return CMD_SUCCESS;
}
-ALIAS (capability_opaque,
- ospf_opaque_capable_cmd,
+DEFUN (ospf_opaque,
+ ospf_opaque_cmd,
"ospf opaque-lsa",
"OSPF specific commands\n"
"Enable the Opaque-LSA capability (rfc2370)\n")
+{
+ return capability_opaque (self, vty, argc, argv);
+}
DEFUN (no_capability_opaque,
no_capability_opaque_cmd,
@@ -799,10 +799,7 @@ DEFUN (no_capability_opaque,
"Enable specific OSPF feature\n"
"Opaque LSA\n")
{
- struct ospf *ospf = (struct ospf *) vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
/* Turn off the "master switch" of opaque-lsa capability. */
if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
@@ -816,20 +813,23 @@ DEFUN (no_capability_opaque,
return CMD_SUCCESS;
}
-ALIAS (no_capability_opaque,
- no_ospf_opaque_capable_cmd,
+DEFUN (no_ospf_opaque,
+ no_ospf_opaque_cmd,
"no ospf opaque-lsa",
NO_STR
"OSPF specific commands\n"
- "Disable the Opaque-LSA capability (rfc2370)\n")
+ "Enable the Opaque-LSA capability (rfc2370)\n")
+{
+ return no_capability_opaque (self, vty, argc, argv);
+}
static void
ospf_opaque_register_vty (void)
{
install_element (OSPF_NODE, &capability_opaque_cmd);
install_element (OSPF_NODE, &no_capability_opaque_cmd);
- install_element (OSPF_NODE, &ospf_opaque_capable_cmd);
- install_element (OSPF_NODE, &no_ospf_opaque_capable_cmd);
+ install_element (OSPF_NODE, &ospf_opaque_cmd);
+ install_element (OSPF_NODE, &no_ospf_opaque_cmd);
return;
}
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index f7d1d0fa7d..bf78336ad5 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -22,6 +22,7 @@
#include <zebra.h>
+#include "monotime.h"
#include "thread.h"
#include "memory.h"
#include "linklist.h"
@@ -521,16 +522,18 @@ ospf_ls_upd_timer (struct thread *thread)
struct ospf_lsa *lsa;
if ((lsa = rn->info) != NULL)
- /* Don't retransmit an LSA if we received it within
- the last RxmtInterval seconds - this is to allow the
- neighbour a chance to acknowledge the LSA as it may
- have ben just received before the retransmit timer
- fired. This is a small tweak to what is in the RFC,
- but it will cut out out a lot of retransmit traffic
- - MAG */
- if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
- int2tv (retransmit_interval)) >= 0)
- listnode_add (update, rn->info);
+ {
+ /* Don't retransmit an LSA if we received it within
+ the last RxmtInterval seconds - this is to allow the
+ neighbour a chance to acknowledge the LSA as it may
+ have ben just received before the retransmit timer
+ fired. This is a small tweak to what is in the RFC,
+ but it will cut out out a lot of retransmit traffic
+ - MAG */
+ if (monotime_since (&lsa->tv_recv, NULL)
+ >= retransmit_interval * 1000000LL)
+ listnode_add (update, rn->info);
+ }
}
}
@@ -1469,10 +1472,8 @@ ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
}
else
{
- struct timeval t, now;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
- t = tv_sub (now, nbr->last_send_ts);
- if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
+ if (monotime_since (&nbr->last_send_ts, NULL)
+ < nbr->v_inactivity * 1000000LL)
{
/* In states Loading and Full the slave must resend
its last Database Description packet in response to
@@ -2074,12 +2075,8 @@ ospf_ls_upd (struct ospf *ospf, struct ip *iph, struct ospf_header *ospfh,
recent) LSA instance. */
else
{
- struct timeval now;
-
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
-
- if (tv_cmp (tv_sub (now, current->tv_orig),
- msec2tv (ospf->min_ls_arrival)) >= 0)
+ if (monotime_since (&current->tv_orig, NULL)
+ >= ospf->min_ls_arrival * 1000LL)
/* Trap NSSA type later.*/
ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
DISCARD_LSA (lsa, 8);
@@ -3577,7 +3574,7 @@ ospf_db_desc_send (struct ospf_neighbor *nbr)
if (nbr->last_send)
ospf_packet_free (nbr->last_send);
nbr->last_send = ospf_packet_dup (op);
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
+ monotime(&nbr->last_send_ts);
}
/* Re-send Database Description. */
diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c
index 65659709b2..883ea7cad9 100644
--- a/ospfd/ospf_ri.c
+++ b/ospfd/ospf_ri.c
@@ -1176,11 +1176,14 @@ ospf_router_info_config_write_router (struct vty *vty)
DEFUN (router_info,
router_info_area_cmd,
- "router-info area A.B.C.D",
+ "router-info <as|area A.B.C.D>",
OSPF_RI_STR
+ "Enable the Router Information functionality with AS flooding scope\n"
"Enable the Router Information functionality with Area flooding scope\n"
"OSPF area ID in IP format")
{
+ int idx_ipv4 = 2;
+ char *area = (argc == 3) ? argv[idx_ipv4]->arg : NULL;
u_int8_t scope;
@@ -1188,14 +1191,9 @@ DEFUN (router_info,
return CMD_SUCCESS;
/* Check and get Area value if present */
- if (argc == 1)
+ if (area)
{
- if (!inet_aton (argv[0], &OspfRI.area_id))
- {
- vty_out (vty, "Please specify Router Info Area by A.B.C.D%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ inet_aton (area, &OspfRI.area_id);
scope = OSPF_OPAQUE_AREA_LSA;
}
else
@@ -1236,11 +1234,6 @@ DEFUN (router_info,
}
-ALIAS (router_info,
- router_info_as_cmd,
- "router-info as",
- OSPF_RI_STR
- "Enable the Router Information functionality with AS flooding scope\n")
DEFUN (no_router_info,
no_router_info_cmd,
@@ -1285,13 +1278,14 @@ DEFUN (pce_address,
"Stable IP address of the PCE\n"
"PCE address in IPv4 address format\n")
{
+ int idx_ipv4 = 2;
struct in_addr value;
struct ospf_pce_info *pi = &OspfRI.pce_info;
if (!ospf_ri_enabled (vty))
return CMD_WARNING;
- if (!inet_aton (argv[0], &value))
+ if (!inet_aton (argv[idx_ipv4]->arg, &value))
{
vty_out (vty, "Please specify PCE Address by A.B.C.D%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -1313,7 +1307,7 @@ DEFUN (pce_address,
DEFUN (no_pce_address,
no_pce_address_cmd,
- "no pce address {A.B.C.D}",
+ "no pce address [A.B.C.D]",
NO_STR
PCE_STR
"Disable PCE address\n"
@@ -1336,13 +1330,14 @@ DEFUN (pce_path_scope,
"Path scope visibilities of the PCE for path computation\n"
"32-bit Hexadecimal value\n")
{
+ int idx_bitpattern = 2;
uint32_t scope;
struct ospf_pce_info *pi = &OspfRI.pce_info;
if (!ospf_ri_enabled (vty))
return CMD_WARNING;
- if (sscanf (argv[0], "0x%x", &scope) != 1)
+ if (sscanf (argv[idx_bitpattern]->arg, "0x%x", &scope) != 1)
{
vty_out (vty, "pce_path_scope: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -1363,7 +1358,7 @@ DEFUN (pce_path_scope,
DEFUN (no_pce_path_scope,
no_pce_path_scope_cmd,
- "no pce scope {BITPATTERN}",
+ "no pce scope [BITPATTERN]",
NO_STR
PCE_STR
"Disable PCE path scope\n"
@@ -1381,12 +1376,13 @@ DEFUN (no_pce_path_scope,
DEFUN (pce_domain,
pce_domain_cmd,
- "pce domain as <0-65535>",
+ "pce domain as (0-65535)",
PCE_STR
"Configure PCE domain AS number\n"
"AS number where the PCE as visibilities for path computation\n"
"AS number in decimal <0-65535>\n")
{
+ int idx_number = 3;
uint32_t as;
struct ospf_pce_info *pce = &OspfRI.pce_info;
@@ -1396,7 +1392,7 @@ DEFUN (pce_domain,
if (!ospf_ri_enabled (vty))
return CMD_WARNING;
- if (sscanf (argv[0], "%d", &as) != 1)
+ if (sscanf (argv[idx_number]->arg, "%d", &as) != 1)
{
vty_out (vty, "pce_domain: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -1422,18 +1418,19 @@ DEFUN (pce_domain,
DEFUN (no_pce_domain,
no_pce_domain_cmd,
- "no pce domain as <0-65535>",
+ "no pce domain as (0-65535)",
NO_STR
PCE_STR
"Disable PCE domain AS number\n"
"AS number where the PCE as visibilities for path computation\n"
"AS number in decimal <0-65535>\n")
{
+ int idx_number = 4;
uint32_t as;
struct ospf_pce_info *pce = &OspfRI.pce_info;
- if (sscanf (argv[0], "%d", &as) != 1)
+ if (sscanf (argv[idx_number]->arg, "%d", &as) != 1)
{
vty_out (vty, "no_pce_domain: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -1452,12 +1449,13 @@ DEFUN (no_pce_domain,
DEFUN (pce_neigbhor,
pce_neighbor_cmd,
- "pce neighbor as <0-65535>",
+ "pce neighbor as (0-65535)",
PCE_STR
"Configure PCE neighbor domain AS number\n"
"AS number of PCE neighbors\n"
"AS number in decimal <0-65535>\n")
{
+ int idx_number = 3;
uint32_t as;
struct ospf_pce_info *pce = &OspfRI.pce_info;
@@ -1467,7 +1465,7 @@ DEFUN (pce_neigbhor,
if (!ospf_ri_enabled (vty))
return CMD_WARNING;
- if (sscanf (argv[0], "%d", &as) != 1)
+ if (sscanf (argv[idx_number]->arg, "%d", &as) != 1)
{
vty_out (vty, "pce_neighbor: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -1493,18 +1491,19 @@ DEFUN (pce_neigbhor,
DEFUN (no_pce_neighbor,
no_pce_neighbor_cmd,
- "no pce neighbor as <0-65535>",
+ "no pce neighbor as (0-65535)",
NO_STR
PCE_STR
"Disable PCE neighbor AS number\n"
"AS number of PCE neighbor\n"
"AS number in decimal <0-65535>\n")
{
+ int idx_number = 4;
uint32_t as;
struct ospf_pce_info *pce = &OspfRI.pce_info;
- if (sscanf (argv[0], "%d", &as) != 1)
+ if (sscanf (argv[idx_number]->arg, "%d", &as) != 1)
{
vty_out (vty, "no_pce_neighbor: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -1528,6 +1527,7 @@ DEFUN (pce_cap_flag,
"Capabilities of the PCE for path computation\n"
"32-bit Hexadecimal value\n")
{
+ int idx_bitpattern = 2;
uint32_t cap;
struct ospf_pce_info *pce = &OspfRI.pce_info;
@@ -1535,7 +1535,7 @@ DEFUN (pce_cap_flag,
if (!ospf_ri_enabled (vty))
return CMD_WARNING;
- if (sscanf (argv[0], "0x%x", &cap) != 1)
+ if (sscanf (argv[idx_bitpattern]->arg, "0x%x", &cap) != 1)
{
vty_out (vty, "pce_cap_flag: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -1652,7 +1652,6 @@ ospf_router_info_register_vty (void)
install_element (VIEW_NODE, &show_ip_ospf_router_info_pce_cmd);
install_element (OSPF_NODE, &router_info_area_cmd);
- install_element (OSPF_NODE, &router_info_as_cmd);
install_element (OSPF_NODE, &no_router_info_cmd);
install_element (OSPF_NODE, &pce_address_cmd);
install_element (OSPF_NODE, &no_pce_address_cmd);
@@ -1663,6 +1662,7 @@ ospf_router_info_register_vty (void)
install_element (OSPF_NODE, &pce_neighbor_cmd);
install_element (OSPF_NODE, &no_pce_neighbor_cmd);
install_element (OSPF_NODE, &pce_cap_flag_cmd);
+ install_element (OSPF_NODE, &no_pce_cap_flag_cmd);
return;
}
diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c
index f1483885c0..717dc25f94 100644
--- a/ospfd/ospf_routemap.c
+++ b/ospfd/ospf_routemap.c
@@ -27,6 +27,7 @@
#include "memory.h"
#include "prefix.h"
#include "table.h"
+#include "vty.h"
#include "routemap.h"
#include "command.h"
#include "log.h"
@@ -118,9 +119,10 @@ ospf_route_map_event (route_map_event_t event, const char *name)
/* Delete rip route map rule. */
static int
-ospf_route_match_delete (struct vty *vty, struct route_map_index *index,
+ospf_route_match_delete (struct vty *vty,
const char *command, const char *arg)
{
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
int ret;
ret = route_map_delete_match (index, command, arg);
@@ -141,59 +143,13 @@ ospf_route_match_delete (struct vty *vty, struct route_map_index *index,
}
static int
-ospf_route_match_add (struct vty *vty, struct route_map_index *index,
+ospf_route_match_add (struct vty *vty,
const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_add_match (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% OSPF Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% OSPF Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- return CMD_SUCCESS;
-}
-
-static int
-ospf_route_set_add (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
{
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
int ret;
- ret = route_map_add_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% OSPF Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% OSPF Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- return CMD_SUCCESS;
-}
-
-/* Delete rip route map rule. */
-static int
-ospf_route_set_delete (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_delete_set (index, command, arg);
+ ret = route_map_add_match (index, command, arg);
if (ret)
{
switch (ret)
@@ -627,7 +583,7 @@ static struct route_map_rule_cmd route_set_tag_cmd =
DEFUN (match_ip_nexthop,
match_ip_nexthop_cmd,
- "match ip next-hop (<1-199>|<1300-2699>|WORD)",
+ "match ip next-hop <(1-199)|(1300-2699)|WORD>",
MATCH_STR
IP_STR
"Match next-hop address of route\n"
@@ -635,26 +591,13 @@ DEFUN (match_ip_nexthop,
"IP access-list number (expanded range)\n"
"IP access-list name\n")
{
- return ospf_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
+ int idx_acl = 3;
+ return ospf_route_match_add (vty, "ip next-hop", argv[idx_acl]->arg);
}
DEFUN (no_match_ip_nexthop,
no_match_ip_nexthop_cmd,
- "no match ip next-hop",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n")
-{
- if (argc == 0)
- return ospf_route_match_delete (vty, vty->index, "ip next-hop", NULL);
-
- return ospf_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
-}
-
-ALIAS (no_match_ip_nexthop,
- no_match_ip_nexthop_val_cmd,
- "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
+ "no match ip next-hop [<(1-199)|(1300-2699)|WORD>]",
NO_STR
MATCH_STR
IP_STR
@@ -662,285 +605,38 @@ ALIAS (no_match_ip_nexthop,
"IP access-list number\n"
"IP access-list number (expanded range)\n"
"IP access-list name\n")
-
-DEFUN (match_ip_next_hop_prefix_list,
- match_ip_next_hop_prefix_list_cmd,
- "match ip next-hop prefix-list WORD",
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return ospf_route_match_add (vty, vty->index, "ip next-hop prefix-list",
- argv[0]);
-}
-
-DEFUN (no_match_ip_next_hop_prefix_list,
- no_match_ip_next_hop_prefix_list_cmd,
- "no match ip next-hop prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n")
-{
- if (argc == 0)
- return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
- NULL);
- return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
- argv[0]);
-}
-
-ALIAS (no_match_ip_next_hop_prefix_list,
- no_match_ip_next_hop_prefix_list_val_cmd,
- "no match ip next-hop prefix-list WORD",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-
-DEFUN (match_ip_address,
- match_ip_address_cmd,
- "match ip address (<1-199>|<1300-2699>|WORD)",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP access-list name\n")
-{
- return ospf_route_match_add (vty, vty->index, "ip address", argv[0]);
-}
-
-DEFUN (no_match_ip_address,
- no_match_ip_address_cmd,
- "no match ip address",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n")
-{
- if (argc == 0)
- return ospf_route_match_delete (vty, vty->index, "ip address", NULL);
-
- return ospf_route_match_delete (vty, vty->index, "ip address", argv[0]);
-}
-
-ALIAS (no_match_ip_address,
- no_match_ip_address_val_cmd,
- "no match ip address (<1-199>|<1300-2699>|WORD)",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP access-list name\n")
-
-DEFUN (match_ip_address_prefix_list,
- match_ip_address_prefix_list_cmd,
- "match ip address prefix-list WORD",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return ospf_route_match_add (vty, vty->index, "ip address prefix-list",
- argv[0]);
-}
-
-DEFUN (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_cmd,
- "no match ip address prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n")
-{
- if (argc == 0)
- return ospf_route_match_delete (vty, vty->index, "ip address prefix-list",
- NULL);
- return ospf_route_match_delete (vty, vty->index, "ip address prefix-list",
- argv[0]);
-}
-
-ALIAS (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_val_cmd,
- "no match ip address prefix-list WORD",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-
-DEFUN (match_interface,
- match_interface_cmd,
- "match interface WORD",
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
{
- return ospf_route_match_add (vty, vty->index, "interface", argv[0]);
+ char *al = (argc == 5) ? argv[4]->arg : NULL;
+ return ospf_route_match_delete (vty, "ip next-hop", al);
}
-DEFUN (no_match_interface,
- no_match_interface_cmd,
- "no match interface",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n")
-{
- if (argc == 0)
- return ospf_route_match_delete (vty, vty->index, "interface", NULL);
-
- return ospf_route_match_delete (vty, vty->index, "interface", argv[0]);
-}
-
-ALIAS (no_match_interface,
- no_match_interface_val_cmd,
- "no match interface WORD",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-
-DEFUN (match_tag,
- match_tag_cmd,
- "match tag <1-4294967295>",
- MATCH_STR
- "Match tag of route\n"
- "Tag value\n")
-{
- return ospf_route_match_add (vty, vty->index, "tag", argv[0]);
-}
-
-DEFUN (no_match_tag,
- no_match_tag_cmd,
- "no match tag",
- NO_STR
- MATCH_STR
- "Match tag of route\n")
-{
- if (argc == 0)
- return ospf_route_match_delete (vty, vty->index, "tag", NULL);
-
- return ospf_route_match_delete (vty, vty->index, "tag", argv[0]);
-}
-
-ALIAS (no_match_tag,
- no_match_tag_val_cmd,
- "no match tag <1-4294967295>",
- NO_STR
- MATCH_STR
- "Match tag of route\n"
- "Tag value\n")
-
-DEFUN (set_metric,
- set_metric_cmd,
- "set metric <0-4294967295>",
- SET_STR
- "Metric value for destination routing protocol\n"
- "Metric value\n")
-{
- return ospf_route_set_add (vty, vty->index, "metric", argv[0]);
-}
-
-DEFUN (no_set_metric,
- no_set_metric_cmd,
- "no set metric",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n")
-{
- if (argc == 0)
- return ospf_route_set_delete (vty, vty->index, "metric", NULL);
-
- return ospf_route_set_delete (vty, vty->index, "metric", argv[0]);
-}
-
-ALIAS (no_set_metric,
- no_set_metric_val_cmd,
- "no set metric <0-4294967295>",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n"
- "Metric value\n")
-
DEFUN (set_metric_type,
set_metric_type_cmd,
- "set metric-type (type-1|type-2)",
+ "set metric-type <type-1|type-2>",
SET_STR
"Type of metric for destination routing protocol\n"
"OSPF[6] external type 1 metric\n"
"OSPF[6] external type 2 metric\n")
{
- if (strcmp (argv[0], "1") == 0)
- return ospf_route_set_add (vty, vty->index, "metric-type", "type-1");
- if (strcmp (argv[0], "2") == 0)
- return ospf_route_set_add (vty, vty->index, "metric-type", "type-2");
-
- return ospf_route_set_add (vty, vty->index, "metric-type", argv[0]);
+ char *ext = argv[2]->text;
+ return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index),
+ "metric-type", ext);
}
DEFUN (no_set_metric_type,
no_set_metric_type_cmd,
- "no set metric-type",
- NO_STR
- SET_STR
- "Type of metric for destination routing protocol\n")
-{
- if (argc == 0)
- return ospf_route_set_delete (vty, vty->index, "metric-type", NULL);
-
- return ospf_route_set_delete (vty, vty->index, "metric-type", argv[0]);
-}
-
-ALIAS (no_set_metric_type,
- no_set_metric_type_val_cmd,
- "no set metric-type (type-1|type-2)",
+ "no set metric-type [<type-1|type-2>]",
NO_STR
SET_STR
"Type of metric for destination routing protocol\n"
"OSPF[6] external type 1 metric\n"
"OSPF[6] external type 2 metric\n")
-
-DEFUN (set_tag,
- set_tag_cmd,
- "set tag <1-4294967295>",
- SET_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
-{
- return ospf_route_set_add (vty, vty->index, "tag", argv[0]);
-}
-
-DEFUN (no_set_tag,
- no_set_tag_cmd,
- "no set tag",
- NO_STR
- SET_STR
- "Tag value for routing protocol\n")
{
- if (argc == 0)
- ospf_route_set_delete(vty, vty->index, "tag", NULL);
-
- return ospf_route_set_delete (vty, vty->index, "tag", argv[0]);
+ char *ext = (argc == 4) ? argv[3]->text : NULL;
+ return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index),
+ "metric-type", ext);
}
-ALIAS (no_set_tag,
- no_set_tag_val_cmd,
- "no set tag <1-4294967295>",
- NO_STR
- SET_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
-
/* Route-map init */
void
ospf_route_map_init (void)
@@ -950,6 +646,27 @@ ospf_route_map_init (void)
route_map_add_hook (ospf_route_map_update);
route_map_delete_hook (ospf_route_map_update);
route_map_event_hook (ospf_route_map_event);
+
+ route_map_match_interface_hook (generic_match_add);
+ route_map_no_match_interface_hook (generic_match_delete);
+
+ route_map_match_ip_address_hook (generic_match_add);
+ route_map_no_match_ip_address_hook (generic_match_delete);
+
+ route_map_match_ip_address_prefix_list_hook (generic_match_add);
+ route_map_no_match_ip_address_prefix_list_hook (generic_match_delete);
+
+ route_map_match_ip_next_hop_prefix_list_hook (generic_match_add);
+ route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete);
+
+ route_map_match_tag_hook (generic_match_add);
+ route_map_no_match_tag_hook (generic_match_delete);
+
+ route_map_set_metric_hook (generic_set_add);
+ route_map_no_set_metric_hook (generic_set_delete);
+
+ route_map_set_tag_hook (generic_set_add);
+ route_map_no_set_tag_hook (generic_set_delete);
route_map_install_match (&route_match_ip_nexthop_cmd);
route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
@@ -964,30 +681,7 @@ ospf_route_map_init (void)
install_element (RMAP_NODE, &match_ip_nexthop_cmd);
install_element (RMAP_NODE, &no_match_ip_nexthop_cmd);
- install_element (RMAP_NODE, &no_match_ip_nexthop_val_cmd);
- install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
- install_element (RMAP_NODE, &match_ip_address_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
- install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
- install_element (RMAP_NODE, &match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_val_cmd);
- install_element (RMAP_NODE, &match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_val_cmd);
-
- install_element (RMAP_NODE, &set_metric_cmd);
- install_element (RMAP_NODE, &no_set_metric_cmd);
- install_element (RMAP_NODE, &no_set_metric_val_cmd);
+
install_element (RMAP_NODE, &set_metric_type_cmd);
install_element (RMAP_NODE, &no_set_metric_type_cmd);
- install_element (RMAP_NODE, &no_set_metric_type_val_cmd);
- install_element (RMAP_NODE, &set_tag_cmd);
- install_element (RMAP_NODE, &no_set_tag_cmd);
- install_element (RMAP_NODE, &no_set_tag_val_cmd);
}
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 5dfd41dd1e..077d0e68ad 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -20,6 +20,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include <zebra.h>
+#include "monotime.h"
#include "thread.h"
#include "memory.h"
#include "hash.h"
@@ -1279,7 +1280,7 @@ ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table,
/* Increment SPF Calculation Counter. */
area->spf_calculation++;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &area->ospf->ts_spf);
+ monotime(&area->ospf->ts_spf);
area->ts_spf = area->ospf->ts_spf;
if (IS_DEBUG_OSPF_EVENT)
@@ -1300,7 +1301,7 @@ ospf_spf_calculate_timer (struct thread *thread)
struct route_table *new_table, *new_rtrs;
struct ospf_area *area;
struct listnode *node, *nnode;
- struct timeval start_time, stop_time, spf_start_time;
+ struct timeval start_time, spf_start_time;
int areas_processed = 0;
unsigned long ia_time, prune_time, rt_time;
unsigned long abr_time, total_spf_time, spf_time;
@@ -1311,7 +1312,7 @@ ospf_spf_calculate_timer (struct thread *thread)
ospf->t_spf_calc = NULL;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &spf_start_time);
+ monotime(&spf_start_time);
/* Allocate new table tree. */
new_table = route_table_init ();
new_rtrs = route_table_init ();
@@ -1338,24 +1339,19 @@ ospf_spf_calculate_timer (struct thread *thread)
areas_processed++;
}
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
- spf_time = timeval_elapsed (stop_time, spf_start_time);
+ spf_time = monotime_since(&spf_start_time, NULL);
ospf_vl_shut_unapproved (ospf);
- start_time = stop_time; /* saving a call */
-
+ monotime(&start_time);
ospf_ia_routing (ospf, new_table, new_rtrs);
+ ia_time = monotime_since(&start_time, NULL);
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
- ia_time = timeval_elapsed (stop_time, start_time);
-
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time);
+ monotime(&start_time);
ospf_prune_unreachable_networks (new_table);
ospf_prune_unreachable_routers (new_rtrs);
+ prune_time = monotime_since(&start_time, NULL);
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
- prune_time = timeval_elapsed (stop_time, start_time);
/* AS-external-LSA calculation should not be performed here. */
/* If new Router Route is installed,
@@ -1365,13 +1361,11 @@ ospf_spf_calculate_timer (struct thread *thread)
ospf_ase_calculate_timer_add (ospf);
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time);
-
/* Update routing table. */
+ monotime(&start_time);
ospf_route_install (ospf, new_table);
+ rt_time = monotime_since(&start_time, NULL);
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
- rt_time = timeval_elapsed (stop_time, start_time);
/* Update ABR/ASBR routing table */
if (ospf->old_rtrs)
{
@@ -1383,17 +1377,12 @@ ospf_spf_calculate_timer (struct thread *thread)
ospf->old_rtrs = ospf->new_rtrs;
ospf->new_rtrs = new_rtrs;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time);
+ monotime(&start_time);
if (IS_OSPF_ABR (ospf))
ospf_abr_task (ospf);
+ abr_time = monotime_since(&start_time, NULL);
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
- abr_time = timeval_elapsed (stop_time, start_time);
-
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
- total_spf_time = timeval_elapsed (stop_time, spf_start_time);
- ospf->ts_spf_duration.tv_sec = total_spf_time/1000000;
- ospf->ts_spf_duration.tv_usec = total_spf_time % 1000000;
+ total_spf_time = monotime_since(&spf_start_time, &ospf->ts_spf_duration);
ospf_get_spf_reason_str (rbuf);
@@ -1421,7 +1410,6 @@ void
ospf_spf_calculate_schedule (struct ospf *ospf, ospf_spf_reason_t reason)
{
unsigned long delay, elapsed, ht;
- struct timeval result;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("SPF: calculation timer scheduled");
@@ -1440,11 +1428,9 @@ ospf_spf_calculate_schedule (struct ospf *ospf, ospf_spf_reason_t reason)
(void *)ospf->t_spf_calc);
return;
}
-
- /* XXX Monotic timers: we only care about relative time here. */
- result = tv_sub (recent_relative_time (), ospf->ts_spf);
-
- elapsed = (result.tv_sec * 1000) + (result.tv_usec / 1000);
+
+ elapsed = monotime_since (&ospf->ts_spf, NULL) / 1000;
+
ht = ospf->spf_holdtime * ospf->spf_hold_multiplier;
if (ht > ospf->spf_max_holdtime)
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index 60fb7132cc..4c5862e84a 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -746,7 +746,7 @@ update_linkparams(struct mpls_te_link *lp)
else
TLV_TYPE(lp->unrsv_bw) = 0;
- if (IS_PARAM_SET(ifp->link_params, LP_TE))
+ if (IS_PARAM_SET(ifp->link_params, LP_TE_METRIC))
set_linkparams_te_metric(lp, ifp->link_params->te_metric);
else
TLV_TYPE(lp->te_metric) = 0;
@@ -2264,12 +2264,9 @@ DEFUN (ospf_mpls_te_on,
MPLS_TE_STR
"Enable the MPLS-TE functionality\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
struct listnode *node;
struct mpls_te_link *lp;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
if (OspfMplsTE.status == enabled)
return CMD_SUCCESS;
@@ -2299,16 +2296,14 @@ DEFUN (ospf_mpls_te_on,
DEFUN (no_ospf_mpls_te,
no_ospf_mpls_te_cmd,
- "no mpls-te",
+ "no mpls-te [on]",
NO_STR
+ MPLS_TE_STR
"Disable the MPLS-TE functionality\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
struct listnode *node, *nnode;
struct mpls_te_link *lp;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
if (OspfMplsTE.status == disabled)
return CMD_SUCCESS;
@@ -2325,12 +2320,6 @@ DEFUN (no_ospf_mpls_te,
return CMD_SUCCESS;
}
-ALIAS (no_ospf_mpls_te,
- no_ospf_mpls_te_val_cmd,
- "no mpls-te on",
- NO_STR
- MPLS_TE_STR
- "Disable the MPLS-TE functionality\n")
DEFUN (ospf_mpls_te_router_addr,
ospf_mpls_te_router_addr_cmd,
@@ -2339,14 +2328,12 @@ DEFUN (ospf_mpls_te_router_addr,
"Stable IP address of the advertising router\n"
"MPLS-TE router address in IPv4 address format\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4 = 2;
struct te_tlv_router_addr *ra = &OspfMplsTE.router_addr;
struct in_addr value;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
- if (! inet_aton (argv[0], &value))
+ if (! inet_aton (argv[idx_ipv4]->arg, &value))
{
vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -2478,14 +2465,15 @@ DEFUN (ospf_mpls_te_inter_as_as,
DEFUN (ospf_mpls_te_inter_as_area,
ospf_mpls_te_inter_as_area_cmd,
- "mpls-te inter-as area (A.B.C.D|<0-4294967295>)",
+ "mpls-te inter-as area <A.B.C.D|(0-4294967295)>",
MPLS_TE_STR
"Configure MPLS-TE Inter-AS support\n"
"AREA native mode self originate INTER_AS LSA with Type 10 (area flooding scope)\n"
"OSPF area ID in IP format\n"
"OSPF area ID as decimal value\n")
{
- return set_inter_as_mode (vty, "area", argv[0]);
+ int idx_ipv4_number = 3;
+ return set_inter_as_mode (vty, "area", argv[idx_ipv4_number]->arg);
}
DEFUN (no_ospf_mpls_te_inter_as,
@@ -2629,11 +2617,12 @@ DEFUN (show_ip_ospf_mpls_te_link,
"Interface information\n"
"Interface name\n")
{
+ int idx_interface = 5;
struct interface *ifp;
struct listnode *node, *nnode;
/* Show All Interfaces. */
- if (argc == 0)
+ if (argc == 5)
{
for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), node, nnode, ifp))
show_mpls_te_link_sub (vty, ifp);
@@ -2641,7 +2630,7 @@ DEFUN (show_ip_ospf_mpls_te_link,
/* Interface name is specified. */
else
{
- if ((ifp = if_lookup_by_name (argv[0])) == NULL)
+ if ((ifp = if_lookup_by_name (argv[idx_interface]->arg)) == NULL)
vty_out (vty, "No such interface name%s", VTY_NEWLINE);
else
show_mpls_te_link_sub (vty, ifp);
@@ -2658,7 +2647,6 @@ ospf_mpls_te_register_vty (void)
install_element (OSPF_NODE, &ospf_mpls_te_on_cmd);
install_element (OSPF_NODE, &no_ospf_mpls_te_cmd);
- install_element (OSPF_NODE, &no_ospf_mpls_te_val_cmd);
install_element (OSPF_NODE, &ospf_mpls_te_router_addr_cmd);
install_element (OSPF_NODE, &ospf_mpls_te_inter_as_cmd);
install_element (OSPF_NODE, &ospf_mpls_te_inter_as_area_cmd);
diff --git a/ospfd/ospf_te.h b/ospfd/ospf_te.h
index 8bb77c40c5..36f2d8241c 100644
--- a/ospfd/ospf_te.h
+++ b/ospfd/ospf_te.h
@@ -253,7 +253,7 @@ struct te_link_subtlv_llri
/* Inter-RA Export Upward sub-TLV (12) and Inter-RA Export Downward sub-TLV (13) (RFC6827bis) are not yet supported */
/* SUBTLV 14-16 (RFC4203) are not yet supported */
/* Bandwidth Constraints sub-TLV (17) (RFC4124) is not yet supported */
-/* SUBLV 18-20 are for OSPFv6 TE (RFC5329). see ospf6d */
+/* SUBLV 18-20 are for OSPFv3 TE (RFC5329). see ospf6d */
/* For RFC 5392 */
/* Remote AS Number sub-TLV */
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 2c3aaa6808..62498f4c82 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -21,9 +21,9 @@
*/
#include <zebra.h>
-#include <lib/json.h>
#include <string.h>
+#include "monotime.h"
#include "memory.h"
#include "thread.h"
#include "prefix.h"
@@ -33,6 +33,7 @@
#include "plist.h"
#include "log.h"
#include "zclient.h"
+#include <lib/json.h>
#include "ospfd/ospfd.h"
#include "ospfd/ospf_asbr.h"
@@ -143,12 +144,12 @@ ospf_oi_count (struct interface *ifp)
return i;
}
-
DEFUN (router_ospf,
router_ospf_cmd,
- "router ospf",
+ "router ospf [(1-65535)]",
"Enable a routing process\n"
- "Start OSPF configuration\n")
+ "Start OSPF configuration\n"
+ "Instance ID\n")
{
struct ospf *ospf;
u_short instance = 0;
@@ -160,46 +161,38 @@ DEFUN (router_ospf,
return CMD_WARNING;
}
- vty->node = OSPF_NODE;
-
- if (argc)
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ if (argc > 2)
+ VTY_GET_INTEGER ("Instance", instance, argv[2]->arg);
- /* The following logic to set the vty->index is in place to be able
+ /* The following logic to set the vty qobj index is in place to be able
to ignore the commands which dont belong to this instance. */
if (ospf->instance != instance)
- vty->index = NULL;
+ VTY_PUSH_CONTEXT_NULL(OSPF_NODE);
else
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Config command 'router ospf %d' received", instance);
ospf->oi_running = 1;
- vty->index = ospf;
+ VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
ospf_router_id_update (ospf);
}
return CMD_SUCCESS;
}
-ALIAS (router_ospf,
- router_ospf_instance_cmd,
- "router ospf <1-65535>",
- "Enable a routing process\n"
- "Start OSPF configuration\n"
- "Instance ID\n")
-
DEFUN (no_router_ospf,
no_router_ospf_cmd,
- "no router ospf",
+ "no router ospf [(1-65535)]",
NO_STR
"Enable a routing process\n"
- "Start OSPF configuration\n")
+ "Start OSPF configuration\n"
+ "Instance ID\n")
{
struct ospf *ospf;
u_short instance = 0;
- if (argc)
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ if (argc > 3)
+ VTY_GET_INTEGER ("Instance", instance, argv[3]->arg);
if ((ospf = ospf_lookup_instance (instance)) == NULL)
return CMD_SUCCESS;
@@ -209,13 +202,6 @@ DEFUN (no_router_ospf,
return CMD_SUCCESS;
}
-ALIAS (no_router_ospf,
- no_router_ospf_instance_cmd,
- "no router ospf <1-65535>",
- NO_STR
- "Enable a routing process\n"
- "Start OSPF configuration\n"
- "Instance ID\n")
DEFUN (ospf_router_id,
ospf_router_id_cmd,
@@ -224,16 +210,14 @@ DEFUN (ospf_router_id,
"router-id for the OSPF process\n"
"OSPF router-id in IP address format\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4 = 2;
struct listnode *node;
struct ospf_area *area;
struct in_addr router_id;
int ret;
- if (!ospf)
- return CMD_SUCCESS;
-
- ret = inet_aton (argv[0], &router_id);
+ ret = inet_aton (argv[idx_ipv4]->arg, &router_id);
if (!ret)
{
vty_out (vty, "Please specify Router ID by A.B.C.D%s", VTY_NEWLINE);
@@ -255,26 +239,53 @@ DEFUN (ospf_router_id,
return CMD_SUCCESS;
}
-ALIAS_HIDDEN (ospf_router_id,
+DEFUN_HIDDEN (ospf_router_id_old,
ospf_router_id_old_cmd,
"router-id A.B.C.D",
"router-id for the OSPF process\n"
"OSPF router-id in IP address format\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4 = 1;
+ struct listnode *node;
+ struct ospf_area *area;
+ struct in_addr router_id;
+ int ret;
+
+ ret = inet_aton (argv[idx_ipv4]->arg, &router_id);
+ if (!ret)
+ {
+ vty_out (vty, "Please specify Router ID by A.B.C.D%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ospf->router_id_static = router_id;
+
+ for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
+ if (area->full_nbrs)
+ {
+ vty_out (vty, "For this router-id change to take effect,"
+ " save config and restart ospfd%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ ospf_router_id_update (ospf);
+
+ return CMD_SUCCESS;
+}
DEFUN (no_ospf_router_id,
no_ospf_router_id_cmd,
- "no ospf router-id",
+ "no ospf router-id [A.B.C.D]",
NO_STR
"OSPF specific commands\n"
- "router-id for the OSPF process\n")
+ "router-id for the OSPF process\n"
+ "OSPF router-id in IP address format\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
struct listnode *node;
struct ospf_area *area;
- if (!ospf)
- return CMD_SUCCESS;
-
ospf->router_id_static.s_addr = 0;
for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
@@ -290,13 +301,6 @@ DEFUN (no_ospf_router_id,
return CMD_SUCCESS;
}
-ALIAS (no_ospf_router_id,
- no_ospf_router_id_val_cmd,
- "no ospf router-id A.B.C.D",
- NO_STR
- "OSPF specific commands\n"
- "router-id for the OSPF process\n"
- "OSPF router-id in IP address format\n")
static void
ospf_passive_interface_default (struct ospf *ospf, u_char newval)
@@ -363,33 +367,33 @@ ospf_passive_interface_update (struct ospf *ospf, struct interface *ifp,
DEFUN (ospf_passive_interface,
ospf_passive_interface_addr_cmd,
- "passive-interface IFNAME A.B.C.D",
+ "passive-interface <IFNAME [A.B.C.D]|default>",
"Suppress routing updates on an interface\n"
- "Interface's name\n")
+ "Interface's name\n"
+ "IPv4 address\n"
+ "Suppress routing updates on interfaces by default\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4 = 2;
struct interface *ifp;
struct in_addr addr = { .s_addr = INADDR_ANY };
int ret;
struct ospf_if_params *params;
struct route_node *rn;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
- if (argc == 0)
+ if (strcmp (argv[1]->text, "default") == 0)
{
ospf_passive_interface_default (ospf, OSPF_IF_PASSIVE);
return CMD_SUCCESS;
}
- ifp = if_get_by_name (argv[0]);
+ ifp = if_get_by_name (argv[1]->arg);
params = IF_DEF_PARAMS (ifp);
- if (argc == 2)
+ if (argc == 3)
{
- ret = inet_aton(argv[1], &addr);
+ ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret)
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
@@ -430,48 +434,36 @@ DEFUN (ospf_passive_interface,
return CMD_SUCCESS;
}
-ALIAS (ospf_passive_interface,
- ospf_passive_interface_cmd,
- "passive-interface IFNAME",
- "Suppress routing updates on an interface\n"
- "Interface's name\n")
-
-ALIAS (ospf_passive_interface,
- ospf_passive_interface_default_cmd,
- "passive-interface default",
- "Suppress routing updates on an interface\n"
- "Suppress routing updates on interfaces by default\n")
-
DEFUN (no_ospf_passive_interface,
no_ospf_passive_interface_addr_cmd,
- "no passive-interface IFNAME A.B.C.D",
+ "no passive-interface <IFNAME [A.B.C.D]|default>",
NO_STR
"Allow routing updates on an interface\n"
- "Interface's name\n")
+ "Interface's name\n"
+ "IPv4 address\n"
+ "Allow routing updates on interfaces by default\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4 = 3;
struct interface *ifp;
struct in_addr addr = { .s_addr = INADDR_ANY };
struct ospf_if_params *params;
int ret;
struct route_node *rn;
- struct ospf *ospf = vty->index;
- if (!ospf)
- return CMD_SUCCESS;
-
- if (argc == 0)
+ if (strcmp (argv[2]->text, "default") == 0)
{
ospf_passive_interface_default (ospf, OSPF_IF_ACTIVE);
return CMD_SUCCESS;
}
- ifp = if_get_by_name (argv[0]);
+ ifp = if_get_by_name (argv[2]->arg);
params = IF_DEF_PARAMS (ifp);
- if (argc == 2)
+ if (argc == 4)
{
- ret = inet_aton(argv[1], &addr);
+ ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret)
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
@@ -505,37 +497,24 @@ DEFUN (no_ospf_passive_interface,
return CMD_SUCCESS;
}
-ALIAS (no_ospf_passive_interface,
- no_ospf_passive_interface_cmd,
- "no passive-interface IFNAME",
- NO_STR
- "Allow routing updates on an interface\n"
- "Interface's name\n")
-ALIAS (no_ospf_passive_interface,
- no_ospf_passive_interface_default_cmd,
- "no passive-interface default",
- NO_STR
- "Allow routing updates on an interface\n"
- "Allow routing updates on interfaces by default\n")
DEFUN (ospf_network_area,
ospf_network_area_cmd,
- "network A.B.C.D/M area (A.B.C.D|<0-4294967295>)",
+ "network A.B.C.D/M area <A.B.C.D|(0-4294967295)>",
"Enable routing on an IP network\n"
"OSPF network prefix\n"
"Set the OSPF area ID\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n")
{
- struct ospf *ospf= vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_prefixlen = 1;
+ int idx_ipv4_number = 3;
struct prefix_ipv4 p;
struct in_addr area_id;
int ret, format;
- if (!ospf)
- return CMD_SUCCESS;
-
if (ospf->instance)
{
vty_out (vty, "The network command is not supported in multi-instance ospf%s",
@@ -551,8 +530,8 @@ DEFUN (ospf_network_area,
}
/* Get network prefix and Area ID. */
- VTY_GET_IPV4_PREFIX ("network prefix", p, argv[0]);
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[1]);
+ VTY_GET_IPV4_PREFIX ("network prefix", p, argv[idx_ipv4_prefixlen]->arg);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
ret = ospf_network_set (ospf, &p, area_id);
if (ret == 0)
@@ -566,7 +545,7 @@ DEFUN (ospf_network_area,
DEFUN (no_ospf_network_area,
no_ospf_network_area_cmd,
- "no network A.B.C.D/M area (A.B.C.D|<0-4294967295>)",
+ "no network A.B.C.D/M area <A.B.C.D|(0-4294967295)>",
NO_STR
"Enable routing on an IP network\n"
"OSPF network prefix\n"
@@ -574,14 +553,13 @@ DEFUN (no_ospf_network_area,
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n")
{
- struct ospf *ospf = (struct ospf *) vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_prefixlen = 2;
+ int idx_ipv4_number = 4;
struct prefix_ipv4 p;
struct in_addr area_id;
int ret, format;
- if (!ospf)
- return CMD_SUCCESS;
-
if (ospf->instance)
{
vty_out (vty, "The network command is not supported in multi-instance ospf%s",
@@ -590,8 +568,8 @@ DEFUN (no_ospf_network_area,
}
/* Get network prefix and Area ID. */
- VTY_GET_IPV4_PREFIX ("network prefix", p, argv[0]);
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[1]);
+ VTY_GET_IPV4_PREFIX ("network prefix", p, argv[idx_ipv4_prefixlen]->arg);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
ret = ospf_network_unset (ospf, &p, area_id);
if (ret == 0)
@@ -604,51 +582,43 @@ DEFUN (no_ospf_network_area,
return CMD_SUCCESS;
}
-
DEFUN (ospf_area_range,
ospf_area_range_cmd,
- "area (A.B.C.D|<0-4294967295>) range A.B.C.D/M",
+ "area <A.B.C.D|(0-4294967295)> range A.B.C.D/M [advertise [cost (0-16777215)]]",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n")
+ "Area range prefix\n"
+ "Advertise this range (default)\n"
+ "User specified metric for this range\n"
+ "Advertised metric for this range\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
+ int idx_ipv4_prefixlen = 3;
+ int idx_cost = 6;
struct prefix_ipv4 p;
struct in_addr area_id;
int format;
u_int32_t cost;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
- VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
+ VTY_GET_IPV4_PREFIX ("area range", p, argv[idx_ipv4_prefixlen]->arg);
ospf_area_range_set (ospf, area_id, &p, OSPF_AREA_RANGE_ADVERTISE);
- if (argc > 2)
+ if (argc > 5)
{
- VTY_GET_INTEGER ("range cost", cost, argv[2]);
+ VTY_GET_INTEGER ("range cost", cost, argv[idx_cost]->arg);
ospf_area_range_cost_set (ospf, area_id, &p, cost);
}
return CMD_SUCCESS;
}
-ALIAS (ospf_area_range,
- ospf_area_range_advertise_cmd,
- "area (A.B.C.D|<0-4294967295>) range A.B.C.D/M advertise",
- "OSPF area parameters\n"
- "OSPF area ID in IP address format\n"
- "OSPF area ID as a decimal value\n"
- "OSPF area range for route advertise (default)\n"
- "Area range prefix\n"
- "Advertise this range (default)\n")
-
-ALIAS (ospf_area_range,
+DEFUN (ospf_area_range_cost,
ospf_area_range_cost_cmd,
- "area (A.B.C.D|<0-4294967295>) range A.B.C.D/M cost <0-16777215>",
+ "area <A.B.C.D|(0-4294967295)> range A.B.C.D/M cost (0-16777215)",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -656,22 +626,30 @@ ALIAS (ospf_area_range,
"Area range prefix\n"
"User specified metric for this range\n"
"Advertised metric for this range\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
+ int idx_ipv4_prefixlen = 3;
+ int idx_cost = 5;
+ struct prefix_ipv4 p;
+ struct in_addr area_id;
+ int format;
+ u_int32_t cost;
-ALIAS (ospf_area_range,
- ospf_area_range_advertise_cost_cmd,
- "area (A.B.C.D|<0-4294967295>) range A.B.C.D/M advertise cost <0-16777215>",
- "OSPF area parameters\n"
- "OSPF area ID in IP address format\n"
- "OSPF area ID as a decimal value\n"
- "Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n"
- "Advertise this range (default)\n"
- "User specified metric for this range\n"
- "Advertised metric for this range\n")
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
+ VTY_GET_IPV4_PREFIX ("area range", p, argv[idx_ipv4_prefixlen]->arg);
+
+ ospf_area_range_set (ospf, area_id, &p, OSPF_AREA_RANGE_ADVERTISE);
+
+ VTY_GET_INTEGER ("range cost", cost, argv[idx_cost]->arg);
+ ospf_area_range_cost_set (ospf, area_id, &p, cost);
+
+ return CMD_SUCCESS;
+}
DEFUN (ospf_area_range_not_advertise,
ospf_area_range_not_advertise_cmd,
- "area (A.B.C.D|<0-4294967295>) range A.B.C.D/M not-advertise",
+ "area <A.B.C.D|(0-4294967295)> range A.B.C.D/M not-advertise",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -679,16 +657,15 @@ DEFUN (ospf_area_range_not_advertise,
"Area range prefix\n"
"DoNotAdvertise this range\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
+ int idx_ipv4_prefixlen = 3;
struct prefix_ipv4 p;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
- VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
+ VTY_GET_IPV4_PREFIX ("area range", p, argv[idx_ipv4_prefixlen]->arg);
ospf_area_range_set (ospf, area_id, &p, 0);
@@ -697,70 +674,38 @@ DEFUN (ospf_area_range_not_advertise,
DEFUN (no_ospf_area_range,
no_ospf_area_range_cmd,
- "no area (A.B.C.D|<0-4294967295>) range A.B.C.D/M",
+ "no area <A.B.C.D|(0-4294967295)> range A.B.C.D/M [<cost (0-16777215)|advertise [cost (0-16777215)]|not-advertise>]",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n")
+ "Area range prefix\n"
+ "User specified metric for this range\n"
+ "Advertised metric for this range\n"
+ "Advertise this range (default)\n"
+ "User specified metric for this range\n"
+ "Advertised metric for this range\n"
+ "DoNotAdvertise this range\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
+ int idx_ipv4_prefixlen = 4;
struct prefix_ipv4 p;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
- VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
+ VTY_GET_IPV4_PREFIX ("area range", p, argv[idx_ipv4_prefixlen]->arg);
ospf_area_range_unset (ospf, area_id, &p);
return CMD_SUCCESS;
}
-ALIAS (no_ospf_area_range,
- no_ospf_area_range_advertise_cmd,
- "no area (A.B.C.D|<0-4294967295>) range A.B.C.D/M (advertise|not-advertise)",
- NO_STR
- "OSPF area parameters\n"
- "OSPF area ID in IP address format\n"
- "OSPF area ID as a decimal value\n"
- "Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n"
- "Advertise this range (default)\n"
- "DoNotAdvertise this range\n")
-
-ALIAS (no_ospf_area_range,
- no_ospf_area_range_cost_cmd,
- "no area (A.B.C.D|<0-4294967295>) range A.B.C.D/M cost <0-16777215>",
- NO_STR
- "OSPF area parameters\n"
- "OSPF area ID in IP address format\n"
- "OSPF area ID as a decimal value\n"
- "Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n"
- "User specified metric for this range\n"
- "Advertised metric for this range\n")
-
-ALIAS (no_ospf_area_range,
- no_ospf_area_range_advertise_cost_cmd,
- "no area (A.B.C.D|<0-4294967295>) range A.B.C.D/M advertise cost <0-16777215>",
- NO_STR
- "OSPF area parameters\n"
- "OSPF area ID in IP address format\n"
- "OSPF area ID as a decimal value\n"
- "Summarize routes matching address/mask (border routers only)\n"
- "Area range prefix\n"
- "Advertise this range (default)\n"
- "User specified metric for this range\n"
- "Advertised metric for this range\n")
-
DEFUN (ospf_area_range_substitute,
ospf_area_range_substitute_cmd,
- "area (A.B.C.D|<0-4294967295>) range A.B.C.D/M substitute A.B.C.D/M",
+ "area <A.B.C.D|(0-4294967295)> range A.B.C.D/M substitute A.B.C.D/M",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -769,17 +714,17 @@ DEFUN (ospf_area_range_substitute,
"Announce area range as another prefix\n"
"Network prefix to be announced instead of range\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
+ int idx_ipv4_prefixlen = 3;
+ int idx_ipv4_prefixlen_2 = 5;
struct prefix_ipv4 p, s;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
- VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
- VTY_GET_IPV4_PREFIX ("substituted network prefix", s, argv[2]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
+ VTY_GET_IPV4_PREFIX ("area range", p, argv[idx_ipv4_prefixlen]->arg);
+ VTY_GET_IPV4_PREFIX ("substituted network prefix", s, argv[idx_ipv4_prefixlen_2]->arg);
ospf_area_range_substitute_set (ospf, area_id, &p, &s);
@@ -788,7 +733,7 @@ DEFUN (ospf_area_range_substitute,
DEFUN (no_ospf_area_range_substitute,
no_ospf_area_range_substitute_cmd,
- "no area (A.B.C.D|<0-4294967295>) range A.B.C.D/M substitute A.B.C.D/M",
+ "no area <A.B.C.D|(0-4294967295)> range A.B.C.D/M substitute A.B.C.D/M",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -798,17 +743,17 @@ DEFUN (no_ospf_area_range_substitute,
"Announce area range as another prefix\n"
"Network prefix to be announced instead of range\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
+ int idx_ipv4_prefixlen = 4;
+ int idx_ipv4_prefixlen_2 = 6;
struct prefix_ipv4 p, s;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
- VTY_GET_IPV4_PREFIX ("area range", p, argv[1]);
- VTY_GET_IPV4_PREFIX ("substituted network prefix", s, argv[2]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
+ VTY_GET_IPV4_PREFIX ("area range", p, argv[idx_ipv4_prefixlen]->arg);
+ VTY_GET_IPV4_PREFIX ("substituted network prefix", s, argv[idx_ipv4_prefixlen_2]->arg);
ospf_area_range_substitute_unset (ospf, area_id, &p);
@@ -831,7 +776,6 @@ DEFUN (no_ospf_area_range_substitute,
Wed, 21 Feb 2001 15:13:52 +1300
*/
-
/* Configuration data for virtual links
*/
struct ospf_vl_config_data {
@@ -999,7 +943,6 @@ ospf_vl_set_timers (struct ospf_vl_data *vl_data,
}
-
/* The business end of all of the above */
static int
ospf_vl_set (struct ospf *ospf, struct ospf_vl_config_data *vl_config)
@@ -1052,7 +995,7 @@ ospf_vl_set (struct ospf *ospf, struct ospf_vl_config_data *vl_config)
"Time between HELLO packets\n" \
"Time between retransmitting lost link state advertisements\n" \
"Link state transmit delay\n" \
- "Interval after which a neighbor is declared dead\n"
+ "Interval time after which a neighbor is declared down\n"
#define VLINK_HELPSTR_TIME_PARAM \
VLINK_HELPSTR_TIME_PARAM_NOSECS \
@@ -1071,30 +1014,36 @@ ospf_vl_set (struct ospf *ospf, struct ospf_vl_config_data *vl_config)
DEFUN (ospf_area_vlink,
ospf_area_vlink_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D",
- VLINK_HELPSTR_IPADDR)
+ "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication] [<message-digest|null>] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
+ VLINK_HELPSTR_IPADDR
+ "Enable authentication on this virtual link\n" \
+ "Use null authentication\n" \
+ "Use message-digest authentication\n"
+ "Message digest authentication password (key)\n" \
+ "Key ID\n" \
+ "Use MD5 algorithm\n" \
+ "The OSPF password (key)")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
+ int idx_ipv4 = 3;
struct ospf_vl_config_data vl_config;
char auth_key[OSPF_AUTH_SIMPLE_SIZE+1];
char md5_key[OSPF_AUTH_MD5_SIZE+1];
int i;
int ret;
-
- if (!ospf)
- return CMD_SUCCESS;
ospf_vl_config_data_init(&vl_config, vty);
/* Read off first 2 parameters and check them */
- ret = ospf_str2area_id (argv[0], &vl_config.area_id, &vl_config.format);
+ ret = ospf_str2area_id (argv[idx_ipv4_number]->arg, &vl_config.area_id, &vl_config.format);
if (ret < 0)
{
vty_out (vty, "OSPF area ID is invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ret = inet_aton (argv[1], &vl_config.vl_peer);
+ ret = inet_aton (argv[idx_ipv4]->arg, &vl_config.vl_peer);
if (! ret)
{
vty_out (vty, "Please specify valid Router ID as a.b.c.d%s",
@@ -1102,7 +1051,7 @@ DEFUN (ospf_area_vlink,
return CMD_WARNING;
}
- if (argc <=2)
+ if (argc <=4)
{
/* Thats all folks! - BUGS B. strikes again!!!*/
@@ -1110,40 +1059,40 @@ DEFUN (ospf_area_vlink,
}
/* Deal with other parameters */
- for (i=2; i < argc; i++)
+ for (i=5; i < argc; i++)
{
- /* vty_out (vty, "argv[%d] - %s%s", i, argv[i], VTY_NEWLINE); */
+ /* vty_out (vty, "argv[%d]->arg - %s%s", i, argv[i]->text, VTY_NEWLINE); */
- switch (argv[i][0])
+ switch (argv[i]->arg[0])
{
case 'a':
- if (i > 2 || strncmp (argv[i], "authentication-", 15) == 0)
+ if (i >5 || strncmp (argv[i]->arg, "authentication-", 15) == 0)
{
/* authentication-key - this option can occur anywhere on
command line. At start of command line
must check for authentication option. */
memset (auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1);
- strncpy (auth_key, argv[i+1], OSPF_AUTH_SIMPLE_SIZE);
+ strncpy (auth_key, argv[i+1]->text, OSPF_AUTH_SIMPLE_SIZE);
vl_config.auth_key = auth_key;
i++;
}
- else if (strncmp (argv[i], "authentication", 14) == 0)
+ else if (strncmp (argv[i]->arg, "authentication", 14) == 0)
{
/* authentication - this option can only occur at start
of command line */
vl_config.auth_type = OSPF_AUTH_SIMPLE;
if ((i+1) < argc)
{
- if (strncmp (argv[i+1], "n", 1) == 0)
+ if (strncmp (argv[i+1]->arg, "n", 1) == 0)
{
/* "authentication null" */
vl_config.auth_type = OSPF_AUTH_NULL;
i++;
}
- else if (strncmp (argv[i+1], "m", 1) == 0
- && strcmp (argv[i+1], "message-digest-") != 0)
+ else if (strncmp (argv[i+1]->arg, "m", 1) == 0
+ && strcmp (argv[i+1]->arg, "message-digest-") != 0)
{
/* "authentication message-digest" */
vl_config.auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
@@ -1156,63 +1105,101 @@ DEFUN (ospf_area_vlink,
case 'm':
/* message-digest-key */
i++;
- vl_config.crypto_key_id = strtol (argv[i], NULL, 10);
- if (vl_config.crypto_key_id < 0)
- return CMD_WARNING;
- i++;
- memset(md5_key, 0, OSPF_AUTH_MD5_SIZE+1);
- strncpy (md5_key, argv[i], OSPF_AUTH_MD5_SIZE);
- vl_config.md5_key = md5_key;
+ if (i < argc)
+ {
+ vl_config.crypto_key_id = strtol (argv[i]->arg, NULL, 10);
+ if (vl_config.crypto_key_id < 0)
+ return CMD_WARNING;
+ i++;
+ if (i < argc)
+ {
+ memset(md5_key, 0, OSPF_AUTH_MD5_SIZE+1);
+ strncpy (md5_key, argv[i]->arg, OSPF_AUTH_MD5_SIZE);
+ vl_config.md5_key = md5_key;
+ }
+ }
+ else
+ vl_config.md5_key = NULL;
break;
+ }
+ }
- case 'h':
- /* Hello interval */
- i++;
- vl_config.hello_interval = strtol (argv[i], NULL, 10);
- if (vl_config.hello_interval < 0)
- return CMD_WARNING;
- break;
- case 'r':
- /* Retransmit Interval */
- i++;
- vl_config.retransmit_interval = strtol (argv[i], NULL, 10);
- if (vl_config.retransmit_interval < 0)
- return CMD_WARNING;
- break;
+ /* Action configuration */
- case 't':
- /* Transmit Delay */
- i++;
- vl_config.transmit_delay = strtol (argv[i], NULL, 10);
- if (vl_config.transmit_delay < 0)
- return CMD_WARNING;
- break;
+ return ospf_vl_set (ospf, &vl_config);
- case 'd':
- /* Dead Interval */
- i++;
- vl_config.dead_interval = strtol (argv[i], NULL, 10);
- if (vl_config.dead_interval < 0)
- return CMD_WARNING;
- break;
- }
+}
+
+DEFUN (ospf_area_vlink_intervals,
+ ospf_area_vlink_intervals_cmd,
+ "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D"
+ "<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
+ "[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
+ "[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
+ "[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
+ "]]]",
+ VLINK_HELPSTR_IPADDR
+ VLINK_HELPSTR_TIME_PARAM
+ VLINK_HELPSTR_TIME_PARAM
+ VLINK_HELPSTR_TIME_PARAM
+ VLINK_HELPSTR_TIME_PARAM)
+{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ struct ospf_vl_config_data vl_config;
+ int ret = 0;
+
+ ospf_vl_config_data_init(&vl_config, vty);
+
+ char *area_id = argv[1]->arg;
+ char *router_id = argv[3]->arg;
+
+ ret = ospf_str2area_id (area_id, &vl_config.area_id, &vl_config.format);
+ if (ret < 0)
+ {
+ vty_out (vty, "OSPF area ID is invalid%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
+ ret = inet_aton (router_id, &vl_config.vl_peer);
+ if (! ret)
+ {
+ vty_out (vty, "Please specify valid Router ID as a.b.c.d%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ for (unsigned int i = 0; i < 4; i++)
+ {
+ int idx = 0;
+ if (argv_find (argv, argc, "hello-interval", &idx))
+ vl_config.hello_interval = strtol(argv[idx+1]->arg, NULL, 10);
+ else if (argv_find (argv, argc, "retransmit-interval", &idx))
+ vl_config.retransmit_interval = strtol(argv[idx+1]->arg, NULL, 10);
+ else if (argv_find (argv, argc, "transmit-delay", &idx))
+ vl_config.transmit_delay = strtol(argv[idx+1]->arg, NULL, 10);
+ else if (argv_find (argv, argc, "dead-interval", &idx))
+ vl_config.dead_interval = strtol(argv[idx+1]->arg, NULL, 10);
+ }
/* Action configuration */
-
return ospf_vl_set (ospf, &vl_config);
-
}
DEFUN (no_ospf_area_vlink,
no_ospf_area_vlink_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D",
+ "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication] [<message-digest|null>] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
NO_STR
- VLINK_HELPSTR_IPADDR)
+ VLINK_HELPSTR_IPADDR
+ "Enable authentication on this virtual link\n" \
+ "Use null authentication\n" \
+ "Use message-digest authentication\n"
+ "Message digest authentication password (key)\n" \
+ "Key ID\n" \
+ "Use MD5 algorithm\n" \
+ "The OSPF password (key)")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
+ int idx_ipv4 = 4;
struct ospf_area *area;
struct ospf_vl_config_data vl_config;
struct ospf_vl_data *vl_data = NULL;
@@ -1220,12 +1207,9 @@ DEFUN (no_ospf_area_vlink,
int i;
int ret, format;
- if (!ospf)
- return CMD_SUCCESS;
-
ospf_vl_config_data_init(&vl_config, vty);
- ret = ospf_str2area_id (argv[0], &vl_config.area_id, &format);
+ ret = ospf_str2area_id (argv[idx_ipv4_number]->arg, &vl_config.area_id, &format);
if (ret < 0)
{
vty_out (vty, "OSPF area ID is invalid%s", VTY_NEWLINE);
@@ -1239,7 +1223,7 @@ DEFUN (no_ospf_area_vlink,
return CMD_WARNING;
}
- ret = inet_aton (argv[1], &vl_config.vl_peer);
+ ret = inet_aton (argv[idx_ipv4]->arg, &vl_config.vl_peer);
if (! ret)
{
vty_out (vty, "Please specify valid Router ID as a.b.c.d%s",
@@ -1247,7 +1231,7 @@ DEFUN (no_ospf_area_vlink,
return CMD_WARNING;
}
- if (argc <=2)
+ if (argc <=5)
{
/* Basic VLink no command */
/* Thats all folks! - BUGS B. strikes again!!!*/
@@ -1255,22 +1239,22 @@ DEFUN (no_ospf_area_vlink,
ospf_vl_delete (ospf, vl_data);
ospf_area_check_free (ospf, vl_config.area_id);
-
+
return CMD_SUCCESS;
}
/* If we are down here, we are reseting parameters */
/* Deal with other parameters */
- for (i=2; i < argc; i++)
+ for (i=6; i < argc; i++)
{
/* vty_out (vty, "argv[%d] - %s%s", i, argv[i], VTY_NEWLINE); */
- switch (argv[i][0])
+ switch (argv[i]->arg[0])
{
case 'a':
- if (i > 2 || strncmp (argv[i], "authentication-", 15) == 0)
+ if (i > 2 || strncmp (argv[i]->text, "authentication-", 15) == 0)
{
/* authentication-key - this option can occur anywhere on
command line. At start of command line
@@ -1278,7 +1262,7 @@ DEFUN (no_ospf_area_vlink,
memset (auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1);
vl_config.auth_key = auth_key;
}
- else if (strncmp (argv[i], "authentication", 14) == 0)
+ else if (strncmp (argv[i]->text, "authentication", 14) == 0)
{
/* authentication - this option can only occur at start
of command line */
@@ -1292,7 +1276,7 @@ DEFUN (no_ospf_area_vlink,
i++;
if (i < argc)
{
- vl_config.crypto_key_id = strtol (argv[i], NULL, 10);
+ vl_config.crypto_key_id = strtol (argv[i]->arg, NULL, 10);
if (vl_config.crypto_key_id < 0)
return CMD_WARNING;
vl_config.md5_key = NULL;
@@ -1301,26 +1285,6 @@ DEFUN (no_ospf_area_vlink,
return CMD_WARNING;
break;
- case 'h':
- /* Hello interval */
- vl_config.hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
- break;
-
- case 'r':
- /* Retransmit Interval */
- vl_config.retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
- break;
-
- case 't':
- /* Transmit Delay */
- vl_config.transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
- break;
-
- case 'd':
- /* Dead Interval */
- i++;
- vl_config.dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
- break;
}
}
@@ -1330,230 +1294,64 @@ DEFUN (no_ospf_area_vlink,
return ospf_vl_set (ospf, &vl_config);
}
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_param1_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_TIME_PARAM)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_param1_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_TIME_PARAM)
-
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_param2_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_TIME_PARAM
- VLINK_HELPSTR_TIME_PARAM)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_param2_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_TIME_PARAM
- VLINK_HELPSTR_TIME_PARAM)
-
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_param3_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_TIME_PARAM
- VLINK_HELPSTR_TIME_PARAM
- VLINK_HELPSTR_TIME_PARAM)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_param3_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_TIME_PARAM
- VLINK_HELPSTR_TIME_PARAM
- VLINK_HELPSTR_TIME_PARAM)
-
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_param4_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_TIME_PARAM
- VLINK_HELPSTR_TIME_PARAM
- VLINK_HELPSTR_TIME_PARAM
- VLINK_HELPSTR_TIME_PARAM)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_param4_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> "
- "(hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>",
+DEFUN (no_ospf_area_vlink_intervals,
+ no_ospf_area_vlink_intervals_cmd,
+ "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D"
+ "<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
+ "[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
+ "[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
+ "[<hello-interval|retransmit-interval|transmit-delay|dead-interval> (1-65535)"
+ "]]]",
NO_STR
VLINK_HELPSTR_IPADDR
VLINK_HELPSTR_TIME_PARAM
VLINK_HELPSTR_TIME_PARAM
VLINK_HELPSTR_TIME_PARAM
VLINK_HELPSTR_TIME_PARAM)
+{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ struct ospf_vl_config_data vl_config;
+ int ret = 0;
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_authtype_args_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) (message-digest|null)",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_ALL)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_authtype_args_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) (message-digest|null)",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_ALL)
-
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_authtype_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|)",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_SIMPLE)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_authtype_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|)",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_SIMPLE)
-
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_md5_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(message-digest-key|) <1-255> md5 KEY",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTH_MD5)
+ ospf_vl_config_data_init(&vl_config, vty);
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_md5_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(message-digest-key|) <1-255> md5 KEY",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTH_MD5)
+ char *area_id = argv[2]->arg;
+ char *router_id = argv[4]->arg;
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_authkey_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication-key|) AUTH_KEY",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTH_SIMPLE)
+ ret = ospf_str2area_id (area_id, &vl_config.area_id, &vl_config.format);
+ if (ret < 0)
+ {
+ vty_out (vty, "OSPF area ID is invalid%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_authkey_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication-key|) AUTH_KEY",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTH_SIMPLE)
+ ret = inet_aton (router_id, &vl_config.vl_peer);
+ if (! ret)
+ {
+ vty_out (vty, "Please specify valid Router ID as a.b.c.d%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_authtype_args_authkey_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) (message-digest|null) "
- "(authentication-key|) AUTH_KEY",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_ALL
- VLINK_HELPSTR_AUTH_SIMPLE)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_authtype_args_authkey_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) (message-digest|null) "
- "(authentication-key|) AUTH_KEY",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_ALL
- VLINK_HELPSTR_AUTH_SIMPLE)
-
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_authtype_authkey_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) "
- "(authentication-key|) AUTH_KEY",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_SIMPLE
- VLINK_HELPSTR_AUTH_SIMPLE)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_authtype_authkey_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) "
- "(authentication-key|) AUTH_KEY",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_SIMPLE
- VLINK_HELPSTR_AUTH_SIMPLE)
-
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_authtype_args_md5_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) (message-digest|null) "
- "(message-digest-key|) <1-255> md5 KEY",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_ALL
- VLINK_HELPSTR_AUTH_MD5)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_authtype_args_md5_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) (message-digest|null) "
- "(message-digest-key|) <1-255> md5 KEY",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_ALL
- VLINK_HELPSTR_AUTH_MD5)
-
-ALIAS (ospf_area_vlink,
- ospf_area_vlink_authtype_md5_cmd,
- "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) "
- "(message-digest-key|) <1-255> md5 KEY",
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_SIMPLE
- VLINK_HELPSTR_AUTH_MD5)
-
-ALIAS (no_ospf_area_vlink,
- no_ospf_area_vlink_authtype_md5_cmd,
- "no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D "
- "(authentication|) "
- "(message-digest-key|) <1-255> md5 KEY",
- NO_STR
- VLINK_HELPSTR_IPADDR
- VLINK_HELPSTR_AUTHTYPE_SIMPLE
- VLINK_HELPSTR_AUTH_MD5)
+ for (unsigned int i = 0; i < 4; i++)
+ {
+ int idx = 0;
+ if (argv_find (argv, argc, "hello-interval", &idx))
+ vl_config.hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
+ else if (argv_find (argv, argc, "retransmit-interval", &idx))
+ vl_config.retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
+ else if (argv_find (argv, argc, "transmit-delay", &idx))
+ vl_config.transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
+ else if (argv_find (argv, argc, "dead-interval", &idx))
+ vl_config.dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
+ }
+ /* Action configuration */
+ return ospf_vl_set (ospf, &vl_config);
+}
DEFUN (ospf_area_shortcut,
ospf_area_shortcut_cmd,
- "area (A.B.C.D|<0-4294967295>) shortcut (default|enable|disable)",
+ "area <A.B.C.D|(0-4294967295)> shortcut <default|enable|disable>",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -1562,24 +1360,23 @@ DEFUN (ospf_area_shortcut,
"Enable shortcutting through the area\n"
"Disable shortcutting through the area\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
+ int idx_enable_disable = 3;
struct ospf_area *area;
struct in_addr area_id;
int mode;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_get (ospf, area_id, format);
- if (strncmp (argv[1], "de", 2) == 0)
+ if (strncmp (argv[idx_enable_disable]->arg, "de", 2) == 0)
mode = OSPF_SHORTCUT_DEFAULT;
- else if (strncmp (argv[1], "di", 2) == 0)
+ else if (strncmp (argv[idx_enable_disable]->arg, "di", 2) == 0)
mode = OSPF_SHORTCUT_DISABLE;
- else if (strncmp (argv[1], "e", 1) == 0)
+ else if (strncmp (argv[idx_enable_disable]->arg, "e", 1) == 0)
mode = OSPF_SHORTCUT_ENABLE;
else
return CMD_WARNING;
@@ -1596,7 +1393,7 @@ DEFUN (ospf_area_shortcut,
DEFUN (no_ospf_area_shortcut,
no_ospf_area_shortcut_cmd,
- "no area (A.B.C.D|<0-4294967295>) shortcut (enable|disable)",
+ "no area <A.B.C.D|(0-4294967295)> shortcut <enable|disable>",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -1605,15 +1402,13 @@ DEFUN (no_ospf_area_shortcut,
"Deconfigure enabled shortcutting through the area\n"
"Deconfigure disabled shortcutting through the area\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
struct ospf_area *area;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_lookup_by_area_id (ospf, area_id);
if (!area)
@@ -1627,20 +1422,18 @@ DEFUN (no_ospf_area_shortcut,
DEFUN (ospf_area_stub,
ospf_area_stub_cmd,
- "area (A.B.C.D|<0-4294967295>) stub",
+ "area <A.B.C.D|(0-4294967295)> stub",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Configure OSPF area as stub\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
struct in_addr area_id;
int ret, format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[idx_ipv4_number]->arg);
ret = ospf_area_stub_set (ospf, area_id);
if (ret == 0)
@@ -1657,21 +1450,19 @@ DEFUN (ospf_area_stub,
DEFUN (ospf_area_stub_no_summary,
ospf_area_stub_no_summary_cmd,
- "area (A.B.C.D|<0-4294967295>) stub no-summary",
+ "area <A.B.C.D|(0-4294967295)> stub no-summary",
"OSPF stub parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Configure OSPF area as stub\n"
"Do not inject inter-area routes into stub\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
struct in_addr area_id;
int ret, format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[idx_ipv4_number]->arg);
ret = ospf_area_stub_set (ospf, area_id);
if (ret == 0)
@@ -1688,21 +1479,19 @@ DEFUN (ospf_area_stub_no_summary,
DEFUN (no_ospf_area_stub,
no_ospf_area_stub_cmd,
- "no area (A.B.C.D|<0-4294967295>) stub",
+ "no area <A.B.C.D|(0-4294967295)> stub",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Configure OSPF area as stub\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[idx_ipv4_number]->arg);
ospf_area_stub_unset (ospf, area_id);
ospf_area_no_summary_unset (ospf, area_id);
@@ -1712,7 +1501,7 @@ DEFUN (no_ospf_area_stub,
DEFUN (no_ospf_area_stub_no_summary,
no_ospf_area_stub_no_summary_cmd,
- "no area (A.B.C.D|<0-4294967295>) stub no-summary",
+ "no area <A.B.C.D|(0-4294967295)> stub no-summary",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -1720,31 +1509,26 @@ DEFUN (no_ospf_area_stub_no_summary,
"Configure OSPF area as stub\n"
"Do not inject inter-area routes into area\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[idx_ipv4_number]->arg);
ospf_area_no_summary_unset (ospf, area_id);
return CMD_SUCCESS;
}
static int
-ospf_area_nssa_cmd_handler (struct vty *vty, int argc, const char *argv[],
+ospf_area_nssa_cmd_handler (struct vty *vty, int argc, struct cmd_token **argv,
int nosum)
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
struct in_addr area_id;
int ret, format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[1]->arg);
ret = ospf_area_nssa_set (ospf, area_id);
if (ret == 0)
@@ -1756,13 +1540,13 @@ ospf_area_nssa_cmd_handler (struct vty *vty, int argc, const char *argv[],
if (argc > 1)
{
- if (strncmp (argv[1], "translate-c", 11) == 0)
+ if (strncmp (argv[3]->text, "translate-c", 11) == 0)
ospf_area_nssa_translator_role_set (ospf, area_id,
OSPF_NSSA_ROLE_CANDIDATE);
- else if (strncmp (argv[1], "translate-n", 11) == 0)
+ else if (strncmp (argv[3]->text, "translate-n", 11) == 0)
ospf_area_nssa_translator_role_set (ospf, area_id,
OSPF_NSSA_ROLE_NEVER);
- else if (strncmp (argv[1], "translate-a", 11) == 0)
+ else if (strncmp (argv[3]->text, "translate-a", 11) == 0)
ospf_area_nssa_translator_role_set (ospf, area_id,
OSPF_NSSA_ROLE_ALWAYS);
}
@@ -1784,7 +1568,7 @@ ospf_area_nssa_cmd_handler (struct vty *vty, int argc, const char *argv[],
DEFUN (ospf_area_nssa_translate_no_summary,
ospf_area_nssa_translate_no_summary_cmd,
- "area (A.B.C.D|<0-4294967295>) nssa (translate-candidate|translate-never|translate-always) no-summary",
+ "area <A.B.C.D|(0-4294967295)> nssa <translate-candidate|translate-never|translate-always> no-summary",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -1799,7 +1583,7 @@ DEFUN (ospf_area_nssa_translate_no_summary,
DEFUN (ospf_area_nssa_translate,
ospf_area_nssa_translate_cmd,
- "area (A.B.C.D|<0-4294967295>) nssa (translate-candidate|translate-never|translate-always)",
+ "area <A.B.C.D|(0-4294967295)> nssa <translate-candidate|translate-never|translate-always>",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -1813,7 +1597,7 @@ DEFUN (ospf_area_nssa_translate,
DEFUN (ospf_area_nssa,
ospf_area_nssa_cmd,
- "area (A.B.C.D|<0-4294967295>) nssa",
+ "area <A.B.C.D|(0-4294967295)> nssa",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -1824,7 +1608,7 @@ DEFUN (ospf_area_nssa,
DEFUN (ospf_area_nssa_no_summary,
ospf_area_nssa_no_summary_cmd,
- "area (A.B.C.D|<0-4294967295>) nssa no-summary",
+ "area <A.B.C.D|(0-4294967295)> nssa no-summary",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -1836,21 +1620,23 @@ DEFUN (ospf_area_nssa_no_summary,
DEFUN (no_ospf_area_nssa,
no_ospf_area_nssa_cmd,
- "no area (A.B.C.D|<0-4294967295>) nssa",
+ "no area <A.B.C.D|(0-4294967295)> nssa [<translate-candidate|translate-never|translate-always> [no-summary]]",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
- "Configure OSPF area as nssa\n")
+ "Configure OSPF area as nssa\n"
+ "Configure NSSA-ABR for translate election (default)\n"
+ "Configure NSSA-ABR to never translate\n"
+ "Configure NSSA-ABR to always translate\n"
+ "Do not inject inter-area routes into nssa\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[idx_ipv4_number]->arg);
ospf_area_nssa_unset (ospf, area_id);
ospf_area_no_summary_unset (ospf, area_id);
@@ -1860,40 +1646,27 @@ DEFUN (no_ospf_area_nssa,
return CMD_SUCCESS;
}
-ALIAS (no_ospf_area_nssa,
- no_ospf_area_nssa_no_summary_cmd,
- "no area (A.B.C.D|<0-4294967295>) nssa (translate-candidate|translate-never|translate-always|) {no-summary}",
- NO_STR
- "OSPF area parameters\n"
- "OSPF area ID in IP address format\n"
- "OSPF area ID as a decimal value\n"
- "Configure OSPF area as nssa\n"
- "Configure NSSA-ABR for translate election (default)\n"
- "Configure NSSA-ABR to never translate\n"
- "Configure NSSA-ABR to always translate\n"
- "Do not inject inter-area routes into nssa\n")
DEFUN (ospf_area_default_cost,
ospf_area_default_cost_cmd,
- "area (A.B.C.D|<0-4294967295>) default-cost <0-16777215>",
+ "area <A.B.C.D|(0-4294967295)> default-cost (0-16777215)",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Set the summary-default cost of a NSSA or stub area\n"
"Stub's advertised default summary cost\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
+ int idx_number = 3;
struct ospf_area *area;
struct in_addr area_id;
u_int32_t cost;
int format;
struct prefix_ipv4 p;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[0]);
- VTY_GET_INTEGER_RANGE ("stub default cost", cost, argv[1], 0, 16777215);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[idx_ipv4_number]->arg);
+ VTY_GET_INTEGER_RANGE ("stub default cost", cost, argv[idx_number]->arg, 0, 16777215);
area = ospf_area_get (ospf, area_id, format);
@@ -1919,7 +1692,7 @@ DEFUN (ospf_area_default_cost,
DEFUN (no_ospf_area_default_cost,
no_ospf_area_default_cost_cmd,
- "no area (A.B.C.D|<0-4294967295>) default-cost <0-16777215>",
+ "no area <A.B.C.D|(0-4294967295)> default-cost (0-16777215)",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -1927,17 +1700,16 @@ DEFUN (no_ospf_area_default_cost,
"Set the summary-default cost of a NSSA or stub area\n"
"Stub's advertised default summary cost\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
+ int idx_number = 4;
struct ospf_area *area;
struct in_addr area_id;
int format;
struct prefix_ipv4 p;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[0]);
- VTY_CHECK_INTEGER_RANGE ("stub default cost", argv[1], 0, OSPF_LS_INFINITY);
+ VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[idx_ipv4_number]->arg);
+ VTY_CHECK_INTEGER_RANGE ("stub default cost", argv[idx_number]->arg, 0, OSPF_LS_INFINITY);
area = ospf_area_lookup_by_area_id (ospf, area_id);
if (area == NULL)
@@ -1968,32 +1740,30 @@ DEFUN (no_ospf_area_default_cost,
DEFUN (ospf_area_export_list,
ospf_area_export_list_cmd,
- "area (A.B.C.D|<0-4294967295>) export-list NAME",
+ "area <A.B.C.D|(0-4294967295)> export-list NAME",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Set the filter for networks announced to other areas\n"
"Name of the access-list\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
struct ospf_area *area;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_get (ospf, area_id, format);
- ospf_area_export_list_set (ospf, area, argv[1]);
+ ospf_area_export_list_set (ospf, area, argv[3]->arg);
return CMD_SUCCESS;
}
DEFUN (no_ospf_area_export_list,
no_ospf_area_export_list_cmd,
- "no area (A.B.C.D|<0-4294967295>) export-list NAME",
+ "no area <A.B.C.D|(0-4294967295)> export-list NAME",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -2001,15 +1771,13 @@ DEFUN (no_ospf_area_export_list,
"Unset the filter for networks announced to other areas\n"
"Name of the access-list\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
struct ospf_area *area;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_lookup_by_area_id (ospf, area_id);
if (area == NULL)
@@ -2023,32 +1791,30 @@ DEFUN (no_ospf_area_export_list,
DEFUN (ospf_area_import_list,
ospf_area_import_list_cmd,
- "area (A.B.C.D|<0-4294967295>) import-list NAME",
+ "area <A.B.C.D|(0-4294967295)> import-list NAME",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Set the filter for networks from other areas announced to the specified one\n"
"Name of the access-list\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
struct ospf_area *area;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_get (ospf, area_id, format);
- ospf_area_import_list_set (ospf, area, argv[1]);
+ ospf_area_import_list_set (ospf, area, argv[3]->arg);
return CMD_SUCCESS;
}
DEFUN (no_ospf_area_import_list,
no_ospf_area_import_list_cmd,
- "no area (A.B.C.D|<0-4294967295>) import-list NAME",
+ "no area <A.B.C.D|(0-4294967295)> import-list NAME",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -2056,15 +1822,13 @@ DEFUN (no_ospf_area_import_list,
"Unset the filter for networks announced to other areas\n"
"Name of the access-list\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
struct ospf_area *area;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_lookup_by_area_id (ospf, area_id);
if (area == NULL)
@@ -2077,7 +1841,7 @@ DEFUN (no_ospf_area_import_list,
DEFUN (ospf_area_filter_list,
ospf_area_filter_list_cmd,
- "area (A.B.C.D|<0-4294967295>) filter-list prefix WORD (in|out)",
+ "area <A.B.C.D|(0-4294967295)> filter-list prefix WORD <in|out>",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -2087,26 +1851,26 @@ DEFUN (ospf_area_filter_list,
"Filter networks sent to this area\n"
"Filter networks sent from this area\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
+ int idx_word = 4;
+ int idx_in_out = 5;
struct ospf_area *area;
struct in_addr area_id;
struct prefix_list *plist;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_get (ospf, area_id, format);
- plist = prefix_list_lookup (AFI_IP, argv[1]);
- if (strncmp (argv[2], "in", 2) == 0)
+ plist = prefix_list_lookup (AFI_IP, argv[idx_word]->arg);
+ if (strncmp (argv[idx_in_out]->arg, "in", 2) == 0)
{
PREFIX_LIST_IN (area) = plist;
if (PREFIX_NAME_IN (area))
free (PREFIX_NAME_IN (area));
- PREFIX_NAME_IN (area) = strdup (argv[1]);
+ PREFIX_NAME_IN (area) = strdup (argv[idx_word]->arg);
ospf_schedule_abr_task (ospf);
}
else
@@ -2115,7 +1879,7 @@ DEFUN (ospf_area_filter_list,
if (PREFIX_NAME_OUT (area))
free (PREFIX_NAME_OUT (area));
- PREFIX_NAME_OUT (area) = strdup (argv[1]);
+ PREFIX_NAME_OUT (area) = strdup (argv[idx_word]->arg);
ospf_schedule_abr_task (ospf);
}
@@ -2124,7 +1888,7 @@ DEFUN (ospf_area_filter_list,
DEFUN (no_ospf_area_filter_list,
no_ospf_area_filter_list_cmd,
- "no area (A.B.C.D|<0-4294967295>) filter-list prefix WORD (in|out)",
+ "no area <A.B.C.D|(0-4294967295)> filter-list prefix WORD <in|out>",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -2135,23 +1899,23 @@ DEFUN (no_ospf_area_filter_list,
"Filter networks sent to this area\n"
"Filter networks sent from this area\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
+ int idx_word = 5;
+ int idx_in_out = 6;
struct ospf_area *area;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
if ((area = ospf_area_lookup_by_area_id (ospf, area_id)) == NULL)
return CMD_SUCCESS;
- if (strncmp (argv[2], "in", 2) == 0)
+ if (strncmp (argv[idx_in_out]->arg, "in", 2) == 0)
{
if (PREFIX_NAME_IN (area))
- if (strcmp (PREFIX_NAME_IN (area), argv[1]) != 0)
+ if (strcmp (PREFIX_NAME_IN (area), argv[idx_word]->arg) != 0)
return CMD_SUCCESS;
PREFIX_LIST_IN (area) = NULL;
@@ -2165,7 +1929,7 @@ DEFUN (no_ospf_area_filter_list,
else
{
if (PREFIX_NAME_OUT (area))
- if (strcmp (PREFIX_NAME_OUT (area), argv[1]) != 0)
+ if (strcmp (PREFIX_NAME_OUT (area), argv[idx_word]->arg) != 0)
return CMD_SUCCESS;
PREFIX_LIST_OUT (area) = NULL;
@@ -2183,22 +1947,20 @@ DEFUN (no_ospf_area_filter_list,
DEFUN (ospf_area_authentication_message_digest,
ospf_area_authentication_message_digest_cmd,
- "area (A.B.C.D|<0-4294967295>) authentication message-digest",
+ "area <A.B.C.D|(0-4294967295)> authentication message-digest",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Enable authentication\n"
"Use message-digest authentication\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
struct ospf_area *area;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_get (ospf, area_id, format);
area->auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
@@ -2208,21 +1970,19 @@ DEFUN (ospf_area_authentication_message_digest,
DEFUN (ospf_area_authentication,
ospf_area_authentication_cmd,
- "area (A.B.C.D|<0-4294967295>) authentication",
+ "area <A.B.C.D|(0-4294967295)> authentication",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Enable authentication\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 1;
struct ospf_area *area;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_get (ospf, area_id, format);
area->auth_type = OSPF_AUTH_SIMPLE;
@@ -2232,22 +1992,20 @@ DEFUN (ospf_area_authentication,
DEFUN (no_ospf_area_authentication,
no_ospf_area_authentication_cmd,
- "no area (A.B.C.D|<0-4294967295>) authentication",
+ "no area <A.B.C.D|(0-4294967295)> authentication",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
"Enable authentication\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4_number = 2;
struct ospf_area *area;
struct in_addr area_id;
int format;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg);
area = ospf_area_lookup_by_area_id (ospf, area_id);
if (area == NULL)
@@ -2263,7 +2021,7 @@ DEFUN (no_ospf_area_authentication,
DEFUN (ospf_abr_type,
ospf_abr_type_cmd,
- "ospf abr-type (cisco|ibm|shortcut|standard)",
+ "ospf abr-type <cisco|ibm|shortcut|standard>",
"OSPF specific commands\n"
"Set OSPF ABR type\n"
"Alternative ABR, cisco implementation\n"
@@ -2271,19 +2029,17 @@ DEFUN (ospf_abr_type,
"Shortcut ABR\n"
"Standard behavior (RFC2328)\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_vendor = 2;
u_char abr_type = OSPF_ABR_UNKNOWN;
- if (!ospf)
- return CMD_SUCCESS;
-
- if (strncmp (argv[0], "c", 1) == 0)
+ if (strncmp (argv[idx_vendor]->arg, "c", 1) == 0)
abr_type = OSPF_ABR_CISCO;
- else if (strncmp (argv[0], "i", 1) == 0)
+ else if (strncmp (argv[idx_vendor]->arg, "i", 1) == 0)
abr_type = OSPF_ABR_IBM;
- else if (strncmp (argv[0], "sh", 2) == 0)
+ else if (strncmp (argv[idx_vendor]->arg, "sh", 2) == 0)
abr_type = OSPF_ABR_SHORTCUT;
- else if (strncmp (argv[0], "st", 2) == 0)
+ else if (strncmp (argv[idx_vendor]->arg, "st", 2) == 0)
abr_type = OSPF_ABR_STAND;
else
return CMD_WARNING;
@@ -2300,27 +2056,26 @@ DEFUN (ospf_abr_type,
DEFUN (no_ospf_abr_type,
no_ospf_abr_type_cmd,
- "no ospf abr-type (cisco|ibm|shortcut|standard)",
+ "no ospf abr-type <cisco|ibm|shortcut|standard>",
NO_STR
"OSPF specific commands\n"
"Set OSPF ABR type\n"
"Alternative ABR, cisco implementation\n"
"Alternative ABR, IBM implementation\n"
- "Shortcut ABR\n")
+ "Shortcut ABR\n"
+ "Standard ABR\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_vendor = 3;
u_char abr_type = OSPF_ABR_UNKNOWN;
- if (!ospf)
- return CMD_SUCCESS;
-
- if (strncmp (argv[0], "c", 1) == 0)
+ if (strncmp (argv[idx_vendor]->arg, "c", 1) == 0)
abr_type = OSPF_ABR_CISCO;
- else if (strncmp (argv[0], "i", 1) == 0)
+ else if (strncmp (argv[idx_vendor]->arg, "i", 1) == 0)
abr_type = OSPF_ABR_IBM;
- else if (strncmp (argv[0], "sh", 2) == 0)
+ else if (strncmp (argv[idx_vendor]->arg, "sh", 2) == 0)
abr_type = OSPF_ABR_SHORTCUT;
- else if (strncmp (argv[0], "st", 2) == 0)
+ else if (strncmp (argv[idx_vendor]->arg, "st", 2) == 0)
abr_type = OSPF_ABR_STAND;
else
return CMD_WARNING;
@@ -2340,10 +2095,7 @@ DEFUN (ospf_log_adjacency_changes,
"log-adjacency-changes",
"Log changes in adjacency state\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
@@ -2356,10 +2108,7 @@ DEFUN (ospf_log_adjacency_changes_detail,
"Log changes in adjacency state\n"
"Log all state changes\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
@@ -2372,10 +2121,7 @@ DEFUN (no_ospf_log_adjacency_changes,
NO_STR
"Log changes in adjacency state\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
@@ -2389,10 +2135,7 @@ DEFUN (no_ospf_log_adjacency_changes_detail,
"Log changes in adjacency state\n"
"Log all state changes\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
@@ -2405,10 +2148,7 @@ DEFUN (ospf_compatible_rfc1583,
"OSPF compatibility list\n"
"compatible with RFC 1583\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
{
@@ -2425,10 +2165,7 @@ DEFUN (no_ospf_compatible_rfc1583,
"OSPF compatibility list\n"
"compatible with RFC 1583\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
{
@@ -2439,27 +2176,24 @@ DEFUN (no_ospf_compatible_rfc1583,
}
ALIAS (ospf_compatible_rfc1583,
- ospf_rfc1583_flag_cmd,
- "ospf rfc1583compatibility",
- "OSPF specific commands\n"
- "Enable the RFC1583Compatibility flag\n")
+ ospf_rfc1583_flag_cmd,
+ "ospf rfc1583compatibility",
+ "OSPF specific commands\n"
+ "Enable the RFC1583Compatibility flag\n")
ALIAS (no_ospf_compatible_rfc1583,
- no_ospf_rfc1583_flag_cmd,
- "no ospf rfc1583compatibility",
- NO_STR
- "OSPF specific commands\n"
- "Disable the RFC1583Compatibility flag\n")
+ no_ospf_rfc1583_flag_cmd,
+ "no ospf rfc1583compatibility",
+ NO_STR
+ "OSPF specific commands\n"
+ "Disable the RFC1583Compatibility flag\n")
static int
ospf_timers_spf_set (struct vty *vty, unsigned int delay,
unsigned int hold,
unsigned int max)
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
ospf->spf_delay = delay;
ospf->spf_holdtime = hold;
@@ -2470,26 +2204,24 @@ ospf_timers_spf_set (struct vty *vty, unsigned int delay,
DEFUN (ospf_timers_min_ls_interval,
ospf_timers_min_ls_interval_cmd,
- "timers throttle lsa all <0-5000>",
+ "timers throttle lsa all (0-5000)",
"Adjust routing timers\n"
"Throttling adaptive timer\n"
"LSA delay between transmissions\n"
"All LSA types\n"
"Delay (msec) between sending LSAs\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 4;
unsigned int interval;
- if (!ospf)
- return CMD_SUCCESS;
-
if (argc != 1)
{
vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_INTEGER ("LSA interval", interval, argv[0]);
+ VTY_GET_INTEGER ("LSA interval", interval, argv[idx_number]->arg);
ospf->min_ls_interval = interval;
@@ -2498,50 +2230,40 @@ DEFUN (ospf_timers_min_ls_interval,
DEFUN (no_ospf_timers_min_ls_interval,
no_ospf_timers_min_ls_interval_cmd,
- "no timers throttle lsa all",
+ "no timers throttle lsa all [(0-5000)]",
NO_STR
"Adjust routing timers\n"
"Throttling adaptive timer\n"
"LSA delay between transmissions\n"
- "All LSA types\n")
+ "All LSA types\n"
+ "Delay (msec) between sending LSAs\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL;
return CMD_SUCCESS;
}
-ALIAS (no_ospf_timers_min_ls_interval,
- no_ospf_timers_min_ls_interval_val_cmd,
- "no timers throttle lsa all <0-5000>",
- NO_STR
- "Adjust routing timers\n"
- "Throttling adaptive timer\n"
- "LSA delay between transmissions\n"
- "All LSA types\n"
- "Delay (msec) between sending LSAs\n")
DEFUN (ospf_timers_min_ls_arrival,
ospf_timers_min_ls_arrival_cmd,
- "timers lsa arrival <0-1000>",
+ "timers lsa arrival (0-1000)",
"Adjust routing timers\n"
"Throttling link state advertisement delays\n"
"OSPF minimum arrival interval delay\n"
"Delay (msec) between accepted LSAs\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 3;
unsigned int arrival;
- if (!ospf)
- return CMD_SUCCESS;
-
if (argc != 1)
{
vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_INTEGER_RANGE ("minimum LSA inter-arrival time", arrival, argv[0], 0, 1000);
+ VTY_GET_INTEGER_RANGE ("minimum LSA inter-arrival time", arrival, argv[idx_number]->arg, 0, 1000);
ospf->min_ls_arrival = arrival;
@@ -2550,34 +2272,24 @@ DEFUN (ospf_timers_min_ls_arrival,
DEFUN (no_ospf_timers_min_ls_arrival,
no_ospf_timers_min_ls_arrival_cmd,
- "no timers lsa arrival",
+ "no timers lsa arrival [(0-1000)]",
NO_STR
"Adjust routing timers\n"
"Throttling link state advertisement delays\n"
- "OSPF minimum arrival interval delay\n")
+ "OSPF minimum arrival interval delay\n"
+ "Delay (msec) between accepted LSAs\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
return CMD_SUCCESS;
}
-ALIAS (no_ospf_timers_min_ls_arrival,
- no_ospf_timers_min_ls_arrival_val_cmd,
- "no timers lsa arrival <0-1000>",
- NO_STR
- "Adjust routing timers\n"
- "Throttling link state advertisement delays\n"
- "OSPF minimum arrival interval delay\n"
- "Delay (msec) between accepted LSAs\n")
DEFUN (ospf_timers_throttle_spf,
ospf_timers_throttle_spf_cmd,
- "timers throttle spf <0-600000> <0-600000> <0-600000>",
+ "timers throttle spf (0-600000) (0-600000) (0-600000)",
"Adjust routing timers\n"
"Throttling adaptive timer\n"
"OSPF SPF timers\n"
@@ -2585,6 +2297,9 @@ DEFUN (ospf_timers_throttle_spf,
"Initial hold time (msec) between consecutive SPF calculations\n"
"Maximum hold time (msec)\n")
{
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 5;
unsigned int delay, hold, max;
if (argc != 3)
@@ -2593,20 +2308,23 @@ DEFUN (ospf_timers_throttle_spf,
return CMD_WARNING;
}
- VTY_GET_INTEGER_RANGE ("SPF delay timer", delay, argv[0], 0, 600000);
- VTY_GET_INTEGER_RANGE ("SPF hold timer", hold, argv[1], 0, 600000);
- VTY_GET_INTEGER_RANGE ("SPF max-hold timer", max, argv[2], 0, 600000);
+ VTY_GET_INTEGER_RANGE ("SPF delay timer", delay, argv[idx_number]->arg, 0, 600000);
+ VTY_GET_INTEGER_RANGE ("SPF hold timer", hold, argv[idx_number_2]->arg, 0, 600000);
+ VTY_GET_INTEGER_RANGE ("SPF max-hold timer", max, argv[idx_number_3]->arg, 0, 600000);
return ospf_timers_spf_set (vty, delay, hold, max);
}
DEFUN (no_ospf_timers_throttle_spf,
no_ospf_timers_throttle_spf_cmd,
- "no timers throttle spf",
+ "no timers throttle spf [(0-600000)(0-600000)(0-600000)]",
NO_STR
"Adjust routing timers\n"
"Throttling adaptive timer\n"
- "OSPF SPF timers\n")
+ "OSPF SPF timers\n"
+ "Delay (msec) from first change received till SPF calculation\n"
+ "Initial hold time (msec) between consecutive SPF calculations\n"
+ "Maximum hold time (msec)\n")
{
return ospf_timers_spf_set (vty,
OSPF_SPF_DELAY_DEFAULT,
@@ -2614,30 +2332,18 @@ DEFUN (no_ospf_timers_throttle_spf,
OSPF_SPF_MAX_HOLDTIME_DEFAULT);
}
-ALIAS (no_ospf_timers_throttle_spf,
- no_ospf_timers_throttle_spf_val_cmd,
- "no timers throttle spf <0-600000> <0-600000> <0-600000>",
- NO_STR
- "Adjust routing timers\n"
- "Throttling adaptive timer\n"
- "OSPF SPF timers\n"
- "Delay (msec) from first change received till SPF calculation\n"
- "Initial hold time (msec) between consecutive SPF calculations\n"
- "Maximum hold time (msec)\n")
DEFUN (ospf_timers_lsa,
ospf_timers_lsa_cmd,
- "timers lsa min-arrival <0-600000>",
+ "timers lsa min-arrival (0-600000)",
"Adjust routing timers\n"
"OSPF LSA timers\n"
"Minimum delay in receiving new version of a LSA\n"
"Delay in milliseconds\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 3;
unsigned int minarrival;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
if (argc != 1)
{
@@ -2645,7 +2351,7 @@ DEFUN (ospf_timers_lsa,
return CMD_WARNING;
}
- VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]);
+ VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[idx_number]->arg);
ospf->min_ls_arrival = minarrival;
@@ -2654,21 +2360,19 @@ DEFUN (ospf_timers_lsa,
DEFUN (no_ospf_timers_lsa,
no_ospf_timers_lsa_cmd,
- "no timers lsa min-arrival",
+ "no timers lsa min-arrival [(0-600000)]",
NO_STR
"Adjust routing timers\n"
"OSPF LSA timers\n"
- "Minimum delay in receiving new version of a LSA\n")
+ "Minimum delay in receiving new version of a LSA\n"
+ "Delay in milliseconds\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
unsigned int minarrival;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
- if (argc)
+ if (argc > 4)
{
- VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]);
+ VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[4]->arg);
if (ospf->min_ls_arrival != minarrival ||
minarrival == OSPF_MIN_LS_ARRIVAL)
@@ -2680,181 +2384,133 @@ DEFUN (no_ospf_timers_lsa,
return CMD_SUCCESS;
}
-ALIAS (no_ospf_timers_lsa,
- no_ospf_timers_lsa_val_cmd,
- "no timers lsa min-arrival <0-600000>",
- NO_STR
- "Adjust routing timers\n"
- "OSPF LSA timers\n"
- "Minimum delay in receiving new version of a LSA\n"
- "Delay in milliseconds\n")
-
-
DEFUN (ospf_neighbor,
ospf_neighbor_cmd,
- "neighbor A.B.C.D",
+ "neighbor A.B.C.D [priority (0-255) [poll-interval (1-65535)]]",
NEIGHBOR_STR
- "Neighbor IP address\n")
+ "Neighbor IP address\n"
+ "Neighbor Priority\n"
+ "Priority\n"
+ "Dead Neighbor Polling interval\n"
+ "Seconds\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4 = 1;
+ int idx_pri = 3;
+ int idx_poll = 5;
struct in_addr nbr_addr;
unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[0]);
-
- if (argc > 1)
- VTY_GET_INTEGER_RANGE ("neighbor priority", priority, argv[1], 0, 255);
+ VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[idx_ipv4]->arg);
if (argc > 2)
- VTY_GET_INTEGER_RANGE ("poll interval", interval, argv[2], 1, 65535);
+ VTY_GET_INTEGER_RANGE ("neighbor priority", priority, argv[idx_pri]->arg, 0, 255);
+
+ if (argc > 4)
+ VTY_GET_INTEGER_RANGE ("poll interval", interval, argv[idx_poll]->arg, 1, 65535);
ospf_nbr_nbma_set (ospf, nbr_addr);
- if (argc > 1)
- ospf_nbr_nbma_priority_set (ospf, nbr_addr, priority);
+
if (argc > 2)
+ ospf_nbr_nbma_priority_set (ospf, nbr_addr, priority);
+
+ if (argc > 4)
ospf_nbr_nbma_poll_interval_set (ospf, nbr_addr, interval);
return CMD_SUCCESS;
}
-ALIAS (ospf_neighbor,
- ospf_neighbor_priority_poll_interval_cmd,
- "neighbor A.B.C.D priority <0-255> poll-interval <1-65535>",
- NEIGHBOR_STR
- "Neighbor IP address\n"
- "Neighbor Priority\n"
- "Priority\n"
- "Dead Neighbor Polling interval\n"
- "Seconds\n")
-
-ALIAS (ospf_neighbor,
- ospf_neighbor_priority_cmd,
- "neighbor A.B.C.D priority <0-255>",
- NEIGHBOR_STR
- "Neighbor IP address\n"
- "Neighbor Priority\n"
- "Seconds\n")
-
DEFUN (ospf_neighbor_poll_interval,
ospf_neighbor_poll_interval_cmd,
- "neighbor A.B.C.D poll-interval <1-65535>",
+ "neighbor A.B.C.D poll-interval (1-65535) [priority (0-255)]",
NEIGHBOR_STR
"Neighbor IP address\n"
"Dead Neighbor Polling interval\n"
- "Seconds\n")
+ "Seconds\n"
+ "OSPF priority of non-broadcast neighbor\n"
+ "Priority\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4 = 1;
+ int idx_poll = 3;
+ int idx_pri = 5;
struct in_addr nbr_addr;
unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT;
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[idx_ipv4]->arg);
- VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[0]);
+ VTY_GET_INTEGER_RANGE ("poll interval", interval, argv[idx_poll]->arg, 1, 65535);
- if (argc > 1)
- VTY_GET_INTEGER_RANGE ("poll interval", interval, argv[1], 1, 65535);
-
- if (argc > 2)
- VTY_GET_INTEGER_RANGE ("neighbor priority", priority, argv[2], 0, 255);
+ if (argc > 4)
+ VTY_GET_INTEGER_RANGE ("neighbor priority", priority, argv[idx_pri]->arg, 0, 255);
ospf_nbr_nbma_set (ospf, nbr_addr);
- if (argc > 1)
- ospf_nbr_nbma_poll_interval_set (ospf, nbr_addr, interval);
- if (argc > 2)
+ ospf_nbr_nbma_poll_interval_set (ospf, nbr_addr, interval);
+
+ if (argc > 4)
ospf_nbr_nbma_priority_set (ospf, nbr_addr, priority);
return CMD_SUCCESS;
}
-ALIAS (ospf_neighbor_poll_interval,
- ospf_neighbor_poll_interval_priority_cmd,
- "neighbor A.B.C.D poll-interval <1-65535> priority <0-255>",
- NEIGHBOR_STR
- "Neighbor address\n"
- "OSPF dead-router polling interval\n"
- "Seconds\n"
- "OSPF priority of non-broadcast neighbor\n"
- "Priority\n")
-
DEFUN (no_ospf_neighbor,
no_ospf_neighbor_cmd,
- "no neighbor A.B.C.D",
+ "no neighbor A.B.C.D [priority (0-255) [poll-interval (1-65525)]]",
NO_STR
NEIGHBOR_STR
- "Neighbor IP address\n")
+ "Neighbor IP address\n"
+ "Neighbor Priority\n"
+ "Priority\n"
+ "Dead Neighbor Polling interval\n"
+ "Seconds\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4 = 2;
struct in_addr nbr_addr;
- if (!ospf)
- return CMD_SUCCESS;
-
- VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[0]);
+ VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[idx_ipv4]->arg);
(void)ospf_nbr_nbma_unset (ospf, nbr_addr);
return CMD_SUCCESS;
}
-ALIAS (no_ospf_neighbor,
- no_ospf_neighbor_priority_cmd,
- "no neighbor A.B.C.D priority <0-255>",
+DEFUN (no_ospf_neighbor_poll,
+ no_ospf_neighbor_poll_cmd,
+ "no neighbor A.B.C.D poll-interval (1-65535) [priority (0-255)]",
NO_STR
NEIGHBOR_STR
"Neighbor IP address\n"
+ "Dead Neighbor Polling interval\n"
+ "Seconds\n"
"Neighbor Priority\n"
"Priority\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ipv4 = 2;
+ struct in_addr nbr_addr;
-ALIAS (no_ospf_neighbor,
- no_ospf_neighbor_poll_interval_cmd,
- "no neighbor A.B.C.D poll-interval <1-65535>",
- NO_STR
- NEIGHBOR_STR
- "Neighbor IP address\n"
- "Dead Neighbor Polling interval\n"
- "Seconds\n")
+ VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[idx_ipv4]->arg);
-ALIAS (no_ospf_neighbor,
- no_ospf_neighbor_poll_interval_priority_cmd,
- "no neighbor A.B.C.D poll-interval <1-65535> priority <0-255>",
- NO_STR
- NEIGHBOR_STR
- "Neighbor IP address\n"
- "Dead Neighbor Polling interval\n"
- "Seconds\n"
- "OSPF priority of non-broadcast neighbor\n"
- "Priority\n")
+ (void)ospf_nbr_nbma_unset (ospf, nbr_addr);
-ALIAS (no_ospf_neighbor,
- no_ospf_neighbor_priority_pollinterval_cmd,
- "no neighbor A.B.C.D priority <0-255> poll-interval <1-65535>",
- NO_STR
- NEIGHBOR_STR
- "Neighbor IP address\n"
- "Neighbor Priority\n"
- "Priority\n"
- "Dead Neighbor Polling interval\n"
- "Seconds\n")
+ return CMD_SUCCESS;
+}
-DEFUN (ospf_refresh_timer, ospf_refresh_timer_cmd,
- "refresh timer <10-1800>",
+DEFUN (ospf_refresh_timer,
+ ospf_refresh_timer_cmd,
+ "refresh timer (10-1800)",
"Adjust refresh parameters\n"
"Set refresh timer\n"
"Timer value in seconds\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 2;
unsigned int interval;
-
- if (!ospf)
- return CMD_SUCCESS;
- VTY_GET_INTEGER_RANGE ("refresh timer", interval, argv[0], 10, 1800);
+ VTY_GET_INTEGER_RANGE ("refresh timer", interval, argv[idx_number]->arg, 10, 1800);
interval = (interval / OSPF_LSA_REFRESHER_GRANULARITY) * OSPF_LSA_REFRESHER_GRANULARITY;
ospf_timers_refresh_set (ospf, interval);
@@ -2862,21 +2518,21 @@ DEFUN (ospf_refresh_timer, ospf_refresh_timer_cmd,
return CMD_SUCCESS;
}
-DEFUN (no_ospf_refresh_timer, no_ospf_refresh_timer_val_cmd,
- "no refresh timer <10-1800>",
+DEFUN (no_ospf_refresh_timer,
+ no_ospf_refresh_timer_val_cmd,
+ "no refresh timer [(10-1800)]",
+ NO_STR
"Adjust refresh parameters\n"
"Unset refresh timer\n"
"Timer value in seconds\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 3;
unsigned int interval;
- if (!ospf)
- return CMD_SUCCESS;
-
if (argc == 1)
{
- VTY_GET_INTEGER_RANGE ("refresh timer", interval, argv[0], 10, 1800);
+ VTY_GET_INTEGER_RANGE ("refresh timer", interval, argv[idx_number]->arg, 10, 1800);
if (ospf->lsa_refresh_interval != interval ||
interval == OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
@@ -2888,28 +2544,21 @@ DEFUN (no_ospf_refresh_timer, no_ospf_refresh_timer_val_cmd,
return CMD_SUCCESS;
}
-ALIAS (no_ospf_refresh_timer,
- no_ospf_refresh_timer_cmd,
- "no refresh timer",
- "Adjust refresh parameters\n"
- "Unset refresh timer\n")
DEFUN (ospf_auto_cost_reference_bandwidth,
ospf_auto_cost_reference_bandwidth_cmd,
- "auto-cost reference-bandwidth <1-4294967>",
+ "auto-cost reference-bandwidth (1-4294967)",
"Calculate OSPF interface cost according to bandwidth\n"
"Use reference bandwidth method to assign OSPF cost\n"
"The reference bandwidth in terms of Mbits per second\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 2;
u_int32_t refbw;
struct listnode *node;
struct interface *ifp;
- if (!ospf)
- return CMD_SUCCESS;
-
- refbw = strtol (argv[0], NULL, 10);
+ refbw = strtol (argv[idx_number]->arg, NULL, 10);
if (refbw < 1 || refbw > 4294967)
{
vty_out (vty, "reference-bandwidth value is invalid%s", VTY_NEWLINE);
@@ -2929,18 +2578,16 @@ DEFUN (ospf_auto_cost_reference_bandwidth,
DEFUN (no_ospf_auto_cost_reference_bandwidth,
no_ospf_auto_cost_reference_bandwidth_cmd,
- "no auto-cost reference-bandwidth",
+ "no auto-cost reference-bandwidth [(1-4294967)]",
NO_STR
"Calculate OSPF interface cost according to bandwidth\n"
- "Use reference bandwidth method to assign OSPF cost\n")
+ "Use reference bandwidth method to assign OSPF cost\n"
+ "The reference bandwidth in terms of Mbits per second\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
struct listnode *node, *nnode;
struct interface *ifp;
- if (!ospf)
- return CMD_SUCCESS;
-
if (ospf->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH)
return CMD_SUCCESS;
@@ -2954,28 +2601,23 @@ DEFUN (no_ospf_auto_cost_reference_bandwidth,
return CMD_SUCCESS;
}
-ALIAS (no_ospf_auto_cost_reference_bandwidth,
- no_ospf_auto_cost_reference_bandwidth_val_cmd,
- "no auto-cost reference-bandwidth <1-4294967>",
- NO_STR
- "Calculate OSPF interface cost according to bandwidth\n"
- "Use reference bandwidth method to assign OSPF cost\n"
- "The reference bandwidth in terms of Mbits per second\n")
-
DEFUN (ospf_write_multiplier,
ospf_write_multiplier_cmd,
- "ospf write-multiplier <1-100>",
+ "ospf write-multiplier (1-100)",
"OSPF specific commands\n"
"Write multiplier\n"
"Maximum number of interface serviced per write\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number;
u_int32_t write_oi_count;
- if (!ospf)
- return CMD_SUCCESS;
+ if (argc == 3)
+ idx_number = 2;
+ else
+ idx_number = 1;
- write_oi_count = strtol (argv[0], NULL, 10);
+ write_oi_count = strtol (argv[idx_number]->arg, NULL, 10);
if (write_oi_count < 1 || write_oi_count > 100)
{
vty_out (vty, "write-multiplier value is invalid%s", VTY_NEWLINE);
@@ -2987,40 +2629,31 @@ DEFUN (ospf_write_multiplier,
}
ALIAS (ospf_write_multiplier,
- write_multiplier_cmd,
- "write-multiplier <1-100>",
- "Write multiplier\n"
- "Maximum number of interface serviced per write\n")
+ write_multiplier_cmd,
+ "write-multiplier (1-100)",
+ "Write multiplier\n"
+ "Maximum number of interface serviced per write\n")
DEFUN (no_ospf_write_multiplier,
no_ospf_write_multiplier_cmd,
- "no ospf write-multiplier <1-100>",
+ "no ospf write-multiplier (1-100)",
NO_STR
"OSPF specific commands\n"
"Write multiplier\n"
"Maximum number of interface serviced per write\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
ospf->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
return CMD_SUCCESS;
}
ALIAS (no_ospf_write_multiplier,
- no_write_multiplier_cmd,
- "no write-multiplier",
- NO_STR
- "Write multiplier\n")
-
-ALIAS (no_ospf_write_multiplier,
- no_write_multiplier_val_cmd,
- "no write-multiplier <1-100>",
- NO_STR
- "Write multiplier\n"
- "Maximum number of interface serviced per write\n")
+ no_write_multiplier_cmd,
+ "no write-multiplier (1-100)",
+ NO_STR
+ "Write multiplier\n"
+ "Maximum number of interface serviced per write\n")
const char *ospf_abr_type_descr_str[] =
{
@@ -3177,10 +2810,8 @@ show_ip_ospf_area (struct vty *vty, struct ospf_area *area, json_object *json_ar
json_object_boolean_true_add(json_area, "indefiniteActiveAdmin");
if (area->t_stub_router)
{
- struct timeval result;
- unsigned long time_store = 0;
- result = tv_sub (area->t_stub_router->u.sands, recent_relative_time());
- time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000);
+ long time_store;
+ time_store = monotime_until(&area->t_stub_router->u.sands, NULL) / 1000LL;
json_object_int_add(json_area, "activeStartupRemainderMsecs", time_store);
}
}
@@ -3339,9 +2970,8 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json)
{
if (use_json)
{
- unsigned long time_store = 0;
- result = tv_sub (ospf->t_deferred_shutdown->u.sands, recent_relative_time());
- time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000);
+ long time_store;
+ time_store = monotime_until(&ospf->t_deferred_shutdown->u.sands, NULL) / 1000LL;
json_object_int_add(json, "deferredShutdownMsecs", time_store);
}
else
@@ -3434,11 +3064,9 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json)
{
if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec)
{
- unsigned long time_store = 0;
+ long time_store = 0;
- result = tv_sub (recent_relative_time(), ospf->ts_spf);
- result = tv_sub (result, recent_relative_time());
- time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000);
+ time_store = monotime_since(&ospf->ts_spf, NULL) / 1000LL;
json_object_int_add(json, "spfLastExecutedMsecs", time_store);
time_store = (1000 * ospf->ts_spf_duration.tv_sec) + (ospf->ts_spf_duration.tv_usec / 1000);
@@ -3452,7 +3080,7 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json)
vty_out (vty, " SPF algorithm ");
if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec)
{
- result = tv_sub (recent_relative_time(), ospf->ts_spf);
+ monotime_since(&ospf->ts_spf, &result);
vty_out (vty, "last executed %s ago%s",
ospf_timeval_dump (&result, timebuf, sizeof (timebuf)),
VTY_NEWLINE);
@@ -3466,13 +3094,10 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json)
if (use_json)
{
- struct timeval temp_time;
- unsigned long time_store = 0;
-
if (ospf->t_spf_calc)
{
- temp_time = tv_sub (ospf->t_spf_calc->u.sands, recent_relative_time());
- time_store = (1000 * temp_time.tv_sec) + (temp_time.tv_usec / 1000);
+ long time_store;
+ time_store = monotime_until(&ospf->t_spf_calc->u.sands, NULL) / 1000LL;
json_object_int_add(json, "spfTimerDueInMsecs", time_store);
}
@@ -3593,11 +3218,11 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json)
DEFUN (show_ip_ospf,
show_ip_ospf_cmd,
- "show ip ospf {json}",
+ "show ip ospf [json]",
SHOW_STR
IP_STR
"OSPF information\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
@@ -3610,18 +3235,19 @@ DEFUN (show_ip_ospf,
DEFUN (show_ip_ospf_instance,
show_ip_ospf_instance_cmd,
- "show ip ospf <1-65535> {json}",
+ "show ip ospf (1-65535) [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
u_char uj = use_json(argc, argv);
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -3876,16 +3502,9 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, struct interface
char timebuf[OSPF_TIME_DUMP_SIZE];
if (use_json)
{
- struct timeval result;
- unsigned long time_store = 0;
- if (oi->t_hello)
- result = tv_sub (oi->t_hello->u.sands, recent_relative_time());
- else
- {
- result.tv_sec = 0;
- result.tv_usec = 0;
- }
- time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000);
+ long time_store = 0;
+ if (oi->t_hello)
+ time_store = monotime_until(&oi->t_hello->u.sands, NULL) / 1000LL;
json_object_int_add(json_interface_sub, "timerHelloInMsecs", time_store);
}
else
@@ -3916,7 +3535,7 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, struct interface
static int
show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc,
- const char **argv, int iface_argv, u_char use_json)
+ struct cmd_token **argv, int iface_argv, u_char use_json)
{
struct interface *ifp;
struct listnode *node;
@@ -3951,7 +3570,7 @@ show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc,
}
}
}
- else if (argv[iface_argv] && strcmp(argv[iface_argv], "json") == 0)
+ else if (argv[iface_argv] && strcmp(argv[iface_argv]->arg, "json") == 0)
{
if (!use_json)
{
@@ -3973,7 +3592,7 @@ show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc,
else
{
/* Interface name is specified. */
- if ((ifp = if_lookup_by_name (argv[iface_argv])) == NULL)
+ if ((ifp = if_lookup_by_name (argv[iface_argv]->arg)) == NULL)
{
if (use_json)
json_object_boolean_true_add(json, "noSuchIface");
@@ -4001,13 +3620,13 @@ show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc,
DEFUN (show_ip_ospf_interface,
show_ip_ospf_interface_cmd,
- "show ip ospf interface [INTERFACE] {json}",
+ "show ip ospf interface [INTERFACE] [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Interface information\n"
"Interface name\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
@@ -4020,20 +3639,21 @@ DEFUN (show_ip_ospf_interface,
DEFUN (show_ip_ospf_instance_interface,
show_ip_ospf_instance_interface_cmd,
- "show ip ospf <1-65535> interface [INTERFACE] {json}",
+ "show ip ospf (1-65535) interface [INTERFACE] [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
"Interface information\n"
"Interface name\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
u_char uj = use_json(argc, argv);
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -4074,11 +3694,9 @@ show_ip_ospf_neighbor_sub (struct vty *vty, struct ospf_interface *oi, json_obje
json_neighbor = json_object_new_object();
ospf_nbr_state_message (nbr, msgbuf, 16);
- struct timeval result;
- unsigned long time_store = 0;
+ long time_store;
- result = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time());
- time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000);
+ time_store = monotime_until(&nbr->t_inactivity->u.sands, NULL) / 1000LL;
json_object_int_add (json_neighbor, "priority", nbr->priority);
json_object_string_add (json_neighbor, "state", msgbuf);
@@ -4158,12 +3776,12 @@ show_ip_ospf_neighbor_common (struct vty *vty, struct ospf *ospf, u_char use_jso
DEFUN (show_ip_ospf_neighbor,
show_ip_ospf_neighbor_cmd,
- "show ip ospf neighbor {json}",
+ "show ip ospf neighbor [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Neighbor list\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
@@ -4177,19 +3795,20 @@ DEFUN (show_ip_ospf_neighbor,
DEFUN (show_ip_ospf_instance_neighbor,
show_ip_ospf_instance_neighbor_cmd,
- "show ip ospf <1-65535> neighbor {json}",
+ "show ip ospf (1-65535) neighbor [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
"Neighbor list\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
u_char uj = use_json(argc, argv);
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -4269,13 +3888,13 @@ show_ip_ospf_neighbor_all_common (struct vty *vty, struct ospf *ospf, u_char use
DEFUN (show_ip_ospf_neighbor_all,
show_ip_ospf_neighbor_all_cmd,
- "show ip ospf neighbor all {json}",
+ "show ip ospf neighbor all [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Neighbor list\n"
"include down status neighbor\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
@@ -4288,20 +3907,21 @@ DEFUN (show_ip_ospf_neighbor_all,
DEFUN (show_ip_ospf_instance_neighbor_all,
show_ip_ospf_instance_neighbor_all_cmd,
- "show ip ospf <1-65535> neighbor all {json}",
+ "show ip ospf (1-65535) neighbor all [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
"Neighbor list\n"
"include down status neighbor\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
u_char uj = use_json(argc, argv);
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -4310,7 +3930,7 @@ DEFUN (show_ip_ospf_instance_neighbor_all,
static int
show_ip_ospf_neighbor_int_common (struct vty *vty, struct ospf *ospf, int arg_base,
- const char **argv, u_char use_json)
+ struct cmd_token **argv, u_char use_json)
{
struct interface *ifp;
struct route_node *rn;
@@ -4330,7 +3950,7 @@ show_ip_ospf_neighbor_int_common (struct vty *vty, struct ospf *ospf, int arg_ba
VTY_NEWLINE, VTY_NEWLINE);
}
- ifp = if_lookup_by_name (argv[arg_base]);
+ ifp = if_lookup_by_name (argv[arg_base]->arg);
if (!ifp)
{
if (use_json)
@@ -4363,13 +3983,13 @@ show_ip_ospf_neighbor_int_common (struct vty *vty, struct ospf *ospf, int arg_ba
DEFUN (show_ip_ospf_neighbor_int,
show_ip_ospf_neighbor_int_cmd,
- "show ip ospf neighbor IFNAME {json}",
+ "show ip ospf neighbor IFNAME [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Neighbor list\n"
"Interface name\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
@@ -4382,20 +4002,21 @@ DEFUN (show_ip_ospf_neighbor_int,
DEFUN (show_ip_ospf_instance_neighbor_int,
show_ip_ospf_instance_neighbor_int_cmd,
- "show ip ospf <1-65535> neighbor IFNAME {json}",
+ "show ip ospf (1-65535) neighbor IFNAME [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
"Neighbor list\n"
"Interface name\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
u_char uj = use_json(argc, argv);
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -4456,9 +4077,8 @@ show_ip_ospf_nbr_nbma_detail_sub (struct vty *vty, struct ospf_interface *oi, st
/* Show poll-interval timer. */
if (use_json)
{
- struct timeval res = tv_sub (nbr_nbma->t_poll->u.sands, recent_relative_time ());
- unsigned long time_store = 0;
- time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000);
+ long time_store;
+ time_store = monotime_until(&nbr_nbma->t_poll->u.sands, NULL) / 1000LL;
json_object_int_add(json_sub, "pollIntervalTimerDueMsec", time_store);
}
else
@@ -4533,11 +4153,12 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi,
if (nbr->ts_last_progress.tv_sec || nbr->ts_last_progress.tv_usec)
{
- struct timeval res = tv_sub (recent_relative_time (), nbr->ts_last_progress);
+ struct timeval res;
+ long time_store;
+
+ time_store = monotime_since(&nbr->ts_last_progress, &res) / 1000LL;
if (use_json)
{
- unsigned long time_store = 0;
- time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000);
json_object_int_add(json_sub, "lastPrgrsvChangeMsec", time_store);
}
else
@@ -4552,11 +4173,12 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi,
if (nbr->ts_last_regress.tv_sec || nbr->ts_last_regress.tv_usec)
{
- struct timeval res = tv_sub (recent_relative_time (), nbr->ts_last_regress);
+ struct timeval res;
+ long time_store;
+
+ time_store = monotime_since(&nbr->ts_last_regress, &res) / 1000LL;
if (use_json)
{
- unsigned long time_store = 0;
- time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000);
json_object_int_add(json_sub, "lastRegressiveChangeMsec", time_store);
if (nbr->last_regress_str)
json_object_string_add(json_sub, "lastRegressiveChangeReason", nbr->last_regress_str);
@@ -4597,9 +4219,8 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi,
{
if (nbr->t_inactivity)
{
- struct timeval res = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time ());
- unsigned long time_store = 0;
- time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000);
+ long time_store;
+ time_store = monotime_until(&nbr->t_inactivity->u.sands, NULL) / 1000LL;
json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", time_store);
}
else
@@ -4684,7 +4305,7 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi,
static int
show_ip_ospf_neighbor_id_common (struct vty *vty, struct ospf *ospf,
- int arg_base, const char **argv, u_char use_json)
+ int arg_base, struct cmd_token **argv, u_char use_json)
{
struct listnode *node;
struct ospf_neighbor *nbr;
@@ -4705,7 +4326,7 @@ show_ip_ospf_neighbor_id_common (struct vty *vty, struct ospf *ospf,
VTY_NEWLINE, VTY_NEWLINE);
}
- ret = inet_aton (argv[arg_base], &router_id);
+ ret = inet_aton (argv[arg_base]->arg, &router_id);
if (!ret)
{
if (!use_json)
@@ -4734,13 +4355,13 @@ show_ip_ospf_neighbor_id_common (struct vty *vty, struct ospf *ospf,
DEFUN (show_ip_ospf_neighbor_id,
show_ip_ospf_neighbor_id_cmd,
- "show ip ospf neighbor A.B.C.D {json}",
+ "show ip ospf neighbor A.B.C.D [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Neighbor list\n"
"Neighbor ID\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
@@ -4753,20 +4374,21 @@ DEFUN (show_ip_ospf_neighbor_id,
DEFUN (show_ip_ospf_instance_neighbor_id,
show_ip_ospf_instance_neighbor_id_cmd,
- "show ip ospf <1-65535> neighbor A.B.C.D {json}",
+ "show ip ospf (1-65535) neighbor A.B.C.D [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
"Neighbor list\n"
"Neighbor ID\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
u_char uj = use_json(argc, argv);
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -4825,13 +4447,13 @@ show_ip_ospf_neighbor_detail_common (struct vty *vty, struct ospf *ospf, u_char
DEFUN (show_ip_ospf_neighbor_detail,
show_ip_ospf_neighbor_detail_cmd,
- "show ip ospf neighbor detail {json}",
+ "show ip ospf neighbor detail [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Neighbor list\n"
"detail of all neighbors\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
@@ -4844,20 +4466,21 @@ DEFUN (show_ip_ospf_neighbor_detail,
DEFUN (show_ip_ospf_instance_neighbor_detail,
show_ip_ospf_instance_neighbor_detail_cmd,
- "show ip ospf <1-65535> neighbor detail {json}",
+ "show ip ospf (1-65535) neighbor detail [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
"Neighbor list\n"
"detail of all neighbors\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
u_char uj = use_json(argc, argv);
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -4922,14 +4545,14 @@ show_ip_ospf_neighbor_detail_all_common (struct vty *vty, struct ospf *ospf, u_c
DEFUN (show_ip_ospf_neighbor_detail_all,
show_ip_ospf_neighbor_detail_all_cmd,
- "show ip ospf neighbor detail all {json}",
+ "show ip ospf neighbor detail all [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Neighbor list\n"
"detail of all neighbors\n"
"include down status neighbor\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
@@ -4942,7 +4565,7 @@ DEFUN (show_ip_ospf_neighbor_detail_all,
DEFUN (show_ip_ospf_instance_neighbor_detail_all,
show_ip_ospf_instance_neighbor_detail_all_cmd,
- "show ip ospf <1-65535> neighbor detail all {json}",
+ "show ip ospf (1-65535) neighbor detail all [json]",
SHOW_STR
IP_STR
"OSPF information\n"
@@ -4950,13 +4573,14 @@ DEFUN (show_ip_ospf_instance_neighbor_detail_all,
"Neighbor list\n"
"detail of all neighbors\n"
"include down status neighbor\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
u_char uj = use_json(argc, argv);
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -4965,7 +4589,7 @@ DEFUN (show_ip_ospf_instance_neighbor_detail_all,
static int
show_ip_ospf_neighbor_int_detail_common (struct vty *vty, struct ospf *ospf,
- int arg_base, const char **argv, u_char use_json)
+ int arg_base, struct cmd_token **argv, u_char use_json)
{
struct ospf_interface *oi;
struct interface *ifp;
@@ -4985,7 +4609,7 @@ show_ip_ospf_neighbor_int_detail_common (struct vty *vty, struct ospf *ospf,
VTY_NEWLINE, VTY_NEWLINE);
}
- ifp = if_lookup_by_name (argv[arg_base]);
+ ifp = if_lookup_by_name (argv[arg_base]->arg);
if (!ifp)
{
if (!use_json)
@@ -5024,14 +4648,14 @@ show_ip_ospf_neighbor_int_detail_common (struct vty *vty, struct ospf *ospf,
DEFUN (show_ip_ospf_neighbor_int_detail,
show_ip_ospf_neighbor_int_detail_cmd,
- "show ip ospf neighbor IFNAME detail {json}",
+ "show ip ospf neighbor IFNAME detail [json]",
SHOW_STR
IP_STR
"OSPF information\n"
"Neighbor list\n"
"Interface name\n"
"detail of all neighbors\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
@@ -5044,7 +4668,7 @@ DEFUN (show_ip_ospf_neighbor_int_detail,
DEFUN (show_ip_ospf_instance_neighbor_int_detail,
show_ip_ospf_instance_neighbor_int_detail_cmd,
- "show ip ospf <1-65535> neighbor IFNAME detail {json}",
+ "show ip ospf (1-65535) neighbor IFNAME detail [json]",
SHOW_STR
IP_STR
"OSPF information\n"
@@ -5052,13 +4676,14 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail,
"Neighbor list\n"
"Interface name\n"
"detail of all neighbors\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
u_char uj = use_json(argc, argv);
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -5368,7 +4993,6 @@ show_as_external_lsa_detail (struct vty *vty, struct ospf_lsa *lsa)
return 0;
}
-
#if 0
static int
show_as_external_lsa_stdvty (struct ospf_lsa *lsa)
@@ -5394,7 +5018,6 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa)
return 0;
}
#endif
-
/* Show AS-NSSA-LSA detail information. */
static int
show_as_nssa_lsa_detail (struct vty *vty, struct ospf_lsa *lsa)
@@ -5681,11 +5304,6 @@ show_ip_ospf_database_maxage (struct vty *vty, struct ospf *ospf)
#define OSPF_LSA_TYPE_OPAQUE_AS_DESC "Link AS Opaque-LSA\n"
#define OSPF_LSA_TYPE_OPAQUE_CMD_STR "|opaque-link|opaque-area|opaque-as"
-#define OSPF_LSA_TYPES_CMD_STR \
- "asbr-summary|external|network|router|summary" \
- OSPF_LSA_TYPE_NSSA_CMD_STR \
- OSPF_LSA_TYPE_OPAQUE_CMD_STR
-
#define OSPF_LSA_TYPES_DESC \
"ASBR summary link states\n" \
"External link states\n" \
@@ -5699,8 +5317,9 @@ show_ip_ospf_database_maxage (struct vty *vty, struct ospf *ospf)
static int
show_ip_ospf_database_common (struct vty *vty, struct ospf *ospf,
- int arg_base, int argc, const char **argv)
+ int arg_base, int argc, struct cmd_token **argv)
{
+ int idx_type = 4;
int type, ret;
struct in_addr id, adv_router;
@@ -5712,64 +5331,64 @@ show_ip_ospf_database_common (struct vty *vty, struct ospf *ospf,
inet_ntoa (ospf->router_id), VTY_NEWLINE, VTY_NEWLINE);
/* Show all LSA. */
- if (argc == arg_base + 0)
+ if (argc == arg_base + 4)
{
show_ip_ospf_database_summary (vty, ospf, 0);
return CMD_SUCCESS;
}
/* Set database type to show. */
- if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ if (strncmp (argv[arg_base + idx_type]->text, "r", 1) == 0)
type = OSPF_ROUTER_LSA;
- else if (strncmp (argv[arg_base + 0], "ne", 2) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "ne", 2) == 0)
type = OSPF_NETWORK_LSA;
- else if (strncmp (argv[arg_base + 0], "ns", 2) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "ns", 2) == 0)
type = OSPF_AS_NSSA_LSA;
- else if (strncmp (argv[arg_base + 0], "su", 2) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "su", 2) == 0)
type = OSPF_SUMMARY_LSA;
- else if (strncmp (argv[arg_base + 0], "a", 1) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "a", 1) == 0)
type = OSPF_ASBR_SUMMARY_LSA;
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "e", 1) == 0)
type = OSPF_AS_EXTERNAL_LSA;
- else if (strncmp (argv[arg_base + 0], "se", 2) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "se", 2) == 0)
{
show_ip_ospf_database_summary (vty, ospf, 1);
return CMD_SUCCESS;
}
- else if (strncmp (argv[arg_base + 0], "m", 1) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "m", 1) == 0)
{
show_ip_ospf_database_maxage (vty, ospf);
return CMD_SUCCESS;
}
- else if (strncmp (argv[arg_base + 0], "opaque-l", 8) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "opaque-l", 8) == 0)
type = OSPF_OPAQUE_LINK_LSA;
- else if (strncmp (argv[arg_base + 0], "opaque-ar", 9) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0)
type = OSPF_OPAQUE_AREA_LSA;
- else if (strncmp (argv[arg_base + 0], "opaque-as", 9) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "opaque-as", 9) == 0)
type = OSPF_OPAQUE_AS_LSA;
else
return CMD_WARNING;
/* `show ip ospf database LSA'. */
- if (argc == arg_base + 1)
+ if (argc == arg_base + 5)
show_lsa_detail (vty, ospf, type, NULL, NULL);
- else if (argc >= arg_base + 2)
+ else if (argc >= arg_base + 6)
{
- ret = inet_aton (argv[arg_base + 1], &id);
+ ret = inet_aton (argv[arg_base + 5]->arg, &id);
if (!ret)
return CMD_WARNING;
/* `show ip ospf database LSA ID'. */
- if (argc == arg_base + 2)
+ if (argc == arg_base + 6)
show_lsa_detail (vty, ospf, type, &id, NULL);
/* `show ip ospf database LSA ID adv-router ADV_ROUTER'. */
- else if (argc == arg_base + 3)
+ else if (argc == arg_base + 7)
{
- if (strncmp (argv[arg_base + 2], "s", 1) == 0)
+ if (strncmp (argv[arg_base + 6]->text, "s", 1) == 0)
adv_router = ospf->router_id;
else
{
- ret = inet_aton (argv[arg_base + 2], &adv_router);
+ ret = inet_aton (argv[arg_base + 7]->arg, &adv_router);
if (!ret)
return CMD_WARNING;
}
@@ -5780,13 +5399,15 @@ show_ip_ospf_database_common (struct vty *vty, struct ospf *ospf,
return CMD_SUCCESS;
}
-DEFUN (show_ip_ospf_database,
- show_ip_ospf_database_cmd,
- "show ip ospf database",
+DEFUN (show_ip_ospf_database_max,
+ show_ip_ospf_database_max_cmd,
+ "show ip ospf database <max-age|self-originate>",
SHOW_STR
IP_STR
"OSPF information\n"
- "Database summary\n")
+ "Database summary\n"
+ "LSAs in MaxAge list\n"
+ "Self-originated link states\n")
{
struct ospf *ospf;
@@ -5796,125 +5417,68 @@ DEFUN (show_ip_ospf_database,
return (show_ip_ospf_database_common(vty, ospf, 0, argc, argv));
}
-ALIAS (show_ip_ospf_database,
- show_ip_ospf_database_type_cmd,
- "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR "|max-age|self-originate)",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Database summary\n"
- OSPF_LSA_TYPES_DESC
- "LSAs in MaxAge list\n"
- "Self-originated link states\n")
-
-ALIAS (show_ip_ospf_database,
- show_ip_ospf_database_type_id_cmd,
- "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Database summary\n"
- OSPF_LSA_TYPES_DESC
- "Link State ID (as an IP address)\n")
-
-ALIAS (show_ip_ospf_database,
- show_ip_ospf_database_type_id_adv_router_cmd,
- "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D adv-router A.B.C.D",
+DEFUN (show_ip_ospf_instance_database,
+ show_ip_ospf_instance_database_cmd,
+ "show ip ospf [(1-65535)] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]",
SHOW_STR
IP_STR
"OSPF information\n"
+ "Instance ID\n"
"Database summary\n"
- OSPF_LSA_TYPES_DESC
+ OSPF_LSA_TYPES_DESC
"Link State ID (as an IP address)\n"
+ "Self-originated link states\n"
"Advertising Router link states\n"
"Advertising Router (as an IP address)\n")
-
-ALIAS (show_ip_ospf_database,
- show_ip_ospf_database_type_id_self_cmd,
- "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D (self-originate|)",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Database summary\n"
- OSPF_LSA_TYPES_DESC
- "Link State ID (as an IP address)\n"
- "Self-originated link states\n"
- "\n")
-
-DEFUN (show_ip_ospf_instance_database,
- show_ip_ospf_instance_database_cmd,
- "show ip ospf <1-65535> database",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Instance ID\n"
- "Database summary\n")
{
struct ospf *ospf;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ int idx = 0;
+ if (argv_find (argv, argc, "(1-65535)", &idx))
+ {
+ VTY_GET_INTEGER ("Instance", instance, argv[idx]->arg);
+ ospf = ospf_lookup_instance (instance);
+ }
+ else {
+ ospf = ospf_lookup();
+ }
- if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running)
+ if (!ospf || !ospf->oi_running)
return CMD_SUCCESS;
- return (show_ip_ospf_database_common(vty, ospf, 1, argc, argv));
+ return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, argc, argv));
}
-ALIAS (show_ip_ospf_instance_database,
- show_ip_ospf_instance_database_type_cmd,
- "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR "|max-age|self-originate)",
+DEFUN (show_ip_ospf_instance_database_max,
+ show_ip_ospf_instance_database_max_cmd,
+ "show ip ospf (1-65535) database <max-age|self-originate>",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
"Database summary\n"
- OSPF_LSA_TYPES_DESC
"LSAs in MaxAge list\n"
"Self-originated link states\n")
+{
+ int idx_number = 3;
+ struct ospf *ospf;
+ u_short instance = 0;
-ALIAS (show_ip_ospf_instance_database,
- show_ip_ospf_instance_database_type_id_cmd,
- "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Instance ID\n"
- "Database summary\n"
- OSPF_LSA_TYPES_DESC
- "Link State ID (as an IP address)\n")
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
-ALIAS (show_ip_ospf_instance_database,
- show_ip_ospf_instance_database_type_id_adv_router_cmd,
- "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D adv-router A.B.C.D",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Instance ID\n"
- "Database summary\n"
- OSPF_LSA_TYPES_DESC
- "Link State ID (as an IP address)\n"
- "Advertising Router link states\n"
- "Advertising Router (as an IP address)\n")
+ if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
-ALIAS (show_ip_ospf_instance_database,
- show_ip_ospf_instance_database_type_id_self_cmd,
- "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D (self-originate|)",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Instance ID\n"
- "Database summary\n"
- OSPF_LSA_TYPES_DESC
- "Link State ID (as an IP address)\n"
- "Self-originated link states\n"
- "\n")
+ return (show_ip_ospf_database_common(vty, ospf, 1, argc, argv));
+}
static int
show_ip_ospf_database_type_adv_router_common (struct vty *vty, struct ospf *ospf,
- int arg_base, int argc, const char **argv)
+ int arg_base, int argc, struct cmd_token **argv)
{
+ int idx_type = 4;
int type, ret;
struct in_addr adv_router;
@@ -5925,37 +5489,37 @@ show_ip_ospf_database_type_adv_router_common (struct vty *vty, struct ospf *ospf
vty_out (vty, "%s OSPF Router with ID (%s)%s%s", VTY_NEWLINE,
inet_ntoa (ospf->router_id), VTY_NEWLINE, VTY_NEWLINE);
- if (argc != arg_base + 2)
+ if (argc != arg_base + 7)
return CMD_WARNING;
/* Set database type to show. */
- if (strncmp (argv[arg_base + 0], "r", 1) == 0)
+ if (strncmp (argv[arg_base + idx_type]->text, "r", 1) == 0)
type = OSPF_ROUTER_LSA;
- else if (strncmp (argv[arg_base + 0], "ne", 2) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "ne", 2) == 0)
type = OSPF_NETWORK_LSA;
- else if (strncmp (argv[arg_base + 0], "ns", 2) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "ns", 2) == 0)
type = OSPF_AS_NSSA_LSA;
- else if (strncmp (argv[arg_base + 0], "s", 1) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "s", 1) == 0)
type = OSPF_SUMMARY_LSA;
- else if (strncmp (argv[arg_base + 0], "a", 1) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "a", 1) == 0)
type = OSPF_ASBR_SUMMARY_LSA;
- else if (strncmp (argv[arg_base + 0], "e", 1) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "e", 1) == 0)
type = OSPF_AS_EXTERNAL_LSA;
- else if (strncmp (argv[arg_base + 0], "opaque-l", 8) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "opaque-l", 8) == 0)
type = OSPF_OPAQUE_LINK_LSA;
- else if (strncmp (argv[arg_base + 0], "opaque-ar", 9) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0)
type = OSPF_OPAQUE_AREA_LSA;
- else if (strncmp (argv[arg_base + 0], "opaque-as", 9) == 0)
+ else if (strncmp (argv[arg_base + idx_type]->text, "opaque-as", 9) == 0)
type = OSPF_OPAQUE_AS_LSA;
else
return CMD_WARNING;
/* `show ip ospf database LSA adv-router ADV_ROUTER'. */
- if (strncmp (argv[arg_base + 1], "s", 1) == 0)
+ if (strncmp (argv[arg_base + 5]->text, "s", 1) == 0)
adv_router = ospf->router_id;
else
{
- ret = inet_aton (argv[arg_base + 1], &adv_router);
+ ret = inet_aton (argv[arg_base + 6]->arg, &adv_router);
if (!ret)
return CMD_WARNING;
}
@@ -5967,14 +5531,15 @@ show_ip_ospf_database_type_adv_router_common (struct vty *vty, struct ospf *ospf
DEFUN (show_ip_ospf_database_type_adv_router,
show_ip_ospf_database_type_adv_router_cmd,
- "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") adv-router A.B.C.D",
+ "show ip ospf database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
SHOW_STR
IP_STR
"OSPF information\n"
"Database summary\n"
OSPF_LSA_TYPES_DESC
"Advertising Router link states\n"
- "Advertising Router (as an IP address)\n")
+ "Advertising Router (as an IP address)\n"
+ "Self-originated link states\n")
{
struct ospf *ospf;
@@ -5984,19 +5549,9 @@ DEFUN (show_ip_ospf_database_type_adv_router,
return (show_ip_ospf_database_type_adv_router_common(vty, ospf, 0, argc, argv));
}
-ALIAS (show_ip_ospf_database_type_adv_router,
- show_ip_ospf_database_type_self_cmd,
- "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") (self-originate|)",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Database summary\n"
- OSPF_LSA_TYPES_DESC
- "Self-originated link states\n")
-
DEFUN (show_ip_ospf_instance_database_type_adv_router,
show_ip_ospf_instance_database_type_adv_router_cmd,
- "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") adv-router A.B.C.D",
+ "show ip ospf (1-65535) database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
SHOW_STR
IP_STR
"OSPF information\n"
@@ -6004,12 +5559,14 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
"Database summary\n"
OSPF_LSA_TYPES_DESC
"Advertising Router link states\n"
- "Advertising Router (as an IP address)\n")
+ "Advertising Router (as an IP address)\n"
+ "Self-originated link states\n")
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -6017,38 +5574,28 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
return (show_ip_ospf_database_type_adv_router_common(vty, ospf, 1, argc, argv));
}
-ALIAS (show_ip_ospf_instance_database_type_adv_router,
- show_ip_ospf_instance_database_type_self_cmd,
- "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") (self-originate|)",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Instance ID\n"
- "Database summary\n"
- OSPF_LSA_TYPES_DESC
- "Self-originated link states\n")
-
DEFUN (ip_ospf_authentication_args,
ip_ospf_authentication_args_addr_cmd,
- "ip ospf authentication (null|message-digest) A.B.C.D",
+ "ip ospf authentication <null|message-digest> [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Enable authentication on this interface\n"
"Use null authentication\n"
"Use message-digest authentication\n"
- "Address of interface")
+ "Address of interface\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_encryption = 3;
+ int idx_ipv4 = 4;
struct in_addr addr;
int ret;
struct ospf_if_params *params;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 2)
+ if (argc == 5)
{
- ret = inet_aton(argv[1], &addr);
+ ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret)
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
@@ -6061,7 +5608,7 @@ DEFUN (ip_ospf_authentication_args,
}
/* Handle null authentication */
- if ( argv[0][0] == 'n' )
+ if ( argv[idx_encryption]->arg[0] == 'n' )
{
SET_IF_PARAM (params, auth_type);
params->auth_type = OSPF_AUTH_NULL;
@@ -6069,7 +5616,7 @@ DEFUN (ip_ospf_authentication_args,
}
/* Handle message-digest authentication */
- if ( argv[0][0] == 'm' )
+ if ( argv[idx_encryption]->arg[0] == 'm' )
{
SET_IF_PARAM (params, auth_type);
params->auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
@@ -6080,34 +5627,25 @@ DEFUN (ip_ospf_authentication_args,
return CMD_WARNING;
}
-ALIAS (ip_ospf_authentication_args,
- ip_ospf_authentication_args_cmd,
- "ip ospf authentication (null|message-digest)",
- "IP Information\n"
- "OSPF interface commands\n"
- "Enable authentication on this interface\n"
- "Use null authentication\n"
- "Use message-digest authentication\n")
-
DEFUN (ip_ospf_authentication,
ip_ospf_authentication_addr_cmd,
- "ip ospf authentication A.B.C.D",
+ "ip ospf authentication [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Enable authentication on this interface\n"
"Address of interface")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_ipv4 = 3;
struct in_addr addr;
int ret;
struct ospf_if_params *params;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 1)
+ if (argc == 4)
{
- ret = inet_aton(argv[0], &addr);
+ ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret)
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
@@ -6125,16 +5663,9 @@ DEFUN (ip_ospf_authentication,
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_authentication,
- ip_ospf_authentication_cmd,
- "ip ospf authentication",
- "IP Information\n"
- "OSPF interface commands\n"
- "Enable authentication on this interface\n")
-
DEFUN (no_ip_ospf_authentication_args,
no_ip_ospf_authentication_args_addr_cmd,
- "no ip ospf authentication (null|message-digest) A.B.C.D",
+ "no ip ospf authentication <null|message-digest> [A.B.C.D]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
@@ -6143,19 +5674,20 @@ DEFUN (no_ip_ospf_authentication_args,
"Use message-digest authentication\n"
"Address of interface")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_encryption = 4;
+ int idx_ipv4 = 5;
struct in_addr addr;
int ret;
struct ospf_if_params *params;
struct route_node *rn;
int auth_type;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 2)
+ if (argc == 6)
{
- ret = inet_aton(argv[1], &addr);
+ ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret)
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
@@ -6179,11 +5711,11 @@ DEFUN (no_ip_ospf_authentication_args,
}
else
{
- if ( argv[0][0] == 'n' )
+ if ( argv[idx_encryption]->arg[0] == 'n' )
{
auth_type = OSPF_AUTH_NULL;
}
- else if ( argv[0][0] == 'm' )
+ else if ( argv[idx_encryption]->arg[0] == 'm' )
{
auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
}
@@ -6225,37 +5757,27 @@ DEFUN (no_ip_ospf_authentication_args,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_authentication_args,
- no_ip_ospf_authentication_args_cmd,
- "no ip ospf authentication (null|message-digest)",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Enable authentication on this interface\n"
- "Use null authentication\n"
- "Use message-digest authentication\n")
-
DEFUN (no_ip_ospf_authentication,
no_ip_ospf_authentication_addr_cmd,
- "no ip ospf authentication A.B.C.D",
+ "no ip ospf authentication [A.B.C.D]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
"Enable authentication on this interface\n"
"Address of interface")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_ipv4 = 4;
struct in_addr addr;
int ret;
struct ospf_if_params *params;
struct route_node *rn;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 1)
+ if (argc == 5)
{
- ret = inet_aton(argv[0], &addr);
+ ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret)
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
@@ -6317,35 +5839,26 @@ DEFUN (no_ip_ospf_authentication,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_authentication,
- no_ip_ospf_authentication_cmd,
- "no ip ospf authentication",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Enable authentication on this interface\n")
DEFUN (ip_ospf_authentication_key,
ip_ospf_authentication_key_addr_cmd,
- "ip ospf authentication-key AUTH_KEY A.B.C.D",
+ "ip ospf authentication-key AUTH_KEY [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Authentication password (key)\n"
"The OSPF password (key)\n"
"Address of interface")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 2)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -6357,48 +5870,41 @@ DEFUN (ip_ospf_authentication_key,
}
memset (params->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE + 1);
- strncpy ((char *) params->auth_simple, argv[0], OSPF_AUTH_SIMPLE_SIZE);
+ strncpy ((char *) params->auth_simple, argv[3]->arg, OSPF_AUTH_SIMPLE_SIZE);
SET_IF_PARAM (params, auth_simple);
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_authentication_key,
- ip_ospf_authentication_key_cmd,
- "ip ospf authentication-key AUTH_KEY",
- "IP Information\n"
- "OSPF interface commands\n"
- "Authentication password (key)\n"
- "The OSPF password (key)")
-
-ALIAS_HIDDEN (ip_ospf_authentication_key,
+DEFUN_HIDDEN (ospf_authentication_key,
ospf_authentication_key_cmd,
- "ospf authentication-key AUTH_KEY",
+ "ospf authentication-key AUTH_KEY [A.B.C.D]",
"OSPF interface commands\n"
"Authentication password (key)\n"
- "The OSPF password (key)")
+ "The OSPF password (key)\n"
+ "Address of interface\n")
+{
+ return ip_ospf_authentication_key (self, vty, argc, argv);
+}
DEFUN (no_ip_ospf_authentication_key,
no_ip_ospf_authentication_key_authkey_addr_cmd,
- "no ip ospf authentication-key AUTH_KEY A.B.C.D",
+ "no ip ospf authentication-key [AUTH_KEY [A.B.C.D]]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
"Authentication password (key)\n"
"The OSPF password (key)")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct in_addr addr;
struct ospf_if_params *params;
- int ret;
-
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 2)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -6412,81 +5918,55 @@ DEFUN (no_ip_ospf_authentication_key,
memset (params->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
UNSET_IF_PARAM (params, auth_simple);
-
+
if (params != IF_DEF_PARAMS (ifp))
{
ospf_free_if_params (ifp, addr);
ospf_if_update_params (ifp, addr);
}
-
+
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_authentication_key,
- no_ip_ospf_authentication_key_authkey_cmd,
- "no ip ospf authentication-key AUTH_KEY",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Authentication password (key)\n")
-
-ALIAS (no_ip_ospf_authentication_key,
- no_ip_ospf_authentication_key_cmd,
- "no ip ospf authentication-key",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Authentication password (key)\n")
-
-ALIAS (no_ip_ospf_authentication_key,
- no_ospf_authentication_key_cmd,
- "no ospf authentication-key",
- NO_STR
- "OSPF interface commands\n"
- "Authentication password (key)\n")
-
-ALIAS (no_ip_ospf_authentication_key,
- no_ospf_authentication_key_authkey_cmd,
- "no ospf authentication-key AUTH_KEY",
- NO_STR
- "OSPF interface commands\n"
- "Authentication password (key)\n"
- "The OSPF password (key)\n")
-
-ALIAS (no_ip_ospf_authentication_key,
- no_ospf_authentication_key_authkey_ip_cmd,
- "no ospf authentication-key AUTH_KEY A.B.C.D",
- NO_STR
- "OSPF interface commands\n"
- "Authentication password (key)\n"
- "The OSPF password (key)\n"
- "Address of interface")
+DEFUN_HIDDEN (no_ospf_authentication_key,
+ no_ospf_authentication_key_authkey_addr_cmd,
+ "no ospf authentication-key [AUTH_KEY [A.B.C.D]]",
+ NO_STR
+ "OSPF interface commands\n"
+ "Authentication password (key)\n"
+ "The OSPF password (key)")
+{
+ return no_ip_ospf_authentication_key (self, vty, argc, argv);
+}
DEFUN (ip_ospf_message_digest_key,
- ip_ospf_message_digest_key_addr_cmd,
- "ip ospf message-digest-key <1-255> md5 KEY A.B.C.D",
+ ip_ospf_message_digest_key_cmd,
+ "ip ospf message-digest-key (1-255) md5 KEY [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Message digest authentication password (key)\n"
"Key ID\n"
"Use MD5 algorithm\n"
- "The OSPF password (key)"
- "Address of interface")
+ "The OSPF password (key)\n"
+ "Address of interface\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct crypt_key *ck;
u_char key_id;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
+ int idx = 0;
- if (argc == 3)
+ argv_find (argv, argc, "(1-255)", &idx);
+ char *keyid = argv[idx]->arg;
+ argv_find (argv, argc, "KEY", &idx);
+ char *cryptkey = argv[idx]->arg;
+
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- ret = inet_aton(argv[2], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -6497,7 +5977,7 @@ DEFUN (ip_ospf_message_digest_key,
ospf_if_update_params (ifp, addr);
}
- key_id = strtol (argv[0], NULL, 10);
+ key_id = strtol (keyid, NULL, 10);
if (ospf_crypt_key_lookup (params->auth_crypt, key_id) != NULL)
{
vty_out (vty, "OSPF: Key %d already exists%s", key_id, VTY_NEWLINE);
@@ -6507,7 +5987,7 @@ DEFUN (ip_ospf_message_digest_key,
ck = ospf_crypt_key_new ();
ck->key_id = (u_char) key_id;
memset (ck->auth_key, 0, OSPF_AUTH_MD5_SIZE+1);
- strncpy ((char *) ck->auth_key, argv[1], OSPF_AUTH_MD5_SIZE);
+ strncpy ((char *) ck->auth_key, cryptkey, OSPF_AUTH_MD5_SIZE);
ospf_crypt_key_add (params->auth_crypt, ck);
SET_IF_PARAM (params, auth_crypt);
@@ -6515,51 +5995,45 @@ DEFUN (ip_ospf_message_digest_key,
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_message_digest_key,
- ip_ospf_message_digest_key_cmd,
- "ip ospf message-digest-key <1-255> md5 KEY",
- "IP Information\n"
- "OSPF interface commands\n"
- "Message digest authentication password (key)\n"
- "Key ID\n"
- "Use MD5 algorithm\n"
- "The OSPF password (key)")
-
-ALIAS_HIDDEN (ip_ospf_message_digest_key,
+DEFUN_HIDDEN (ospf_message_digest_key,
ospf_message_digest_key_cmd,
- "ospf message-digest-key <1-255> md5 KEY",
+ "ospf message-digest-key (1-255) md5 KEY [A.B.C.D]",
"OSPF interface commands\n"
"Message digest authentication password (key)\n"
"Key ID\n"
"Use MD5 algorithm\n"
- "The OSPF password (key)")
+ "The OSPF password (key)\n"
+ "Address of interface\n")
+{
+ return ip_ospf_message_digest_key (self, vty, argc, argv);
+}
-DEFUN (no_ip_ospf_message_digest_key_md5,
- no_ip_ospf_message_digest_key_md5_addr_cmd,
- "no ip ospf message-digest-key <1-255> md5 KEY A.B.C.D",
+DEFUN (no_ip_ospf_message_digest_key,
+ no_ip_ospf_message_digest_key_cmd,
+ "no ip ospf message-digest-key (1-255) [md5 KEY] [A.B.C.D]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
"Message digest authentication password (key)\n"
"Key ID\n"
"Use MD5 algorithm\n"
- "The OSPF password (key)"
- "Address of interface")
+ "The OSPF password (key)\n"
+ "Address of interface\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct crypt_key *ck;
int key_id;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
-
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 3)
+ argv_find (argv, argc, "(1-255)", &idx);
+ char *keyid = argv[idx]->arg;
+
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- ret = inet_aton(argv[2], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -6571,7 +6045,7 @@ DEFUN (no_ip_ospf_message_digest_key_md5,
return CMD_SUCCESS;
}
- key_id = strtol (argv[0], NULL, 10);
+ key_id = strtol (keyid, NULL, 10);
ck = ospf_crypt_key_lookup (params->auth_crypt, key_id);
if (ck == NULL)
{
@@ -6590,118 +6064,44 @@ DEFUN (no_ip_ospf_message_digest_key_md5,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_message_digest_key_md5,
- no_ip_ospf_message_digest_key_md5_cmd,
- "no ip ospf message-digest-key <1-255> md5 KEY",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Message digest authentication password (key)\n"
- "Key ID\n"
- "Use MD5 algorithm\n"
- "The OSPF password (key)")
-
-DEFUN (no_ip_ospf_message_digest_key,
- no_ip_ospf_message_digest_key_addr_cmd,
- "no ip ospf message-digest-key <1-255> A.B.C.D",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Message digest authentication password (key)\n"
- "Key ID\n"
- "Address of interface")
+DEFUN_HIDDEN (no_ospf_message_digest_key,
+ no_ospf_message_digest_key_cmd,
+ "no ospf message-digest-key (1-255) [md5 KEY] [A.B.C.D]",
+ NO_STR
+ "OSPF interface commands\n"
+ "Message digest authentication password (key)\n"
+ "Key ID\n"
+ "Address of interface")
{
- struct interface *ifp;
- struct crypt_key *ck;
- int key_id;
- struct in_addr addr;
- int ret;
- struct ospf_if_params *params;
-
- ifp = vty->index;
- params = IF_DEF_PARAMS (ifp);
-
- if (argc == 2)
- {
- ret = inet_aton(argv[1], &addr);
- if (!ret)
- {
- vty_out (vty, "Please specify interface address by A.B.C.D%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- params = ospf_lookup_if_params (ifp, addr);
- if (params == NULL)
- return CMD_SUCCESS;
- }
-
- key_id = strtol (argv[0], NULL, 10);
- ck = ospf_crypt_key_lookup (params->auth_crypt, key_id);
- if (ck == NULL)
- {
- vty_out (vty, "OSPF: Key %d does not exist%s", key_id, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ospf_crypt_key_delete (params->auth_crypt, key_id);
-
- if (params != IF_DEF_PARAMS (ifp))
- {
- ospf_free_if_params (ifp, addr);
- ospf_if_update_params (ifp, addr);
- }
-
- return CMD_SUCCESS;
+ return no_ip_ospf_message_digest_key (self, vty, argc, argv);
}
-ALIAS (no_ip_ospf_message_digest_key,
- no_ip_ospf_message_digest_key_cmd,
- "no ip ospf message-digest-key <1-255>",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Message digest authentication password (key)\n"
- "Key ID\n")
-
-ALIAS (no_ip_ospf_message_digest_key,
- no_ospf_message_digest_key_cmd,
- "no ospf message-digest-key <1-255>",
- NO_STR
- "OSPF interface commands\n"
- "Message digest authentication password (key)\n"
- "Key ID\n")
-
DEFUN (ip_ospf_cost,
- ip_ospf_cost_u32_inet4_cmd,
- "ip ospf cost <1-65535> A.B.C.D",
+ ip_ospf_cost_cmd,
+ "ip ospf cost (1-65535) [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Interface cost\n"
"Cost\n"
- "Address of interface")
+ "Address of interface\n")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
u_int32_t cost;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
-
params = IF_DEF_PARAMS (ifp);
- cost = strtol (argv[0], NULL, 10);
+ // get arguments
+ char *coststr = NULL, *ifaddr = NULL;
+ coststr = argv_find (argv, argc, "(1-65535)", &idx) ? argv[idx]->arg : NULL;
+ ifaddr = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
- /* cost range is <1-65535>. */
- if (cost < 1 || cost > 65535)
- {
- vty_out (vty, "Interface output cost is invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ cost = strtol (coststr, NULL, 10);
- if (argc == 2)
+ if (ifaddr)
{
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if(!inet_aton(ifaddr, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -6716,135 +6116,47 @@ DEFUN (ip_ospf_cost,
params->output_cost_cmd = cost;
ospf_if_recalculate_output_cost (ifp);
-
+
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_cost,
- ip_ospf_cost_u32_cmd,
- "ip ospf cost <1-65535>",
- "IP Information\n"
- "OSPF interface commands\n"
- "Interface cost\n"
- "Cost")
-
-ALIAS_HIDDEN (ip_ospf_cost,
- ospf_cost_u32_cmd,
- "ospf cost <1-65535>",
- "OSPF interface commands\n"
- "Interface cost\n"
- "Cost")
-
-ALIAS_HIDDEN (ip_ospf_cost,
- ospf_cost_u32_inet4_cmd,
- "ospf cost <1-65535> A.B.C.D",
+DEFUN_HIDDEN (ospf_cost,
+ ospf_cost_cmd,
+ "ospf cost (1-65535) [A.B.C.D]",
"OSPF interface commands\n"
"Interface cost\n"
"Cost\n"
- "Address of interface")
-
-DEFUN (no_ip_ospf_cost,
- no_ip_ospf_cost_inet4_cmd,
- "no ip ospf cost A.B.C.D",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Interface cost\n"
- "Address of interface")
+ "Address of interface\n")
{
- struct interface *ifp = vty->index;
- struct in_addr addr;
- int ret;
- struct ospf_if_params *params;
-
- ifp = vty->index;
- params = IF_DEF_PARAMS (ifp);
-
- if (argc == 1)
- {
- ret = inet_aton(argv[0], &addr);
- if (!ret)
- {
- vty_out (vty, "Please specify interface address by A.B.C.D%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- params = ospf_lookup_if_params (ifp, addr);
- if (params == NULL)
- return CMD_SUCCESS;
- }
-
- UNSET_IF_PARAM (params, output_cost_cmd);
-
- if (params != IF_DEF_PARAMS (ifp))
- {
- ospf_free_if_params (ifp, addr);
- ospf_if_update_params (ifp, addr);
- }
-
- ospf_if_recalculate_output_cost (ifp);
-
- return CMD_SUCCESS;
+ return ip_ospf_cost (self, vty, argc, argv);
}
-ALIAS (no_ip_ospf_cost,
+DEFUN (no_ip_ospf_cost,
no_ip_ospf_cost_cmd,
- "no ip ospf cost",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Interface cost\n")
-
-ALIAS (no_ip_ospf_cost,
- no_ospf_cost_cmd,
- "no ospf cost",
- NO_STR
- "OSPF interface commands\n"
- "Interface cost\n")
-
-ALIAS (no_ip_ospf_cost,
- no_ospf_cost_inet4_cmd,
- "no ospf cost A.B.C.D",
+ "no ip ospf cost [(1-65535)] [A.B.C.D]",
NO_STR
"OSPF interface commands\n"
"Interface cost\n"
"Address of interface")
-
-DEFUN (no_ip_ospf_cost2,
- no_ip_ospf_cost_u32_cmd,
- "no ip ospf cost <1-65535>",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Interface cost\n"
- "Cost")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct in_addr addr;
- u_int32_t cost;
- int ret;
struct ospf_if_params *params;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
+ // get arguments
+ char *ifaddr = NULL;
+ ifaddr = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
+
/* According to the semantics we are mimicking "no ip ospf cost N" is
* always treated as "no ip ospf cost" regardless of the actual value
- * of N already configured for the interface. Thus the first argument
- * is always checked to be a number, but is ignored after that.
- */
- cost = strtol (argv[0], NULL, 10);
- if (cost < 1 || cost > 65535)
- {
- vty_out (vty, "Interface output cost is invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ * of N already configured for the interface. Thus ignore cost. */
- if (argc == 2)
+ if (ifaddr)
{
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if (!inet_aton(ifaddr, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -6869,32 +6181,17 @@ DEFUN (no_ip_ospf_cost2,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_cost2,
- no_ospf_cost_u32_cmd,
- "no ospf cost <1-65535>",
- NO_STR
- "OSPF interface commands\n"
- "Interface cost\n"
- "Cost")
-
-ALIAS (no_ip_ospf_cost2,
- no_ip_ospf_cost_u32_inet4_cmd,
- "no ip ospf cost <1-65535> A.B.C.D",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Interface cost\n"
- "Cost\n"
- "Address of interface")
-
-ALIAS (no_ip_ospf_cost2,
- no_ospf_cost_u32_inet4_cmd,
- "no ospf cost <1-65535> A.B.C.D",
- NO_STR
- "OSPF interface commands\n"
- "Interface cost\n"
- "Cost\n"
- "Address of interface")
+DEFUN_HIDDEN (no_ospf_cost,
+ no_ospf_cost_cmd,
+ "no ospf cost [(1-65535)] [A.B.C.D]",
+ NO_STR
+ "OSPF interface commands\n"
+ "Interface cost\n"
+ "Cost\n"
+ "Address of interface\n")
+{
+ return no_ip_ospf_cost (self, vty, argc, argv);
+}
static void
ospf_nbr_timer_update (struct ospf_interface *oi)
@@ -6917,7 +6214,7 @@ ospf_vty_dead_interval_set (struct vty *vty, const char *interval_str,
const char *nbr_str,
const char *fast_hello_str)
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
u_int32_t seconds;
u_char hellomult;
struct in_addr addr;
@@ -6991,87 +6288,75 @@ ospf_vty_dead_interval_set (struct vty *vty, const char *interval_str,
return CMD_SUCCESS;
}
-
DEFUN (ip_ospf_dead_interval,
- ip_ospf_dead_interval_addr_cmd,
- "ip ospf dead-interval <1-65535> A.B.C.D",
+ ip_ospf_dead_interval_cmd,
+ "ip ospf dead-interval (1-65535) [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n"
+ "Interval time after which a neighbor is declared down\n"
"Seconds\n"
"Address of interface\n")
{
- if (argc == 2)
- return ospf_vty_dead_interval_set (vty, argv[0], argv[1], NULL);
- else
- return ospf_vty_dead_interval_set (vty, argv[0], NULL, NULL);
+ int idx = 0;
+ char *interval = argv_find (argv, argc, "(1-65535)", &idx) ? argv[idx]->arg : NULL;
+ char *ifaddr = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
+ return ospf_vty_dead_interval_set (vty, interval, ifaddr, NULL);
}
-ALIAS (ip_ospf_dead_interval,
- ip_ospf_dead_interval_cmd,
- "ip ospf dead-interval <1-65535>",
- "IP Information\n"
- "OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n"
- "Seconds\n")
-ALIAS_HIDDEN (ip_ospf_dead_interval,
+DEFUN_HIDDEN (ospf_dead_interval,
ospf_dead_interval_cmd,
- "ospf dead-interval <1-65535>",
+ "ospf dead-interval (1-65535) [A.B.C.D]",
"OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n"
- "Seconds\n")
+ "Interval time after which a neighbor is declared down\n"
+ "Seconds\n"
+ "Address of interface\n")
+{
+ return ip_ospf_dead_interval (self, vty, argc, argv);
+}
DEFUN (ip_ospf_dead_interval_minimal,
ip_ospf_dead_interval_minimal_addr_cmd,
- "ip ospf dead-interval minimal hello-multiplier <1-10> A.B.C.D",
+ "ip ospf dead-interval minimal hello-multiplier (1-10) [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n"
+ "Interval time after which a neighbor is declared down\n"
"Minimal 1s dead-interval with fast sub-second hellos\n"
"Hello multiplier factor\n"
"Number of Hellos to send each second\n"
"Address of interface\n")
{
- if (argc == 2)
- return ospf_vty_dead_interval_set (vty, NULL, argv[1], argv[0]);
+ int idx_number = 5;
+ int idx_ipv4 = 6;
+ if (argc == 7)
+ return ospf_vty_dead_interval_set (vty, NULL, argv[idx_ipv4]->arg, argv[idx_number]->arg);
else
- return ospf_vty_dead_interval_set (vty, NULL, NULL, argv[0]);
+ return ospf_vty_dead_interval_set (vty, NULL, NULL, argv[idx_number]->arg);
}
-ALIAS (ip_ospf_dead_interval_minimal,
- ip_ospf_dead_interval_minimal_cmd,
- "ip ospf dead-interval minimal hello-multiplier <1-10>",
- "IP Information\n"
- "OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n"
- "Minimal 1s dead-interval with fast sub-second hellos\n"
- "Hello multiplier factor\n"
- "Number of Hellos to send each second\n")
-
DEFUN (no_ip_ospf_dead_interval,
- no_ip_ospf_dead_interval_addr_cmd,
- "no ip ospf dead-interval <1-65535> A.B.C.D",
+ no_ip_ospf_dead_interval_cmd,
+ "no ip ospf dead-interval [<(1-65535)|minimal hello-multiplier (1-10)> [A.B.C.D]]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n"
+ "Interval time after which a neighbor is declared down\n"
"Seconds\n"
"Address of interface")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_ipv4 = argc - 1;
struct in_addr addr;
int ret;
struct ospf_if_params *params;
struct ospf_interface *oi;
struct route_node *rn;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 2)
+ if (argv[idx_ipv4]->type == IPV4_TKN)
{
- ret = inet_aton(argv[1], &addr);
+ ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret)
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
@@ -7118,83 +6403,40 @@ DEFUN (no_ip_ospf_dead_interval,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_dead_interval,
- no_ip_ospf_dead_interval_seconds_cmd,
- "no ip ospf dead-interval <1-65535>",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n"
- "Seconds\n")
-
-ALIAS (no_ip_ospf_dead_interval,
- no_ip_ospf_dead_interval_cmd,
- "no ip ospf dead-interval",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n")
-
-ALIAS (no_ip_ospf_dead_interval,
- no_ospf_dead_interval_cmd,
- "no ospf dead-interval",
- NO_STR
- "OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n")
-
-ALIAS (no_ip_ospf_dead_interval,
- no_ip_ospf_dead_interval_minimal_addr_cmd,
- "no ip ospf dead-interval minimal hello-multiplier <1-10> A.B.C.D",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n"
- "Minimal 1s dead-interval with fast sub-second hellos\n"
- "Hello multiplier factor\n"
- "Number of Hellos to send each second\n"
- "Address of interface\n")
-
-ALIAS (no_ip_ospf_dead_interval,
- no_ip_ospf_dead_interval_minimal_cmd,
- "no ip ospf dead-interval minimal hello-multiplier <1-10>",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Interval after which a neighbor is declared dead\n"
- "Minimal 1s dead-interval with fast sub-second hellos\n"
- "Hello multiplier factor\n"
- "Number of Hellos to send each second\n")
+DEFUN_HIDDEN (no_ospf_dead_interval,
+ no_ospf_dead_interval_cmd,
+ "no ospf dead-interval [<(1-65535)|minimal hello-multiplier (1-10)> [A.B.C.D]]",
+ NO_STR
+ "OSPF interface commands\n"
+ "Interval time after which a neighbor is declared down\n"
+ "Seconds\n"
+ "Address of interface")
+{
+ return no_ip_ospf_dead_interval (self, vty, argc, argv);
+}
DEFUN (ip_ospf_hello_interval,
- ip_ospf_hello_interval_addr_cmd,
- "ip ospf hello-interval <1-65535> A.B.C.D",
+ ip_ospf_hello_interval_cmd,
+ "ip ospf hello-interval (1-65535) [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Time between HELLO packets\n"
"Seconds\n"
- "Address of interface")
+ "Address of interface\n")
{
- struct interface *ifp = vty->index;
- u_int32_t seconds;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
-
params = IF_DEF_PARAMS (ifp);
+ u_int32_t seconds = 0;
- seconds = strtol (argv[0], NULL, 10);
+ argv_find (argv, argc, "(1-65535)", &idx);
+ seconds = strtol (argv[idx]->arg, NULL, 10);
- /* HelloInterval range is <1-65535>. */
- if (seconds < 1 || seconds > 65535)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- vty_out (vty, "Hello Interval is invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (argc == 2)
- {
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if(!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -7211,43 +6453,36 @@ DEFUN (ip_ospf_hello_interval,
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_hello_interval,
- ip_ospf_hello_interval_cmd,
- "ip ospf hello-interval <1-65535>",
- "IP Information\n"
- "OSPF interface commands\n"
- "Time between HELLO packets\n"
- "Seconds\n")
-
-ALIAS_HIDDEN (ip_ospf_hello_interval,
+DEFUN_HIDDEN (ospf_hello_interval,
ospf_hello_interval_cmd,
- "ospf hello-interval <1-65535>",
+ "ospf hello-interval (1-65535) [A.B.C.D]",
"OSPF interface commands\n"
"Time between HELLO packets\n"
- "Seconds\n")
+ "Seconds\n"
+ "Address of interface\n")
+{
+ return ip_ospf_hello_interval (self, vty, argc, argv);
+}
DEFUN (no_ip_ospf_hello_interval,
- no_ip_ospf_hello_interval_addr_cmd,
- "no ip ospf hello-interval <1-65535> A.B.C.D",
+ no_ip_ospf_hello_interval_cmd,
+ "no ip ospf hello-interval [(1-65535) [A.B.C.D]]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
- "Time between HELLO packets\n"
+ "Time between HELLO packets\n" // ignored
"Seconds\n"
- "Address of interface")
+ "Address of interface\n")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
-
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 2)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if(!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -7271,34 +6506,21 @@ DEFUN (no_ip_ospf_hello_interval,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_hello_interval,
- no_ip_ospf_hello_interval_seconds_cmd,
- "no ip ospf hello-interval <1-65535>",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Time between HELLO packets\n"
- "Seconds\n")
-
-ALIAS (no_ip_ospf_hello_interval,
- no_ip_ospf_hello_interval_cmd,
- "no ip ospf hello-interval",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Time between HELLO packets\n")
-
-ALIAS (no_ip_ospf_hello_interval,
- no_ospf_hello_interval_cmd,
- "no ospf hello-interval <1-65535>",
- NO_STR
- "OSPF interface commands\n"
- "Time between HELLO packets\n"
- "Seconds\n")
+DEFUN_HIDDEN (no_ospf_hello_interval,
+ no_ospf_hello_interval_cmd,
+ "no ospf hello-interval [(1-65535) [A.B.C.D]]",
+ NO_STR
+ "OSPF interface commands\n"
+ "Time between HELLO packets\n" // ignored
+ "Seconds\n"
+ "Address of interface\n")
+{
+ return no_ip_ospf_hello_interval (self, vty, argc, argv);
+}
DEFUN (ip_ospf_network,
ip_ospf_network_cmd,
- "ip ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point)",
+ "ip ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point>",
"IP Information\n"
"OSPF interface commands\n"
"Network type\n"
@@ -7307,7 +6529,8 @@ DEFUN (ip_ospf_network,
"Specify OSPF point-to-multipoint network\n"
"Specify OSPF point-to-point network\n")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
int old_type = IF_DEF_PARAMS (ifp)->type;
struct route_node *rn;
@@ -7317,13 +6540,13 @@ DEFUN (ip_ospf_network,
return CMD_WARNING;
}
- if (strncmp (argv[0], "b", 1) == 0)
+ if (argv_find (argv, argc, "broadcast", &idx))
IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;
- else if (strncmp (argv[0], "n", 1) == 0)
+ else if (argv_find (argv, argc, "non-broadcast", &idx))
IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_NBMA;
- else if (strncmp (argv[0], "point-to-m", 10) == 0)
+ else if (argv_find (argv, argc, "point-to-multipoint", &idx))
IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_POINTOMULTIPOINT;
- else if (strncmp (argv[0], "point-to-p", 10) == 0)
+ else if (argv_find (argv, argc, "point-to-point", &idx))
IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_POINTOPOINT;
if (IF_DEF_PARAMS (ifp)->type == old_type)
@@ -7350,25 +6573,32 @@ DEFUN (ip_ospf_network,
return CMD_SUCCESS;
}
-ALIAS_HIDDEN (ip_ospf_network,
+DEFUN_HIDDEN (ospf_network,
ospf_network_cmd,
- "ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point)",
+ "ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point>",
"OSPF interface commands\n"
"Network type\n"
"Specify OSPF broadcast multi-access network\n"
"Specify OSPF NBMA network\n"
"Specify OSPF point-to-multipoint network\n"
"Specify OSPF point-to-point network\n")
+{
+ return ip_ospf_network (self, vty, argc, argv);
+}
DEFUN (no_ip_ospf_network,
no_ip_ospf_network_cmd,
- "no ip ospf network",
+ "no ip ospf network [<broadcast|non-broadcast|point-to-multipoint|point-to-point>]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
- "Network type\n")
+ "Network type\n"
+ "Specify OSPF broadcast multi-access network\n"
+ "Specify OSPF NBMA network\n"
+ "Specify OSPF point-to-multipoint network\n"
+ "Specify OSPF point-to-point network\n")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
int old_type = IF_DEF_PARAMS (ifp)->type;
struct route_node *rn;
@@ -7383,9 +6613,9 @@ DEFUN (no_ip_ospf_network,
if (!oi)
continue;
-
+
oi->type = IF_DEF_PARAMS (ifp)->type;
-
+
if (oi->state > ISM_Down)
{
OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
@@ -7396,67 +6626,43 @@ DEFUN (no_ip_ospf_network,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_network,
- no_ip_ospf_network_val_cmd,
- "no ip ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point)",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Network type\n"
- "Specify OSPF broadcast multi-access network\n"
- "Specify OSPF NBMA network\n"
- "Specify OSPF point-to-multipoint network\n"
- "Specify OSPF point-to-point network\n")
-
-ALIAS (no_ip_ospf_network,
- no_ospf_network_cmd,
- "no ospf network",
- NO_STR
- "OSPF interface commands\n"
- "Network type\n")
-
-ALIAS (no_ip_ospf_network,
- no_ospf_network_val_cmd,
- "no ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point)",
- NO_STR
- "OSPF interface commands\n"
- "Network type\n"
- "Specify OSPF broadcast multi-access network\n"
- "Specify OSPF NBMA network\n"
- "Specify OSPF point-to-multipoint network\n"
- "Specify OSPF point-to-point network\n")
+DEFUN_HIDDEN (no_ospf_network,
+ no_ospf_network_cmd,
+ "no ospf network [<broadcast|non-broadcast|point-to-multipoint|point-to-point>]",
+ NO_STR
+ "OSPF interface commands\n"
+ "Network type\n"
+ "Specify OSPF broadcast multi-access network\n"
+ "Specify OSPF NBMA network\n"
+ "Specify OSPF point-to-multipoint network\n"
+ "Specify OSPF point-to-point network\n")
+{
+ return no_ip_ospf_network (self, vty, argc, argv);
+}
DEFUN (ip_ospf_priority,
- ip_ospf_priority_addr_cmd,
- "ip ospf priority <0-255> A.B.C.D",
+ ip_ospf_priority_cmd,
+ "ip ospf priority (0-255) [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Router priority\n"
"Priority\n"
"Address of interface")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
long priority;
struct route_node *rn;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
-
params = IF_DEF_PARAMS (ifp);
- priority = strtol (argv[0], NULL, 10);
-
- /* Router Priority range is <0-255>. */
- if (priority < 0 || priority > 255)
- {
- vty_out (vty, "Router Priority is invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ argv_find (argv, argc, "(0-255)", &idx);
+ priority = strtol (argv[idx]->arg, NULL, 10);
- if (argc == 2)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -7466,17 +6672,16 @@ DEFUN (ip_ospf_priority,
params = ospf_get_if_params (ifp, addr);
ospf_if_update_params (ifp, addr);
}
-
+
SET_IF_PARAM (params, priority);
params->priority = priority;
for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
{
struct ospf_interface *oi = rn->info;
-
+
if (!oi)
continue;
-
if (PRIORITY (oi) != OSPF_IF_PARAM (oi, priority))
{
@@ -7484,48 +6689,42 @@ DEFUN (ip_ospf_priority,
OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
}
}
-
+
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_priority,
- ip_ospf_priority_cmd,
- "ip ospf priority <0-255>",
- "IP Information\n"
- "OSPF interface commands\n"
- "Router priority\n"
- "Priority\n")
-
-ALIAS_HIDDEN (ip_ospf_priority,
+DEFUN_HIDDEN (ospf_priority,
ospf_priority_cmd,
- "ospf priority <0-255>",
+ "ospf priority (0-255) [A.B.C.D]",
"OSPF interface commands\n"
"Router priority\n"
- "Priority\n")
+ "Priority\n"
+ "Address of interface")
+{
+ return ip_ospf_priority (self, vty, argc, argv);
+}
DEFUN (no_ip_ospf_priority,
- no_ip_ospf_priority_addr_cmd,
- "no ip ospf priority <0-255> A.B.C.D",
+ no_ip_ospf_priority_cmd,
+ "no ip ospf priority [(0-255) [A.B.C.D]]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
- "Router priority\n"
+ "Router priority\n" // ignored
"Priority\n"
"Address of interface")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct route_node *rn;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc == 2)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -7553,7 +6752,6 @@ DEFUN (no_ip_ospf_priority,
if (!oi)
continue;
-
if (PRIORITY (oi) != OSPF_IF_PARAM (oi, priority))
{
PRIORITY (oi) = OSPF_IF_PARAM (oi, priority);
@@ -7564,62 +6762,40 @@ DEFUN (no_ip_ospf_priority,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_priority,
- no_ip_ospf_priority_no_param_cmd,
- "no ip ospf priority",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Router priority\n");
-
-ALIAS (no_ip_ospf_priority,
- no_ip_ospf_priority_cmd,
- "no ip ospf priority <0-255>",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Router priority\n"
- "Priority\n")
-
-ALIAS (no_ip_ospf_priority,
- no_ospf_priority_cmd,
- "no ospf priority <0-255>",
- NO_STR
- "OSPF interface commands\n"
- "Router priority\n"
- "Priority\n")
-
+DEFUN_HIDDEN (no_ospf_priority,
+ no_ospf_priority_cmd,
+ "no ospf priority [(0-255) [A.B.C.D]]",
+ NO_STR
+ "OSPF interface commands\n"
+ "Router priority\n"
+ "Priority\n"
+ "Address of interface")
+{
+ return no_ip_ospf_priority (self, vty, argc, argv);
+}
DEFUN (ip_ospf_retransmit_interval,
ip_ospf_retransmit_interval_addr_cmd,
- "ip ospf retransmit-interval <3-65535> A.B.C.D",
+ "ip ospf retransmit-interval (3-65535) [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Time between retransmitting lost link state advertisements\n"
"Seconds\n"
"Address of interface")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
u_int32_t seconds;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
-
params = IF_DEF_PARAMS (ifp);
- seconds = strtol (argv[0], NULL, 10);
-
- /* Retransmit Interval range is <3-65535>. */
- if (seconds < 3 || seconds > 65535)
- {
- vty_out (vty, "Retransmit Interval is invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ argv_find (argv, argc, "(3-65535)", &idx);
+ seconds = strtol (argv[idx]->arg, NULL, 10);
- if (argc == 2)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -7636,48 +6812,37 @@ DEFUN (ip_ospf_retransmit_interval,
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_retransmit_interval,
- ip_ospf_retransmit_interval_cmd,
- "ip ospf retransmit-interval <3-65535>",
- "IP Information\n"
- "OSPF interface commands\n"
- "Time between retransmitting lost link state advertisements\n"
- "Seconds\n")
-
-ALIAS_HIDDEN (ip_ospf_retransmit_interval,
+DEFUN_HIDDEN (ospf_retransmit_interval,
ospf_retransmit_interval_cmd,
- "ospf retransmit-interval <3-65535>",
+ "ospf retransmit-interval (3-65535) [A.B.C.D]",
"OSPF interface commands\n"
"Time between retransmitting lost link state advertisements\n"
- "Seconds\n")
+ "Seconds\n"
+ "Address of interface")
+{
+ return ip_ospf_retransmit_interval (self, vty, argc, argv);
+}
DEFUN (no_ip_ospf_retransmit_interval,
no_ip_ospf_retransmit_interval_addr_cmd,
- "no ip ospf retransmit-interval A.B.C.D",
+ "no ip ospf retransmit-interval [(3-65535)] [A.B.C.D]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
"Time between retransmitting lost link state advertisements\n"
- "Address of interface")
+ "Seconds\n"
+ "Address of interface\n")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
- int addr_index;
-
- ifp = vty->index;
+
params = IF_DEF_PARAMS (ifp);
- if (argc >= 1)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- if (argc == 1)
- addr_index = 0;
- else
- addr_index = 1;
-
- ret = inet_aton(argv[addr_index], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -7701,82 +6866,40 @@ DEFUN (no_ip_ospf_retransmit_interval,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_retransmit_interval,
- no_ip_ospf_retransmit_interval_sec_addr_cmd,
- "no ip ospf retransmit-interval <3-65535> A.B.C.D",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Time between retransmitting lost link state advertisements\n"
- "Seconds\n"
- "Address of interface")
-
-ALIAS (no_ip_ospf_retransmit_interval,
- no_ip_ospf_retransmit_interval_cmd,
- "no ip ospf retransmit-interval",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Time between retransmitting lost link state advertisements\n")
-
-ALIAS (no_ip_ospf_retransmit_interval,
+DEFUN_HIDDEN (no_ospf_retransmit_interval,
no_ospf_retransmit_interval_cmd,
- "no ospf retransmit-interval",
+ "no ospf retransmit-interval [(3-65535)] [A.B.C.D]",
NO_STR
"OSPF interface commands\n"
- "Time between retransmitting lost link state advertisements\n")
-
-DEFUN (no_ip_ospf_retransmit_interval_sec,
- no_ip_ospf_retransmit_interval_sec_cmd,
- "no ip ospf retransmit-interval <3-65535>",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
"Time between retransmitting lost link state advertisements\n"
- "Seconds\n")
+ "Seconds\n"
+ "Address of interface\n")
{
- struct interface *ifp = vty->index;
- struct ospf_if_params *params;
-
- ifp = vty->index;
- params = IF_DEF_PARAMS (ifp);
-
- UNSET_IF_PARAM (params, retransmit_interval);
- params->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
-
- return CMD_SUCCESS;
+ return no_ip_ospf_retransmit_interval (self, vty, argc, argv);
}
-
DEFUN (ip_ospf_transmit_delay,
ip_ospf_transmit_delay_addr_cmd,
- "ip ospf transmit-delay <1-65535> A.B.C.D",
+ "ip ospf transmit-delay (1-65535) [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Link state transmit delay\n"
"Seconds\n"
"Address of interface")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
u_int32_t seconds;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
-
- params = IF_DEF_PARAMS (ifp);
- seconds = strtol (argv[0], NULL, 10);
- /* Transmit Delay range is <1-65535>. */
- if (seconds < 1 || seconds > 65535)
- {
- vty_out (vty, "Transmit Delay is invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ params = IF_DEF_PARAMS (ifp);
+ argv_find (argv, argc, "(1-65535)", &idx);
+ seconds = strtol (argv[idx]->arg, NULL, 10);
- if (argc == 2)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- ret = inet_aton(argv[1], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -7787,54 +6910,42 @@ DEFUN (ip_ospf_transmit_delay,
ospf_if_update_params (ifp, addr);
}
- SET_IF_PARAM (params, transmit_delay);
+ SET_IF_PARAM (params, transmit_delay);
params->transmit_delay = seconds;
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_transmit_delay,
- ip_ospf_transmit_delay_cmd,
- "ip ospf transmit-delay <1-65535>",
- "IP Information\n"
- "OSPF interface commands\n"
- "Link state transmit delay\n"
- "Seconds\n")
-
-ALIAS_HIDDEN (ip_ospf_transmit_delay,
+DEFUN_HIDDEN (ospf_transmit_delay,
ospf_transmit_delay_cmd,
- "ospf transmit-delay <1-65535>",
+ "ospf transmit-delay (1-65535) [A.B.C.D]",
"OSPF interface commands\n"
"Link state transmit delay\n"
- "Seconds\n")
+ "Seconds\n"
+ "Address of interface")
+{
+ return ip_ospf_transmit_delay (self, vty, argc, argv);
+}
DEFUN (no_ip_ospf_transmit_delay,
no_ip_ospf_transmit_delay_addr_cmd,
- "no ip ospf transmit-delay A.B.C.D",
+ "no ip ospf transmit-delay [(1-65535)] [A.B.C.D]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
"Link state transmit delay\n"
"Address of interface")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct in_addr addr;
- int ret;
struct ospf_if_params *params;
- int addr_index;
- ifp = vty->index;
params = IF_DEF_PARAMS (ifp);
- if (argc >= 1)
+ if (argv_find (argv, argc, "A.B.C.D", &idx))
{
- if (argc == 1)
- addr_index = 0;
- else
- addr_index = 1;
-
- ret = inet_aton(argv[addr_index], &addr);
- if (!ret)
+ if (!inet_aton(argv[idx]->arg, &addr))
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
VTY_NEWLINE);
@@ -7858,63 +6969,29 @@ DEFUN (no_ip_ospf_transmit_delay,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_transmit_delay,
- no_ip_ospf_transmit_delay_sec_addr_cmd,
- "no ip ospf transmit-delay <1-65535> A.B.C.D",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Link state transmit delay\n"
- "Seconds\n"
- "Address of interface")
-ALIAS (no_ip_ospf_transmit_delay,
- no_ip_ospf_transmit_delay_cmd,
- "no ip ospf transmit-delay",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Link state transmit delay\n")
-
-ALIAS (no_ip_ospf_transmit_delay,
- no_ospf_transmit_delay_cmd,
- "no ospf transmit-delay",
- NO_STR
- "OSPF interface commands\n"
- "Link state transmit delay\n")
-
-DEFUN (no_ip_ospf_transmit_delay_sec,
- no_ip_ospf_transmit_delay_sec_cmd,
- "no ip ospf transmit-delay <1-65535>",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Link state transmit delay\n"
- "Seconds\n"
- "Address of interface")
+DEFUN_HIDDEN (no_ospf_transmit_delay,
+ no_ospf_transmit_delay_cmd,
+ "no ospf transmit-delay",
+ NO_STR
+ "OSPF interface commands\n"
+ "Link state transmit delay\n")
{
- struct interface *ifp = vty->index;
- struct ospf_if_params *params;
-
- ifp = vty->index;
- params = IF_DEF_PARAMS (ifp);
-
- UNSET_IF_PARAM (params, transmit_delay);
- params->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
-
- return CMD_SUCCESS;
+ return no_ip_ospf_transmit_delay (self, vty, argc, argv);
}
DEFUN (ip_ospf_area,
ip_ospf_area_cmd,
- "ip ospf area (A.B.C.D|<0-4294967295>)",
+ "ip ospf [(1-65535)] area <A.B.C.D|(0-4294967295)>",
"IP Information\n"
"OSPF interface commands\n"
+ "Instance ID\n"
"Enable OSPF on this interface\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
int format, ret;
struct in_addr area_id;
struct ospf *ospf;
@@ -7922,8 +6999,9 @@ DEFUN (ip_ospf_area,
struct route_node *rn;
u_short instance = 0;
- if (argc == 2)
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ if (argv_find (argv, argc, "(1-65535)", &idx))
+ instance = strtol (argv[idx]->arg, NULL, 10);
+ char *areaid = argv[argc - 1]->arg;
ospf = ospf_lookup_instance (instance);
if (ospf == NULL)
@@ -7938,7 +7016,7 @@ DEFUN (ip_ospf_area,
return CMD_SUCCESS;
}
- ret = ospf_str2area_id (argv[instance ? 1 : 0], &area_id, &format);
+ ret = ospf_str2area_id (areaid, &area_id, &format);
if (ret < 0)
{
vty_out (vty, "Please specify area by A.B.C.D|<0-4294967295>%s",
@@ -7976,69 +7054,25 @@ DEFUN (ip_ospf_area,
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_area,
- ip_ospf_instance_area_cmd,
- "ip ospf <1-65535> area (A.B.C.D|<0-4294967295>)",
- "IP Information\n"
- "OSPF interface commands\n"
- "Instance ID\n"
- "Enable OSPF on this interface\n"
- "OSPF area ID in IP address format\n"
- "OSPF area ID as a decimal value\n")
-
DEFUN (no_ip_ospf_area,
no_ip_ospf_area_cmd,
- "no ip ospf area",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Disable OSPF on this interface\n")
-{
- struct interface *ifp = vty->index;
- struct ospf *ospf;
- struct ospf_if_params *params;
- u_short instance = 0;
-
- if ((ospf = ospf_lookup_instance (instance)) == NULL)
- return CMD_SUCCESS;
-
- params = IF_DEF_PARAMS (ifp);
- if (!OSPF_IF_PARAM_CONFIGURED(params, if_area))
- {
- vty_out (vty, "Can't find specified inteface area configuration.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ospf_interface_unset (ifp);
- ospf->if_ospf_cli_count--;
- return CMD_SUCCESS;
-}
-
-ALIAS (no_ip_ospf_area,
- no_ip_ospf_area_val_cmd,
- "no ip ospf area (A.B.C.D|<0-4294967295>)",
+ "no ip ospf [(1-65535)] area [<A.B.C.D|(0-4294967295)>]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
+ "Instance ID\n"
"Disable OSPF on this interface\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n")
-
-DEFUN (no_ip_ospf_instance_area,
- no_ip_ospf_instance_area_cmd,
- "no ip ospf <1-65535> area",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Instance ID\n"
- "Disable OSPF on this interface\n")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx = 0;
struct ospf *ospf;
struct ospf_if_params *params;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ if (argv_find (argv, argc, "(1-65535)", &idx))
+ instance = strtol (argv[idx]->arg, NULL, 10);
if ((ospf = ospf_lookup_instance (instance)) == NULL)
return CMD_SUCCESS;
@@ -8046,7 +7080,7 @@ DEFUN (no_ip_ospf_instance_area,
params = IF_DEF_PARAMS (ifp);
if (!OSPF_IF_PARAM_CONFIGURED(params, if_area))
{
- vty_out (vty, "Can't find specified inteface area configuration.%s", VTY_NEWLINE);
+ vty_out (vty, "Can't find specified interface area configuration.%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -8055,21 +7089,9 @@ DEFUN (no_ip_ospf_instance_area,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_instance_area,
- no_ip_ospf_instance_area_val_cmd,
- "no ip ospf <1-65535> area (A.B.C.D|<0-4294967295>)",
- NO_STR
- "IP Information\n"
- "OSPF interface commands\n"
- "Instance ID\n"
- "Disable OSPF on this interface\n"
- "OSPF area ID in IP address format\n"
- "OSPF area ID as a decimal value\n")
-
DEFUN (ospf_redistribute_source,
ospf_redistribute_source_cmd,
- "redistribute " FRR_REDIST_STR_OSPFD
- " {metric <0-16777214>|metric-type (1|2)|route-map WORD}",
+ "redistribute " FRR_REDIST_STR_OSPFD " [<metric (0-16777214)|metric-type (1-2)|route-map WORD>]",
REDIST_STR
FRR_REDIST_HELP_STR_OSPFD
"Metric for redistributed routes\n"
@@ -8080,40 +7102,38 @@ DEFUN (ospf_redistribute_source,
"Route map reference\n"
"Pointer to route-map entries\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_protocol = 1;
int source;
int type = -1;
int metric = -1;
struct ospf_redist *red;
-
- if (!ospf)
- return CMD_SUCCESS;
-
- if (argc < 4)
- return CMD_WARNING; /* should not happen */
+ int idx = 0;
if (!ospf)
return CMD_SUCCESS;
/* Get distribute source. */
- source = proto_redistnum(AFI_IP, argv[0]);
- if (source < 0 || source == ZEBRA_ROUTE_OSPF)
+ source = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
+ if (source < 0)
return CMD_WARNING;
+ red = ospf_redist_add(ospf, source, 0);
+
/* Get metric value. */
- if (argv[1] != NULL)
- if (!str2metric (argv[1], &metric))
+ if (argv_find (argv, argc, "(0-16777214)", &idx)) {
+ if (!str2metric (argv[idx]->arg, &metric))
return CMD_WARNING;
-
+ }
/* Get metric type. */
- if (argv[2] != NULL)
- if (!str2metric_type (argv[2], &type))
+ else if (argv_find (argv, argc, "(1-2)", &idx)) {
+ if (!str2metric_type (argv[idx]->arg, &type))
return CMD_WARNING;
-
- red = ospf_redist_add(ospf, source, 0);
-
- if (argv[3] != NULL)
- ospf_routemap_set (red, argv[3]);
+ }
+ /* Get route-map */
+ else if (argv_find (argv, argc, "WORD", &idx)) {
+ ospf_routemap_set (red, argv[idx]->arg);
+ }
else
ospf_routemap_unset (red);
@@ -8122,8 +7142,7 @@ DEFUN (ospf_redistribute_source,
DEFUN (no_ospf_redistribute_source,
no_ospf_redistribute_source_cmd,
- "no redistribute " FRR_REDIST_STR_OSPFD
- " {metric <0-16777214>|metric-type (1|2)|route-map WORD}",
+ "no redistribute " FRR_REDIST_STR_OSPFD " [<metric (0-16777214)|metric-type (1-2)|route-map WORD>]",
NO_STR
REDIST_STR
FRR_REDIST_HELP_STR_OSPFD
@@ -8135,14 +7154,13 @@ DEFUN (no_ospf_redistribute_source,
"Route map reference\n"
"Pointer to route-map entries\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_protocol = 2;
int source;
struct ospf_redist *red;
- if (!ospf)
- return CMD_SUCCESS;
- source = proto_redistnum(AFI_IP, argv[0]);
- if (source < 0 || source == ZEBRA_ROUTE_OSPF)
+ source = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
+ if (source < 0)
return CMD_WARNING;
red = ospf_redist_lookup(ospf, source, 0);
@@ -8155,8 +7173,7 @@ DEFUN (no_ospf_redistribute_source,
DEFUN (ospf_redistribute_instance_source,
ospf_redistribute_instance_source_cmd,
- "redistribute (ospf|table) <1-65535>"
- " {metric <0-16777214>|metric-type (1|2)|route-map WORD}",
+ "redistribute <ospf|table> (1-65535) [<metric (0-16777214)|metric-type (1-2)|route-map WORD>]",
REDIST_STR
"Open Shortest Path First\n"
"Non-main Kernel Routing Table\n"
@@ -8169,7 +7186,10 @@ DEFUN (ospf_redistribute_instance_source,
"Route map reference\n"
"Pointer to route-map entries\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ospf_table = 1;
+ int idx_number = 2;
+ int idx_redist_param = 3;
int source;
int type = -1;
int metric = -1;
@@ -8179,12 +7199,9 @@ DEFUN (ospf_redistribute_instance_source,
if (!ospf)
return CMD_SUCCESS;
- if (strncmp(argv[0], "o", 1) == 0)
- source = ZEBRA_ROUTE_OSPF;
- else
- source = ZEBRA_ROUTE_TABLE;
+ source = proto_redistnum (AFI_IP, argv[idx_ospf_table]->text);
- VTY_GET_INTEGER ("Instance ID", instance, argv[1]);
+ VTY_GET_INTEGER ("Instance ID", instance, argv[idx_number]->arg);
if (!ospf)
return CMD_SUCCESS;
@@ -8204,18 +7221,19 @@ DEFUN (ospf_redistribute_instance_source,
}
/* Get metric value. */
- if (argv[2] != NULL)
- if (!str2metric (argv[2], &metric))
+ if (strcmp (argv[idx_redist_param]->arg, "metric") == 0)
+ if (!str2metric (argv[idx_redist_param+1]->arg, &metric))
return CMD_WARNING;
/* Get metric type. */
- if (argv[3] != NULL)
- if (!str2metric_type (argv[3], &type))
+ if (strcmp (argv[idx_redist_param]->arg, "metric-type") == 0)
+ if (!str2metric_type (argv[idx_redist_param+1]->arg, &type))
return CMD_WARNING;
red = ospf_redist_add(ospf, source, instance);
- if (argv[4] != NULL)
- ospf_routemap_set (red, argv[4]);
+
+ if (strcmp (argv[idx_redist_param]->arg, "route-map") == 0)
+ ospf_routemap_set (red, argv[idx_redist_param+1]->arg);
else
ospf_routemap_unset (red);
@@ -8224,8 +7242,7 @@ DEFUN (ospf_redistribute_instance_source,
DEFUN (no_ospf_redistribute_instance_source,
no_ospf_redistribute_instance_source_cmd,
- "no redistribute (ospf|table) <1-65535>"
- " {metric <0-16777214>|metric-type (1|2)|route-map WORD}",
+ "no redistribute <ospf|table> (1-65535) [<metric (0-16777214)|metric-type (1-2)|route-map WORD>]",
NO_STR
REDIST_STR
"Open Shortest Path First\n"
@@ -8239,20 +7256,19 @@ DEFUN (no_ospf_redistribute_instance_source,
"Route map reference\n"
"Pointer to route-map entries\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_ospf_table = 2;
+ int idx_number = 3;
u_int instance;
struct ospf_redist *red;
int source;
- if (!ospf)
- return CMD_SUCCESS;
-
- if (strncmp(argv[0], "o", 1) == 0)
+ if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
source = ZEBRA_ROUTE_OSPF;
else
source = ZEBRA_ROUTE_TABLE;
- VTY_GET_INTEGER ("Instance ID", instance, argv[1]);
+ VTY_GET_INTEGER ("Instance ID", instance, argv[idx_number]->arg);
if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance)
{
@@ -8284,18 +7300,18 @@ DEFUN (ospf_distribute_list_out,
OUT_STR
FRR_REDIST_HELP_STR_OSPFD)
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_word = 1;
int source;
- if (!ospf)
- return CMD_SUCCESS;
+ char *proto = argv[argc - 1]->text;
/* Get distribute source. */
- source = proto_redistnum(AFI_IP, argv[1]);
- if (source < 0 || source == ZEBRA_ROUTE_OSPF)
+ source = proto_redistnum(AFI_IP, proto);
+ if (source < 0)
return CMD_WARNING;
- return ospf_distribute_list_out_set (ospf, source, argv[0]);
+ return ospf_distribute_list_out_set (ospf, source, argv[idx_word]->arg);
}
DEFUN (no_ospf_distribute_list_out,
@@ -8307,24 +7323,22 @@ DEFUN (no_ospf_distribute_list_out,
OUT_STR
FRR_REDIST_HELP_STR_OSPFD)
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_word = 2;
int source;
- if (!ospf)
- return CMD_SUCCESS;
-
- source = proto_redistnum(AFI_IP, argv[1]);
- if (source < 0 || source == ZEBRA_ROUTE_OSPF)
+ char *proto = argv[argc - 1]->text;
+ source = proto_redistnum(AFI_IP, proto);
+ if (source < 0)
return CMD_WARNING;
- return ospf_distribute_list_out_unset (ospf, source, argv[0]);
+ return ospf_distribute_list_out_unset (ospf, source, argv[idx_word]->arg);
}
/* Default information originate. */
DEFUN (ospf_default_information_originate,
ospf_default_information_originate_cmd,
- "default-information originate "
- "{always|metric <0-16777214>|metric-type (1|2)|route-map WORD}",
+ "default-information originate [<always|metric (0-16777214)|metric-type (1-2)|route-map WORD>]",
"Control distribution of default information\n"
"Distribute a default route\n"
"Always advertise default route\n"
@@ -8336,36 +7350,31 @@ DEFUN (ospf_default_information_originate,
"Route map reference\n"
"Pointer to route-map entries\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
int default_originate = DEFAULT_ORIGINATE_ZEBRA;
int type = -1;
int metric = -1;
struct ospf_redist *red;
+ int idx = 0;
- if (!ospf)
- return CMD_SUCCESS;
-
- if (argc < 4)
- return CMD_WARNING; /* this should not happen */
+ red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
/* Check whether "always" was specified */
- if (argv[0] != NULL)
+ if (argv_find (argv, argc, "always", &idx))
default_originate = DEFAULT_ORIGINATE_ALWAYS;
-
- red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
-
- /* Get metric value. */
- if (argv[1] != NULL)
- if (!str2metric (argv[1], &metric))
+ /* Get metric value */
+ else if (argv_find (argv, argc, "(0-16777214)", &idx)) {
+ if (!str2metric (argv[idx]->arg, &metric))
return CMD_WARNING;
-
+ }
/* Get metric type. */
- if (argv[2] != NULL)
- if (!str2metric_type (argv[2], &type))
+ else if (argv_find (argv, argc, "(1-2)", &idx)) {
+ if (!str2metric_type (argv[idx]->arg, &type))
return CMD_WARNING;
-
- if (argv[3] != NULL)
- ospf_routemap_set (red, argv[3]);
+ }
+ /* Get route-map */
+ else if (argv_find (argv, argc, "WORD", &idx))
+ ospf_routemap_set (red, argv[idx]->arg);
else
ospf_routemap_unset (red);
@@ -8375,8 +7384,7 @@ DEFUN (ospf_default_information_originate,
DEFUN (no_ospf_default_information_originate,
no_ospf_default_information_originate_cmd,
- "no default-information originate"
- "{always|metric <0-16777214>|metric-type (1|2)|route-map WORD}",
+ "no default-information originate [<always|metric (0-16777214)|metric-type (1-2)|route-map WORD>]",
NO_STR
"Control distribution of default information\n"
"Distribute a default route\n"
@@ -8389,13 +7397,10 @@ DEFUN (no_ospf_default_information_originate,
"Route map reference\n"
"Pointer to route-map entries\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
struct prefix_ipv4 p;
struct ospf_external *ext;
struct ospf_redist *red;
-
- if (!ospf)
- return CMD_SUCCESS;
p.family = AF_INET;
p.prefix.s_addr = 0;
@@ -8419,17 +7424,15 @@ DEFUN (no_ospf_default_information_originate,
DEFUN (ospf_default_metric,
ospf_default_metric_cmd,
- "default-metric <0-16777214>",
+ "default-metric (0-16777214)",
"Set metric of redistributed routes\n"
"Default metric\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 1;
int metric = -1;
- if (!ospf)
- return CMD_SUCCESS;
-
- if (!str2metric (argv[0], &metric))
+ if (!str2metric (argv[idx_number]->arg, &metric))
return CMD_WARNING;
ospf->default_metric = metric;
@@ -8439,54 +7442,41 @@ DEFUN (ospf_default_metric,
DEFUN (no_ospf_default_metric,
no_ospf_default_metric_cmd,
- "no default-metric",
+ "no default-metric [(0-16777214)]",
NO_STR
- "Set metric of redistributed routes\n")
+ "Set metric of redistributed routes\n"
+ "Default metric\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
ospf->default_metric = -1;
return CMD_SUCCESS;
}
-ALIAS (no_ospf_default_metric,
- no_ospf_default_metric_val_cmd,
- "no default-metric <0-16777214>",
- NO_STR
- "Set metric of redistributed routes\n"
- "Default metric\n")
DEFUN (ospf_distance,
ospf_distance_cmd,
- "distance <1-255>",
+ "distance (1-255)",
"Define an administrative distance\n"
"OSPF Administrative distance\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 1;
- if (!ospf)
- return CMD_SUCCESS;
-
- ospf->distance_all = atoi (argv[0]);
+ ospf->distance_all = atoi (argv[idx_number]->arg);
return CMD_SUCCESS;
}
DEFUN (no_ospf_distance,
no_ospf_distance_cmd,
- "no distance <1-255>",
+ "no distance (1-255)",
NO_STR
"Define an administrative distance\n"
"OSPF Administrative distance\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
ospf->distance_all = 0;
@@ -8495,7 +7485,7 @@ DEFUN (no_ospf_distance,
DEFUN (no_ospf_distance_ospf,
no_ospf_distance_ospf_cmd,
- "no distance ospf {intra-area <1-255>|inter-area <1-255>|external <1-255>}",
+ "no distance ospf [<intra-area (1-255)|inter-area (1-255)|external (1-255)>]",
NO_STR
"Define an administrative distance\n"
"OSPF Administrative distance\n"
@@ -8506,7 +7496,8 @@ DEFUN (no_ospf_distance_ospf,
"External routes\n"
"Distance for external routes\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_area_distance = 3;
if (!ospf)
return CMD_SUCCESS;
@@ -8517,7 +7508,7 @@ DEFUN (no_ospf_distance_ospf,
if (!ospf)
return CMD_SUCCESS;
- if (argv[0] != NULL)
+ if (argv[idx_area_distance]->arg != NULL)
ospf->distance_intra = 0;
if (argv[1] != NULL)
@@ -8526,7 +7517,7 @@ DEFUN (no_ospf_distance_ospf,
if (argv[2] != NULL)
ospf->distance_external = 0;
- if (argv[0] || argv[1] || argv[2])
+ if (argv[idx_area_distance]->arg || argv[1] || argv[2])
return CMD_SUCCESS;
/* If no arguments are given, clear all distance information */
@@ -8539,8 +7530,7 @@ DEFUN (no_ospf_distance_ospf,
DEFUN (ospf_distance_ospf,
ospf_distance_ospf_cmd,
- "distance ospf "
- "{intra-area <1-255>|inter-area <1-255>|external <1-255>}",
+ "distance ospf [<intra-area (1-255)|inter-area (1-255)|external (1-255)>]",
"Define an administrative distance\n"
"OSPF Administrative distance\n"
"Intra-area routes\n"
@@ -8550,123 +7540,134 @@ DEFUN (ospf_distance_ospf,
"External routes\n"
"Distance for external routes\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_area_distance = 2;
if (argc < 3) /* should not happen */
return CMD_WARNING;
- if (!argv[0] && !argv[1] && !argv[2])
+ if (!argv[idx_area_distance]->arg && !argv[1] && !argv[2])
{
vty_out(vty, "%% Command incomplete. (Arguments required)%s",
VTY_NEWLINE);
return CMD_WARNING;
}
- if (argv[0] != NULL)
- ospf->distance_intra = atoi(argv[0]);
+ if (strcmp (argv[idx_area_distance]->text, "intra") == 0)
+ ospf->distance_intra = atoi(argv[idx_area_distance+1]->arg);
- if (argv[1] != NULL)
- ospf->distance_inter = atoi(argv[1]);
+ if (strcmp (argv[idx_area_distance]->text, "inter") == 0)
+ ospf->distance_inter = atoi(argv[idx_area_distance+1]->arg);
- if (argv[2] != NULL)
- ospf->distance_external = atoi(argv[2]);
+ if (strcmp (argv[idx_area_distance]->text, "external") == 0)
+ ospf->distance_external = atoi(argv[idx_area_distance+1]->arg);
return CMD_SUCCESS;
}
+#if 0
DEFUN (ospf_distance_source,
ospf_distance_source_cmd,
- "distance <1-255> A.B.C.D/M",
+ "distance (1-255) A.B.C.D/M",
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 1;
+ int idx_ipv4_prefixlen = 2;
if (!ospf)
return CMD_SUCCESS;
- ospf_distance_set (vty, ospf, argv[0], argv[1], NULL);
+ ospf_distance_set (vty, ospf, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
return CMD_SUCCESS;
}
DEFUN (no_ospf_distance_source,
no_ospf_distance_source_cmd,
- "no distance <1-255> A.B.C.D/M",
+ "no distance (1-255) A.B.C.D/M",
NO_STR
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 2;
+ int idx_ipv4_prefixlen = 3;
if (!ospf)
return CMD_SUCCESS;
- ospf_distance_unset (vty, ospf, argv[0], argv[1], NULL);
+ ospf_distance_unset (vty, ospf, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
return CMD_SUCCESS;
}
DEFUN (ospf_distance_source_access_list,
ospf_distance_source_access_list_cmd,
- "distance <1-255> A.B.C.D/M WORD",
+ "distance (1-255) A.B.C.D/M WORD",
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n"
"Access list name\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 1;
+ int idx_ipv4_prefixlen = 2;
+ int idx_word = 3;
if (!ospf)
return CMD_SUCCESS;
- ospf_distance_set (vty, ospf, argv[0], argv[1], argv[2]);
+ ospf_distance_set (vty, ospf, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
return CMD_SUCCESS;
}
DEFUN (no_ospf_distance_source_access_list,
no_ospf_distance_source_access_list_cmd,
- "no distance <1-255> A.B.C.D/M WORD",
+ "no distance (1-255) A.B.C.D/M WORD",
NO_STR
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n"
"Access list name\n")
{
- struct ospf *ospf = vty->index;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 2;
+ int idx_ipv4_prefixlen = 3;
+ int idx_word = 4;
if (!ospf)
return CMD_SUCCESS;
- ospf_distance_unset (vty, ospf, argv[0], argv[1], argv[2]);
+ ospf_distance_unset (vty, ospf, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
return CMD_SUCCESS;
}
+#endif
DEFUN (ip_ospf_mtu_ignore,
ip_ospf_mtu_ignore_addr_cmd,
- "ip ospf mtu-ignore A.B.C.D",
+ "ip ospf mtu-ignore [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
- "Disable mtu mismatch detection\n"
+ "Disable MTU mismatch detection on this interface\n"
"Address of interface")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_ipv4 = 3;
struct in_addr addr;
int ret;
struct ospf_if_params *params;
params = IF_DEF_PARAMS (ifp);
- if (argc == 1)
+ if (argc == 4)
{
- ret = inet_aton(argv[0], &addr);
+ ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret)
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
@@ -8691,32 +7692,25 @@ DEFUN (ip_ospf_mtu_ignore,
return CMD_SUCCESS;
}
-ALIAS (ip_ospf_mtu_ignore,
- ip_ospf_mtu_ignore_cmd,
- "ip ospf mtu-ignore",
- "IP Information\n"
- "OSPF interface commands\n"
- "Disable mtu mismatch detection\n")
-
-
DEFUN (no_ip_ospf_mtu_ignore,
no_ip_ospf_mtu_ignore_addr_cmd,
- "no ip ospf mtu-ignore A.B.C.D",
+ "no ip ospf mtu-ignore [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
- "Disable mtu mismatch detection\n"
+ "Disable MTU mismatch detection on this interface\n"
"Address of interface")
{
- struct interface *ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_ipv4 = 4;
struct in_addr addr;
int ret;
struct ospf_if_params *params;
params = IF_DEF_PARAMS (ifp);
- if (argc == 1)
+ if (argc == 5)
{
- ret = inet_aton(argv[0], &addr);
+ ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret)
{
vty_out (vty, "Please specify interface address by A.B.C.D%s",
@@ -8741,12 +7735,6 @@ DEFUN (no_ip_ospf_mtu_ignore,
return CMD_SUCCESS;
}
-ALIAS (no_ip_ospf_mtu_ignore,
- no_ip_ospf_mtu_ignore_cmd,
- "no ip ospf mtu-ignore",
- "IP Information\n"
- "OSPF interface commands\n"
- "Disable mtu mismatch detection\n")
DEFUN (ospf_max_metric_router_lsa_admin,
ospf_max_metric_router_lsa_admin_cmd,
@@ -8755,12 +7743,9 @@ DEFUN (ospf_max_metric_router_lsa_admin,
"Advertise own Router-LSA with infinite distance (stub router)\n"
"Administratively applied, for an indefinite period\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
struct listnode *ln;
struct ospf_area *area;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
{
@@ -8784,12 +7769,9 @@ DEFUN (no_ospf_max_metric_router_lsa_admin,
"Advertise own Router-LSA with infinite distance (stub router)\n"
"Administratively applied, for an indefinite period\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
struct listnode *ln;
struct ospf_area *area;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
{
@@ -8809,17 +7791,15 @@ DEFUN (no_ospf_max_metric_router_lsa_admin,
DEFUN (ospf_max_metric_router_lsa_startup,
ospf_max_metric_router_lsa_startup_cmd,
- "max-metric router-lsa on-startup <5-86400>",
+ "max-metric router-lsa on-startup (5-86400)",
"OSPF maximum / infinite-distance metric\n"
"Advertise own Router-LSA with infinite distance (stub router)\n"
"Automatically advertise stub Router-LSA on startup of OSPF\n"
"Time (seconds) to advertise self as stub-router\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 3;
unsigned int seconds;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
if (argc != 1)
{
@@ -8827,7 +7807,7 @@ DEFUN (ospf_max_metric_router_lsa_startup,
return CMD_WARNING;
}
- VTY_GET_INTEGER ("stub-router startup period", seconds, argv[0]);
+ VTY_GET_INTEGER ("stub-router startup period", seconds, argv[idx_number]->arg);
ospf->stub_router_startup_time = seconds;
@@ -8836,19 +7816,16 @@ DEFUN (ospf_max_metric_router_lsa_startup,
DEFUN (no_ospf_max_metric_router_lsa_startup,
no_ospf_max_metric_router_lsa_startup_cmd,
- "no max-metric router-lsa on-startup <5-86400>",
+ "no max-metric router-lsa on-startup [(5-86400)]",
NO_STR
"OSPF maximum / infinite-distance metric\n"
"Advertise own Router-LSA with infinite distance (stub router)\n"
"Automatically advertise stub Router-LSA on startup of OSPF\n"
"Time (seconds) to advertise self as stub-router\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
struct listnode *ln;
struct ospf_area *area;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
ospf->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
@@ -8867,27 +7844,18 @@ DEFUN (no_ospf_max_metric_router_lsa_startup,
return CMD_SUCCESS;
}
-ALIAS (no_ospf_max_metric_router_lsa_startup,
- no_ospf_max_metric_router_lsa_startup_no_param_cmd,
- "no max-metric router-lsa on-startup",
- NO_STR
- "OSPF maximum / infinite-distance metric\n"
- "Advertise own Router-LSA with infinite distance (stub router)\n"
- "Automatically advertise stub Router-LSA on startup of OSPF\n");
DEFUN (ospf_max_metric_router_lsa_shutdown,
ospf_max_metric_router_lsa_shutdown_cmd,
- "max-metric router-lsa on-shutdown <5-100>",
+ "max-metric router-lsa on-shutdown (5-100)",
"OSPF maximum / infinite-distance metric\n"
"Advertise own Router-LSA with infinite distance (stub router)\n"
"Advertise stub-router prior to full shutdown of OSPF\n"
"Time (seconds) to wait till full shutdown\n")
{
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
+ int idx_number = 3;
unsigned int seconds;
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
if (argc != 1)
{
@@ -8895,7 +7863,7 @@ DEFUN (ospf_max_metric_router_lsa_shutdown,
return CMD_WARNING;
}
- VTY_GET_INTEGER ("stub-router shutdown wait period", seconds, argv[0]);
+ VTY_GET_INTEGER ("stub-router shutdown wait period", seconds, argv[idx_number]->arg);
ospf->stub_router_shutdown_time = seconds;
@@ -8904,31 +7872,20 @@ DEFUN (ospf_max_metric_router_lsa_shutdown,
DEFUN (no_ospf_max_metric_router_lsa_shutdown,
no_ospf_max_metric_router_lsa_shutdown_cmd,
- "no max-metric router-lsa on-shutdown <5-100>",
+ "no max-metric router-lsa on-shutdown [(5-100)]",
NO_STR
"OSPF maximum / infinite-distance metric\n"
"Advertise own Router-LSA with infinite distance (stub router)\n"
"Advertise stub-router prior to full shutdown of OSPF\n"
"Time (seconds) to wait till full shutdown\n")
{
- struct ospf *ospf = vty->index;
-
- if (!ospf)
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf, ospf);
ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
return CMD_SUCCESS;
}
-ALIAS (no_ospf_max_metric_router_lsa_shutdown,
- no_ospf_max_metric_router_lsa_shutdown_no_param_cmd,
- "no max-metric router-lsa on-shutdown",
- NO_STR
- "OSPF maximum / infinite-distance metric\n"
- "Advertise own Router-LSA with infinite distance (stub router)\n"
- "Advertise stub-router prior to full shutdown of OSPF\n");
-
static void
config_write_stub_router (struct vty *vty, struct ospf *ospf)
{
@@ -9148,17 +8105,18 @@ DEFUN (show_ip_ospf_border_routers,
DEFUN (show_ip_ospf_instance_border_routers,
show_ip_ospf_instance_border_routers_cmd,
- "show ip ospf <1-65535> border-routers",
+ "show ip ospf (1-65535) border-routers",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
"Show all the ABR's and ASBR's\n")
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -9210,17 +8168,18 @@ DEFUN (show_ip_ospf_route,
DEFUN (show_ip_ospf_instance_route,
show_ip_ospf_instance_route_cmd,
- "show ip ospf <1-65535> route",
+ "show ip ospf (1-65535) route",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
"OSPF routing table\n")
{
+ int idx_number = 3;
struct ospf *ospf;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running)
return CMD_SUCCESS;
@@ -9992,21 +8951,12 @@ ospf_vty_show_init (void)
install_element (VIEW_NODE, &show_ip_ospf_instance_cmd);
/* "show ip ospf database" commands. */
- install_element (VIEW_NODE, &show_ip_ospf_database_type_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_database_type_id_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_database_type_id_adv_router_cmd);
install_element (VIEW_NODE, &show_ip_ospf_database_type_adv_router_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_database_type_id_self_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_database_type_self_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_database_cmd);
+ install_element (VIEW_NODE, &show_ip_ospf_database_max_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_adv_router_cmd);
install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_self_cmd);
- install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_self_cmd);
install_element (VIEW_NODE, &show_ip_ospf_instance_database_cmd);
+ install_element (VIEW_NODE, &show_ip_ospf_instance_database_max_cmd);
/* "show ip ospf interface" commands. */
install_element (VIEW_NODE, &show_ip_ospf_interface_cmd);
@@ -10053,126 +9003,70 @@ ospf_vty_if_init (void)
{
/* Install interface node. */
install_node (&interface_node, config_write_interface);
-
- install_element (CONFIG_NODE, &interface_cmd);
- install_element (CONFIG_NODE, &no_interface_cmd);
- install_default (INTERFACE_NODE);
-
- /* "description" commands. */
- install_element (INTERFACE_NODE, &interface_desc_cmd);
- install_element (INTERFACE_NODE, &no_interface_desc_cmd);
+ if_cmd_init ();
/* "ip ospf authentication" commands. */
install_element (INTERFACE_NODE, &ip_ospf_authentication_args_addr_cmd);
- install_element (INTERFACE_NODE, &ip_ospf_authentication_args_cmd);
install_element (INTERFACE_NODE, &ip_ospf_authentication_addr_cmd);
- install_element (INTERFACE_NODE, &ip_ospf_authentication_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_authentication_args_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_authentication_args_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_authentication_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_authentication_cmd);
install_element (INTERFACE_NODE, &ip_ospf_authentication_key_addr_cmd);
- install_element (INTERFACE_NODE, &ip_ospf_authentication_key_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_authentication_key_authkey_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_authentication_key_authkey_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_authentication_key_cmd);
+ install_element (INTERFACE_NODE, &no_ospf_authentication_key_authkey_addr_cmd);
/* "ip ospf message-digest-key" commands. */
- install_element (INTERFACE_NODE, &ip_ospf_message_digest_key_addr_cmd);
install_element (INTERFACE_NODE, &ip_ospf_message_digest_key_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_message_digest_key_addr_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_message_digest_key_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_message_digest_key_md5_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_message_digest_key_md5_cmd);
/* "ip ospf cost" commands. */
- install_element (INTERFACE_NODE, &ip_ospf_cost_u32_inet4_cmd);
- install_element (INTERFACE_NODE, &ip_ospf_cost_u32_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_cost_u32_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_cost_u32_inet4_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_cost_inet4_cmd);
+ install_element (INTERFACE_NODE, &ip_ospf_cost_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_cost_cmd);
/* "ip ospf mtu-ignore" commands. */
install_element (INTERFACE_NODE, &ip_ospf_mtu_ignore_addr_cmd);
- install_element (INTERFACE_NODE, &ip_ospf_mtu_ignore_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_mtu_ignore_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_mtu_ignore_cmd);
/* "ip ospf dead-interval" commands. */
- install_element (INTERFACE_NODE, &ip_ospf_dead_interval_addr_cmd);
install_element (INTERFACE_NODE, &ip_ospf_dead_interval_cmd);
install_element (INTERFACE_NODE, &ip_ospf_dead_interval_minimal_addr_cmd);
- install_element (INTERFACE_NODE, &ip_ospf_dead_interval_minimal_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_dead_interval_addr_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_dead_interval_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_dead_interval_seconds_cmd);
/* "ip ospf hello-interval" commands. */
- install_element (INTERFACE_NODE, &ip_ospf_hello_interval_addr_cmd);
install_element (INTERFACE_NODE, &ip_ospf_hello_interval_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_hello_interval_addr_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_hello_interval_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_hello_interval_seconds_cmd);
/* "ip ospf network" commands. */
install_element (INTERFACE_NODE, &ip_ospf_network_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_network_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_network_val_cmd);
/* "ip ospf priority" commands. */
- install_element (INTERFACE_NODE, &ip_ospf_priority_addr_cmd);
install_element (INTERFACE_NODE, &ip_ospf_priority_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_priority_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_priority_no_param_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_priority_addr_cmd);
/* "ip ospf retransmit-interval" commands. */
install_element (INTERFACE_NODE, &ip_ospf_retransmit_interval_addr_cmd);
- install_element (INTERFACE_NODE, &ip_ospf_retransmit_interval_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_retransmit_interval_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_retransmit_interval_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_retransmit_interval_sec_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_retransmit_interval_sec_cmd);
/* "ip ospf transmit-delay" commands. */
install_element (INTERFACE_NODE, &ip_ospf_transmit_delay_addr_cmd);
- install_element (INTERFACE_NODE, &ip_ospf_transmit_delay_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_sec_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_sec_cmd);
/* "ip ospf area" commands. */
install_element (INTERFACE_NODE, &ip_ospf_area_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_area_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_area_val_cmd);
- install_element (INTERFACE_NODE, &ip_ospf_instance_area_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_instance_area_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_instance_area_val_cmd);
/* These commands are compatibitliy for previous version. */
install_element (INTERFACE_NODE, &ospf_authentication_key_cmd);
- install_element (INTERFACE_NODE, &no_ospf_authentication_key_cmd);
- install_element (INTERFACE_NODE, &no_ospf_authentication_key_authkey_cmd);
- install_element (INTERFACE_NODE, &no_ospf_authentication_key_authkey_ip_cmd);
install_element (INTERFACE_NODE, &ospf_message_digest_key_cmd);
install_element (INTERFACE_NODE, &no_ospf_message_digest_key_cmd);
- install_element (INTERFACE_NODE, &ospf_cost_u32_cmd);
- install_element (INTERFACE_NODE, &ospf_cost_u32_inet4_cmd);
- install_element (INTERFACE_NODE, &no_ospf_cost_cmd);
- install_element (INTERFACE_NODE, &no_ospf_cost_u32_cmd);
- install_element (INTERFACE_NODE, &no_ospf_cost_u32_inet4_cmd);
- install_element (INTERFACE_NODE, &no_ospf_cost_inet4_cmd);
install_element (INTERFACE_NODE, &ospf_dead_interval_cmd);
install_element (INTERFACE_NODE, &no_ospf_dead_interval_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_dead_interval_minimal_addr_cmd);
- install_element (INTERFACE_NODE, &no_ip_ospf_dead_interval_minimal_cmd);
install_element (INTERFACE_NODE, &ospf_hello_interval_cmd);
install_element (INTERFACE_NODE, &no_ospf_hello_interval_cmd);
+ install_element (INTERFACE_NODE, &ospf_cost_cmd);
+ install_element (INTERFACE_NODE, &no_ospf_cost_cmd);
install_element (INTERFACE_NODE, &ospf_network_cmd);
install_element (INTERFACE_NODE, &no_ospf_network_cmd);
- install_element (INTERFACE_NODE, &no_ospf_network_val_cmd);
install_element (INTERFACE_NODE, &ospf_priority_cmd);
install_element (INTERFACE_NODE, &no_ospf_priority_cmd);
install_element (INTERFACE_NODE, &ospf_retransmit_interval_cmd);
@@ -10197,7 +9091,6 @@ ospf_vty_zebra_init (void)
install_element (OSPF_NODE, &ospf_default_metric_cmd);
install_element (OSPF_NODE, &no_ospf_default_metric_cmd);
- install_element (OSPF_NODE, &no_ospf_default_metric_val_cmd);
install_element (OSPF_NODE, &ospf_distance_cmd);
install_element (OSPF_NODE, &no_ospf_distance_cmd);
@@ -10238,17 +9131,18 @@ DEFUN (clear_ip_ospf_interface,
"Interface information\n"
"Interface name\n")
{
+ int idx_ifname = 4;
struct interface *ifp;
struct listnode *node;
- if (argc == 0) /* Clear all the ospfv2 interfaces. */
+ if (argc == 4) /* Clear all the ospfv2 interfaces. */
{
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
ospf_interface_clear(ifp);
}
else /* Interface name is specified. */
{
- if ((ifp = if_lookup_by_name (argv[0])) == NULL)
+ if ((ifp = if_lookup_by_name (argv[idx_ifname]->text)) == NULL)
vty_out (vty, "No such interface name%s", VTY_NEWLINE);
else
ospf_interface_clear(ifp);
@@ -10275,8 +9169,6 @@ ospf_vty_init (void)
install_element (CONFIG_NODE, &router_ospf_cmd);
install_element (CONFIG_NODE, &no_router_ospf_cmd);
- install_element (CONFIG_NODE, &router_ospf_instance_cmd);
- install_element (CONFIG_NODE, &no_router_ospf_instance_cmd);
install_default (OSPF_NODE);
@@ -10284,15 +9176,10 @@ ospf_vty_init (void)
install_element (OSPF_NODE, &ospf_router_id_cmd);
install_element (OSPF_NODE, &ospf_router_id_old_cmd);
install_element (OSPF_NODE, &no_ospf_router_id_cmd);
- install_element (OSPF_NODE, &no_ospf_router_id_val_cmd);
/* "passive-interface" commands. */
install_element (OSPF_NODE, &ospf_passive_interface_addr_cmd);
- install_element (OSPF_NODE, &ospf_passive_interface_cmd);
- install_element (OSPF_NODE, &ospf_passive_interface_default_cmd);
install_element (OSPF_NODE, &no_ospf_passive_interface_addr_cmd);
- install_element (OSPF_NODE, &no_ospf_passive_interface_cmd);
- install_element (OSPF_NODE, &no_ospf_passive_interface_default_cmd);
/* "ospf abr-type" commands. */
install_element (OSPF_NODE, &ospf_abr_type_cmd);
@@ -10305,10 +9192,10 @@ ospf_vty_init (void)
install_element (OSPF_NODE, &no_ospf_log_adjacency_changes_detail_cmd);
/* "ospf rfc1583-compatible" commands. */
- install_element (OSPF_NODE, &ospf_rfc1583_flag_cmd);
- install_element (OSPF_NODE, &no_ospf_rfc1583_flag_cmd);
install_element (OSPF_NODE, &ospf_compatible_rfc1583_cmd);
install_element (OSPF_NODE, &no_ospf_compatible_rfc1583_cmd);
+ install_element (OSPF_NODE, &ospf_rfc1583_flag_cmd);
+ install_element (OSPF_NODE, &no_ospf_rfc1583_flag_cmd);
/* "network area" commands. */
install_element (OSPF_NODE, &ospf_network_area_cmd);
@@ -10321,53 +9208,26 @@ ospf_vty_init (void)
/* "area range" commands. */
install_element (OSPF_NODE, &ospf_area_range_cmd);
- install_element (OSPF_NODE, &ospf_area_range_advertise_cmd);
install_element (OSPF_NODE, &ospf_area_range_cost_cmd);
- install_element (OSPF_NODE, &ospf_area_range_advertise_cost_cmd);
install_element (OSPF_NODE, &ospf_area_range_not_advertise_cmd);
install_element (OSPF_NODE, &no_ospf_area_range_cmd);
- install_element (OSPF_NODE, &no_ospf_area_range_advertise_cmd);
- install_element (OSPF_NODE, &no_ospf_area_range_cost_cmd);
- install_element (OSPF_NODE, &no_ospf_area_range_advertise_cost_cmd);
install_element (OSPF_NODE, &ospf_area_range_substitute_cmd);
install_element (OSPF_NODE, &no_ospf_area_range_substitute_cmd);
/* "area virtual-link" commands. */
install_element (OSPF_NODE, &ospf_area_vlink_cmd);
+ install_element (OSPF_NODE, &ospf_area_vlink_intervals_cmd);
install_element (OSPF_NODE, &no_ospf_area_vlink_cmd);
+ install_element (OSPF_NODE, &no_ospf_area_vlink_intervals_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_param1_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_param1_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_param2_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_param2_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_param3_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_param3_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_param4_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_param4_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_authtype_args_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_authtype_args_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_authtype_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_authtype_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_md5_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_md5_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_authkey_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_authkey_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_authtype_args_authkey_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_authtype_args_authkey_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_authtype_authkey_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_authtype_authkey_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_authtype_args_md5_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_authtype_args_md5_cmd);
- install_element (OSPF_NODE, &ospf_area_vlink_authtype_md5_cmd);
- install_element (OSPF_NODE, &no_ospf_area_vlink_authtype_md5_cmd);
/* "area stub" commands. */
install_element (OSPF_NODE, &ospf_area_stub_no_summary_cmd);
@@ -10381,7 +9241,6 @@ ospf_vty_init (void)
install_element (OSPF_NODE, &ospf_area_nssa_translate_cmd);
install_element (OSPF_NODE, &ospf_area_nssa_no_summary_cmd);
install_element (OSPF_NODE, &no_ospf_area_nssa_cmd);
- install_element (OSPF_NODE, &no_ospf_area_nssa_no_summary_cmd);
install_element (OSPF_NODE, &ospf_area_default_cost_cmd);
install_element (OSPF_NODE, &no_ospf_area_default_cost_cmd);
@@ -10401,57 +9260,42 @@ ospf_vty_init (void)
/* SPF timer commands */
install_element (OSPF_NODE, &ospf_timers_throttle_spf_cmd);
install_element (OSPF_NODE, &no_ospf_timers_throttle_spf_cmd);
- install_element (OSPF_NODE, &no_ospf_timers_throttle_spf_val_cmd);
/* LSA timers commands */
install_element (OSPF_NODE, &ospf_timers_min_ls_interval_cmd);
install_element (OSPF_NODE, &no_ospf_timers_min_ls_interval_cmd);
- install_element (OSPF_NODE, &no_ospf_timers_min_ls_interval_val_cmd);
install_element (OSPF_NODE, &ospf_timers_min_ls_arrival_cmd);
install_element (OSPF_NODE, &no_ospf_timers_min_ls_arrival_cmd);
- install_element (OSPF_NODE, &no_ospf_timers_min_ls_arrival_val_cmd);
install_element (OSPF_NODE, &ospf_timers_lsa_cmd);
install_element (OSPF_NODE, &no_ospf_timers_lsa_cmd);
- install_element (OSPF_NODE, &no_ospf_timers_lsa_val_cmd);
/* refresh timer commands */
install_element (OSPF_NODE, &ospf_refresh_timer_cmd);
install_element (OSPF_NODE, &no_ospf_refresh_timer_val_cmd);
- install_element (OSPF_NODE, &no_ospf_refresh_timer_cmd);
/* max-metric commands */
install_element (OSPF_NODE, &ospf_max_metric_router_lsa_admin_cmd);
install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_admin_cmd);
install_element (OSPF_NODE, &ospf_max_metric_router_lsa_startup_cmd);
install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_startup_cmd);
- install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_startup_no_param_cmd);
install_element (OSPF_NODE, &ospf_max_metric_router_lsa_shutdown_cmd);
install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_shutdown_cmd);
- install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_shutdown_no_param_cmd);
/* reference bandwidth commands */
install_element (OSPF_NODE, &ospf_auto_cost_reference_bandwidth_cmd);
install_element (OSPF_NODE, &no_ospf_auto_cost_reference_bandwidth_cmd);
- install_element (OSPF_NODE, &no_ospf_auto_cost_reference_bandwidth_val_cmd);
/* "neighbor" commands. */
install_element (OSPF_NODE, &ospf_neighbor_cmd);
- install_element (OSPF_NODE, &ospf_neighbor_priority_poll_interval_cmd);
- install_element (OSPF_NODE, &ospf_neighbor_priority_cmd);
install_element (OSPF_NODE, &ospf_neighbor_poll_interval_cmd);
- install_element (OSPF_NODE, &ospf_neighbor_poll_interval_priority_cmd);
install_element (OSPF_NODE, &no_ospf_neighbor_cmd);
- install_element (OSPF_NODE, &no_ospf_neighbor_priority_cmd);
- install_element (OSPF_NODE, &no_ospf_neighbor_poll_interval_cmd);
- install_element (OSPF_NODE, &no_ospf_neighbor_poll_interval_priority_cmd);
- install_element (OSPF_NODE, &no_ospf_neighbor_priority_pollinterval_cmd);
+ install_element (OSPF_NODE, &no_ospf_neighbor_poll_cmd);
/* write multiplier commands */
install_element (OSPF_NODE, &ospf_write_multiplier_cmd);
- install_element (OSPF_NODE, &no_ospf_write_multiplier_cmd);
install_element (OSPF_NODE, &write_multiplier_cmd);
+ install_element (OSPF_NODE, &no_ospf_write_multiplier_cmd);
install_element (OSPF_NODE, &no_write_multiplier_cmd);
- install_element (OSPF_NODE, &no_write_multiplier_val_cmd);
/* Init interface related vty commands. */
ospf_vty_if_init ();
diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h
index 7cfae417e3..8e93ed2691 100644
--- a/ospfd/ospf_zebra.h
+++ b/ospfd/ospf_zebra.h
@@ -42,8 +42,6 @@ struct ospf_distance
};
/* Prototypes */
-extern void ospf_zclient_start (void);
-
extern void ospf_zebra_add (struct prefix_ipv4 *, struct ospf_route *);
extern void ospf_zebra_delete (struct prefix_ipv4 *, struct ospf_route *);
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index b83093db3c..570734bd8c 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -55,6 +55,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "ospfd/ospf_ase.h"
+DEFINE_QOBJ_TYPE(ospf)
/* OSPF process wide configuration. */
static struct ospf_master ospf_master;
@@ -272,7 +273,7 @@ ospf_new (u_short instance)
new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
new, new->lsa_refresh_interval);
- new->lsa_refresher_started = quagga_monotime ();
+ new->lsa_refresher_started = monotime(NULL);
if ((new->fd = ospf_sock_init()) < 0)
{
@@ -292,6 +293,8 @@ ospf_new (u_short instance)
/* Enable "log-adjacency-changes" */
SET_FLAG(new->config, OSPF_LOG_ADJACENCY_CHANGES);
+ QOBJ_REG (new, ospf);
+
return new;
}
@@ -505,6 +508,8 @@ ospf_finish_final (struct ospf *ospf)
int i;
u_short instance = 0;
+ QOBJ_UNREG (ospf);
+
ospf_opaque_type11_lsa_term (ospf);
/* be nice if this worked, but it doesn't */
@@ -1578,7 +1583,7 @@ ospf_timers_refresh_set (struct ospf *ospf, int interval)
return 1;
time_left = ospf->lsa_refresh_interval -
- (quagga_monotime () - ospf->lsa_refresher_started);
+ (monotime(NULL) - ospf->lsa_refresher_started);
if (time_left > interval)
{
@@ -1597,7 +1602,7 @@ ospf_timers_refresh_unset (struct ospf *ospf)
int time_left;
time_left = ospf->lsa_refresh_interval -
- (quagga_monotime () - ospf->lsa_refresher_started);
+ (monotime(NULL) - ospf->lsa_refresher_started);
if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
{
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 01395ff985..8ebd3c4ec6 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -24,6 +24,7 @@
#define _ZEBRA_OSPFD_H
#include <zebra.h>
+#include "qobj.h"
#include "libospf.h"
#include "filter.h"
@@ -303,7 +304,10 @@ struct ospf
u_int32_t if_ospf_cli_count;
struct route_table *distance_table;
+
+ QOBJ_FIELDS
};
+DECLARE_QOBJ_TYPE(ospf)
/* OSPF area structure. */
struct ospf_area
diff --git a/pimd/Makefile.am b/pimd/Makefile.am
index 14c4a76ac9..5c40d2ac64 100644
--- a/pimd/Makefile.am
+++ b/pimd/Makefile.am
@@ -19,7 +19,6 @@
# 330, Boston, MA 02111-1307, USA.
# PIM_DEBUG_BYDEFAULT: Automatically enables all pimd "debug ..." commands
-# PIM_ZCLIENT_DEBUG: Support for internal ZEBRA client debugging
# PIM_CHECK_RECV_IFINDEX_SANITY: Compare socket ifindex with recv ifindex
# PIM_REPORT_RECV_IFINDEX_MISMATCH: Report sock/recv ifindex mismatch
# PIM_ENFORCE_LOOPFREE_MFC: Refuse adding looping MFC entries
@@ -27,9 +26,8 @@
PIM_DEFS =
#PIM_DEFS += -DPIM_DEBUG_BYDEFAULT
-PIM_DEFS += -DPIM_CHECK_RECV_IFINDEX_SANITY
+#PIM_DEFS += -DPIM_CHECK_RECV_IFINDEX_SANITY
#PIM_DEFS += -DPIM_REPORT_RECV_IFINDEX_MISMATCH
-PIM_DEFS += -DPIM_ZCLIENT_DEBUG
PIM_DEFS += -DPIM_ENFORCE_LOOPFREE_MFC
#PIM_DEFS += -DPIM_UNEXPECTED_KERNEL_UPCALL
@@ -47,24 +45,26 @@ noinst_PROGRAMS = test_igmpv3_join
libpim_a_SOURCES = \
pim_memory.c \
pimd.c pim_version.c pim_cmd.c pim_signals.c pim_iface.c \
- pim_vty.c pim_igmp.c pim_sock.c pim_zebra.c \
+ pim_vty.c pim_igmp.c pim_sock.c pim_zebra.c pim_igmpv2.c \
pim_igmpv3.c pim_str.c pim_mroute.c pim_util.c pim_time.c \
pim_oil.c pim_zlookup.c pim_pim.c pim_tlv.c pim_neighbor.c \
pim_hello.c pim_ifchannel.c pim_join.c pim_assert.c \
pim_msg.c pim_upstream.c pim_rpf.c pim_macro.c \
pim_ssmpingd.c pim_int.c pim_rp.c \
- pim_static.c pim_br.c pim_register.c pim_routemap.c
+ pim_static.c pim_br.c pim_register.c pim_routemap.c \
+ pim_msdp.c pim_msdp_socket.c pim_msdp_packet.c
noinst_HEADERS = \
pim_memory.h \
pimd.h pim_version.h pim_cmd.h pim_signals.h pim_iface.h \
- pim_vty.h pim_igmp.h pim_sock.h pim_zebra.h \
+ pim_vty.h pim_igmp.h pim_sock.h pim_zebra.h pim_igmpv2.h \
pim_igmpv3.h pim_str.h pim_mroute.h pim_util.h pim_time.h \
pim_oil.h pim_zlookup.h pim_pim.h pim_tlv.h pim_neighbor.h \
pim_hello.h pim_ifchannel.h pim_join.h pim_assert.h \
pim_msg.h pim_upstream.h pim_rpf.h pim_macro.h \
pim_igmp_join.h pim_ssmpingd.h pim_int.h pim_rp.h \
- pim_static.h pim_br.h pim_register.h
+ pim_static.h pim_br.h pim_register.h \
+ pim_msdp.h pim_msdp_socket.h pim_msdp_packet.h
pimd_SOURCES = \
pim_main.c $(libpim_a_SOURCES)
diff --git a/pimd/README b/pimd/README
index c8997808b6..3d03979a9a 100644
--- a/pimd/README
+++ b/pimd/README
@@ -1,18 +1,17 @@
INTRODUCTION
qpimd aims to implement a PIM (Protocol Independent Multicast)
- daemon for the Quagga Routing Suite.
+ daemon for the FRR Routing Suite.
- Initially qpimd targets only PIM SSM (Source-Specific
- Multicast) mode as defined in section 4.8.2 (PIM-SSM-Only
- Routers) of RFC 4601.
+ qpimd implements PIM-SM (Sparse Mode) of RFC 4601.
+ Additionally MSDP has been implemented.
In order to deliver end-to-end multicast routing control
- plane, qpimd includes the router-side of IGMPv3 (RFC 3376).
+ plane, qpimd includes the router-side of IGMPv[2|3] (RFC 3376).
LICENSE
- qpimd - pimd for quagga
+ qpimd - pimd for FRR
Copyright (C) 2008 Everton da Silva Marques
qpimd is free software; you can redistribute it and/or modify
@@ -34,78 +33,16 @@ HOME SITE
qpimd lives at:
- https://github.com/udhos/qpimd
+ https://github.com/freerangerouting/frr
PLATFORMS
- qpimd has been tested with Debian Lenny under Linux 2.6.
+ qpimd has been tested with Debian Jessie.
REQUIREMENTS
- qpimd requires Quagga (0.99.11 or higher from http://www.quagga.net)
+ qpimd requires FRR (2.0 or higher)
- The GNU Build System (Autotools) is required to build from
- source code repository.
-
- gawk is also needed to build with Autotools. Any other awk
- usually won't work.
-
-BUILDING FROM QUAGGA GIT REPOSITORY
-
- 1) Get the latest quagga source tree
-
- # git clone git://code.quagga.net/quagga.git quagga
-
- 2) Apply qpimd patch into quagga source tree
-
- # patch -p1 -d quagga < pimd-0.153-quagga-git20090623.patch
-
- 3) Compile and install quagga
-
- # cd quagga
- # ./bootstrap.sh
- # ./configure --prefix=/usr/local/quagga --enable-pimd
- # make
- # make install
-
-BUILDING FROM QUAGGA TARBALL
-
- 1) Get the latest quagga tarball
-
- # wget http://www.quagga.net/download/quagga-0.99.13.tar.gz
-
- 2) Unpack the quagga tarball
-
- # tar xzf quagga-0.99.13.tar.gz
-
- 3) Apply qpimd patch into quagga source tree
-
- # patch -p1 -d quagga-0.99.13 < pimd-0.153-quagga-0.99.13.patch
-
- 4) Compile and install quagga
-
- # cd quagga-0.99.13
- # ./configure --prefix=/usr/local/quagga --enable-pimd
- # make
- # make install
-
-USAGE
-
- 1) Configure and start the zebra daemon
-
- # cp /usr/local/quagga/etc/zebra.conf.sample /usr/local/quagga/etc/zebra.conf
- # vi /usr/local/quagga/etc/zebra.conf
- # /usr/local/quagga/sbin/zebra
-
- 2) Configure and start the pimd daemon
-
- # cp /usr/local/quagga/etc/pimd.conf.sample /usr/local/quagga/etc/pimd.conf
- # vi /usr/local/quagga/etc/pimd.conf
- # /usr/local/quagga/sbin/pimd
-
- 3) Access pimd vty interface at port TCP 2611
-
- # telnet localhost 2611
CONFIGURATION COMMANDS
@@ -120,7 +57,7 @@ SUPPORT
Please post comments, questions, patches, bug reports at the
support site:
- https://github.com/udhos/qpimd
+ https://freerangerouting/frr
RELATED WORK
diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c
index f09540ea00..d6f372cc44 100644
--- a/pimd/pim_assert.c
+++ b/pimd/pim_assert.c
@@ -54,31 +54,23 @@ void pim_ifassert_winner_set(struct pim_ifchannel *ch,
if (PIM_DEBUG_PIM_EVENTS) {
if (ch->ifassert_state != new_state) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s: (S,G)=(%s,%s) assert state changed from %s to %s on interface %s",
- __PRETTY_FUNCTION__,
- src_str, grp_str,
- pim_ifchannel_ifassert_name(ch->ifassert_state),
- pim_ifchannel_ifassert_name(new_state),
- ch->interface->name);
+ zlog_debug("%s: (S,G)=%s assert state changed from %s to %s on interface %s",
+ __PRETTY_FUNCTION__,
+ ch->sg_str,
+ pim_ifchannel_ifassert_name(ch->ifassert_state),
+ pim_ifchannel_ifassert_name(new_state),
+ ch->interface->name);
}
if (winner_changed) {
- char src_str[100];
- char grp_str[100];
- char was_str[100];
- char winner_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
+ char was_str[INET_ADDRSTRLEN];
+ char winner_str[INET_ADDRSTRLEN];
pim_inet4_dump("<was?>", ch->ifassert_winner, was_str, sizeof(was_str));
pim_inet4_dump("<winner?>", winner, winner_str, sizeof(winner_str));
- zlog_debug("%s: (S,G)=(%s,%s) assert winner changed from %s to %s on interface %s",
- __PRETTY_FUNCTION__,
- src_str, grp_str,
- was_str, winner_str, ch->interface->name);
+ zlog_debug("%s: (S,G)=%s assert winner changed from %s to %s on interface %s",
+ __PRETTY_FUNCTION__,
+ ch->sg_str,
+ was_str, winner_str, ch->interface->name);
}
} /* PIM_DEBUG_PIM_EVENTS */
@@ -98,7 +90,7 @@ static void on_trace(const char *label,
struct interface *ifp, struct in_addr src)
{
if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
zlog_debug("%s: from %s on %s",
label, src_str, ifp->name);
@@ -138,13 +130,9 @@ static void if_could_assert_do_a1(const char *caller,
{
if (PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
if (assert_action_a1(ch)) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: %s: (S,G)=(%s,%s) assert_action_a1 failure on interface %s",
+ zlog_warn("%s: %s: (S,G)=%s assert_action_a1 failure on interface %s",
__PRETTY_FUNCTION__, caller,
- src_str, grp_str, ch->interface->name);
+ ch->sg_str, ch->interface->name);
/* log warning only */
}
}
@@ -156,16 +144,16 @@ static int dispatch_assert(struct interface *ifp,
struct pim_assert_metric recv_metric)
{
struct pim_ifchannel *ch;
+ struct prefix_sg sg;
- ch = pim_ifchannel_add(ifp, source_addr, group_addr);
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = source_addr;
+ sg.grp = group_addr;
+ ch = pim_ifchannel_add(ifp, &sg, 0);
if (!ch) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- zlog_warn("%s: (S,G)=(%s,%s) failure creating channel on interface %s",
+ zlog_warn("%s: (S,G)=%s failure creating channel on interface %s",
__PRETTY_FUNCTION__,
- source_str, group_str, ifp->name);
+ pim_str_sg_dump (&sg), ifp->name);
return -1;
}
@@ -193,7 +181,6 @@ static int dispatch_assert(struct interface *ifp,
}
else {
if (inferior_assert(&ch->ifassert_my_metric, &recv_metric)) {
- zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER); /* a3 requirement */
assert_action_a3(ch);
}
}
@@ -222,13 +209,9 @@ static int dispatch_assert(struct interface *ifp,
break;
default:
{
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- zlog_warn("%s: (S,G)=(%s,%s) invalid assert state %d on interface %s",
+ zlog_warn("%s: (S,G)=%s invalid assert state %d on interface %s",
__PRETTY_FUNCTION__,
- source_str, group_str, ch->ifassert_state, ifp->name);
+ ch->sg_str, ch->ifassert_state, ifp->name);
}
return -2;
}
@@ -241,7 +224,7 @@ int pim_assert_recv(struct interface *ifp,
struct in_addr src_addr,
uint8_t *buf, int buf_size)
{
- struct prefix msg_group_addr;
+ struct prefix_sg sg;
struct prefix msg_source_addr;
struct pim_assert_metric msg_metric;
int offset;
@@ -256,9 +239,10 @@ int pim_assert_recv(struct interface *ifp,
/*
Parse assert group addr
*/
- offset = pim_parse_addr_group (&msg_group_addr, curr, curr_size);
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ offset = pim_parse_addr_group (&sg, curr, curr_size);
if (offset < 1) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: pim_parse_addr_group() failure: from %s on %s",
__PRETTY_FUNCTION__,
@@ -273,7 +257,7 @@ int pim_assert_recv(struct interface *ifp,
*/
offset = pim_parse_addr_ucast (&msg_source_addr, curr, curr_size);
if (offset < 1) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
__PRETTY_FUNCTION__,
@@ -284,7 +268,7 @@ int pim_assert_recv(struct interface *ifp,
curr_size -= offset;
if (curr_size != 8) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: preference/metric size is not 8: size=%d from %s on interface %s",
__PRETTY_FUNCTION__,
@@ -311,12 +295,12 @@ int pim_assert_recv(struct interface *ifp,
msg_metric.route_metric = pim_read_uint32_host(curr);
if (PIM_DEBUG_PIM_TRACE) {
- char neigh_str[100];
- char source_str[100];
- char group_str[100];
+ char neigh_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<neigh?>", src_addr, neigh_str, sizeof(neigh_str));
pim_inet4_dump("<src?>", msg_source_addr.u.prefix4, source_str, sizeof(source_str));
- pim_inet4_dump("<grp?>", msg_group_addr.u.prefix4, group_str, sizeof(group_str));
+ pim_inet4_dump("<grp?>", sg.grp, group_str, sizeof(group_str));
zlog_debug("%s: from %s on %s: (S,G)=(%s,%s) pref=%u metric=%u rpt_bit=%u",
__PRETTY_FUNCTION__, neigh_str, ifp->name,
source_str, group_str,
@@ -329,7 +313,7 @@ int pim_assert_recv(struct interface *ifp,
return dispatch_assert(ifp,
msg_source_addr.u.prefix4,
- msg_group_addr.u.prefix4,
+ sg.grp,
msg_metric);
}
@@ -399,7 +383,7 @@ int pim_assert_build_msg(uint8_t *pim_msg, int buf_size,
remain,
group_addr);
if (!pim_msg_curr) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
zlog_warn("%s: failure encoding group address %s: space left=%d",
__PRETTY_FUNCTION__, group_str, remain);
@@ -412,7 +396,7 @@ int pim_assert_build_msg(uint8_t *pim_msg, int buf_size,
remain,
source_addr);
if (!pim_msg_curr) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: failure encoding source address %s: space left=%d",
__PRETTY_FUNCTION__, source_str, remain);
@@ -448,17 +432,23 @@ static int pim_assert_do(struct pim_ifchannel *ch,
int pim_msg_size;
ifp = ch->interface;
- zassert(ifp);
-
+ if (!ifp)
+ {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: channel%s has no associated interface!",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ return -1;
+ }
pim_ifp = ifp->info;
if (!pim_ifp) {
- zlog_warn("%s: pim not enabled on interface: %s",
- __PRETTY_FUNCTION__, ifp->name);
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: channel %s pim not enabled on interface: %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
return -1;
}
pim_msg_size = pim_assert_build_msg(pim_msg, sizeof(pim_msg), ifp,
- ch->group_addr, ch->source_addr,
+ ch->sg.grp, ch->sg.src,
metric.metric_preference,
metric.route_metric,
metric.rpt_bit_flag);
@@ -480,19 +470,16 @@ static int pim_assert_do(struct pim_ifchannel *ch,
pim_hello_require(ifp);
if (PIM_DEBUG_PIM_TRACE) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<grp?>", ch->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: to %s: (S,G)=(%s,%s) pref=%u metric=%u rpt_bit=%u",
+ zlog_debug("%s: to %s: (S,G)=%s pref=%u metric=%u rpt_bit=%u",
__PRETTY_FUNCTION__,
- ifp->name, source_str, group_str,
+ ifp->name, ch->sg_str,
metric.metric_preference,
metric.route_metric,
PIM_FORCE_BOOLEAN(metric.rpt_bit_flag));
}
if (pim_msg_send(pim_ifp->pim_sock_fd,
+ pim_ifp->primary_address,
qpim_all_pim_routers_addr,
pim_msg,
pim_msg_size,
@@ -523,7 +510,7 @@ static int pim_assert_cancel(struct pim_ifchannel *ch)
metric.rpt_bit_flag = 0;
metric.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_MAX;
metric.route_metric = PIM_ASSERT_ROUTE_METRIC_MAX;
- metric.ip_address = ch->source_addr;
+ metric.ip_address = ch->sg.src;
return pim_assert_do(ch, metric);
}
@@ -533,28 +520,20 @@ static int on_assert_timer(struct thread *t)
struct pim_ifchannel *ch;
struct interface *ifp;
- zassert(t);
ch = THREAD_ARG(t);
- zassert(ch);
ifp = ch->interface;
- zassert(ifp);
if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s: (S,G)=(%s,%s) timer expired on interface %s",
+ zlog_debug("%s: (S,G)=%s timer expired on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ ch->sg_str, ifp->name);
}
- ch->t_ifassert_timer = 0;
+ ch->t_ifassert_timer = NULL;
switch (ch->ifassert_state) {
case PIM_IFASSERT_I_AM_WINNER:
- zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER); /* a3 requirement */
assert_action_a3(ch);
break;
case PIM_IFASSERT_I_AM_LOSER:
@@ -562,13 +541,10 @@ static int on_assert_timer(struct thread *t)
break;
default:
{
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<grp?>", ch->group_addr, group_str, sizeof(group_str));
- zlog_warn("%s: (S,G)=(%s,%s) invalid assert state %d on interface %s",
- __PRETTY_FUNCTION__,
- source_str, group_str, ch->ifassert_state, ifp->name);
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn("%s: (S,G)=%s invalid assert state %d on interface %s",
+ __PRETTY_FUNCTION__,
+ ch->sg_str, ch->ifassert_state, ifp->name);
}
}
@@ -577,46 +553,25 @@ static int on_assert_timer(struct thread *t)
static void assert_timer_off(struct pim_ifchannel *ch)
{
- struct interface *ifp;
-
- zassert(ch);
- ifp = ch->interface;
- zassert(ifp);
-
if (PIM_DEBUG_PIM_TRACE) {
if (ch->t_ifassert_timer) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s: (S,G)=(%s,%s) cancelling timer on interface %s",
+ zlog_debug("%s: (S,G)=%s cancelling timer on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ ch->sg_str, ch->interface->name);
}
}
THREAD_OFF(ch->t_ifassert_timer);
- zassert(!ch->t_ifassert_timer);
}
static void pim_assert_timer_set(struct pim_ifchannel *ch,
int interval)
{
- struct interface *ifp;
-
- zassert(ch);
- ifp = ch->interface;
- zassert(ifp);
-
assert_timer_off(ch);
if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s: (S,G)=(%s,%s) starting %u sec timer on interface %s",
+ zlog_debug("%s: (S,G)=%s starting %u sec timer on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, interval, ifp->name);
+ ch->sg_str, interval, ch->interface->name);
}
THREAD_TIMER_ON(master, ch->t_ifassert_timer,
@@ -644,17 +599,11 @@ int assert_action_a1(struct pim_ifchannel *ch)
struct interface *ifp = ch->interface;
struct pim_interface *pim_ifp;
- zassert(ifp);
-
pim_ifp = ifp->info;
if (!pim_ifp) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: (S,G)=(%s,%s) multicast not enabled on interface %s",
+ zlog_warn("%s: (S,G)=%s multicast not enabled on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ ch->sg_str, ifp->name);
return -1; /* must return since pim_ifp is used below */
}
@@ -664,19 +613,19 @@ int assert_action_a1(struct pim_ifchannel *ch)
pim_macro_spt_assert_metric(&ch->upstream->rpf,
pim_ifp->primary_address));
- zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER); /* a3 requirement */
if (assert_action_a3(ch)) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: (S,G)=(%s,%s) assert_action_a3 failure on interface %s",
+ zlog_warn("%s: (S,G)=%s assert_action_a3 failure on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ ch->sg_str, ifp->name);
/* warning only */
}
- zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER);
+ if (ch->ifassert_state != PIM_IFASSERT_I_AM_WINNER)
+ {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn("%s: channel%s not in expected PIM_IFASSERT_I_AM_WINNER state",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
return 0;
}
@@ -699,7 +648,12 @@ static void assert_action_a2(struct pim_ifchannel *ch,
pim_assert_timer_set(ch, PIM_ASSERT_TIME);
- zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER);
+ if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
+ {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn("%s: channel%s not in expected PIM_IFASSERT_I_AM_LOSER state",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
}
/*
@@ -712,24 +666,23 @@ static void assert_action_a2(struct pim_ifchannel *ch,
*/
static int assert_action_a3(struct pim_ifchannel *ch)
{
- zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER);
+ if (ch->ifassert_state != PIM_IFASSERT_I_AM_WINNER)
+ {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn("%s: channel%s expected to be in PIM_IFASSERT_I_AM_WINNER state",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ return -1;
+ }
pim_assert_timer_reset(ch);
if (pim_assert_send(ch)) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
-
- zlog_warn("%s: (S,G)=(%s,%s) failure sending assert on interface %s",
+ zlog_warn("%s: (S,G)=%s failure sending assert on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ch->interface->name);
+ ch->sg_str, ch->interface->name);
return -1;
}
- zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER);
-
return 0;
}
@@ -746,19 +699,20 @@ static int assert_action_a3(struct pim_ifchannel *ch)
void assert_action_a4(struct pim_ifchannel *ch)
{
if (pim_assert_cancel(ch)) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: failure sending AssertCancel(%s,%s) on interface %s",
+ zlog_warn("%s: failure sending AssertCancel%s on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ch->interface->name);
+ ch->sg_str, ch->interface->name);
/* log warning only */
}
assert_action_a5(ch);
- zassert(ch->ifassert_state == PIM_IFASSERT_NOINFO);
+ if (ch->ifassert_state != PIM_IFASSERT_NOINFO)
+ {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn("%s: channel%s not in PIM_IFASSERT_NOINFO state as expected",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
}
/*
@@ -772,7 +726,12 @@ void assert_action_a4(struct pim_ifchannel *ch)
void assert_action_a5(struct pim_ifchannel *ch)
{
reset_ifassert_state(ch);
- zassert(ch->ifassert_state == PIM_IFASSERT_NOINFO);
+ if (ch->ifassert_state != PIM_IFASSERT_NOINFO)
+ {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn("%s: channel%s not in PIM_IFSSERT_NOINFO state as expected",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
}
/*
@@ -799,6 +758,11 @@ static void assert_action_a6(struct pim_ifchannel *ch,
if (ch->upstream->join_state == PIM_UPSTREAM_JOINED)
ch->upstream->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER);
+ if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
+ {
+ if(PIM_DEBUG_PIM_EVENTS)
+ zlog_warn("%s: channel%s not in PIM_IFASSERT_I_AM_LOSER state as expected",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
}
diff --git a/pimd/pim_br.c b/pimd/pim_br.c
index 121a45fd16..3f84de79c8 100644
--- a/pimd/pim_br.c
+++ b/pimd/pim_br.c
@@ -30,8 +30,7 @@
#include "linklist.h"
struct pim_br {
- struct in_addr source;
- struct in_addr group;
+ struct prefix_sg sg;
struct in_addr pmbr;
};
@@ -40,14 +39,14 @@ struct in_addr pim_br_unknown = { .s_addr = 0 };
static struct list *pim_br_list = NULL;
struct in_addr
-pim_br_get_pmbr (struct in_addr source, struct in_addr group)
+pim_br_get_pmbr (struct prefix_sg *sg)
{
struct listnode *node;
struct pim_br *pim_br;
for (ALL_LIST_ELEMENTS_RO (pim_br_list, node, pim_br)) {
- if (source.s_addr == pim_br->source.s_addr &&
- group.s_addr == pim_br->group.s_addr)
+ if (sg->src.s_addr == pim_br->sg.src.s_addr &&
+ sg->grp.s_addr == pim_br->sg.grp.s_addr)
return pim_br->pmbr;
}
@@ -55,14 +54,14 @@ pim_br_get_pmbr (struct in_addr source, struct in_addr group)
}
void
-pim_br_set_pmbr (struct in_addr source, struct in_addr group, struct in_addr br)
+pim_br_set_pmbr (struct prefix_sg *sg, struct in_addr br)
{
struct listnode *node, *next;
struct pim_br *pim_br;
for (ALL_LIST_ELEMENTS (pim_br_list, node, next, pim_br)) {
- if (source.s_addr == pim_br->source.s_addr &&
- group.s_addr == pim_br->group.s_addr)
+ if (sg->src.s_addr == pim_br->sg.src.s_addr &&
+ sg->grp.s_addr == pim_br->sg.grp.s_addr)
break;
}
@@ -73,8 +72,7 @@ pim_br_set_pmbr (struct in_addr source, struct in_addr group, struct in_addr br)
return;
}
- pim_br->source = source;
- pim_br->group = group;
+ pim_br->sg = *sg;
listnode_add(pim_br_list, pim_br);
}
@@ -86,14 +84,14 @@ pim_br_set_pmbr (struct in_addr source, struct in_addr group, struct in_addr br)
* Remove the (S,G) from the stored values
*/
void
-pim_br_clear_pmbr (struct in_addr source, struct in_addr group)
+pim_br_clear_pmbr (struct prefix_sg *sg)
{
struct listnode *node, *next;
struct pim_br *pim_br;
for (ALL_LIST_ELEMENTS (pim_br_list, node, next, pim_br)) {
- if (source.s_addr == pim_br->source.s_addr &&
- group.s_addr == pim_br->group.s_addr)
+ if (sg->src.s_addr == pim_br->sg.src.s_addr &&
+ sg->grp.s_addr == pim_br->sg.grp.s_addr)
break;
}
diff --git a/pimd/pim_br.h b/pimd/pim_br.h
index 06b10ada30..8e4f719ed0 100644
--- a/pimd/pim_br.h
+++ b/pimd/pim_br.h
@@ -21,10 +21,10 @@
#ifndef PIM_BR_H
#define PIM_BR_H
-struct in_addr pim_br_get_pmbr (struct in_addr source, struct in_addr group);
+struct in_addr pim_br_get_pmbr (struct prefix_sg *sg);
-void pim_br_set_pmbr (struct in_addr source, struct in_addr group, struct in_addr value);
-void pim_br_clear_pmbr (struct in_addr source, struct in_addr group);
+void pim_br_set_pmbr (struct prefix_sg *sg, struct in_addr value);
+void pim_br_clear_pmbr (struct prefix_sg *sg);
void pim_br_init (void);
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 3901992361..ae23499d97 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -20,10 +20,12 @@
#include <zebra.h>
+#include "lib/json.h"
#include "command.h"
#include "if.h"
#include "prefix.h"
#include "zclient.h"
+#include "plist.h"
#include "pimd.h"
#include "pim_mroute.h"
@@ -50,6 +52,8 @@
#include "pim_zebra.h"
#include "pim_static.h"
#include "pim_rp.h"
+#include "pim_zlookup.h"
+#include "pim_msdp.h"
static struct cmd_node pim_global_node = {
PIM_NODE,
@@ -63,6 +67,13 @@ static struct cmd_node interface_node = {
1 /* vtysh ? yes */
};
+static struct cmd_node debug_node =
+{
+ DEBUG_NODE,
+ "",
+ 1
+};
+
static void pim_if_membership_clear(struct interface *ifp)
{
struct pim_interface *pim_ifp;
@@ -127,9 +138,12 @@ static void pim_if_membership_refresh(struct interface *ifp)
for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) {
- pim_ifchannel_local_membership_add(ifp,
- src->source_addr,
- grp->group_addr);
+ struct prefix_sg sg;
+
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = src->source_addr;
+ sg.grp = grp->group_addr;
+ pim_ifchannel_local_membership_add(ifp, &sg);
}
} /* scan group sources */
@@ -146,9 +160,11 @@ static void pim_if_membership_refresh(struct interface *ifp)
static void pim_show_assert(struct vty *vty)
{
- struct listnode *ifnode;
- struct interface *ifp;
- time_t now;
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct listnode *ch_node;
+ struct in_addr ifaddr;
+ time_t now;
now = pim_time_monotonic_sec();
@@ -156,55 +172,50 @@ static void pim_show_assert(struct vty *vty)
"Interface Address Source Group State Winner Uptime Timer%s",
VTY_NEWLINE);
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+ char winner_str[INET_ADDRSTRLEN];
+ char uptime[10];
+ char timer[10];
- pim_ifp = ifp->info;
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
- char ch_src_str[100];
- char ch_grp_str[100];
- char winner_str[100];
- char uptime[10];
- char timer[10];
-
- pim_inet4_dump("<ch_src?>", ch->source_addr,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->group_addr,
- ch_grp_str, sizeof(ch_grp_str));
- pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
- winner_str, sizeof(winner_str));
+ pim_inet4_dump("<ch_src?>", ch->sg.src,
+ ch_src_str, sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+ ch_grp_str, sizeof(ch_grp_str));
+ pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
+ winner_str, sizeof(winner_str));
- pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
- pim_time_timer_to_mmss(timer, sizeof(timer),
- ch->t_ifassert_timer);
+ pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
+ pim_time_timer_to_mmss(timer, sizeof(timer),
+ ch->t_ifassert_timer);
- vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
- ifp->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- pim_ifchannel_ifassert_name(ch->ifassert_state),
- winner_str,
- uptime,
- timer,
- VTY_NEWLINE);
- } /* scan interface channels */
- } /* scan interfaces */
+ vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
+ ch->interface->name,
+ inet_ntoa(ifaddr),
+ ch_src_str,
+ ch_grp_str,
+ pim_ifchannel_ifassert_name(ch->ifassert_state),
+ winner_str,
+ uptime,
+ timer,
+ VTY_NEWLINE);
+ } /* scan interface channels */
}
static void pim_show_assert_internal(struct vty *vty)
{
- struct listnode *ifnode;
- struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+ struct in_addr ifaddr;
vty_out(vty,
"CA: CouldAssert%s"
@@ -217,210 +228,301 @@ static void pim_show_assert_internal(struct vty *vty)
"Interface Address Source Group CA eCA ATD eATD%s",
VTY_NEWLINE);
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
-
- pim_ifp = ifp->info;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
- char ch_src_str[100];
- char ch_grp_str[100];
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ch_src?>", ch->source_addr,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->group_addr,
- ch_grp_str, sizeof(ch_grp_str));
- vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
- ifp->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
- pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
- PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
- pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
- VTY_NEWLINE);
- } /* scan interface channels */
- } /* scan interfaces */
+ pim_inet4_dump("<ch_src?>", ch->sg.src,
+ ch_src_str, sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+ ch_grp_str, sizeof(ch_grp_str));
+ vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
+ ch->interface->name,
+ inet_ntoa(ifaddr),
+ ch_src_str,
+ ch_grp_str,
+ PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
+ pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
+ PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
+ pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
+ VTY_NEWLINE);
+ } /* scan interface channels */
}
static void pim_show_assert_metric(struct vty *vty)
{
- struct listnode *ifnode;
- struct interface *ifp;
-
+ struct pim_interface *pim_ifp;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+ struct in_addr ifaddr;
+
vty_out(vty,
"Interface Address Source Group RPT Pref Metric Address %s",
VTY_NEWLINE);
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+ pim_ifp = ch->interface->info;
- pim_ifp = ifp->info;
-
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
- char ch_src_str[100];
- char ch_grp_str[100];
- char addr_str[100];
- struct pim_assert_metric am;
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+ char addr_str[INET_ADDRSTRLEN];
+ struct pim_assert_metric am;
- am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
+ am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
- pim_inet4_dump("<ch_src?>", ch->source_addr,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->group_addr,
- ch_grp_str, sizeof(ch_grp_str));
- pim_inet4_dump("<addr?>", am.ip_address,
- addr_str, sizeof(addr_str));
+ pim_inet4_dump("<ch_src?>", ch->sg.src,
+ ch_src_str, sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+ ch_grp_str, sizeof(ch_grp_str));
+ pim_inet4_dump("<addr?>", am.ip_address,
+ addr_str, sizeof(addr_str));
- vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
- ifp->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- am.rpt_bit_flag ? "yes" : "no",
- am.metric_preference,
- am.route_metric,
- addr_str,
- VTY_NEWLINE);
+ vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
+ ch->interface->name,
+ inet_ntoa(ifaddr),
+ ch_src_str,
+ ch_grp_str,
+ am.rpt_bit_flag ? "yes" : "no",
+ am.metric_preference,
+ am.route_metric,
+ addr_str,
+ VTY_NEWLINE);
} /* scan interface channels */
- } /* scan interfaces */
}
static void pim_show_assert_winner_metric(struct vty *vty)
{
- struct listnode *ifnode;
- struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+ struct in_addr ifaddr;
vty_out(vty,
"Interface Address Source Group RPT Pref Metric Address %s",
VTY_NEWLINE);
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
-
- pim_ifp = ifp->info;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
- char ch_src_str[100];
- char ch_grp_str[100];
- char addr_str[100];
- struct pim_assert_metric *am;
- char pref_str[5];
- char metr_str[7];
-
- am = &ch->ifassert_winner_metric;
-
- pim_inet4_dump("<ch_src?>", ch->source_addr,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->group_addr,
- ch_grp_str, sizeof(ch_grp_str));
- pim_inet4_dump("<addr?>", am->ip_address,
- addr_str, sizeof(addr_str));
-
- if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
- snprintf(pref_str, sizeof(pref_str), "INFI");
- else
- snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+ char addr_str[INET_ADDRSTRLEN];
+ struct pim_assert_metric *am;
+ char pref_str[5];
+ char metr_str[7];
+
+ am = &ch->ifassert_winner_metric;
+
+ pim_inet4_dump("<ch_src?>", ch->sg.src,
+ ch_src_str, sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+ ch_grp_str, sizeof(ch_grp_str));
+ pim_inet4_dump("<addr?>", am->ip_address,
+ addr_str, sizeof(addr_str));
+
+ if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
+ snprintf(pref_str, sizeof(pref_str), "INFI");
+ else
+ snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
+
+ if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
+ snprintf(metr_str, sizeof(metr_str), "INFI");
+ else
+ snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
+
+ vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
+ ch->interface->name,
+ inet_ntoa(ifaddr),
+ ch_src_str,
+ ch_grp_str,
+ am->rpt_bit_flag ? "yes" : "no",
+ pref_str,
+ metr_str,
+ addr_str,
+ VTY_NEWLINE);
+ } /* scan interface channels */
+}
- if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
- snprintf(metr_str, sizeof(metr_str), "INFI");
- else
- snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
+static void json_object_pim_ifp_add(struct json_object *json, struct interface *ifp)
+{
+ struct pim_interface *pim_ifp;
- vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
- ifp->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- am->rpt_bit_flag ? "yes" : "no",
- pref_str,
- metr_str,
- addr_str,
- VTY_NEWLINE);
- } /* scan interface channels */
- } /* scan interfaces */
+ pim_ifp = ifp->info;
+ json_object_string_add(json, "name", ifp->name);
+ json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
+ json_object_string_add(json, "address", inet_ntoa(pim_ifp->primary_address));
+ json_object_int_add(json, "index", ifp->ifindex);
+
+ if (if_is_multicast(ifp))
+ json_object_boolean_true_add(json, "flagMulticast");
+
+ if (if_is_broadcast(ifp))
+ json_object_boolean_true_add(json, "flagBroadcast");
+
+ if (ifp->flags & IFF_ALLMULTI)
+ json_object_boolean_true_add(json, "flagAllMulticast");
+
+ if (ifp->flags & IFF_PROMISC)
+ json_object_boolean_true_add(json, "flagPromiscuous");
+
+ if (PIM_IF_IS_DELETED(ifp))
+ json_object_boolean_true_add(json, "flagDeleted");
+
+ if (pim_if_lan_delay_enabled(ifp))
+ json_object_boolean_true_add(json, "lanDelayEnabled");
}
-static void pim_show_membership(struct vty *vty)
+static void pim_show_membership(struct vty *vty, u_char uj)
{
- struct listnode *ifnode;
- struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+ enum json_type type;
+ json_object *json = NULL;
+ json_object *json_iface = NULL;
+ json_object *json_row = NULL;
+ json_object *json_tmp = NULL;
- vty_out(vty,
- "Interface Address Source Group Membership%s",
- VTY_NEWLINE);
+ json = json_object_new_object();
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+
+ pim_ifp = ch->interface->info;
- pim_ifp = ifp->info;
-
if (!pim_ifp)
continue;
- ifaddr = pim_ifp->primary_address;
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
- char ch_src_str[100];
- char ch_grp_str[100];
+ pim_inet4_dump("<ch_src?>", ch->sg.src,
+ ch_src_str, sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+ ch_grp_str, sizeof(ch_grp_str));
- pim_inet4_dump("<ch_src?>", ch->source_addr,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->group_addr,
- ch_grp_str, sizeof(ch_grp_str));
+ json_object_object_get_ex(json, ch->interface->name, &json_iface);
- vty_out(vty, "%-9s %-15s %-15s %-15s %-10s%s",
- ifp->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ?
- "NOINFO" : "INCLUDE",
- VTY_NEWLINE);
- } /* scan interface channels */
- } /* scan interfaces */
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ json_object_pim_ifp_add(json_iface, ch->interface);
+ json_object_object_add(json, ch->interface->name, json_iface);
+ }
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", ch_src_str);
+ json_object_string_add(json_row, "group", ch_grp_str);
+ json_object_string_add(json_row, "localMembership",
+ ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ? "NOINFO" : "INCLUDE");
+ json_object_object_add(json_iface, ch_grp_str, json_row);
+ } /* scan interface channels */
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ } else {
+ vty_out(vty,
+ "Interface Address Source Group Membership%s",
+ VTY_NEWLINE);
+
+ /*
+ * Example of the json data we are traversing
+ *
+ * {
+ * "swp3":{
+ * "name":"swp3",
+ * "state":"up",
+ * "address":"10.1.20.1",
+ * "index":5,
+ * "flagMulticast":true,
+ * "flagBroadcast":true,
+ * "lanDelayEnabled":true,
+ * "226.10.10.10":{
+ * "source":"*",
+ * "group":"226.10.10.10",
+ * "localMembership":"INCLUDE"
+ * }
+ * }
+ * }
+ */
+
+ /* foreach interface */
+ json_object_object_foreach(json, key, val) {
+
+ /* Find all of the keys where the val is an object. In the example
+ * above the only one is 226.10.10.10
+ */
+ json_object_object_foreach(val, if_field_key, if_field_val) {
+ type = json_object_get_type(if_field_val);
+
+ if (type == json_type_object) {
+ vty_out(vty, "%-9s ", key);
+
+ json_object_object_get_ex(val, "address", &json_tmp);
+ vty_out(vty, "%-15s ", json_object_get_string(json_tmp));
+
+ json_object_object_get_ex(if_field_val, "source", &json_tmp);
+ vty_out(vty, "%-15s ", json_object_get_string(json_tmp));
+
+ /* Group */
+ vty_out(vty, "%-15s ", if_field_key);
+
+ json_object_object_get_ex(if_field_val, "localMembership", &json_tmp);
+ vty_out(vty, "%-10s%s", json_object_get_string(json_tmp), VTY_NEWLINE);
+ }
+ }
+ }
+ }
+
+ json_object_free(json);
+}
+
+static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp, int mloop)
+{
+ vty_out(vty, "Flags%s", VTY_NEWLINE);
+ vty_out(vty, "-----%s", VTY_NEWLINE);
+ vty_out(vty, "All Multicast : %s%s", (ifp->flags & IFF_ALLMULTI) ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, "Broadcast : %s%s", if_is_broadcast(ifp)? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, "Deleted : %s%s", PIM_IF_IS_DELETED(ifp) ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, "Interface Index : %d%s", ifp->ifindex, VTY_NEWLINE);
+ vty_out(vty, "Multicast : %s%s", if_is_multicast(ifp) ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, "Multicast Loop : %d%s", mloop, VTY_NEWLINE);
+ vty_out(vty, "Promiscuous : %s%s", (ifp->flags & IFF_PROMISC) ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
}
-static void igmp_show_interfaces(struct vty *vty)
+static void igmp_show_interfaces(struct vty *vty, u_char uj)
{
struct listnode *node;
struct interface *ifp;
time_t now;
-
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
now = pim_time_monotonic_sec();
- vty_out(vty,
- "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s",
- VTY_NEWLINE);
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Interface State Address V Querier Query Timer Uptime%s",
+ VTY_NEWLINE);
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
struct pim_interface *pim_ifp;
@@ -428,33 +530,176 @@ static void igmp_show_interfaces(struct vty *vty)
struct igmp_sock *igmp;
pim_ifp = ifp->info;
-
+
if (!pim_ifp)
continue;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
char uptime[10];
- int mloop;
+ char query_hhmmss[10];
pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
+ pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
- mloop = pim_socket_mcastloop_get(igmp->fd);
-
- vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
- ifp->name,
- inet_ntoa(igmp->ifaddr),
- ifp->ifindex,
- igmp->fd,
- uptime,
- if_is_multicast(ifp) ? "yes" : "no",
- if_is_broadcast(ifp) ? "yes" : "no",
- (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
- (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
- (ifp->flags & IFF_PROMISC) ? "yes" : "no",
- PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
- VTY_NEWLINE);
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_int_add(json_row, "version", pim_ifp->igmp_version);
+
+ if (igmp->t_igmp_query_timer) {
+ json_object_boolean_true_add(json_row, "querier");
+ json_object_string_add(json_row, "queryTimer", query_hhmmss);
+ }
+
+ json_object_object_add(json, ifp->name, json_row);
+
+ } else {
+ vty_out(vty, "%-9s %5s %15s %d %7s %11s %8s%s",
+ ifp->name,
+ if_is_up(ifp) ? "up" : "down",
+ inet_ntoa(igmp->ifaddr),
+ pim_ifp->igmp_version,
+ igmp->t_igmp_query_timer ? "local" : "other",
+ query_hhmmss,
+ uptime,
+ VTY_NEWLINE);
+ }
+ }
+ }
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
+}
+
+static void igmp_show_interfaces_single(struct vty *vty, const char *ifname, u_char uj)
+{
+ struct igmp_sock *igmp;
+ struct interface *ifp;
+ struct listnode *node;
+ struct listnode *sock_node;
+ struct pim_interface *pim_ifp;
+ char uptime[10];
+ char query_hhmmss[10];
+ char other_hhmmss[10];
+ int found_ifname = 0;
+ int sqi;
+ int mloop;
+ long gmi_msec; /* Group Membership Interval */
+ long lmqt_msec;
+ long ohpi_msec;
+ long oqpi_msec; /* Other Querier Present Interval */
+ long qri_msec;
+ time_t now;
+
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+
+ now = pim_time_monotonic_sec();
+
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
+ found_ifname = 1;
+ pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
+ pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
+ pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
+
+ gmi_msec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
+ igmp->querier_query_interval,
+ pim_ifp->igmp_query_max_response_time_dsec);
+
+ sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
+
+ oqpi_msec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
+ igmp->querier_query_interval,
+ pim_ifp->igmp_query_max_response_time_dsec);
+
+ lmqt_msec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
+ igmp->querier_robustness_variable);
+
+ ohpi_msec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
+ igmp->querier_query_interval,
+ pim_ifp->igmp_query_max_response_time_dsec) * 100;
+
+ qri_msec = pim_ifp->igmp_query_max_response_time_dsec * 100;
+ mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_string_add(json_row, "querier", igmp->t_igmp_query_timer ? "local" : "other");
+ json_object_int_add(json_row, "queryStartCount", igmp->startup_query_count);
+ json_object_string_add(json_row, "queryQueryTimer", query_hhmmss);
+ json_object_string_add(json_row, "queryOtherTimer", other_hhmmss);
+ json_object_int_add(json_row, "version", pim_ifp->igmp_version);
+ json_object_int_add(json_row, "timerGroupMembershipIntervalMsec", gmi_msec);
+ json_object_int_add(json_row, "timerLastMemberQueryMsec", lmqt_msec);
+ json_object_int_add(json_row, "timerOlderHostPresentIntervalMsec", ohpi_msec);
+ json_object_int_add(json_row, "timerOtherQuerierPresentIntervalMsec", oqpi_msec);
+ json_object_int_add(json_row, "timerQueryInterval", igmp->querier_query_interval);
+ json_object_int_add(json_row, "timerQueryResponseIntervalMsec", qri_msec);
+ json_object_int_add(json_row, "timerRobustnessVariable", igmp->querier_robustness_variable);
+ json_object_int_add(json_row, "timerStartupQueryInterval", sqi);
+
+ json_object_object_add(json, ifp->name, json_row);
+
+ } else {
+ vty_out(vty, "Interface : %s%s", ifp->name, VTY_NEWLINE);
+ vty_out(vty, "State : %s%s", if_is_up(ifp) ? "up" : "down", VTY_NEWLINE);
+ vty_out(vty, "Address : %s%s", inet_ntoa(pim_ifp->primary_address), VTY_NEWLINE);
+ vty_out(vty, "Uptime : %s%s", uptime, VTY_NEWLINE);
+ vty_out(vty, "Version : %d%s", pim_ifp->igmp_version, VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ vty_out(vty, "Querier%s", VTY_NEWLINE);
+ vty_out(vty, "-------%s", VTY_NEWLINE);
+ vty_out(vty, "Querier : %s%s", igmp->t_igmp_query_timer ? "local" : "other", VTY_NEWLINE);
+ vty_out(vty, "Start Count : %d%s", igmp->startup_query_count, VTY_NEWLINE);
+ vty_out(vty, "Query Timer : %s%s", query_hhmmss, VTY_NEWLINE);
+ vty_out(vty, "Other Timer : %s%s", other_hhmmss, VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ vty_out(vty, "Timers%s", VTY_NEWLINE);
+ vty_out(vty, "------%s", VTY_NEWLINE);
+ vty_out(vty, "Group Membership Interval : %lis%s", gmi_msec/1000, VTY_NEWLINE);
+ vty_out(vty, "Last Member Query Time : %lis%s", lmqt_msec/1000, VTY_NEWLINE);
+ vty_out(vty, "Older Host Present Interval : %lis%s", ohpi_msec/1000, VTY_NEWLINE);
+ vty_out(vty, "Other Querier Present Interval : %lis%s", oqpi_msec/1000, VTY_NEWLINE);
+ vty_out(vty, "Query Interval : %ds%s", igmp->querier_query_interval, VTY_NEWLINE);
+ vty_out(vty, "Query Response Interval : %lis%s", qri_msec/1000, VTY_NEWLINE);
+ vty_out(vty, "Robustness Variable : %d%s", igmp->querier_robustness_variable, VTY_NEWLINE);
+ vty_out(vty, "Startup Query Interval : %ds%s", sqi, VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ pim_print_ifp_flags(vty, ifp, mloop);
+ }
}
}
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ } else {
+ if (!found_ifname)
+ vty_out (vty, "%% No such interface%s", VTY_NEWLINE);
+ }
}
static void igmp_show_interface_join(struct vty *vty)
@@ -474,7 +719,7 @@ static void igmp_show_interface_join(struct vty *vty)
struct listnode *join_node;
struct igmp_join *ij;
struct in_addr pri_addr;
- char pri_addr_str[100];
+ char pri_addr_str[INET_ADDRSTRLEN];
pim_ifp = ifp->info;
@@ -488,8 +733,8 @@ static void igmp_show_interface_join(struct vty *vty)
pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node, ij)) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
char uptime[10];
pim_time_uptime(uptime, sizeof(uptime), now - ij->sock_creation);
@@ -510,159 +755,297 @@ static void igmp_show_interface_join(struct vty *vty)
}
-static void show_interface_address(struct vty *vty)
+static void pim_show_interfaces_single(struct vty *vty, const char *ifname, u_char uj)
{
- struct listnode *ifpnode;
+ struct in_addr ifaddr;
struct interface *ifp;
-
- vty_out(vty,
- "Interface Primary Secondary %s",
- VTY_NEWLINE);
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifpnode, ifp)) {
- struct listnode *ifcnode;
- struct connected *ifc;
- struct in_addr pri_addr;
- char pri_addr_str[100];
-
- pri_addr = pim_find_primary_addr(ifp);
-
- pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
-
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, ifcnode, ifc)) {
- char sec_addr_str[100];
- struct prefix *p = ifc->address;
-
- if (p->family != AF_INET)
- continue;
-
- if (p->u.prefix4.s_addr == pri_addr.s_addr) {
- sec_addr_str[0] = '\0';
- }
- else {
- pim_inet4_dump("<sec?>", p->u.prefix4, sec_addr_str, sizeof(sec_addr_str));
- }
-
- vty_out(vty, "%-9s %-15s %-15s%s",
- ifp->name,
- pri_addr_str,
- sec_addr_str,
- VTY_NEWLINE);
- }
- }
-}
+ struct listnode *neighnode;
+ struct listnode*node;
+ struct listnode *upnode;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ struct pim_upstream *up;
+ time_t now;
+ char dr_str[INET_ADDRSTRLEN];
+ char dr_uptime[10];
+ char expire[10];
+ char grp_str[INET_ADDRSTRLEN];
+ char hello_period[10];
+ char hello_timer[10];
+ char neigh_src_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ char stat_uptime[10];
+ char uptime[10];
+ int mloop;
+ int found_ifname = 0;
+ int print_header;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+ json_object *json_pim_neighbor = NULL;
+ json_object *json_pim_neighbors = NULL;
+ json_object *json_group = NULL;
+ json_object *json_group_source = NULL;
+ json_object *json_fhr_sources = NULL;
+ struct pim_secondary_addr *sec_addr;
+ struct listnode *sec_node;
-static void pim_show_dr(struct vty *vty)
-{
- struct listnode *node;
- struct interface *ifp;
- time_t now;
-
now = pim_time_monotonic_sec();
- vty_out(vty,
- "NonPri: Number of neighbors missing DR Priority hello option%s"
- "DrPri: Designated Router Priority sent%s%s",
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
-
- vty_out(vty, "Interface Address DR Uptime Elections Changes NonPri DrPri%s", VTY_NEWLINE);
+ if (uj)
+ json = json_object_new_object();
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- char dr_str[100];
- char dr_uptime[10];
-
pim_ifp = ifp->info;
-
+
if (!pim_ifp)
continue;
if (pim_ifp->pim_sock_fd < 0)
continue;
+ if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
+ continue;
+
+ found_ifname = 1;
ifaddr = pim_ifp->primary_address;
+ pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str, sizeof(dr_str));
+ pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now, pim_ifp->pim_dr_election_last);
+ pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer), pim_ifp->t_pim_hello_timer);
+ pim_time_mmss(hello_period, sizeof(hello_period), pim_ifp->pim_hello_period);
+ pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start);
+ mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
- pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime),
- now, pim_ifp->pim_dr_election_last);
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
- pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr,
- dr_str, sizeof(dr_str));
+ if (pim_ifp->update_source.s_addr != INADDR_ANY) {
+ json_object_string_add(json_row, "useSource", inet_ntoa(pim_ifp->update_source));
+ }
+ if (pim_ifp->sec_addr_list) {
+ json_object *sec_list = NULL;
+
+ sec_list = json_object_new_array();
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, sec_node, sec_addr)) {
+ json_object_array_add(sec_list, json_object_new_string(inet_ntoa(sec_addr->addr)));
+ }
+ json_object_object_add(json_row, "secondaryAddressList", sec_list);
+ }
- vty_out(vty, "%-9s %-15s %-15s %8s %9d %7d %6d %10d%s",
- ifp->name,
- inet_ntoa(ifaddr),
- dr_str,
- dr_uptime,
- pim_ifp->pim_dr_election_count,
- pim_ifp->pim_dr_election_changes,
- pim_ifp->pim_dr_num_nondrpri_neighbors,
- pim_ifp->pim_dr_priority,
- VTY_NEWLINE);
- }
-}
+ // PIM neighbors
+ if (pim_ifp->pim_neighbor_list->count) {
+ json_pim_neighbors = json_object_new_object();
-static void pim_show_hello(struct vty *vty)
-{
- struct listnode *node;
- struct interface *ifp;
- time_t now;
-
- now = pim_time_monotonic_sec();
-
- vty_out(vty, "Interface Address Period Timer StatStart Recv Rfail Send Sfail%s", VTY_NEWLINE);
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
+ json_pim_neighbor = json_object_new_object();
+ pim_inet4_dump("<src?>", neigh->source_addr, neigh_src_str, sizeof(neigh_src_str));
+ pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire), neigh->t_expire_timer);
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- char hello_period[10];
- char hello_timer[10];
- char stat_uptime[10];
+ json_object_string_add(json_pim_neighbor, "address", neigh_src_str);
+ json_object_string_add(json_pim_neighbor, "upTime", uptime);
+ json_object_string_add(json_pim_neighbor, "holdtime", expire);
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
+ json_object_object_add(json_pim_neighbors, neigh_src_str, json_pim_neighbor);
+ }
- if (pim_ifp->pim_sock_fd < 0)
- continue;
+ json_object_object_add(json_row, "neighbors", json_pim_neighbors);
+ }
- ifaddr = pim_ifp->primary_address;
+ json_object_string_add(json_row, "drAddress", dr_str);
+ json_object_int_add(json_row, "drPriority", pim_ifp->pim_dr_priority);
+ json_object_string_add(json_row, "drUptime", dr_uptime);
+ json_object_int_add(json_row, "drElections", pim_ifp->pim_dr_election_count);
+ json_object_int_add(json_row, "drChanges", pim_ifp->pim_dr_election_changes);
+
+ // FHR
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
+ if (ifp == up->rpf.source_nexthop.interface) {
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR) {
+ if (!json_fhr_sources) {
+ json_fhr_sources = json_object_new_object();
+ }
+
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+ pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
+
+ /* Does this group live in json_fhr_sources? If not create it. */
+ json_object_object_get_ex(json_fhr_sources, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json_fhr_sources, grp_str, json_group);
+ }
+
+ json_group_source = json_object_new_object();
+ json_object_string_add(json_group_source, "source", src_str);
+ json_object_string_add(json_group_source, "group", grp_str);
+ json_object_string_add(json_group_source, "upTime", uptime);
+ json_object_object_add(json_group, src_str, json_group_source);
+ }
+ }
+ }
- pim_time_timer_to_mmss(hello_timer, sizeof(hello_timer), pim_ifp->t_pim_hello_timer);
- pim_time_mmss(hello_period, sizeof(hello_period), pim_ifp->pim_hello_period);
- pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start);
+ if (json_fhr_sources) {
+ json_object_object_add(json_row, "firstHopRouter", json_fhr_sources);
+ }
- vty_out(vty, "%-9s %-15s %6s %5s %9s %4u %5u %4u %5u%s",
- ifp->name,
- inet_ntoa(ifaddr),
- hello_period,
- hello_timer,
- stat_uptime,
- pim_ifp->pim_ifstat_hello_recv,
- pim_ifp->pim_ifstat_hello_recvfail,
- pim_ifp->pim_ifstat_hello_sent,
- pim_ifp->pim_ifstat_hello_sendfail,
- VTY_NEWLINE);
+ json_object_int_add(json_row, "helloPeriod", pim_ifp->pim_hello_period);
+ json_object_string_add(json_row, "helloTimer", hello_timer);
+ json_object_string_add(json_row, "helloStatStart", stat_uptime);
+ json_object_int_add(json_row, "helloReceived", pim_ifp->pim_ifstat_hello_recv);
+ json_object_int_add(json_row, "helloReceivedFailed", pim_ifp->pim_ifstat_hello_recvfail);
+ json_object_int_add(json_row, "helloSend", pim_ifp->pim_ifstat_hello_sent);
+ json_object_int_add(json_row, "hellosendFailed", pim_ifp->pim_ifstat_hello_sendfail);
+ json_object_int_add(json_row, "helloGenerationId", pim_ifp->pim_generation_id);
+ json_object_int_add(json_row, "flagMulticastLoop", mloop);
+
+ json_object_int_add(json_row, "effectivePropagationDelay", pim_if_effective_propagation_delay_msec(ifp));
+ json_object_int_add(json_row, "effectiveOverrideInterval", pim_if_effective_override_interval_msec(ifp));
+ json_object_int_add(json_row, "joinPruneOverrideInterval", pim_if_jp_override_interval_msec(ifp));
+
+ json_object_int_add(json_row, "propagationDelay", pim_ifp->pim_propagation_delay_msec);
+ json_object_int_add(json_row, "propagationDelayHighest", pim_ifp->pim_neighbors_highest_propagation_delay_msec);
+ json_object_int_add(json_row, "overrideInterval", pim_ifp->pim_override_interval_msec);
+ json_object_int_add(json_row, "overrideIntervalHighest", pim_ifp->pim_neighbors_highest_override_interval_msec);
+ json_object_object_add(json, ifp->name, json_row);
+
+ } else {
+ vty_out(vty, "Interface : %s%s", ifp->name, VTY_NEWLINE);
+ vty_out(vty, "State : %s%s", if_is_up(ifp) ? "up" : "down", VTY_NEWLINE);
+ if (pim_ifp->update_source.s_addr != INADDR_ANY) {
+ vty_out(vty, "Use Source : %s%s", inet_ntoa(pim_ifp->update_source), VTY_NEWLINE);
+ }
+ if (pim_ifp->sec_addr_list) {
+ vty_out(vty, "Address : %s (primary)%s",
+ inet_ntoa(ifaddr), VTY_NEWLINE);
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, sec_node, sec_addr)) {
+ vty_out(vty, " %s%s",
+ inet_ntoa(sec_addr->addr), VTY_NEWLINE);
+ }
+ } else {
+ vty_out(vty, "Address : %s%s", inet_ntoa(ifaddr), VTY_NEWLINE);
+ }
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ // PIM neighbors
+ print_header = 1;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
+
+ if (print_header) {
+ vty_out(vty, "PIM Neighbors%s", VTY_NEWLINE);
+ vty_out(vty, "-------------%s", VTY_NEWLINE);
+ print_header = 0;
+ }
+
+ pim_inet4_dump("<src?>", neigh->source_addr, neigh_src_str, sizeof(neigh_src_str));
+ pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire), neigh->t_expire_timer);
+ vty_out(vty, "%-15s : up for %s, holdtime expires in %s%s", neigh_src_str, uptime, expire, VTY_NEWLINE);
+ }
+
+ if (!print_header) {
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+
+ vty_out(vty, "Designated Router%s", VTY_NEWLINE);
+ vty_out(vty, "-----------------%s", VTY_NEWLINE);
+ vty_out(vty, "Address : %s%s", dr_str, VTY_NEWLINE);
+ vty_out(vty, "Priority : %d%s", pim_ifp->pim_dr_priority, VTY_NEWLINE);
+ vty_out(vty, "Uptime : %s%s", dr_uptime, VTY_NEWLINE);
+ vty_out(vty, "Elections : %d%s", pim_ifp->pim_dr_election_count, VTY_NEWLINE);
+ vty_out(vty, "Changes : %d%s", pim_ifp->pim_dr_election_changes, VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ // FHR
+ print_header = 1;
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
+ if (strcmp(ifp->name, up->rpf.source_nexthop.interface->name) == 0) {
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR) {
+
+ if (print_header) {
+ vty_out(vty, "FHR - First Hop Router%s", VTY_NEWLINE);
+ vty_out(vty, "----------------------%s", VTY_NEWLINE);
+ print_header = 0;
+ }
+
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+ pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
+ vty_out(vty, "%s : %s is a source, uptime is %s%s", grp_str, src_str, uptime, VTY_NEWLINE);
+ }
+ }
+ }
+
+ if (!print_header) {
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+
+ vty_out(vty, "Hellos%s", VTY_NEWLINE);
+ vty_out(vty, "------%s", VTY_NEWLINE);
+ vty_out(vty, "Period : %d%s", pim_ifp->pim_hello_period, VTY_NEWLINE);
+ vty_out(vty, "Timer : %s%s", hello_timer, VTY_NEWLINE);
+ vty_out(vty, "StatStart : %s%s", stat_uptime, VTY_NEWLINE);
+ vty_out(vty, "Receive : %d%s", pim_ifp->pim_ifstat_hello_recv, VTY_NEWLINE);
+ vty_out(vty, "Receive Failed : %d%s", pim_ifp->pim_ifstat_hello_recvfail, VTY_NEWLINE);
+ vty_out(vty, "Send : %d%s", pim_ifp->pim_ifstat_hello_sent, VTY_NEWLINE);
+ vty_out(vty, "Send Failed : %d%s", pim_ifp->pim_ifstat_hello_sendfail, VTY_NEWLINE);
+ vty_out(vty, "Generation ID : %08x%s", pim_ifp->pim_generation_id, VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ pim_print_ifp_flags(vty, ifp, mloop);
+
+ vty_out(vty, "Join Prune Interval%s", VTY_NEWLINE);
+ vty_out(vty, "-------------------%s", VTY_NEWLINE);
+ vty_out(vty, "LAN Delay : %s%s", pim_if_lan_delay_enabled(ifp) ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, "Effective Propagation Delay : %d msec%s", pim_if_effective_propagation_delay_msec(ifp), VTY_NEWLINE);
+ vty_out(vty, "Effective Override Interval : %d msec%s", pim_if_effective_override_interval_msec(ifp), VTY_NEWLINE);
+ vty_out(vty, "Join Prune Override Interval : %d msec%s", pim_if_jp_override_interval_msec(ifp), VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ vty_out(vty, "LAN Prune Delay%s", VTY_NEWLINE);
+ vty_out(vty, "---------------%s", VTY_NEWLINE);
+ vty_out(vty, "Propagation Delay : %d msec%s", pim_ifp->pim_propagation_delay_msec, VTY_NEWLINE);
+ vty_out(vty, "Propagation Delay (Highest) : %d msec%s", pim_ifp->pim_neighbors_highest_propagation_delay_msec, VTY_NEWLINE);
+ vty_out(vty, "Override Interval : %d msec%s", pim_ifp->pim_override_interval_msec, VTY_NEWLINE);
+ vty_out(vty, "Override Interval (Highest) : %d msec%s", pim_ifp->pim_neighbors_highest_override_interval_msec, VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+ }
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ } else {
+ if (!found_ifname)
+ vty_out (vty, "%% No such interface%s", VTY_NEWLINE);
}
}
-static void pim_show_interfaces(struct vty *vty)
+static void pim_show_interfaces(struct vty *vty, u_char uj)
{
- struct listnode *node;
struct interface *ifp;
- time_t now;
-
- now = pim_time_monotonic_sec();
+ struct listnode *node;
+ struct listnode *upnode;
+ struct pim_interface *pim_ifp;
+ struct pim_upstream *up;
+ int fhr = 0;
+ int pim_nbrs = 0;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+ json_object *json_tmp;
- vty_out(vty, "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s", VTY_NEWLINE);
+ json = json_object_new_object();
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- char uptime[10];
- int mloop;
-
pim_ifp = ifp->info;
if (!pim_ifp)
@@ -671,73 +1054,136 @@ static void pim_show_interfaces(struct vty *vty)
if (pim_ifp->pim_sock_fd < 0)
continue;
- ifaddr = pim_ifp->primary_address;
+ pim_nbrs = pim_ifp->pim_neighbor_list->count;
+ fhr = 0;
- pim_time_uptime(uptime, sizeof(uptime), now - pim_ifp->pim_sock_creation);
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up))
+ if (ifp == up->rpf.source_nexthop.interface)
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
+ fhr++;
- mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
-
- vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
- ifp->name,
- inet_ntoa(ifaddr),
- ifp->ifindex,
- pim_ifp->pim_sock_fd,
- uptime,
- if_is_multicast(ifp) ? "yes" : "no",
- if_is_broadcast(ifp) ? "yes" : "no",
- (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
- (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
- (ifp->flags & IFF_PROMISC) ? "yes" : "no",
- PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
- VTY_NEWLINE);
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+ json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
+ json_object_int_add(json_row, "firstHopRouter", fhr);
+ json_object_string_add(json_row, "pimDesignatedRouter", inet_ntoa(pim_ifp->pim_dr_addr));
+
+ if (pim_ifp->pim_dr_addr.s_addr == pim_ifp->primary_address.s_addr)
+ json_object_boolean_true_add(json_row, "pimDesignatedRouterLocal");
+
+ json_object_object_add(json, ifp->name, json_row);
+ }
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ } else {
+ vty_out(vty, "Interface State Address PIM Nbrs PIM DR FHR%s", VTY_NEWLINE);
+
+ json_object_object_foreach(json, key, val) {
+ vty_out(vty, "%-9s ", key);
+
+ json_object_object_get_ex(val, "state", &json_tmp);
+ vty_out(vty, "%5s ", json_object_get_string(json_tmp));
+
+ json_object_object_get_ex(val, "address", &json_tmp);
+ vty_out(vty, "%15s ", json_object_get_string(json_tmp));
+
+ json_object_object_get_ex(val, "pimNeighbors", &json_tmp);
+ vty_out(vty, "%8d ", json_object_get_int(json_tmp));
+
+ if (json_object_object_get_ex(val, "pimDesignatedRouterLocal", &json_tmp)) {
+ vty_out(vty, "%15s ", "local");
+ } else {
+ json_object_object_get_ex(val, "pimDesignatedRouter", &json_tmp);
+ vty_out(vty, "%15s ", json_object_get_string(json_tmp));
+ }
+
+ json_object_object_get_ex(val, "firstHopRouter", &json_tmp);
+ vty_out(vty, "%3d%s", json_object_get_int(json_tmp), VTY_NEWLINE);
+ }
}
+
+ json_object_free(json);
}
-static void pim_show_join(struct vty *vty)
+static void pim_show_join(struct vty *vty, u_char uj)
{
- struct listnode *ifnode;
- struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct in_addr ifaddr;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
time_t now;
+ json_object *json = NULL;
+ json_object *json_iface = NULL;
+ json_object *json_row = NULL;
+ json_object *json_grp = NULL;
now = pim_time_monotonic_sec();
- vty_out(vty,
- "Interface Address Source Group State Uptime Expire Prune%s",
- VTY_NEWLINE);
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Interface Address Source Group State Uptime Expire Prune%s",
+ VTY_NEWLINE);
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
- pim_ifp = ifp->info;
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
- char ch_src_str[100];
- char ch_grp_str[100];
- char uptime[10];
- char expire[10];
- char prune[10];
-
- pim_inet4_dump("<ch_src?>", ch->source_addr,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->group_addr,
- ch_grp_str, sizeof(ch_grp_str));
-
- pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
- pim_time_timer_to_mmss(expire, sizeof(expire),
- ch->t_ifjoin_expiry_timer);
- pim_time_timer_to_mmss(prune, sizeof(prune),
- ch->t_ifjoin_prune_pending_timer);
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+ char uptime[10];
+ char expire[10];
+ char prune[10];
+
+ pim_inet4_dump("<ch_src?>", ch->sg.src,
+ ch_src_str, sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp,
+ ch_grp_str, sizeof(ch_grp_str));
+
+ pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
+ pim_time_timer_to_mmss(expire, sizeof(expire),
+ ch->t_ifjoin_expiry_timer);
+ pim_time_timer_to_mmss(prune, sizeof(prune),
+ ch->t_ifjoin_prune_pending_timer);
+
+ if (uj) {
+ json_object_object_get_ex(json, ch->interface->name, &json_iface);
+
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ json_object_pim_ifp_add(json_iface, ch->interface);
+ json_object_object_add(json, ch->interface->name, json_iface);
+ }
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", ch_src_str);
+ json_object_string_add(json_row, "group", ch_grp_str);
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_string_add(json_row, "expire", expire);
+ json_object_string_add(json_row, "prune", prune);
+ json_object_string_add(json_row, "channelJoinName", pim_ifchannel_ifjoin_name(ch->ifjoin_state));
+ if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
+ json_object_int_add(json_row, "SGRpt", 1);
+
+ json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
+ if (!json_grp)
+ {
+ json_grp = json_object_new_object();
+ json_object_object_add(json_grp, ch_src_str, json_row);
+ json_object_object_add(json_iface, ch_grp_str, json_grp);
+ }
+ else
+ json_object_object_add(json_grp, ch_src_str, json_row);
+ } else {
vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
- ifp->name,
+ ch->interface->name,
inet_ntoa(ifaddr),
ch_src_str,
ch_grp_str,
@@ -746,172 +1192,374 @@ static void pim_show_join(struct vty *vty)
expire,
prune,
VTY_NEWLINE);
- } /* scan interface channels */
- } /* scan interfaces */
+ }
+ } /* scan interface channels */
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
}
-static void pim_show_neighbors(struct vty *vty)
+static void pim_show_neighbors_single(struct vty *vty, const char *neighbor, u_char uj)
{
struct listnode *node;
+ struct listnode *neighnode;
struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
time_t now;
-
- now = pim_time_monotonic_sec();
+ int found_neighbor = 0;
+ int option_address_list;
+ int option_dr_priority;
+ int option_generation_id;
+ int option_holdtime;
+ int option_lan_prune_delay;
+ int option_t_bit;
+ char uptime[10];
+ char expire[10];
+ char neigh_src_str[INET_ADDRSTRLEN];
+
+ json_object *json = NULL;
+ json_object *json_ifp = NULL;
+ json_object *json_row = NULL;
- vty_out(vty,
- "Recv flags: H=holdtime L=lan_prune_delay P=dr_priority G=generation_id A=address_list%s"
- " T=can_disable_join_suppression%s%s",
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
+ now = pim_time_monotonic_sec();
- vty_out(vty, "Interface Address Neighbor Uptime Timer Holdt DrPri GenId Recv %s", VTY_NEWLINE);
+ if (uj)
+ json = json_object_new_object();
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *neighnode;
- struct pim_neighbor *neigh;
-
pim_ifp = ifp->info;
-
+
if (!pim_ifp)
continue;
if (pim_ifp->pim_sock_fd < 0)
continue;
- ifaddr = pim_ifp->primary_address;
-
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
- char uptime[10];
- char holdtime[10];
- char expire[10];
- char neigh_src_str[100];
- char recv[7];
-
pim_inet4_dump("<src?>", neigh->source_addr,
neigh_src_str, sizeof(neigh_src_str));
+
+ /*
+ * The user can specify either the interface name or the PIM neighbor IP.
+ * If this pim_ifp matches neither then skip.
+ */
+ if (strcmp(neighbor, "detail") &&
+ strcmp(neighbor, ifp->name) &&
+ strcmp(neighbor, neigh_src_str))
+ continue;
+
+ found_neighbor = 1;
pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
- pim_time_mmss(holdtime, sizeof(holdtime), neigh->holdtime);
- pim_time_timer_to_mmss(expire, sizeof(expire), neigh->t_expire_timer);
-
- recv[0] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_HOLDTIME) ? 'H' : ' ';
- recv[1] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? 'L' : ' ';
- recv[2] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY) ? 'P' : ' ';
- recv[3] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID) ? 'G' : ' ';
- recv[4] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_ADDRESS_LIST) ? 'A' : ' ';
- recv[5] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION) ? 'T' : ' ';
- recv[6] = '\0';
-
- vty_out(vty, "%-9s %-15s %-15s %8s %5s %5s %5u %08x %6s%s",
- ifp->name,
- inet_ntoa(ifaddr),
- neigh_src_str,
- uptime,
- expire,
- holdtime,
- neigh->dr_priority,
- neigh->generation_id,
- recv,
- VTY_NEWLINE);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire), neigh->t_expire_timer);
+
+ option_address_list = 0;
+ option_dr_priority = 0;
+ option_generation_id = 0;
+ option_holdtime = 0;
+ option_lan_prune_delay = 0;
+ option_t_bit = 0;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_ADDRESS_LIST))
+ option_address_list = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY))
+ option_dr_priority = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID))
+ option_generation_id = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_HOLDTIME))
+ option_holdtime = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY))
+ option_lan_prune_delay = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
+ option_t_bit = 1;
+
+ if (uj) {
+
+ /* Does this ifp live in json? If not create it. */
+ json_object_object_get_ex(json, ifp->name, &json_ifp);
+
+ if (!json_ifp) {
+ json_ifp = json_object_new_object();
+ json_object_pim_ifp_add(json_ifp, ifp);
+ json_object_object_add(json, ifp->name, json_ifp);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "interface", ifp->name);
+ json_object_string_add(json_row, "address", neigh_src_str);
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_string_add(json_row, "holdtime", expire);
+ json_object_int_add(json_row, "drPriority", neigh->dr_priority);
+ json_object_int_add(json_row, "generationId", neigh->generation_id);
+
+ if (option_address_list)
+ json_object_boolean_true_add(json_row, "helloOptionAddressList");
+
+ if (option_dr_priority)
+ json_object_boolean_true_add(json_row, "helloOptionDrPriority");
+
+ if (option_generation_id)
+ json_object_boolean_true_add(json_row, "helloOptionGenerationId");
+
+ if (option_holdtime)
+ json_object_boolean_true_add(json_row, "helloOptionHoldtime");
+
+ if (option_lan_prune_delay)
+ json_object_boolean_true_add(json_row, "helloOptionLanPruneDelay");
+
+ if (option_t_bit)
+ json_object_boolean_true_add(json_row, "helloOptionTBit");
+
+ json_object_object_add(json_ifp, neigh_src_str, json_row);
+
+ } else {
+ vty_out(vty, "Interface : %s%s", ifp->name, VTY_NEWLINE);
+ vty_out(vty, "Neighbor : %s%s", neigh_src_str, VTY_NEWLINE);
+ vty_out(vty, " Uptime : %s%s", uptime, VTY_NEWLINE);
+ vty_out(vty, " Holdtime : %s%s", expire, VTY_NEWLINE);
+ vty_out(vty, " DR Priority : %d%s", neigh->dr_priority, VTY_NEWLINE);
+ vty_out(vty, " Generation ID : %08x%s", neigh->generation_id, VTY_NEWLINE);
+ vty_out(vty, " Override Interval (msec) : %d%s", neigh->override_interval_msec, VTY_NEWLINE);
+ vty_out(vty, " Propagation Delay (msec) : %d%s", neigh->propagation_delay_msec, VTY_NEWLINE);
+ vty_out(vty, " Hello Option - Address List : %s%s", option_address_list ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, " Hello Option - DR Priority : %s%s", option_dr_priority ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, " Hello Option - Generation ID : %s%s", option_generation_id? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, " Hello Option - Holdtime : %s%s", option_holdtime ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, " Hello Option - LAN Prune Delay : %s%s", option_lan_prune_delay ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, " Hello Option - T-bit : %s%s", option_t_bit ? "yes" : "no", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
}
+ }
-
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ } else {
+ {
+ if (!found_neighbor)
+ vty_out (vty, "%% No such interface or neighbor%s", VTY_NEWLINE);
+ }
}
}
-static void pim_show_lan_prune_delay(struct vty *vty)
+static void
+pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_char uj)
{
- struct listnode *node;
- struct interface *ifp;
+ struct channel_oil *c_oil;
+ struct listnode *node;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_ifp_in = NULL;
+ json_object *json_ifp_out = NULL;
+ json_object *json_source = NULL;
+ time_t now;
+ int first_oif;
+ now = pim_time_monotonic_sec();
- vty_out(vty,
- "PrDly=propagation_delay (msec) OvInt=override_interval (msec)%s"
- "HiDly=highest_propagation_delay (msec) HiInt=highest_override_interval (msec)%s"
- "NoDly=number_of_non_lan_delay_neighbors%s"
- "T=t_bit LPD=lan_prune_delay_hello_option%s%s",
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
+ vty_out(vty, "%sInstalled Source Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE);
+ }
- vty_out(vty, "Interface Address PrDly OvInt NoDly HiDly HiInt T | Neighbor LPD PrDly OvInt T%s", VTY_NEWLINE);
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ char grp_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ char in_ifname[INTERFACE_NAMSIZ+1];
+ char out_ifname[INTERFACE_NAMSIZ+1];
+ int oif_vif_index;
+ struct interface *ifp_in;
+ first_oif = 1;
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *neighnode;
- struct pim_neighbor *neigh;
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
+ ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
+ if (ifp_in)
+ strcpy(in_ifname, ifp_in->name);
+ else
+ strcpy(in_ifname, "<iif?>");
- if (pim_ifp->pim_sock_fd < 0)
- continue;
+ if (src_or_group)
+ {
+ if (strcmp(src_or_group, src_str) && strcmp(src_or_group, grp_str))
+ continue;
- ifaddr = pim_ifp->primary_address;
+ if (group && strcmp(group, grp_str))
+ continue;
+ }
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
- char neigh_src_str[100];
+ if (uj) {
- pim_inet4_dump("<src?>", neigh->source_addr,
- neigh_src_str, sizeof(neigh_src_str));
+ /* Find the group, create it if it doesn't exist */
+ json_object_object_get_ex(json, grp_str, &json_group);
- vty_out(vty, "%-9s %-15s %5u %5u %5u %5u %5u %1u | %-15s %-3s %5u %5u %1u%s",
- ifp->name,
- inet_ntoa(ifaddr),
- pim_ifp->pim_propagation_delay_msec,
- pim_ifp->pim_override_interval_msec,
- pim_ifp->pim_number_of_nonlandelay_neighbors,
- pim_ifp->pim_neighbors_highest_propagation_delay_msec,
- pim_ifp->pim_neighbors_highest_override_interval_msec,
- PIM_FORCE_BOOLEAN(PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options)),
- neigh_src_str,
- PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? "yes" : "no",
- neigh->propagation_delay_msec,
- neigh->override_interval_msec,
- PIM_FORCE_BOOLEAN(PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION)),
- VTY_NEWLINE);
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
+
+ /* Find the source nested under the group, create it if it doesn't exist */
+ json_object_object_get_ex(json_group, src_str, &json_source);
+
+ if (!json_source) {
+ json_source = json_object_new_object();
+ json_object_object_add(json_group, src_str, json_source);
+ }
+
+ /* Find the inbound interface nested under the source, create it if it doesn't exist */
+ json_object_object_get_ex(json_source, in_ifname, &json_ifp_in);
+
+ if (!json_ifp_in) {
+ json_ifp_in = json_object_new_object();
+ json_object_object_add(json_source, in_ifname, json_ifp_in);
+ }
+ } else {
+ vty_out(vty, "%-9d %-15s %-15s %-7s ",
+ c_oil->installed,
+ src_str,
+ grp_str,
+ ifp_in->name);
}
+ for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
+ struct interface *ifp_out;
+ char oif_uptime[10];
+ int ttl;
+
+ ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
+ if (ttl < 1)
+ continue;
+
+ ifp_out = pim_if_find_by_vif_index(oif_vif_index);
+ pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
+
+ if (ifp_out)
+ strcpy(out_ifname, ifp_out->name);
+ else
+ strcpy(out_ifname, "<oif?>");
+
+ if (uj) {
+ json_ifp_out = json_object_new_object();
+ json_object_string_add(json_ifp_out, "source", src_str);
+ json_object_string_add(json_ifp_out, "group", grp_str);
+ json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
+ json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
+ json_object_int_add(json_ifp_out, "installed", c_oil->installed);
+
+ json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
+ } else {
+ if (first_oif)
+ {
+ first_oif = 0;
+ vty_out(vty, "%s(%c%c%c%c)", out_ifname,
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ');
+ }
+ else
+ vty_out(vty, ", %s(%c%c%c%c)", out_ifname,
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ' );
+ }
+ }
+
+ if (!uj)
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ } else {
+ vty_out(vty, "%s", VTY_NEWLINE);
}
}
-static void pim_show_jp_override_interval(struct vty *vty)
+static void pim_show_neighbors(struct vty *vty, u_char uj)
{
- struct listnode *node;
+ struct listnode *node;
+ struct listnode *neighnode;
struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ time_t now;
+ char uptime[10];
+ char expire[10];
+ char neigh_src_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
+ json_object *json_ifp_rows = NULL;
+ json_object *json_row = NULL;
- vty_out(vty,
- "EffPDelay=effective_propagation_delay (msec)%s"
- "EffOvrInt=override_interval (msec)%s"
- "JPOvrInt=jp_override_interval (msec)%s%s",
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
+ now = pim_time_monotonic_sec();
- vty_out(vty, "Interface Address LAN_Delay EffPDelay EffOvrInt JPOvrInt%s", VTY_NEWLINE);
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty, "Interface Neighbor Uptime Holdtime DR Pri%s", VTY_NEWLINE);
+ }
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
-
pim_ifp = ifp->info;
-
+
if (!pim_ifp)
continue;
if (pim_ifp->pim_sock_fd < 0)
continue;
- ifaddr = pim_ifp->primary_address;
+ if (uj)
+ json_ifp_rows = json_object_new_object();
- vty_out(vty, "%-9s %-15s %-9s %9u %9u %8u%s",
- ifp->name,
- inet_ntoa(ifaddr),
- pim_if_lan_delay_enabled(ifp) ? "enabled" : "disabled",
- pim_if_effective_propagation_delay_msec(ifp),
- pim_if_effective_override_interval_msec(ifp),
- pim_if_jp_override_interval_msec(ifp),
- VTY_NEWLINE);
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
+ pim_inet4_dump("<src?>", neigh->source_addr,
+ neigh_src_str, sizeof(neigh_src_str));
+ pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire), neigh->t_expire_timer);
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "interface", ifp->name);
+ json_object_string_add(json_row, "neighbor", neigh_src_str);
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_string_add(json_row, "holdTime", expire);
+ json_object_int_add(json_row, "holdTimeMax", neigh->holdtime);
+ json_object_int_add(json_row, "drPriority", neigh->dr_priority);
+ json_object_object_add(json_ifp_rows, neigh_src_str, json_row);
+
+ } else {
+ vty_out(vty, "%-9s %15s %8s %8s %6d%s",
+ ifp->name,
+ neigh_src_str,
+ uptime,
+ expire,
+ neigh->dr_priority,
+ VTY_NEWLINE);
+ }
+ }
+
+ if (uj) {
+ json_object_object_add(json, ifp->name, json_ifp_rows);
+ json_ifp_rows = NULL;
+ }
+ }
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
}
}
@@ -939,7 +1587,7 @@ static void pim_show_neighbors_secondary(struct vty *vty)
ifaddr = pim_ifp->primary_address;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
- char neigh_src_str[100];
+ char neigh_src_str[INET_ADDRSTRLEN];
struct listnode *prefix_node;
struct prefix *p;
@@ -950,7 +1598,7 @@ static void pim_show_neighbors_secondary(struct vty *vty)
neigh_src_str, sizeof(neigh_src_str));
for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
- char neigh_sec_str[100];
+ char neigh_sec_str[INET_ADDRSTRLEN];
if (p->family != AF_INET)
continue;
@@ -969,68 +1617,169 @@ static void pim_show_neighbors_secondary(struct vty *vty)
}
}
-static void pim_show_upstream(struct vty *vty)
+static void
+json_object_pim_upstream_add (json_object *json, struct pim_upstream *up)
+{
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
+ json_object_boolean_true_add(json, "drJoinDesired");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
+ json_object_boolean_true_add(json, "drJoinDesiredUpdated");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
+ json_object_boolean_true_add(json, "firstHopRouter");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+ json_object_boolean_true_add(json, "sourceIgmp");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
+ json_object_boolean_true_add(json, "sourcePim");
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
+ json_object_boolean_true_add(json, "sourceStream");
+
+ /* XXX: need to print ths flag in the plain text display as well */
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
+ json_object_boolean_true_add(json, "sourceMsdp");
+}
+
+static void pim_show_upstream(struct vty *vty, u_char uj)
{
struct listnode *upnode;
struct pim_upstream *up;
time_t now;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
now = pim_time_monotonic_sec();
- vty_out(vty, "Iif Source Group State Uptime JoinTimer RefCnt%s", VTY_NEWLINE);
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty, "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s", VTY_NEWLINE);
- for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
- char src_str[100];
- char grp_str[100];
- char uptime[10];
- char join_timer[10];
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char uptime[10];
+ char join_timer[10];
+ char rs_timer[10];
+ char ka_timer[10];
+ char msdp_reg_timer[10];
+
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+ pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
+ pim_time_timer_to_hhmmss (join_timer, sizeof(join_timer), up->t_join_timer);
+ pim_time_timer_to_hhmmss (rs_timer, sizeof (rs_timer), up->t_rs_timer);
+ pim_time_timer_to_hhmmss (ka_timer, sizeof (ka_timer), up->t_ka_timer);
+ pim_time_timer_to_hhmmss (msdp_reg_timer, sizeof (msdp_reg_timer), up->t_msdp_reg_timer);
+
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
- pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer), up->t_join_timer);
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(json_row, "inboundInterface", up->rpf.source_nexthop.interface->name);
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "state", pim_upstream_state2str (up->join_state));
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_string_add(json_row, "joinTimer", join_timer);
+ json_object_string_add(json_row, "resetTimer", rs_timer);
+ json_object_string_add(json_row, "keepaliveTimer", ka_timer);
+ json_object_string_add(json_row, "msdpRegTimer", msdp_reg_timer);
+ json_object_int_add(json_row, "refCount", up->ref_count);
+ json_object_int_add(json_row, "sptBit", up->sptbit);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty, "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d%s",
+ up->rpf.source_nexthop.interface->name,
+ src_str,
+ grp_str,
+ pim_upstream_state2str (up->join_state),
+ uptime,
+ join_timer,
+ rs_timer,
+ ka_timer,
+ up->ref_count,
+ VTY_NEWLINE);
+ }
+ }
- vty_out(vty, "%-10s%-15s %-15s %-5s %-8s %-9s %6d%s",
- up->rpf.source_nexthop.interface->name,
- src_str,
- grp_str,
- up->join_state == PIM_UPSTREAM_JOINED ? "Jnd" : "NtJnd",
- uptime,
- join_timer,
- up->ref_count,
- VTY_NEWLINE);
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
}
}
-static void pim_show_join_desired(struct vty *vty)
+static void pim_show_join_desired(struct vty *vty, u_char uj)
{
- struct listnode *ifnode;
struct listnode *chnode;
- struct interface *ifp;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
- char src_str[100];
- char grp_str[100];
-
- vty_out(vty,
- "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
- VTY_NEWLINE);
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
+ VTY_NEWLINE);
- /* scan all interfaces */
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- pim_ifp = ifp->info;
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, chnode, ch)) {
+ /* scan all interfaces */
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, chnode, ch)) {
- struct pim_upstream *up = ch->upstream;
+ struct pim_upstream *up = ch->upstream;
+
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(json_row, "interface", ch->interface->name);
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+
+ if (pim_macro_ch_lost_assert(ch))
+ json_object_boolean_true_add(json_row, "lostAssert");
+
+ if (pim_macro_chisin_joins(ch))
+ json_object_boolean_true_add(json_row, "joins");
+
+ if (pim_macro_chisin_pim_include(ch))
+ json_object_boolean_true_add(json_row, "pimInclude");
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
+ if (pim_upstream_evaluate_join_desired(up))
+ json_object_boolean_true_add(json_row, "evaluateJoinDesired");
+ json_object_object_add(json_group, src_str, json_row);
+
+ } else {
vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
- ifp->name,
+ ch->interface->name,
src_str,
grp_str,
pim_macro_ch_lost_assert(ch) ? "yes" : "no",
@@ -1041,61 +1790,109 @@ static void pim_show_join_desired(struct vty *vty)
VTY_NEWLINE);
}
}
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
}
-static void pim_show_upstream_rpf(struct vty *vty)
+static void pim_show_upstream_rpf(struct vty *vty, u_char uj)
{
struct listnode *upnode;
struct pim_upstream *up;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
- vty_out(vty,
- "Source Group RpfIface RibNextHop RpfAddress %s",
- VTY_NEWLINE);
-
- for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
- char src_str[100];
- char grp_str[100];
- char rpf_nexthop_str[100];
- char rpf_addr_str[100];
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Source Group RpfIface RibNextHop RpfAddress %s",
+ VTY_NEWLINE);
+
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char rpf_nexthop_str[PREFIX_STRLEN];
+ char rpf_addr_str[PREFIX_STRLEN];
struct pim_rpf *rpf;
const char *rpf_ifname;
-
+
rpf = &up->rpf;
-
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
- pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
-
+
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+ pim_addr_dump("<nexthop?>", &rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
+ pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
+
rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
-
- vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
- src_str,
- grp_str,
- rpf_ifname,
- rpf_nexthop_str,
- rpf_addr_str,
- VTY_NEWLINE);
+
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rpfInterface", rpf_ifname);
+ json_object_string_add(json_row, "ribNexthop", rpf_nexthop_str);
+ json_object_string_add(json_row, "rpfAddress", rpf_addr_str);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
+ src_str,
+ grp_str,
+ rpf_ifname,
+ rpf_nexthop_str,
+ rpf_addr_str,
+ VTY_NEWLINE);
+ }
+ }
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
}
}
-static void show_rpf_refresh_stats(struct vty *vty, time_t now)
+static void show_rpf_refresh_stats(struct vty *vty, time_t now, json_object *json)
{
char refresh_uptime[10];
pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, qpim_rpf_cache_refresh_last);
- vty_out(vty,
- "RPF Cache Refresh Delay: %ld msecs%s"
- "RPF Cache Refresh Timer: %ld msecs%s"
- "RPF Cache Refresh Requests: %lld%s"
- "RPF Cache Refresh Events: %lld%s"
- "RPF Cache Refresh Last: %s%s",
- qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
- pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
- (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
- (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE,
- refresh_uptime, VTY_NEWLINE);
+ if (json) {
+ json_object_int_add(json, "rpfCacheRefreshDelayMsecs", qpim_rpf_cache_refresh_delay_msec);
+ json_object_int_add(json, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(qpim_rpf_cache_refresher));
+ json_object_int_add(json, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests);
+ json_object_int_add(json, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events);
+ json_object_string_add(json, "rpfCacheRefreshLast", refresh_uptime);
+ json_object_int_add(json, "nexthopLookups", qpim_nexthop_lookups);
+ json_object_int_add(json, "nexthopLookupsAvoided", nexthop_lookups_avoided);
+ } else {
+ vty_out(vty,
+ "RPF Cache Refresh Delay: %ld msecs%s"
+ "RPF Cache Refresh Timer: %ld msecs%s"
+ "RPF Cache Refresh Requests: %lld%s"
+ "RPF Cache Refresh Events: %lld%s"
+ "RPF Cache Refresh Last: %s%s"
+ "Nexthop Lookups: %lld%s"
+ "Nexthop Lookups Avoided: %lld%s",
+ qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
+ pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
+ (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
+ (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE,
+ refresh_uptime, VTY_NEWLINE,
+ (long long) qpim_nexthop_lookups, VTY_NEWLINE,
+ (long long)nexthop_lookups_avoided, VTY_NEWLINE);
+ }
}
static void show_scan_oil_stats(struct vty *vty, time_t now)
@@ -1117,90 +1914,93 @@ static void show_scan_oil_stats(struct vty *vty, time_t now)
uptime_mroute_del, (long long) qpim_mroute_del_events, VTY_NEWLINE);
}
-static void pim_show_rpf(struct vty *vty)
+static void pim_show_rpf(struct vty *vty, u_char uj)
{
struct listnode *up_node;
struct pim_upstream *up;
time_t now = pim_time_monotonic_sec();
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
+ show_rpf_refresh_stats(vty, now, json);
+ } else {
+ show_rpf_refresh_stats(vty, now, json);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty,
+ "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
+ VTY_NEWLINE);
+ }
- show_rpf_refresh_stats(vty, now);
-
- vty_out(vty, "%s", VTY_NEWLINE);
-
- vty_out(vty,
- "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
- VTY_NEWLINE);
-
- for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
- char src_str[100];
- char grp_str[100];
- char rpf_addr_str[100];
- char rib_nexthop_str[100];
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, up_node, up)) {
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char rpf_addr_str[PREFIX_STRLEN];
+ char rib_nexthop_str[PREFIX_STRLEN];
const char *rpf_ifname;
struct pim_rpf *rpf = &up->rpf;
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
- pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+ pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
+ pim_addr_dump("<nexthop?>", &rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
- vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
- src_str,
- grp_str,
- rpf_ifname,
- rpf_addr_str,
- rib_nexthop_str,
- rpf->source_nexthop.mrib_route_metric,
- rpf->source_nexthop.mrib_metric_preference,
- VTY_NEWLINE);
- }
-}
-
-static void igmp_show_querier(struct vty *vty)
-{
- struct listnode *node;
- struct interface *ifp;
-
- vty_out(vty, "Interface Address Querier StartCount Query-Timer Other-Timer%s", VTY_NEWLINE);
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
-
- if (!pim_ifp)
- continue;
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char query_hhmmss[10];
- char other_hhmmss[10];
-
- pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
- pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
- vty_out(vty, "%-9s %-15s %-7s %10d %11s %11s%s",
- ifp->name,
- inet_ntoa(igmp->ifaddr),
- igmp->t_igmp_query_timer ? "THIS" : "OTHER",
- igmp->startup_query_count,
- query_hhmmss,
- other_hhmmss,
- VTY_NEWLINE);
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rpfInterface", rpf_ifname);
+ json_object_string_add(json_row, "rpfAddress", rpf_addr_str);
+ json_object_string_add(json_row, "ribNexthop", rib_nexthop_str);
+ json_object_int_add(json_row, "routeMetric", rpf->source_nexthop.mrib_route_metric);
+ json_object_int_add(json_row, "routePreference", rpf->source_nexthop.mrib_metric_preference);
+ json_object_object_add(json_group, src_str, json_row);
+
+ } else {
+ vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
+ src_str,
+ grp_str,
+ rpf_ifname,
+ rpf_addr_str,
+ rib_nexthop_str,
+ rpf->source_nexthop.mrib_route_metric,
+ rpf->source_nexthop.mrib_metric_preference,
+ VTY_NEWLINE);
}
}
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
}
-static void igmp_show_groups(struct vty *vty)
+static void igmp_show_groups(struct vty *vty, u_char uj)
{
struct listnode *ifnode;
struct interface *ifp;
time_t now;
+ json_object *json = NULL;
+ json_object *json_iface = NULL;
+ json_object *json_row = NULL;
now = pim_time_monotonic_sec();
- vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
/* scan interfaces */
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
@@ -1213,7 +2013,7 @@ static void igmp_show_groups(struct vty *vty)
/* scan igmp sockets */
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
struct listnode *grpnode;
struct igmp_group *grp;
@@ -1221,7 +2021,7 @@ static void igmp_show_groups(struct vty *vty)
/* scan igmp groups */
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
char hhmmss[10];
char uptime[10];
@@ -1229,20 +2029,48 @@ static void igmp_show_groups(struct vty *vty)
pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
- vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
- ifp->name,
- ifaddr_str,
- group_str,
- grp->group_filtermode_isexcl ? "EXCL" : "INCL",
- hhmmss,
- grp->group_source_list ? listcount(grp->group_source_list) : 0,
- igmp_group_compat_mode(igmp, grp),
- uptime,
- VTY_NEWLINE);
-
+ if (uj) {
+ json_object_object_get_ex(json, ifp->name, &json_iface);
+
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ json_object_pim_ifp_add(json_iface, ifp);
+ json_object_object_add(json, ifp->name, json_iface);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", ifaddr_str);
+ json_object_string_add(json_row, "group", group_str);
+
+ if (grp->igmp_version == 3)
+ json_object_string_add(json_row, "mode", grp->group_filtermode_isexcl ? "EXCLUDE" : "INCLUDE");
+
+ json_object_string_add(json_row, "timer", hhmmss);
+ json_object_int_add(json_row, "sourcesCount", grp->group_source_list ? listcount(grp->group_source_list) : 0);
+ json_object_int_add(json_row, "version", grp->igmp_version);
+ json_object_string_add(json_row, "uptime", uptime);
+ json_object_object_add(json_iface, group_str, json_row);
+
+ } else {
+ vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
+ ifp->name,
+ ifaddr_str,
+ group_str,
+ grp->igmp_version == 3 ? (grp->group_filtermode_isexcl ? "EXCL" : "INCL") : "----",
+ hhmmss,
+ grp->group_source_list ? listcount(grp->group_source_list) : 0,
+ grp->igmp_version,
+ uptime,
+ VTY_NEWLINE);
+ }
} /* scan igmp groups */
} /* scan igmp sockets */
} /* scan interfaces */
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
}
static void igmp_show_group_retransmission(struct vty *vty)
@@ -1263,7 +2091,7 @@ static void igmp_show_group_retransmission(struct vty *vty)
/* scan igmp sockets */
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
struct listnode *grpnode;
struct igmp_group *grp;
@@ -1271,7 +2099,7 @@ static void igmp_show_group_retransmission(struct vty *vty)
/* scan igmp groups */
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
char grp_retr_mmss[10];
struct listnode *src_node;
struct igmp_source *src;
@@ -1302,80 +2130,6 @@ static void igmp_show_group_retransmission(struct vty *vty)
} /* scan interfaces */
}
-static void igmp_show_parameters(struct vty *vty)
-{
- struct listnode *ifnode;
- struct interface *ifp;
-
- vty_out(vty,
- "QRV: Robustness Variable SQI: Startup Query Interval%s"
- "QQI: Query Interval OQPI: Other Querier Present Interval%s"
- "QRI: Query Response Interval LMQT: Last Member Query Time%s"
- "GMI: Group Membership Interval OHPI: Older Host Present Interval%s%s",
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
-
- vty_out(vty,
- "Interface Address QRV QQI QRI GMI SQI OQPI LMQT OHPI %s",
- VTY_NEWLINE);
-
- /* scan interfaces */
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
-
- if (!pim_ifp)
- continue;
-
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char ifaddr_str[100];
- long gmi_dsec; /* Group Membership Interval */
- long oqpi_dsec; /* Other Querier Present Interval */
- int sqi;
- long lmqt_dsec;
- long ohpi_dsec;
- long qri_dsec;
-
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
-
- gmi_dsec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec) / 100;
-
- sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
-
- oqpi_dsec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec) / 100;
-
- lmqt_dsec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
- igmp->querier_robustness_variable) / 100;
-
- ohpi_dsec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec);
-
- qri_dsec = pim_ifp->igmp_query_max_response_time_dsec;
-
- vty_out(vty,
- "%-9s %-15s %3d %3d %3ld.%ld %3ld.%ld %3d %3ld.%ld %3ld.%ld %3ld.%ld%s",
- ifp->name,
- ifaddr_str,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- qri_dsec / 10, qri_dsec % 10,
- gmi_dsec / 10, gmi_dsec % 10,
- sqi,
- oqpi_dsec / 10, oqpi_dsec % 10,
- lmqt_dsec / 10, lmqt_dsec % 10,
- ohpi_dsec / 10, ohpi_dsec % 10,
- VTY_NEWLINE);
-
- } /* scan igmp sockets */
- } /* scan interfaces */
-}
-
static void igmp_show_sources(struct vty *vty)
{
struct listnode *ifnode;
@@ -1397,7 +2151,7 @@ static void igmp_show_sources(struct vty *vty)
/* scan igmp sockets */
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
struct listnode *grpnode;
struct igmp_group *grp;
@@ -1405,7 +2159,7 @@ static void igmp_show_sources(struct vty *vty)
/* scan igmp groups */
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
struct listnode *srcnode;
struct igmp_source *src;
@@ -1413,7 +2167,7 @@ static void igmp_show_sources(struct vty *vty)
/* scan group sources */
for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
char mmss[10];
char uptime[10];
@@ -1457,7 +2211,7 @@ static void igmp_show_source_retransmission(struct vty *vty)
/* scan igmp sockets */
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
struct listnode *grpnode;
struct igmp_group *grp;
@@ -1465,7 +2219,7 @@ static void igmp_show_source_retransmission(struct vty *vty)
/* scan igmp groups */
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
struct listnode *srcnode;
struct igmp_source *src;
@@ -1473,7 +2227,7 @@ static void igmp_show_source_retransmission(struct vty *vty)
/* scan group sources */
for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
@@ -1525,46 +2279,6 @@ static void clear_interfaces()
clear_pim_interfaces();
}
-DEFUN (pim_interface,
- pim_interface_cmd,
- "interface IFNAME",
- "Select an interface to configure\n"
- "Interface's name\n")
-{
- struct interface *ifp;
- const char *ifname = argv[0];
- size_t sl;
-
- sl = strlen(ifname);
- if (sl > INTERFACE_NAMSIZ) {
- vty_out(vty, "%% Interface name %s is invalid: length exceeds "
- "%d characters%s",
- ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ifp = if_lookup_by_name_len(ifname, sl);
- if (!ifp) {
- vty_out(vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
-
- /* Returning here would prevent pimd from booting when there are
- interface commands in pimd.conf, since all interfaces are
- unknown at pimd boot time (the zebra daemon has not been
- contacted for interface discovery). */
-
- ifp = if_get_by_name_len(ifname, sl);
- if (!ifp) {
- vty_out(vty, "%% Could not create interface %s%s", ifname, VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- vty->index = ifp;
- vty->node = INTERFACE_NODE;
-
- return CMD_SUCCESS;
-}
-
DEFUN (clear_ip_interfaces,
clear_ip_interfaces_cmd,
"clear ip interfaces",
@@ -1595,11 +2309,11 @@ static void mroute_add_all()
struct listnode *node;
struct channel_oil *c_oil;
- for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
- if (pim_mroute_add(c_oil)) {
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
/* just log warning */
- char source_str[100];
- char group_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
@@ -1614,11 +2328,11 @@ static void mroute_del_all()
struct listnode *node;
struct channel_oil *c_oil;
- for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
- if (pim_mroute_del(c_oil)) {
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) {
/* just log warning */
- char source_str[100];
- char group_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
@@ -1634,10 +2348,10 @@ static void static_mroute_add_all()
struct static_route *s_route;
for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
- if (pim_mroute_add(&s_route->c_oil)) {
+ if (pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__)) {
/* just log warning */
- char source_str[100];
- char group_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
@@ -1653,10 +2367,10 @@ static void static_mroute_del_all()
struct static_route *s_route;
for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
- if (pim_mroute_del(&s_route->c_oil)) {
+ if (pim_mroute_del(&s_route->c_oil, __PRETTY_FUNCTION__)) {
/* just log warning */
- char source_str[100];
- char group_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
@@ -1707,13 +2421,23 @@ DEFUN (clear_ip_pim_oil,
DEFUN (show_ip_igmp_interface,
show_ip_igmp_interface_cmd,
- "show ip igmp interface",
+ "show ip igmp interface [detail|WORD] [json]",
SHOW_STR
IP_STR
IGMP_STR
- "IGMP interface information\n")
+ "IGMP interface information\n"
+ "Detailed output\n"
+ "interface name\n"
+ "JavaScript Object Notation\n")
{
- igmp_show_interfaces(vty);
+ u_char uj = use_json(argc, argv);
+ int idx = 0;
+
+ if (argv_find(argv, argc, "detail", &idx) ||
+ argv_find(argv, argc, "WORD", &idx))
+ igmp_show_interfaces_single(vty, argv[idx]->arg, uj);
+ else
+ igmp_show_interfaces(vty, uj);
return CMD_SUCCESS;
}
@@ -1733,13 +2457,15 @@ DEFUN (show_ip_igmp_join,
DEFUN (show_ip_igmp_groups,
show_ip_igmp_groups_cmd,
- "show ip igmp groups",
+ "show ip igmp groups [json]",
SHOW_STR
IP_STR
IGMP_STR
- IGMP_GROUP_STR)
+ IGMP_GROUP_STR
+ "JavaScript Object Notation\n")
{
- igmp_show_groups(vty);
+ u_char uj = use_json(argc, argv);
+ igmp_show_groups(vty, uj);
return CMD_SUCCESS;
}
@@ -1758,19 +2484,6 @@ DEFUN (show_ip_igmp_groups_retransmissions,
return CMD_SUCCESS;
}
-DEFUN (show_ip_igmp_parameters,
- show_ip_igmp_parameters_cmd,
- "show ip igmp parameters",
- SHOW_STR
- IP_STR
- IGMP_STR
- "IGMP parameters information\n")
-{
- igmp_show_parameters(vty);
-
- return CMD_SUCCESS;
-}
-
DEFUN (show_ip_igmp_sources,
show_ip_igmp_sources_cmd,
"show ip igmp sources",
@@ -1798,32 +2511,6 @@ DEFUN (show_ip_igmp_sources_retransmissions,
return CMD_SUCCESS;
}
-DEFUN (show_ip_igmp_querier,
- show_ip_igmp_querier_cmd,
- "show ip igmp querier",
- SHOW_STR
- IP_STR
- IGMP_STR
- "IGMP querier information\n")
-{
- igmp_show_querier(vty);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_pim_address,
- show_ip_pim_address_cmd,
- "show ip pim address",
- SHOW_STR
- IP_STR
- PIM_STR
- "PIM interface address\n")
-{
- show_interface_address(vty);
-
- return CMD_SUCCESS;
-}
-
DEFUN (show_ip_pim_assert,
show_ip_pim_assert_cmd,
"show ip pim assert",
@@ -1876,106 +2563,79 @@ DEFUN (show_ip_pim_assert_winner_metric,
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_dr,
- show_ip_pim_dr_cmd,
- "show ip pim designated-router",
- SHOW_STR
- IP_STR
- PIM_STR
- "PIM interface designated router\n")
-{
- pim_show_dr(vty);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_pim_hello,
- show_ip_pim_hello_cmd,
- "show ip pim hello",
- SHOW_STR
- IP_STR
- PIM_STR
- "PIM interface hello information\n")
-{
- pim_show_hello(vty);
-
- return CMD_SUCCESS;
-}
-
DEFUN (show_ip_pim_interface,
show_ip_pim_interface_cmd,
- "show ip pim interface",
+ "show ip pim interface [detail|WORD] [json]",
SHOW_STR
IP_STR
PIM_STR
- "PIM interface information\n")
+ "PIM interface information\n"
+ "Detailed output\n"
+ "interface name\n"
+ "JavaScript Object Notation\n")
{
- pim_show_interfaces(vty);
+ u_char uj = use_json(argc, argv);
+ int idx = 0;
- return CMD_SUCCESS;
-}
+ if (argv_find(argv, argc, "WORD", &idx) ||
+ argv_find(argv, argc, "detail", &idx))
+ pim_show_interfaces_single(vty, argv[idx]->arg, uj);
-DEFUN (show_ip_pim_join,
- show_ip_pim_join_cmd,
- "show ip pim join",
- SHOW_STR
- IP_STR
- PIM_STR
- "PIM interface join information\n")
-{
- pim_show_join(vty);
+ else
+ pim_show_interfaces(vty, uj);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_lan_prune_delay,
- show_ip_pim_lan_prune_delay_cmd,
- "show ip pim lan-prune-delay",
+DEFUN (show_ip_pim_join,
+ show_ip_pim_join_cmd,
+ "show ip pim join [json]",
SHOW_STR
IP_STR
PIM_STR
- "PIM neighbors LAN prune delay parameters\n")
+ "PIM interface join information\n"
+ JSON_STR)
{
- pim_show_lan_prune_delay(vty);
+ u_char uj = use_json(argc, argv);
+ pim_show_join(vty, uj);
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_local_membership,
show_ip_pim_local_membership_cmd,
- "show ip pim local-membership",
- SHOW_STR
- IP_STR
- PIM_STR
- "PIM interface local-membership\n")
-{
- pim_show_membership(vty);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_pim_jp_override_interval,
- show_ip_pim_jp_override_interval_cmd,
- "show ip pim jp-override-interval",
+ "show ip pim local-membership [json]",
SHOW_STR
IP_STR
PIM_STR
- "PIM interface J/P override interval\n")
+ "PIM interface local-membership\n"
+ JSON_STR)
{
- pim_show_jp_override_interval(vty);
+ u_char uj = use_json(argc, argv);
+ pim_show_membership(vty, uj);
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_neighbor,
show_ip_pim_neighbor_cmd,
- "show ip pim neighbor",
+ "show ip pim neighbor [detail|WORD] [json]",
SHOW_STR
IP_STR
PIM_STR
- "PIM neighbor information\n")
+ "PIM neighbor information\n"
+ "Detailed output\n"
+ "Name of interface or neighbor\n"
+ "JavaScript Object Notation\n")
{
- pim_show_neighbors(vty);
+ u_char uj = use_json(argc, argv);
+ int idx = 0;
+
+ if (argv_find(argv, argc, "detail", &idx) ||
+ argv_find(argv, argc, "WORD", &idx))
+ pim_show_neighbors_single(vty, argv[idx]->arg, uj);
+ else
+ pim_show_neighbors(vty, uj);
return CMD_SUCCESS;
}
@@ -1993,54 +2653,107 @@ DEFUN (show_ip_pim_secondary,
return CMD_SUCCESS;
}
+DEFUN (show_ip_pim_state,
+ show_ip_pim_state_cmd,
+ "show ip pim state [A.B.C.D [A.B.C.D]] [json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ "PIM state information\n"
+ "Unicast or Multicast address\n"
+ "Multicast address\n"
+ "JavaScript Object Notation\n")
+{
+ const char *src_or_group = NULL;
+ const char *group = NULL;
+ u_char uj = use_json(argc, argv);
+ if (uj)
+ argc--;
+
+ if (argc == 5)
+ {
+ src_or_group = argv[4]->arg;
+ group = argv[5]->arg;
+ }
+ else if (argc == 4)
+ src_or_group = argv[4]->arg;
+
+ pim_show_state(vty, src_or_group, group, uj);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_ip_pim_upstream,
show_ip_pim_upstream_cmd,
- "show ip pim upstream",
+ "show ip pim upstream [json]",
SHOW_STR
IP_STR
PIM_STR
- "PIM upstream information\n")
+ "PIM upstream information\n"
+ "JavaScript Object Notation\n")
{
- pim_show_upstream(vty);
+ u_char uj = use_json(argc, argv);
+ pim_show_upstream(vty, uj);
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_upstream_join_desired,
show_ip_pim_upstream_join_desired_cmd,
- "show ip pim upstream-join-desired",
+ "show ip pim upstream-join-desired [json]",
SHOW_STR
IP_STR
PIM_STR
- "PIM upstream join-desired\n")
+ "PIM upstream join-desired\n"
+ "JavaScript Object Notation\n")
{
- pim_show_join_desired(vty);
+ u_char uj = use_json(argc, argv);
+ pim_show_join_desired(vty, uj);
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_upstream_rpf,
show_ip_pim_upstream_rpf_cmd,
- "show ip pim upstream-rpf",
+ "show ip pim upstream-rpf [json]",
SHOW_STR
IP_STR
PIM_STR
- "PIM upstream source rpf\n")
+ "PIM upstream source rpf\n"
+ "JavaScript Object Notation\n")
{
- pim_show_upstream_rpf(vty);
+ u_char uj = use_json(argc, argv);
+ pim_show_upstream_rpf(vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_pim_rp,
+ show_ip_pim_rp_cmd,
+ "show ip pim rp-info [json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ "PIM RP information\n"
+ "JavaScript Object Notation\n")
+{
+ u_char uj = use_json(argc, argv);
+ pim_rp_show_information (vty, uj);
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_rpf,
show_ip_pim_rpf_cmd,
- "show ip pim rpf",
+ "show ip pim rpf [json]",
SHOW_STR
IP_STR
PIM_STR
- "PIM cached source rpf information\n")
+ "PIM cached source rpf information\n"
+ "JavaScript Object Notation\n")
{
- pim_show_rpf(vty);
+ u_char uj = use_json(argc, argv);
+ pim_show_rpf(vty, uj);
return CMD_SUCCESS;
}
@@ -2120,27 +2833,11 @@ DEFUN (show_ip_multicast,
}
vty_out(vty, "%s", VTY_NEWLINE);
- vty_out(vty, "Zclient update socket: ");
- if (qpim_zclient_update) {
- vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
- qpim_zclient_update->fail, VTY_NEWLINE);
- }
- else {
- vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
- }
- vty_out(vty, "Zclient lookup socket: ");
- if (qpim_zclient_lookup) {
- vty_out(vty, "%d failures=%d%s", qpim_zclient_lookup->sock,
- qpim_zclient_lookup->fail, VTY_NEWLINE);
- }
- else {
- vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
- }
+
+ pim_zebra_zclient_update (vty);
+ pim_zlookup_show_ip_multicast (vty);
vty_out(vty, "%s", VTY_NEWLINE);
- vty_out(vty, "Current highest VifIndex: %d%s",
- qpim_mroute_oif_highest_vif_index,
- VTY_NEWLINE);
vty_out(vty, "Maximum highest VifIndex: %d%s",
PIM_MAX_USABLE_VIFS,
VTY_NEWLINE);
@@ -2155,7 +2852,7 @@ DEFUN (show_ip_multicast,
vty_out(vty, "%s", VTY_NEWLINE);
- show_rpf_refresh_stats(vty, now);
+ show_rpf_refresh_stats(vty, now, NULL);
vty_out(vty, "%s", VTY_NEWLINE);
@@ -2166,127 +2863,299 @@ DEFUN (show_ip_multicast,
return CMD_SUCCESS;
}
-static void show_mroute(struct vty *vty)
+static void show_mroute(struct vty *vty, u_char uj)
{
struct listnode *node;
struct channel_oil *c_oil;
struct static_route *s_route;
time_t now;
-
- vty_out(vty, "Proto: I=IGMP P=PIM S=STATIC O=SOURCE%s%s", VTY_NEWLINE, VTY_NEWLINE);
-
- vty_out(vty, "Source Group Proto Input iVifI Output oVifI TTL Uptime %s",
- VTY_NEWLINE);
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_source = NULL;
+ json_object *json_oil = NULL;
+ json_object *json_ifp_out = NULL;
+ int found_oif = 0;
+ int first = 1;
+ char grp_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ char in_ifname[INTERFACE_NAMSIZ+1];
+ char out_ifname[INTERFACE_NAMSIZ+1];
+ int oif_vif_index;
+ struct interface *ifp_in;
+ char proto[100];
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty, "Source Group Proto Input Output TTL Uptime%s",
+ VTY_NEWLINE);
+ }
now = pim_time_monotonic_sec();
/* print list of PIM and IGMP routes */
- for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
- char group_str[100];
- char source_str[100];
- int oif_vif_index;
-
- if (!c_oil->installed)
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ found_oif = 0;
+ first = 1;
+ if (!c_oil->installed && !uj)
continue;
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
+ ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
+
+ if (ifp_in)
+ strcpy(in_ifname, ifp_in->name);
+ else
+ strcpy(in_ifname, "<iif?>");
+
+ if (uj) {
+
+ /* Find the group, create it if it doesn't exist */
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
+
+ /* Find the source nested under the group, create it if it doesn't exist */
+ json_object_object_get_ex(json_group, src_str, &json_source);
+
+ if (!json_source) {
+ json_source = json_object_new_object();
+ json_object_object_add(json_group, src_str, json_source);
+ }
+
+ /* Find the inbound interface nested under the source, create it if it doesn't exist */
+ json_object_int_add(json_source, "installed", c_oil->installed);
+ json_object_int_add(json_source, "refCount", c_oil->oil_ref_count);
+ json_object_int_add(json_source, "oilSize", c_oil->oil_size);
+ json_object_int_add(json_source, "OilInheritedRescan", c_oil->oil_inherited_rescan);
+ json_object_string_add(json_source, "iif", in_ifname);
+ json_oil = NULL;
+ }
+
for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
- struct interface *ifp_in;
struct interface *ifp_out;
char oif_uptime[10];
int ttl;
- char proto[5];
ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
if (ttl < 1)
continue;
- ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
ifp_out = pim_if_find_by_vif_index(oif_vif_index);
-
pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
+ found_oif = 1;
- proto[0] = '\0';
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
- strcat(proto, "P");
- }
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
- strcat(proto, "I");
- }
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) {
- strcat(proto, "O");
+ if (ifp_out)
+ strcpy(out_ifname, ifp_out->name);
+ else
+ strcpy(out_ifname, "<oif?>");
+
+ if (uj) {
+ json_ifp_out = json_object_new_object();
+ json_object_string_add(json_ifp_out, "source", src_str);
+ json_object_string_add(json_ifp_out, "group", grp_str);
+
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM)
+ json_object_boolean_true_add(json_ifp_out, "protocolPim");
+
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP)
+ json_object_boolean_true_add(json_ifp_out, "protocolIgmp");
+
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE)
+ json_object_boolean_true_add(json_ifp_out, "protocolSource");
+
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR)
+ json_object_boolean_true_add(json_ifp_out, "protocolInherited");
+
+ json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
+ json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
+ json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
+ json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
+ json_object_int_add(json_ifp_out, "ttl", ttl);
+ json_object_string_add(json_ifp_out, "upTime", oif_uptime);
+ if (!json_oil) {
+ json_oil = json_object_new_object();
+ json_object_object_add(json_source, "oil", json_oil);
+ }
+ json_object_object_add(json_oil, out_ifname, json_ifp_out);
+ } else {
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
+ strcpy(proto, "PIM");
+ }
+
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
+ strcpy(proto, "IGMP");
+ }
+
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) {
+ strcpy(proto, "SRC");
+ }
+
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) {
+ strcpy(proto, "STAR");
+ }
+
+ vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
+ src_str,
+ grp_str,
+ proto,
+ in_ifname,
+ out_ifname,
+ ttl,
+ oif_uptime,
+ VTY_NEWLINE);
+
+ if (first)
+ {
+ src_str[0] = '\0';
+ grp_str[0] = '\0';
+ in_ifname[0] = '\0';
+ first = 0;
+ }
}
+ }
- vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
- source_str,
- group_str,
- proto,
- ifp_in ? ifp_in->name : "<iif?>",
- c_oil->oil.mfcc_parent,
- ifp_out ? ifp_out->name : "<oif?>",
- oif_vif_index,
- ttl,
- oif_uptime,
- VTY_NEWLINE);
+ if (!uj && !found_oif) {
+ vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
+ src_str,
+ grp_str,
+ "none",
+ in_ifname,
+ "none",
+ 0,
+ "--:--:--",
+ VTY_NEWLINE);
}
}
/* Print list of static routes */
for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
- char group_str[100];
- char source_str[100];
- int oif_vif_index;
+ first = 1;
if (!s_route->c_oil.installed)
continue;
- pim_inet4_dump("<group?>", s_route->group, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", s_route->source, source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", s_route->group, grp_str, sizeof(grp_str));
+ pim_inet4_dump("<source?>", s_route->source, src_str, sizeof(src_str));
+ ifp_in = pim_if_find_by_vif_index(s_route->iif);
+ found_oif = 0;
+
+ if (ifp_in)
+ strcpy(in_ifname, ifp_in->name);
+ else
+ strcpy(in_ifname, "<iif?>");
+
+ if (uj) {
+
+ /* Find the group, create it if it doesn't exist */
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
+
+ /* Find the source nested under the group, create it if it doesn't exist */
+ json_object_object_get_ex(json_group, src_str, &json_source);
+
+ if (!json_source) {
+ json_source = json_object_new_object();
+ json_object_object_add(json_group, src_str, json_source);
+ }
+
+ json_object_string_add(json_source, "iif", in_ifname);
+ json_oil = NULL;
+ } else {
+ strcpy(proto, "STATIC");
+ }
for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
- struct interface *ifp_in;
struct interface *ifp_out;
char oif_uptime[10];
int ttl;
- char proto[5];
ttl = s_route->oif_ttls[oif_vif_index];
if (ttl < 1)
continue;
- ifp_in = pim_if_find_by_vif_index(s_route->iif);
ifp_out = pim_if_find_by_vif_index(oif_vif_index);
-
pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->c_oil.oif_creation[oif_vif_index]);
+ found_oif = 1;
+
+ if (ifp_out)
+ strcpy(out_ifname, ifp_out->name);
+ else
+ strcpy(out_ifname, "<oif?>");
+
+ if (uj) {
+ json_ifp_out = json_object_new_object();
+ json_object_string_add(json_ifp_out, "source", src_str);
+ json_object_string_add(json_ifp_out, "group", grp_str);
+ json_object_boolean_true_add(json_ifp_out, "protocolStatic");
+ json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
+ json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
+ json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
+ json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
+ json_object_int_add(json_ifp_out, "ttl", ttl);
+ json_object_string_add(json_ifp_out, "upTime", oif_uptime);
+ if (!json_oil) {
+ json_oil = json_object_new_object();
+ json_object_object_add(json_source, "oil", json_oil);
+ }
+ json_object_object_add(json_oil, out_ifname, json_ifp_out);
+ } else {
+ vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
+ src_str,
+ grp_str,
+ proto,
+ in_ifname,
+ out_ifname,
+ ttl,
+ oif_uptime,
+ VTY_NEWLINE);
+ if (first)
+ {
+ src_str[0] = '\0';
+ grp_str[0] = '\0';
+ in_ifname[0] = '\0';
+ first = 0;
+ }
+ }
+ }
- proto[0] = '\0';
- strcat(proto, "S");
-
- vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
- source_str,
- group_str,
- proto,
- ifp_in ? ifp_in->name : "<iif?>",
- s_route->iif,
- ifp_out ? ifp_out->name : "<oif?>",
- oif_vif_index,
- ttl,
- oif_uptime,
- VTY_NEWLINE);
+ if (!uj && !found_oif) {
+ vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
+ src_str,
+ grp_str,
+ proto,
+ in_ifname,
+ "none",
+ 0,
+ "--:--:--",
+ VTY_NEWLINE);
}
}
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
}
DEFUN (show_ip_mroute,
show_ip_mroute_cmd,
- "show ip mroute",
+ "show ip mroute [json]",
SHOW_STR
IP_STR
- MROUTE_STR)
+ MROUTE_STR
+ JSON_STR)
{
- show_mroute(vty);
+ u_char uj = use_json(argc, argv);
+ show_mroute(vty, uj);
return CMD_SUCCESS;
}
@@ -2298,13 +3167,13 @@ static void show_mroute_count(struct vty *vty)
vty_out(vty, "%s", VTY_NEWLINE);
- vty_out(vty, "Source Group Packets Bytes WrongIf %s",
+ vty_out(vty, "Source Group LastUsed Packets Bytes WrongIf %s",
VTY_NEWLINE);
/* Print PIM and IGMP route counts */
- for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
- char group_str[100];
- char source_str[100];
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
if (!c_oil->installed)
continue;
@@ -2314,9 +3183,10 @@ static void show_mroute_count(struct vty *vty)
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
+ vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
source_str,
group_str,
+ c_oil->cc.lastused/100,
c_oil->cc.pktcnt,
c_oil->cc.bytecnt,
c_oil->cc.wrong_if,
@@ -2325,8 +3195,8 @@ static void show_mroute_count(struct vty *vty)
/* Print static route counts */
for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
if (!s_route->c_oil.installed)
continue;
@@ -2336,9 +3206,10 @@ static void show_mroute_count(struct vty *vty)
pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
- vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
+ vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
source_str,
group_str,
+ s_route->c_oil.cc.lastused,
s_route->c_oil.cc.pktcnt,
s_route->c_oil.cc.bytecnt,
s_route->c_oil.cc.wrong_if,
@@ -2366,13 +3237,15 @@ DEFUN (show_ip_rib,
RIB_STR
"Unicast address\n")
{
+ int idx_ipv4 = 3;
struct in_addr addr;
const char *addr_str;
struct pim_nexthop nexthop;
- char nexthop_addr_str[100];
+ char nexthop_addr_str[PREFIX_STRLEN];
int result;
- addr_str = argv[0];
+ memset (&nexthop, 0, sizeof (nexthop));
+ addr_str = argv[idx_ipv4]->arg;
result = inet_pton(AF_INET, addr_str, &addr);
if (result <= 0) {
vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
@@ -2380,7 +3253,7 @@ DEFUN (show_ip_rib,
return CMD_WARNING;
}
- if (pim_nexthop_lookup(&nexthop, addr, NULL)) {
+ if (pim_nexthop_lookup(&nexthop, addr, 0)) {
vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
addr_str, VTY_NEWLINE);
return CMD_WARNING;
@@ -2389,8 +3262,8 @@ DEFUN (show_ip_rib,
vty_out(vty, "Address NextHop Interface Metric Preference%s",
VTY_NEWLINE);
- pim_inet4_dump("<nexthop?>", nexthop.mrib_nexthop_addr,
- nexthop_addr_str, sizeof(nexthop_addr_str));
+ pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
+ nexthop_addr_str, sizeof(nexthop_addr_str));
vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
addr_str,
@@ -2418,11 +3291,11 @@ static void show_ssmpingd(struct vty *vty)
now = pim_time_monotonic_sec();
for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
char ss_uptime[10];
struct sockaddr_in bind_addr;
socklen_t len = sizeof(bind_addr);
- char bind_addr_str[100];
+ char bind_addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
@@ -2456,47 +3329,250 @@ DEFUN (show_ip_ssmpingd,
return CMD_SUCCESS;
}
+static int
+pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const char *plist)
+{
+ int result;
+
+ result = pim_rp_new (rp, group, plist);
+
+ if (result == PIM_MALLOC_FAIL)
+ {
+ vty_out (vty, "%% Out of memory%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (result == PIM_GROUP_BAD_ADDRESS)
+ {
+ vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (result == PIM_RP_BAD_ADDRESS)
+ {
+ vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (result == PIM_RP_NO_PATH)
+ {
+ vty_out (vty, "%% No Path to RP address specified: %s%s", rp, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (result == PIM_GROUP_OVERLAP)
+ {
+ vty_out (vty, "%% Group range specified cannot overlap%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (result == PIM_GROUP_PFXLIST_OVERLAP)
+ {
+ vty_out (vty, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (result == PIM_RP_PFXLIST_IN_USE)
+ {
+ vty_out (vty, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (ip_pim_joinprune_time,
+ ip_pim_joinprune_time_cmd,
+ "ip pim join-prune-interval <60-600>",
+ IP_STR
+ "pim multicast routing\n"
+ "Join Prune Send Interval\n"
+ "Seconds\n")
+{
+ qpim_t_periodic = atoi(argv[3]->arg);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_joinprune_time,
+ no_ip_pim_joinprune_time_cmd,
+ "no ip pim join-prune-interval <60-600>",
+ NO_STR
+ IP_STR
+ "pim multicast routing\n"
+ "Join Prune Send Interval\n"
+ "Seconds\n")
+{
+ qpim_t_periodic = PIM_DEFAULT_T_PERIODIC;
+ return CMD_SUCCESS;
+}
+
+DEFUN (ip_pim_register_suppress,
+ ip_pim_register_suppress_cmd,
+ "ip pim register-suppress-time <5-60000>",
+ IP_STR
+ "pim multicast routing\n"
+ "Register Suppress Timer\n"
+ "Seconds\n")
+{
+ qpim_keep_alive_time = atoi (argv[3]->arg);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_register_suppress,
+ no_ip_pim_register_suppress_cmd,
+ "no ip pim register-suppress-time <5-60000>",
+ NO_STR
+ IP_STR
+ "pim multicast routing\n"
+ "Register Suppress Timer\n"
+ "Seconds\n")
+{
+ qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
+ return CMD_SUCCESS;
+}
+
+DEFUN (ip_pim_keep_alive,
+ ip_pim_keep_alive_cmd,
+ "ip pim keep-alive-timer <31-60000>",
+ IP_STR
+ "pim multicast routing\n"
+ "Keep alive Timer\n"
+ "Seconds\n")
+{
+ qpim_rp_keep_alive_time = atoi (argv[4]->arg);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_keep_alive,
+ no_ip_pim_keep_alive_cmd,
+ "no ip pim keep-alive-timer <31-60000>",
+ NO_STR
+ IP_STR
+ "pim multicast routing\n"
+ "Keep alive Timer\n"
+ "Seconds\n")
+{
+ qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
+ return CMD_SUCCESS;
+}
+
+DEFUN (ip_pim_packets,
+ ip_pim_packets_cmd,
+ "ip pim packets <1-100>",
+ IP_STR
+ "pim multicast routing\n"
+ "packets to process at one time per fd\n"
+ "Number of packets\n")
+{
+ qpim_packet_process = atoi (argv[3]->arg);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_packets,
+ no_ip_pim_packets_cmd,
+ "no ip pim packets <1-100>",
+ NO_STR
+ IP_STR
+ "pim multicast routing\n"
+ "packets to process at one time per fd\n"
+ "Number of packets\n")
+{
+ qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
+ return CMD_SUCCESS;
+}
+
DEFUN (ip_pim_rp,
ip_pim_rp_cmd,
- "ip pim rp A.B.C.D",
+ "ip pim rp A.B.C.D [A.B.C.D/M]",
IP_STR
"pim multicast routing\n"
"Rendevous Point\n"
- "ip address of RP\n")
+ "ip address of RP\n"
+ "Group Address range to cover\n")
{
- int result;
+ int idx_ipv4 = 3;
- result = inet_pton(AF_INET, argv[0], &qpim_rp.rpf_addr.s_addr);
- if (result <= 0) {
- vty_out(vty, "%% Bad RP address specified: %s", argv[0]);
- return CMD_WARNING;
- }
+ if (argc == (idx_ipv4 + 1))
+ return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+ else
+ return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
+}
- if (pim_nexthop_lookup(&qpim_rp.source_nexthop, qpim_rp.rpf_addr, NULL) != 0) {
- vty_out(vty, "%% No Path to RP address specified: %s", argv[0]);
- return CMD_WARNING;
- }
+DEFUN (ip_pim_rp_prefix_list,
+ ip_pim_rp_prefix_list_cmd,
+ "ip pim rp A.B.C.D prefix-list WORD",
+ IP_STR
+ "pim multicast routing\n"
+ "Rendevous Point\n"
+ "ip address of RP\n"
+ "group prefix-list filter\n"
+ "Name of a prefix-list\n")
+{
+ return pim_rp_cmd_worker (vty, argv[3]->arg, NULL, argv[5]->arg);
+}
+
+static int
+pim_no_rp_cmd_worker (struct vty *vty, const char *rp, const char *group,
+ const char *plist)
+{
+ int result = pim_rp_del (rp, group, plist);
+
+ if (result == PIM_GROUP_BAD_ADDRESS)
+ {
+ vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (result == PIM_RP_BAD_ADDRESS)
+ {
+ vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (result == PIM_RP_NOT_FOUND)
+ {
+ vty_out (vty, "%% Unable to find specified RP%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
return CMD_SUCCESS;
}
DEFUN (no_ip_pim_rp,
no_ip_pim_rp_cmd,
- "no ip pim rp {A.B.C.D}",
+ "no ip pim rp A.B.C.D [A.B.C.D/M]",
NO_STR
IP_STR
"pim multicast routing\n"
"Rendevous Point\n"
- "ip address of RP\n")
+ "ip address of RP\n"
+ "Group Address range to cover\n")
{
- qpim_rp.rpf_addr.s_addr = INADDR_NONE;
+ int idx_ipv4 = 4;
- return CMD_SUCCESS;
+ if (argc == (idx_ipv4 + 1))
+ return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+ else
+ return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
+}
+
+DEFUN (no_ip_pim_rp_prefix_list,
+ no_ip_pim_rp_prefix_list_cmd,
+ "no ip pim rp A.B.C.D prefix-list WORD",
+ NO_STR
+ IP_STR
+ "pim multicast routing\n"
+ "Rendevous Point\n"
+ "ip address of RP\n"
+ "group prefix-list filter\n"
+ "Name of a prefix-list\n")
+{
+ return pim_no_rp_cmd_worker (vty, argv[4]->arg, NULL, argv[6]->arg);
}
DEFUN (ip_multicast_routing,
ip_multicast_routing_cmd,
- PIM_CMD_IP_MULTICAST_ROUTING,
+ "ip multicast-routing",
IP_STR
"Enable IP multicast forwarding\n")
{
@@ -2509,7 +3585,7 @@ DEFUN (ip_multicast_routing,
DEFUN (no_ip_multicast_routing,
no_ip_multicast_routing_cmd,
- PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
+ "no ip multicast-routing",
NO_STR
IP_STR
"Global IP configuration subcommands\n"
@@ -2529,9 +3605,10 @@ DEFUN (ip_ssmpingd,
CONF_SSMPINGD_STR
"Source address\n")
{
+ int idx_ipv4 = 2;
int result;
struct in_addr source_addr;
- const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
+ const char *source_str = (argc == idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
@@ -2558,9 +3635,10 @@ DEFUN (no_ip_ssmpingd,
CONF_SSMPINGD_STR
"Source address\n")
{
+ int idx_ipv4 = 3;
int result;
struct in_addr source_addr;
- const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
+ const char *source_str = (argc == idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
@@ -2585,10 +3663,9 @@ DEFUN (interface_ip_igmp,
IP_STR
IFACE_IGMP_STR)
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -2616,10 +3693,9 @@ DEFUN (interface_no_ip_igmp,
IP_STR
IFACE_IGMP_STR)
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp)
return CMD_SUCCESS;
@@ -2646,17 +3722,17 @@ DEFUN (interface_ip_igmp_join,
"Multicast group address\n"
"Source address\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_ipv4 = 3;
+ int idx_ipv4_2 = 4;
const char *group_str;
const char *source_str;
struct in_addr group_addr;
struct in_addr source_addr;
int result;
- ifp = vty->index;
-
/* Group address */
- group_str = argv[0];
+ group_str = argv[idx_ipv4]->arg;
result = inet_pton(AF_INET, group_str, &group_addr);
if (result <= 0) {
vty_out(vty, "Bad group address %s: errno=%d: %s%s",
@@ -2665,7 +3741,7 @@ DEFUN (interface_ip_igmp_join,
}
/* Source address */
- source_str = argv[1];
+ source_str = argv[idx_ipv4_2]->arg;
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
vty_out(vty, "Bad source address %s: errno=%d: %s%s",
@@ -2693,17 +3769,17 @@ DEFUN (interface_no_ip_igmp_join,
"Multicast group address\n"
"Source address\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
const char *group_str;
const char *source_str;
struct in_addr group_addr;
struct in_addr source_addr;
int result;
- ifp = vty->index;
-
/* Group address */
- group_str = argv[0];
+ group_str = argv[idx_ipv4]->arg;
result = inet_pton(AF_INET, group_str, &group_addr);
if (result <= 0) {
vty_out(vty, "Bad group address %s: errno=%d: %s%s",
@@ -2712,7 +3788,7 @@ DEFUN (interface_no_ip_igmp_join,
}
/* Source address */
- source_str = argv[1];
+ source_str = argv[idx_ipv4_2]->arg;
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
vty_out(vty, "Bad source address %s: errno=%d: %s%s",
@@ -2756,7 +3832,7 @@ static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
pim_ifp = ifp->info;
if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
__PRETTY_FUNCTION__,
@@ -2863,18 +3939,17 @@ static void change_query_max_response_time(struct pim_interface *pim_ifp,
DEFUN (interface_ip_igmp_query_interval,
interface_ip_igmp_query_interval_cmd,
- PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
+ "ip igmp query-interval (1-1800)",
IP_STR
IFACE_IGMP_STR
IFACE_IGMP_QUERY_INTERVAL_STR
"Query interval in seconds\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
int query_interval;
int query_interval_dsec;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -2885,7 +3960,7 @@ DEFUN (interface_ip_igmp_query_interval,
return CMD_WARNING;
}
- query_interval = atoi(argv[0]);
+ query_interval = atoi(argv[3]->arg);
query_interval_dsec = 10 * query_interval;
/*
@@ -2922,17 +3997,16 @@ DEFUN (interface_ip_igmp_query_interval,
DEFUN (interface_no_ip_igmp_query_interval,
interface_no_ip_igmp_query_interval_cmd,
- PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
+ "no ip igmp query-interval",
NO_STR
IP_STR
IFACE_IGMP_STR
IFACE_IGMP_QUERY_INTERVAL_STR)
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
int default_query_interval_dsec;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp)
@@ -2953,22 +4027,71 @@ DEFUN (interface_no_ip_igmp_query_interval,
return CMD_SUCCESS;
}
-#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
-#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
+DEFUN (interface_ip_igmp_version,
+ interface_ip_igmp_version_cmd,
+ "ip igmp version (2-3)",
+ IP_STR
+ IFACE_IGMP_STR
+ "IGMP version\n"
+ "IGMP version number\n")
+{
+ VTY_DECLVAR_CONTEXT(interface,ifp);
+ struct pim_interface *pim_ifp;
+ int igmp_version;
+
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp) {
+ vty_out(vty,
+ "IGMP not enabled on interface %s. Please enable IGMP first.%s",
+ ifp->name,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ igmp_version = atoi(argv[3]->arg);
+ pim_ifp->igmp_version = igmp_version;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (interface_no_ip_igmp_version,
+ interface_no_ip_igmp_version_cmd,
+ "no ip igmp version (2-3)",
+ NO_STR
+ IP_STR
+ IFACE_IGMP_STR
+ "IGMP version\n"
+ "IGMP version number\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ return CMD_SUCCESS;
+
+ pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
+
+ return CMD_SUCCESS;
+}
+
+#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
+#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
DEFUN (interface_ip_igmp_query_max_response_time,
interface_ip_igmp_query_max_response_time_cmd,
- PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
+ "ip igmp query-max-response-time (10-250)",
IP_STR
IFACE_IGMP_STR
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
- "Query response value in seconds\n")
+ "Query response value in deci-seconds\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
int query_max_response_time;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -2979,28 +4102,9 @@ DEFUN (interface_ip_igmp_query_max_response_time,
return CMD_WARNING;
}
- query_max_response_time = atoi(argv[0]);
+ query_max_response_time = atoi(argv[3]->arg);
- /*
- It seems we don't need to check bounds since command.c does it
- already, but we verify them anyway for extra safety.
- */
- if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
- vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
- query_max_response_time,
- IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
- vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
- query_max_response_time,
- IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
+ if (query_max_response_time >= pim_ifp->igmp_default_query_interval * 10) {
vty_out(vty,
"Can't set query max response time %d sec >= general query interval %d sec%s",
query_max_response_time, pim_ifp->igmp_default_query_interval,
@@ -3008,39 +4112,28 @@ DEFUN (interface_ip_igmp_query_max_response_time,
return CMD_WARNING;
}
- change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
+ change_query_max_response_time(pim_ifp, query_max_response_time);
return CMD_SUCCESS;
}
DEFUN (interface_no_ip_igmp_query_max_response_time,
interface_no_ip_igmp_query_max_response_time_cmd,
- PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
+ "no ip igmp query-max-response-time (10-250)",
NO_STR
IP_STR
IFACE_IGMP_STR
- IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
+ IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
+ "Time for response in deci-seconds\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
- int default_query_interval_dsec;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp)
return CMD_SUCCESS;
- default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
-
- if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
- vty_out(vty,
- "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
- IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
return CMD_SUCCESS;
@@ -3049,20 +4142,19 @@ DEFUN (interface_no_ip_igmp_query_max_response_time,
#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
-DEFUN (interface_ip_igmp_query_max_response_time_dsec,
- interface_ip_igmp_query_max_response_time_dsec_cmd,
- PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
- IP_STR
- IFACE_IGMP_STR
- IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
- "Query response value in deciseconds\n")
+DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
+ interface_ip_igmp_query_max_response_time_dsec_cmd,
+ "ip igmp query-max-response-time-dsec (10-250)",
+ IP_STR
+ IFACE_IGMP_STR
+ IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
+ "Query response value in deciseconds\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
int query_max_response_time_dsec;
int default_query_interval_dsec;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -3073,26 +4165,7 @@ DEFUN (interface_ip_igmp_query_max_response_time_dsec,
return CMD_WARNING;
}
- query_max_response_time_dsec = atoi(argv[0]);
-
- /*
- It seems we don't need to check bounds since command.c does it
- already, but we verify them anyway for extra safety.
- */
- if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
- vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
- query_max_response_time_dsec,
- IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
- vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
- query_max_response_time_dsec,
- IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ query_max_response_time_dsec = atoi(argv[4]->arg);
default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
@@ -3109,34 +4182,22 @@ DEFUN (interface_ip_igmp_query_max_response_time_dsec,
return CMD_SUCCESS;
}
-DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
- interface_no_ip_igmp_query_max_response_time_dsec_cmd,
- PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
- NO_STR
- IP_STR
- IFACE_IGMP_STR
- IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
+DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
+ interface_no_ip_igmp_query_max_response_time_dsec_cmd,
+ "no ip igmp query-max-response-time-dsec",
+ NO_STR
+ IP_STR
+ IFACE_IGMP_STR
+ IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
- int default_query_interval_dsec;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp)
return CMD_SUCCESS;
- default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
-
- if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
- vty_out(vty,
- "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
- IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
return CMD_SUCCESS;
@@ -3144,17 +4205,17 @@ DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
DEFUN (interface_ip_pim_drprio,
interface_ip_pim_drprio_cmd,
- "ip pim drpriority <1-4294967295>",
+ "ip pim drpriority (1-4294967295)",
IP_STR
PIM_STR
"Set the Designated Router Election Priority\n"
"Value of the new DR Priority\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
struct pim_interface *pim_ifp;
uint32_t old_dr_prio;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -3164,7 +4225,7 @@ DEFUN (interface_ip_pim_drprio,
old_dr_prio = pim_ifp->pim_dr_priority;
- pim_ifp->pim_dr_priority = strtol(argv[0], NULL, 10);
+ pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
if (old_dr_prio != pim_ifp->pim_dr_priority) {
if (pim_if_dr_election(ifp))
@@ -3176,16 +4237,16 @@ DEFUN (interface_ip_pim_drprio,
DEFUN (interface_no_ip_pim_drprio,
interface_no_ip_pim_drprio_cmd,
- "no ip pim drpriority {<1-4294967295>}",
+ "no ip pim drpriority [(1-4294967295)]",
+ NO_STR
IP_STR
PIM_STR
"Revert the Designated Router Priority to default\n"
"Old Value of the Priority\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -3206,7 +4267,6 @@ static int
pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
{
struct pim_interface *pim_ifp = ifp->info;
- struct in_addr null = { .s_addr = 0 };
if (!pim_ifp) {
pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
@@ -3221,8 +4281,6 @@ pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
pim_ifp->itype = itype;
pim_if_addr_add_all(ifp);
pim_if_membership_refresh(ifp);
-
- pim_rp_check_rp (null, pim_ifp->primary_address);
return 1;
}
@@ -3234,9 +4292,7 @@ DEFUN (interface_ip_pim_ssm,
PIM_STR
IFACE_PIM_STR)
{
- struct interface *ifp;
-
- ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SSM)) {
vty_out(vty, "Could not enable PIM SSM on interface%s", VTY_NEWLINE);
@@ -3253,9 +4309,7 @@ DEFUN (interface_ip_pim_sm,
PIM_STR
IFACE_PIM_SM_STR)
{
- struct interface *ifp;
-
- ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SM)) {
vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -3279,18 +4333,13 @@ pim_cmd_interface_delete (struct interface *ifp)
pim_if_membership_clear(ifp);
/*
- pim_if_addr_del_all() removes all sockets from
- pim_ifp->igmp_socket_list.
- */
- pim_if_addr_del_all(ifp);
-
- /*
pim_sock_delete() removes all neighbors from
pim_ifp->pim_neighbor_list.
*/
pim_sock_delete(ifp, "pim unconfigured on interface");
if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ pim_if_addr_del_all(ifp);
pim_if_delete(ifp);
}
@@ -3305,9 +4354,7 @@ DEFUN (interface_no_ip_pim_ssm,
PIM_STR
IFACE_PIM_STR)
{
- struct interface *ifp;
-
- ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
if (!pim_cmd_interface_delete(ifp)) {
vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -3324,9 +4371,7 @@ DEFUN (interface_no_ip_pim_sm,
PIM_STR
IFACE_PIM_SM_STR)
{
- struct interface *ifp;
-
- ifp = vty->index;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
if (!pim_cmd_interface_delete(ifp)) {
vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -3343,7 +4388,9 @@ DEFUN (interface_ip_mroute,
"Outgoing interface name\n"
"Group address\n")
{
- struct interface *iif;
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ int idx_interface = 2;
+ int idx_ipv4 = 3;
struct interface *oif;
const char *oifname;
const char *grp_str;
@@ -3351,9 +4398,7 @@ DEFUN (interface_ip_mroute,
struct in_addr src_addr;
int result;
- iif = vty->index;
-
- oifname = argv[0];
+ oifname = argv[idx_interface]->arg;
oif = if_lookup_by_name(oifname);
if (!oif) {
vty_out(vty, "No such interface name %s%s",
@@ -3361,7 +4406,7 @@ DEFUN (interface_ip_mroute,
return CMD_WARNING;
}
- grp_str = argv[1];
+ grp_str = argv[idx_ipv4]->arg;
result = inet_pton(AF_INET, grp_str, &grp_addr);
if (result <= 0) {
vty_out(vty, "Bad group address %s: errno=%d: %s%s",
@@ -3388,7 +4433,10 @@ DEFUN (interface_ip_mroute_source,
"Group address\n"
"Source address\n")
{
- struct interface *iif;
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ int idx_interface = 2;
+ int idx_ipv4 = 3;
+ int idx_ipv4_2 = 4;
struct interface *oif;
const char *oifname;
const char *grp_str;
@@ -3397,9 +4445,7 @@ DEFUN (interface_ip_mroute_source,
struct in_addr src_addr;
int result;
- iif = vty->index;
-
- oifname = argv[0];
+ oifname = argv[idx_interface]->arg;
oif = if_lookup_by_name(oifname);
if (!oif) {
vty_out(vty, "No such interface name %s%s",
@@ -3407,7 +4453,7 @@ DEFUN (interface_ip_mroute_source,
return CMD_WARNING;
}
- grp_str = argv[1];
+ grp_str = argv[idx_ipv4]->arg;
result = inet_pton(AF_INET, grp_str, &grp_addr);
if (result <= 0) {
vty_out(vty, "Bad group address %s: errno=%d: %s%s",
@@ -3415,7 +4461,7 @@ DEFUN (interface_ip_mroute_source,
return CMD_WARNING;
}
- src_str = argv[2];
+ src_str = argv[idx_ipv4_2]->arg;
result = inet_pton(AF_INET, src_str, &src_addr);
if (result <= 0) {
vty_out(vty, "Bad source address %s: errno=%d: %s%s",
@@ -3440,7 +4486,9 @@ DEFUN (interface_no_ip_mroute,
"Outgoing interface name\n"
"Group Address\n")
{
- struct interface *iif;
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ int idx_interface = 3;
+ int idx_ipv4 = 4;
struct interface *oif;
const char *oifname;
const char *grp_str;
@@ -3448,9 +4496,7 @@ DEFUN (interface_no_ip_mroute,
struct in_addr src_addr;
int result;
- iif = vty->index;
-
- oifname = argv[0];
+ oifname = argv[idx_interface]->arg;
oif = if_lookup_by_name(oifname);
if (!oif) {
vty_out(vty, "No such interface name %s%s",
@@ -3458,7 +4504,7 @@ DEFUN (interface_no_ip_mroute,
return CMD_WARNING;
}
- grp_str = argv[1];
+ grp_str = argv[idx_ipv4]->arg;
result = inet_pton(AF_INET, grp_str, &grp_addr);
if (result <= 0) {
vty_out(vty, "Bad group address %s: errno=%d: %s%s",
@@ -3486,7 +4532,10 @@ DEFUN (interface_no_ip_mroute_source,
"Group Address\n"
"Source Address\n")
{
- struct interface *iif;
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ int idx_interface = 3;
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
struct interface *oif;
const char *oifname;
const char *grp_str;
@@ -3495,9 +4544,7 @@ DEFUN (interface_no_ip_mroute_source,
struct in_addr src_addr;
int result;
- iif = vty->index;
-
- oifname = argv[0];
+ oifname = argv[idx_interface]->arg;
oif = if_lookup_by_name(oifname);
if (!oif) {
vty_out(vty, "No such interface name %s%s",
@@ -3505,7 +4552,7 @@ DEFUN (interface_no_ip_mroute_source,
return CMD_WARNING;
}
- grp_str = argv[1];
+ grp_str = argv[idx_ipv4]->arg;
result = inet_pton(AF_INET, grp_str, &grp_addr);
if (result <= 0) {
vty_out(vty, "Bad group address %s: errno=%d: %s%s",
@@ -3513,7 +4560,7 @@ DEFUN (interface_no_ip_mroute_source,
return CMD_WARNING;
}
- src_str = argv[2];
+ src_str = argv[idx_ipv4_2]->arg;
result = inet_pton(AF_INET, src_str, &src_addr);
if (result <= 0) {
vty_out(vty, "Bad source address %s: errno=%d: %s%s",
@@ -3531,16 +4578,18 @@ DEFUN (interface_no_ip_mroute_source,
DEFUN (interface_ip_pim_hello,
interface_ip_pim_hello_cmd,
- "ip pim hello <1-180>",
+ "ip pim hello (1-180) [(1-180)]",
IP_STR
PIM_STR
IFACE_PIM_HELLO_STR
- IFACE_PIM_HELLO_TIME_STR)
+ IFACE_PIM_HELLO_TIME_STR
+ IFACE_PIM_HELLO_HOLD_STR)
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_time = 3;
+ int idx_hold = 4;
struct pim_interface *pim_ifp;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -3548,27 +4597,19 @@ DEFUN (interface_ip_pim_hello,
return CMD_WARNING;
}
- pim_ifp->pim_hello_period = strtol(argv[0], NULL, 10);
+ pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
- if (argc == 2)
- pim_ifp->pim_default_holdtime = strtol(argv[1], NULL, 10);
+ if (argc == idx_hold)
+ pim_ifp->pim_default_holdtime = strtol(argv[idx_hold]->arg, NULL, 10);
return CMD_SUCCESS;
}
-ALIAS (interface_ip_pim_hello,
- interface_ip_pim_hello_hold_cmd,
- "ip pim hello <1-180> <1-180>",
- IP_STR
- PIM_STR
- IFACE_PIM_HELLO_STR
- IFACE_PIM_HELLO_TIME_STR
- IFACE_PIM_HELLO_HOLD_STR)
DEFUN (interface_no_ip_pim_hello,
interface_no_ip_pim_hello_cmd,
- "no ip pim hello {<1-180> <1-180>}",
+ "no ip pim hello [(1-180) (1-180)]",
NO_STR
IP_STR
PIM_STR
@@ -3576,10 +4617,9 @@ DEFUN (interface_no_ip_pim_hello,
IFACE_PIM_HELLO_TIME_STR
IFACE_PIM_HELLO_HOLD_STR)
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
- ifp = vty->index;
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -3618,11 +4658,6 @@ DEFUN (no_debug_igmp,
return CMD_SUCCESS;
}
-ALIAS (no_debug_igmp,
- undebug_igmp_cmd,
- "undebug igmp",
- UNDEBUG_STR
- DEBUG_IGMP_STR)
DEFUN (debug_igmp_events,
debug_igmp_events_cmd,
@@ -3647,12 +4682,6 @@ DEFUN (no_debug_igmp_events,
return CMD_SUCCESS;
}
-ALIAS (no_debug_igmp_events,
- undebug_igmp_events_cmd,
- "undebug igmp events",
- UNDEBUG_STR
- DEBUG_IGMP_STR
- DEBUG_IGMP_EVENTS_STR)
DEFUN (debug_igmp_packets,
debug_igmp_packets_cmd,
@@ -3677,12 +4706,6 @@ DEFUN (no_debug_igmp_packets,
return CMD_SUCCESS;
}
-ALIAS (no_debug_igmp_packets,
- undebug_igmp_packets_cmd,
- "undebug igmp packets",
- UNDEBUG_STR
- DEBUG_IGMP_STR
- DEBUG_IGMP_PACKETS_STR)
DEFUN (debug_igmp_trace,
debug_igmp_trace_cmd,
@@ -3707,12 +4730,6 @@ DEFUN (no_debug_igmp_trace,
return CMD_SUCCESS;
}
-ALIAS (no_debug_igmp_trace,
- undebug_igmp_trace_cmd,
- "undebug igmp trace",
- UNDEBUG_STR
- DEBUG_IGMP_STR
- DEBUG_IGMP_TRACE_STR)
DEFUN (debug_mroute,
debug_mroute_cmd,
@@ -3724,6 +4741,17 @@ DEFUN (debug_mroute,
return CMD_SUCCESS;
}
+DEFUN (debug_mroute_detail,
+ debug_mroute_detail_cmd,
+ "debug mroute detail",
+ DEBUG_STR
+ DEBUG_MROUTE_STR
+ "detailed\n")
+{
+ PIM_DO_DEBUG_MROUTE_DETAIL;
+ return CMD_SUCCESS;
+}
+
DEFUN (no_debug_mroute,
no_debug_mroute_cmd,
"no debug mroute",
@@ -3735,11 +4763,17 @@ DEFUN (no_debug_mroute,
return CMD_SUCCESS;
}
-ALIAS (no_debug_mroute,
- undebug_mroute_cmd,
- "undebug mroute",
- UNDEBUG_STR
- DEBUG_MROUTE_STR)
+DEFUN (no_debug_mroute_detail,
+ no_debug_mroute_detail_cmd,
+ "no debug mroute detail",
+ NO_STR
+ DEBUG_STR
+ DEBUG_MROUTE_STR
+ "detailed\n")
+{
+ PIM_DONT_DEBUG_MROUTE_DETAIL;
+ return CMD_SUCCESS;
+}
DEFUN (debug_static,
debug_static_cmd,
@@ -3762,11 +4796,6 @@ DEFUN (no_debug_static,
return CMD_SUCCESS;
}
-ALIAS (no_debug_static,
- undebug_static_cmd,
- "undebug static",
- UNDEBUG_STR
- DEBUG_STATIC_STR)
DEFUN (debug_pim,
debug_pim_cmd,
@@ -3777,6 +4806,8 @@ DEFUN (debug_pim,
PIM_DO_DEBUG_PIM_EVENTS;
PIM_DO_DEBUG_PIM_PACKETS;
PIM_DO_DEBUG_PIM_TRACE;
+ PIM_DO_DEBUG_MSDP_EVENTS;
+ PIM_DO_DEBUG_MSDP_PACKETS;
return CMD_SUCCESS;
}
@@ -3790,6 +4821,8 @@ DEFUN (no_debug_pim,
PIM_DONT_DEBUG_PIM_EVENTS;
PIM_DONT_DEBUG_PIM_PACKETS;
PIM_DONT_DEBUG_PIM_TRACE;
+ PIM_DONT_DEBUG_MSDP_EVENTS;
+ PIM_DONT_DEBUG_MSDP_PACKETS;
PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
@@ -3797,11 +4830,6 @@ DEFUN (no_debug_pim,
return CMD_SUCCESS;
}
-ALIAS (no_debug_pim,
- undebug_pim_cmd,
- "undebug pim",
- UNDEBUG_STR
- DEBUG_PIM_STR)
DEFUN (debug_pim_events,
debug_pim_events_cmd,
@@ -3826,91 +4854,73 @@ DEFUN (no_debug_pim_events,
return CMD_SUCCESS;
}
-ALIAS (no_debug_pim_events,
- undebug_pim_events_cmd,
- "undebug pim events",
- UNDEBUG_STR
- DEBUG_PIM_STR
- DEBUG_PIM_EVENTS_STR)
-
DEFUN (debug_pim_packets,
debug_pim_packets_cmd,
- "debug pim packets",
- DEBUG_STR
- DEBUG_PIM_STR
- DEBUG_PIM_PACKETS_STR)
-{
- PIM_DO_DEBUG_PIM_PACKETS;
- vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
- return CMD_SUCCESS;
-}
-
-DEFUN (debug_pim_packets_filter,
- debug_pim_packets_filter_cmd,
- "debug pim packets (hello|joins)",
+ "debug pim packets [<hello|joins|register>]",
DEBUG_STR
DEBUG_PIM_STR
DEBUG_PIM_PACKETS_STR
DEBUG_PIM_HELLO_PACKETS_STR
- DEBUG_PIM_J_P_PACKETS_STR)
+ DEBUG_PIM_J_P_PACKETS_STR
+ DEBUG_PIM_PIM_REG_PACKETS_STR)
{
- if (strncmp(argv[0],"h",1) == 0)
+ int idx = 0;
+ if (argv_find (argv, argc, "hello", &idx))
{
PIM_DO_DEBUG_PIM_HELLO;
- vty_out (vty, "PIM Hello debugging is on %s", VTY_NEWLINE);
+ vty_out (vty, "PIM Hello debugging is on%s", VTY_NEWLINE);
}
- else if (strncmp(argv[0],"j",1) == 0)
+ else if (argv_find (argv, argc ,"joins", &idx))
{
PIM_DO_DEBUG_PIM_J_P;
- vty_out (vty, "PIM Join/Prune debugging is on %s", VTY_NEWLINE);
+ vty_out (vty, "PIM Join/Prune debugging is on%s", VTY_NEWLINE);
+ }
+ else if (argv_find (argv, argc, "register", &idx))
+ {
+ PIM_DO_DEBUG_PIM_REG;
+ vty_out (vty, "PIM Register debugging is on%s", VTY_NEWLINE);
+ }
+ else
+ {
+ PIM_DO_DEBUG_PIM_PACKETS;
+ vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
DEFUN (no_debug_pim_packets,
no_debug_pim_packets_cmd,
- "no debug pim packets",
+ "no debug pim packets [<hello|joins|register>]",
NO_STR
DEBUG_STR
DEBUG_PIM_STR
DEBUG_PIM_PACKETS_STR
DEBUG_PIM_HELLO_PACKETS_STR
- DEBUG_PIM_J_P_PACKETS_STR)
+ DEBUG_PIM_J_P_PACKETS_STR
+ DEBUG_PIM_PIM_REG_PACKETS_STR)
{
- PIM_DONT_DEBUG_PIM_PACKETS;
- vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
- return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_pim_packets_filter,
- no_debug_pim_packets_filter_cmd,
- "no debug pim packets (hello|joins)",
- NO_STR
- DEBUG_STR
- DEBUG_PIM_STR
- DEBUG_PIM_PACKETS_STR
- DEBUG_PIM_HELLO_PACKETS_STR
- DEBUG_PIM_J_P_PACKETS_STR)
-{
- if (strncmp(argv[0],"h",1) == 0)
+ int idx = 0;
+ if (argv_find (argv, argc,"hello",&idx))
{
PIM_DONT_DEBUG_PIM_HELLO;
vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
}
- else if (strncmp(argv[0],"j",1) == 0)
+ else if (argv_find (argv, argc, "joins", &idx))
{
PIM_DONT_DEBUG_PIM_J_P;
vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
}
- return CMD_SUCCESS;
+ else if (argv_find (argv, argc, "register", &idx))
+ {
+ PIM_DONT_DEBUG_PIM_REG;
+ vty_out (vty, "PIM Register debugging is off%s", VTY_NEWLINE);
+ }
+ else
+ PIM_DONT_DEBUG_PIM_PACKETS;
+
+ return CMD_SUCCESS;
}
-ALIAS (no_debug_pim_packets,
- undebug_pim_packets_cmd,
- "undebug pim packets",
- UNDEBUG_STR
- DEBUG_PIM_STR
- DEBUG_PIM_PACKETS_STR)
DEFUN (debug_pim_packetdump_send,
debug_pim_packetdump_send_cmd,
@@ -3937,13 +4947,6 @@ DEFUN (no_debug_pim_packetdump_send,
return CMD_SUCCESS;
}
-ALIAS (no_debug_pim_packetdump_send,
- undebug_pim_packetdump_send_cmd,
- "undebug pim packet-dump send",
- UNDEBUG_STR
- DEBUG_PIM_STR
- DEBUG_PIM_PACKETDUMP_STR
- DEBUG_PIM_PACKETDUMP_SEND_STR)
DEFUN (debug_pim_packetdump_recv,
debug_pim_packetdump_recv_cmd,
@@ -3970,13 +4973,6 @@ DEFUN (no_debug_pim_packetdump_recv,
return CMD_SUCCESS;
}
-ALIAS (no_debug_pim_packetdump_recv,
- undebug_pim_packetdump_recv_cmd,
- "undebug pim packet-dump receive",
- UNDEBUG_STR
- DEBUG_PIM_STR
- DEBUG_PIM_PACKETDUMP_STR
- DEBUG_PIM_PACKETDUMP_RECV_STR)
DEFUN (debug_pim_trace,
debug_pim_trace_cmd,
@@ -4001,12 +4997,6 @@ DEFUN (no_debug_pim_trace,
return CMD_SUCCESS;
}
-ALIAS (no_debug_pim_trace,
- undebug_pim_trace_cmd,
- "undebug pim trace",
- UNDEBUG_STR
- DEBUG_PIM_STR
- DEBUG_PIM_TRACE_STR)
DEFUN (debug_ssmpingd,
debug_ssmpingd_cmd,
@@ -4031,12 +5021,6 @@ DEFUN (no_debug_ssmpingd,
return CMD_SUCCESS;
}
-ALIAS (no_debug_ssmpingd,
- undebug_ssmpingd_cmd,
- "undebug ssmpingd",
- UNDEBUG_STR
- DEBUG_PIM_STR
- DEBUG_SSMPINGD_STR)
DEFUN (debug_pim_zebra,
debug_pim_zebra_cmd,
@@ -4061,12 +5045,95 @@ DEFUN (no_debug_pim_zebra,
return CMD_SUCCESS;
}
-ALIAS (no_debug_pim_zebra,
- undebug_pim_zebra_cmd,
- "undebug pim zebra",
+
+DEFUN (debug_msdp,
+ debug_msdp_cmd,
+ "debug msdp",
+ DEBUG_STR
+ DEBUG_MSDP_STR)
+{
+ PIM_DO_DEBUG_MSDP_EVENTS;
+ PIM_DO_DEBUG_MSDP_PACKETS;
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_msdp,
+ no_debug_msdp_cmd,
+ "no debug msdp",
+ NO_STR
+ DEBUG_STR
+ DEBUG_MSDP_STR)
+{
+ PIM_DONT_DEBUG_MSDP_EVENTS;
+ PIM_DONT_DEBUG_MSDP_PACKETS;
+ return CMD_SUCCESS;
+}
+
+ALIAS (no_debug_msdp,
+ undebug_msdp_cmd,
+ "undebug msdp",
UNDEBUG_STR
- DEBUG_PIM_STR
- DEBUG_PIM_ZEBRA_STR)
+ DEBUG_MSDP_STR)
+
+DEFUN (debug_msdp_events,
+ debug_msdp_events_cmd,
+ "debug msdp events",
+ DEBUG_STR
+ DEBUG_MSDP_STR
+ DEBUG_MSDP_EVENTS_STR)
+{
+ PIM_DO_DEBUG_MSDP_EVENTS;
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_msdp_events,
+ no_debug_msdp_events_cmd,
+ "no debug msdp events",
+ NO_STR
+ DEBUG_STR
+ DEBUG_MSDP_STR
+ DEBUG_MSDP_EVENTS_STR)
+{
+ PIM_DONT_DEBUG_MSDP_EVENTS;
+ return CMD_SUCCESS;
+}
+
+ALIAS (no_debug_msdp_events,
+ undebug_msdp_events_cmd,
+ "undebug msdp events",
+ UNDEBUG_STR
+ DEBUG_MSDP_STR
+ DEBUG_MSDP_EVENTS_STR)
+
+DEFUN (debug_msdp_packets,
+ debug_msdp_packets_cmd,
+ "debug msdp packets",
+ DEBUG_STR
+ DEBUG_MSDP_STR
+ DEBUG_MSDP_PACKETS_STR)
+{
+ PIM_DO_DEBUG_MSDP_PACKETS;
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_msdp_packets,
+ no_debug_msdp_packets_cmd,
+ "no debug msdp packets",
+ NO_STR
+ DEBUG_STR
+ DEBUG_MSDP_STR
+ DEBUG_MSDP_PACKETS_STR)
+{
+ PIM_DONT_DEBUG_MSDP_PACKETS;
+ return CMD_SUCCESS;
+}
+
+ALIAS (no_debug_msdp_packets,
+ undebug_msdp_packets_cmd,
+ "undebug msdp packets",
+ UNDEBUG_STR
+ DEBUG_MSDP_STR
+ DEBUG_MSDP_PACKETS_STR)
DEFUN (show_debugging_pim,
show_debugging_pim_cmd,
@@ -4079,786 +5146,843 @@ DEFUN (show_debugging_pim,
return CMD_SUCCESS;
}
-static struct igmp_sock *find_igmp_sock_by_fd(int fd)
+static int
+interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
{
- struct listnode *ifnode;
- struct interface *ifp;
+ int result;
+ struct in_addr source_addr;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
- /* scan all interfaces */
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp;
- struct igmp_sock *igmp;
-
- if (!ifp->info)
- continue;
+ result = inet_pton(AF_INET, source, &source_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
+ source, errno, safe_strerror(errno), VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- pim_ifp = ifp->info;
+ result = pim_update_source_set(ifp, source_addr);
+ switch (result) {
+ case PIM_SUCCESS:
+ break;
+ case PIM_IFACE_NOT_FOUND:
+ vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
+ break;
+ case PIM_UPDATE_SOURCE_DUP:
+ vty_out(vty, "%% Source already set to %s%s", source, VTY_NEWLINE);
+ break;
+ default:
+ vty_out(vty, "%% Source set failed%s", VTY_NEWLINE);
+ }
- /* lookup igmp socket under current interface */
- igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
- if (igmp)
- return igmp;
- }
-
- return 0;
-}
-
-DEFUN (test_igmp_receive_report,
- test_igmp_receive_report_cmd,
- "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
- "Test\n"
- "Test IGMP protocol\n"
- "Test IGMP message\n"
- "Test IGMP report\n"
- "Socket\n"
- "IGMP group address\n"
- "Record type\n"
- "Sources\n")
-{
- char buf[1000];
- char *igmp_msg;
- struct ip *ip_hdr;
- size_t ip_hlen; /* ip header length in bytes */
- int ip_msg_len;
- int igmp_msg_len;
- const char *socket;
- int socket_fd;
- const char *grp_str;
- struct in_addr grp_addr;
- const char *record_type_str;
- int record_type;
- const char *src_str;
- int result;
- struct igmp_sock *igmp;
- char *group_record;
- int num_sources;
- struct in_addr *sources;
- struct in_addr *src_addr;
- int argi;
-
- socket = argv[0];
- socket_fd = atoi(socket);
- igmp = find_igmp_sock_by_fd(socket_fd);
- if (!igmp) {
- vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
- socket, socket_fd, VTY_NEWLINE);
+ return result?CMD_WARNING:CMD_SUCCESS;
+}
+
+DEFUN (interface_pim_use_source,
+ interface_pim_use_source_cmd,
+ "ip pim use-source A.B.C.D",
+ IP_STR
+ "pim multicast routing\n"
+ "Configure primary IP address\n"
+ "source ip address\n")
+{
+ return interface_pim_use_src_cmd_worker (vty, argv[3]->arg);
+}
+
+DEFUN (interface_no_pim_use_source,
+ interface_no_pim_use_source_cmd,
+ "no ip pim use-source",
+ NO_STR
+ IP_STR
+ "pim multicast routing\n"
+ "Delete source IP address\n")
+{
+ return interface_pim_use_src_cmd_worker (vty, "0.0.0.0");
+}
+
+static int
+ip_msdp_peer_cmd_worker (struct vty *vty, const char *peer, const char *local)
+{
+ enum pim_msdp_err result;
+ struct in_addr peer_addr;
+ struct in_addr local_addr;
+
+ result = inet_pton(AF_INET, peer, &peer_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad peer address %s: errno=%d: %s%s",
+ peer, errno, safe_strerror(errno), VTY_NEWLINE);
return CMD_WARNING;
}
- grp_str = argv[1];
- result = inet_pton(AF_INET, grp_str, &grp_addr);
+ result = inet_pton(AF_INET, local, &local_addr);
if (result <= 0) {
- vty_out(vty, "Bad group address %s: errno=%d: %s%s",
- grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
+ vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
+ local, errno, safe_strerror(errno), VTY_NEWLINE);
return CMD_WARNING;
}
- record_type_str = argv[2];
- record_type = atoi(record_type_str);
-
- /*
- Tweak IP header
- */
- ip_hdr = (struct ip *) buf;
- ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
- ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
- ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
- ip_hdr->ip_src = igmp->ifaddr;
- ip_hdr->ip_dst = igmp->ifaddr;
-
- /*
- Build IGMP v3 report message
- */
- igmp_msg = buf + ip_hlen;
- group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
- *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
- *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
- *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
- *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
- memcpy(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, &grp_addr, sizeof(struct in_addr));
-
- /* Scan LINE sources */
- sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
- src_addr = sources;
- for (argi = 3; argi < argc; ++argi,++src_addr) {
- src_str = argv[argi];
- result = inet_pton(AF_INET, src_str, src_addr);
- if (result <= 0) {
- vty_out(vty, "Bad source address %s: errno=%d: %s%s",
- src_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
- }
+ result = pim_msdp_peer_add(peer_addr, local_addr, "default", NULL/* mp_p */);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_OOM:
+ vty_out(vty, "%% Out of memory%s", VTY_NEWLINE);
+ break;
+ case PIM_MSDP_ERR_PEER_EXISTS:
+ vty_out(vty, "%% Peer exists%s", VTY_NEWLINE);
+ break;
+ case PIM_MSDP_ERR_MAX_MESH_GROUPS:
+ vty_out(vty, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out(vty, "%% peer add failed%s", VTY_NEWLINE);
}
- num_sources = src_addr - sources;
-
- *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
- igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
+ return result?CMD_WARNING:CMD_SUCCESS;
+}
- /* compute checksum */
- *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = in_cksum(igmp_msg, igmp_msg_len);
+DEFUN_HIDDEN (ip_msdp_peer,
+ ip_msdp_peer_cmd,
+ "ip msdp peer A.B.C.D source A.B.C.D",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP peer\n"
+ "peer ip address\n"
+ "Source address for TCP connection\n"
+ "local ip address\n")
+{
+ return ip_msdp_peer_cmd_worker (vty, argv[3]->arg, argv[5]->arg);
+}
- /* "receive" message */
+static int
+ip_no_msdp_peer_cmd_worker (struct vty *vty, const char *peer)
+{
+ enum pim_msdp_err result;
+ struct in_addr peer_addr;
- ip_msg_len = ip_hlen + igmp_msg_len;
- result = pim_igmp_packet(igmp, buf, ip_msg_len);
- if (result) {
- vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
- ip_msg_len, result, VTY_NEWLINE);
+ result = inet_pton(AF_INET, peer, &peer_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad peer address %s: errno=%d: %s%s",
+ peer, errno, safe_strerror(errno), VTY_NEWLINE);
return CMD_WARNING;
}
- return CMD_SUCCESS;
+ result = pim_msdp_peer_del(peer_addr);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_NO_PEER:
+ vty_out(vty, "%% Peer does not exist%s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out(vty, "%% peer del failed%s", VTY_NEWLINE);
+ }
+
+ return result?CMD_WARNING:CMD_SUCCESS;
}
-static int hexval(uint8_t ch)
+DEFUN_HIDDEN (no_ip_msdp_peer,
+ no_ip_msdp_peer_cmd,
+ "no ip msdp peer A.B.C.D",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP peer\n"
+ "peer ip address\n")
{
- return isdigit(ch) ? (ch - '0') : (10 + tolower(ch) - 'a');
+ return ip_no_msdp_peer_cmd_worker (vty, argv[4]->arg);
}
-DEFUN (test_pim_receive_dump,
- test_pim_receive_dump_cmd,
- "test pim receive dump INTERFACE A.B.C.D .LINE",
- "Test\n"
- "Test PIM protocol\n"
- "Test PIM message reception\n"
- "Test PIM packet dump reception from neighbor\n"
- "Interface\n"
- "Neighbor address\n"
- "Packet dump\n")
+static int
+ip_msdp_mesh_group_member_cmd_worker(struct vty *vty, const char *mg, const char *mbr)
{
- uint8_t buf[1000];
- uint8_t *pim_msg;
- struct ip *ip_hdr;
- size_t ip_hlen; /* ip header length in bytes */
- int ip_msg_len;
- int pim_msg_size;
- const char *neigh_str;
- struct in_addr neigh_addr;
- const char *ifname;
- struct interface *ifp;
- int argi;
- int result;
-
- /* Find interface */
- ifname = argv[0];
- ifp = if_lookup_by_name(ifname);
- if (!ifp) {
- vty_out(vty, "No such interface name %s%s",
- ifname, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ enum pim_msdp_err result;
+ struct in_addr mbr_ip;
- /* Neighbor address */
- neigh_str = argv[1];
- result = inet_pton(AF_INET, neigh_str, &neigh_addr);
+ result = inet_pton(AF_INET, mbr, &mbr_ip);
if (result <= 0) {
- vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
- neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
+ vty_out(vty, "%% Bad member address %s: errno=%d: %s%s",
+ mbr, errno, safe_strerror(errno), VTY_NEWLINE);
return CMD_WARNING;
}
- /*
- Tweak IP header
- */
- ip_hdr = (struct ip *) buf;
- ip_hdr->ip_p = PIM_IP_PROTO_PIM;
- ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
- ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
- ip_hdr->ip_src = neigh_addr;
- ip_hdr->ip_dst = qpim_all_pim_routers_addr;
+ result = pim_msdp_mg_mbr_add(mg, mbr_ip);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_OOM:
+ vty_out(vty, "%% Out of memory%s", VTY_NEWLINE);
+ break;
+ case PIM_MSDP_ERR_MG_MBR_EXISTS:
+ vty_out(vty, "%% mesh-group member exists%s", VTY_NEWLINE);
+ break;
+ case PIM_MSDP_ERR_MAX_MESH_GROUPS:
+ vty_out(vty, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out(vty, "%% member add failed%s", VTY_NEWLINE);
+ }
- /*
- Build PIM hello message
- */
- pim_msg = buf + ip_hlen;
- pim_msg_size = 0;
-
- /* Scan LINE dump into buffer */
- for (argi = 2; argi < argc; ++argi) {
- const char *str = argv[argi];
- int str_len = strlen(str);
- int str_last = str_len - 1;
- int i;
-
- if (str_len % 2) {
- vty_out(vty, "%% Uneven hex array arg %d=%s%s",
- argi, str, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ return result?CMD_WARNING:CMD_SUCCESS;
+}
- for (i = 0; i < str_last; i += 2) {
- uint8_t octet;
- int left;
- uint8_t h1 = str[i];
- uint8_t h2 = str[i + 1];
+DEFUN (ip_msdp_mesh_group_member,
+ ip_msdp_mesh_group_member_cmd,
+ "ip msdp mesh-group WORD member A.B.C.D",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP mesh-group\n"
+ "mesh group name\n"
+ "mesh group member\n"
+ "peer ip address\n")
+{
+ return ip_msdp_mesh_group_member_cmd_worker(vty, argv[3]->arg, argv[5]->arg);
+}
- if (!isxdigit(h1) || !isxdigit(h2)) {
- vty_out(vty, "%% Non-hex octet %c%c at hex array arg %d=%s%s",
- h1, h2, argi, str, VTY_NEWLINE);
- return CMD_WARNING;
- }
- octet = (hexval(h1) << 4) + hexval(h2);
+static int
+ip_no_msdp_mesh_group_member_cmd_worker(struct vty *vty, const char *mg, const char *mbr)
+{
+ enum pim_msdp_err result;
+ struct in_addr mbr_ip;
- left = sizeof(buf) - ip_hlen - pim_msg_size;
- if (left < 1) {
- vty_out(vty, "%% Overflow buf_size=%zu buf_left=%d at hex array arg %d=%s octet %02x%s",
- sizeof(buf), left, argi, str, octet, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- pim_msg[pim_msg_size++] = octet;
- }
+ result = inet_pton(AF_INET, mbr, &mbr_ip);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad member address %s: errno=%d: %s%s",
+ mbr, errno, safe_strerror(errno), VTY_NEWLINE);
+ return CMD_WARNING;
}
- ip_msg_len = ip_hlen + pim_msg_size;
+ result = pim_msdp_mg_mbr_del(mg, mbr_ip);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_NO_MG:
+ vty_out(vty, "%% mesh-group does not exist%s", VTY_NEWLINE);
+ break;
+ case PIM_MSDP_ERR_NO_MG_MBR:
+ vty_out(vty, "%% mesh-group member does not exist%s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out(vty, "%% mesh-group member del failed%s", VTY_NEWLINE);
+ }
- vty_out(vty, "Receiving: buf_size=%zu ip_msg_size=%d pim_msg_size=%d%s",
- sizeof(buf), ip_msg_len, pim_msg_size, VTY_NEWLINE);
+ return result?CMD_WARNING:CMD_SUCCESS;
+}
+DEFUN (no_ip_msdp_mesh_group_member,
+ no_ip_msdp_mesh_group_member_cmd,
+ "no ip msdp mesh-group WORD member A.B.C.D",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP mesh-group member\n"
+ "mesh group name\n"
+ "mesh group member\n"
+ "peer ip address\n")
+{
+ return ip_no_msdp_mesh_group_member_cmd_worker(vty, argv[4]->arg, argv[6]->arg);
+}
- /* "receive" message */
+static int
+ip_msdp_mesh_group_source_cmd_worker(struct vty *vty, const char *mg, const char *src)
+{
+ enum pim_msdp_err result;
+ struct in_addr src_ip;
- result = pim_pim_packet(ifp, buf, ip_msg_len);
- if (result) {
- vty_out(vty, "%% pim_pim_packet(len=%d) returned failure: %d%s",
- ip_msg_len, result, VTY_NEWLINE);
+ result = inet_pton(AF_INET, src, &src_ip);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
+ src, errno, safe_strerror(errno), VTY_NEWLINE);
return CMD_WARNING;
}
- return CMD_SUCCESS;
+ result = pim_msdp_mg_src_add(mg, src_ip);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_OOM:
+ vty_out(vty, "%% Out of memory%s", VTY_NEWLINE);
+ break;
+ case PIM_MSDP_ERR_MAX_MESH_GROUPS:
+ vty_out(vty, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out(vty, "%% source add failed%s", VTY_NEWLINE);
+ }
+
+ return result?CMD_WARNING:CMD_SUCCESS;
}
-DEFUN (test_pim_receive_hello,
- test_pim_receive_hello_cmd,
- "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
- "Test\n"
- "Test PIM protocol\n"
- "Test PIM message reception\n"
- "Test PIM hello reception from neighbor\n"
- "Interface\n"
- "Neighbor address\n"
- "Neighbor holdtime\n"
- "Neighbor DR priority\n"
- "Neighbor generation ID\n"
- "Neighbor propagation delay (msec)\n"
- "Neighbor override interval (msec)\n"
- "Neighbor LAN prune delay T-bit\n"
- "Neighbor secondary addresses\n")
-{
- uint8_t buf[1000];
- uint8_t *pim_msg;
- struct ip *ip_hdr;
- size_t ip_hlen; /* ip header length in bytes */
- int ip_msg_len;
- int pim_tlv_size;
- int pim_msg_size;
- const char *neigh_str;
- struct in_addr neigh_addr;
- const char *ifname;
- struct interface *ifp;
- uint16_t neigh_holdtime;
- uint16_t neigh_propagation_delay;
- uint16_t neigh_override_interval;
- int neigh_can_disable_join_suppression;
- uint32_t neigh_dr_priority;
- uint32_t neigh_generation_id;
- int argi;
- int result;
-
- /* Find interface */
- ifname = argv[0];
- ifp = if_lookup_by_name(ifname);
- if (!ifp) {
- vty_out(vty, "No such interface name %s%s",
- ifname, VTY_NEWLINE);
- return CMD_WARNING;
- }
- /* Neighbor address */
- neigh_str = argv[1];
- result = inet_pton(AF_INET, neigh_str, &neigh_addr);
- if (result <= 0) {
- vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
- neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
+DEFUN (ip_msdp_mesh_group_source,
+ ip_msdp_mesh_group_source_cmd,
+ "ip msdp mesh-group WORD source A.B.C.D",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP mesh-group\n"
+ "mesh group name\n"
+ "mesh group local address\n"
+ "source ip address for the TCP connection\n")
+{
+ return ip_msdp_mesh_group_source_cmd_worker(vty, argv[3]->arg, argv[5]->arg);
+}
+
+static int
+ip_no_msdp_mesh_group_source_cmd_worker(struct vty *vty, const char *mg)
+{
+ enum pim_msdp_err result;
+
+ result = pim_msdp_mg_src_del(mg);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_NO_MG:
+ vty_out(vty, "%% mesh-group does not exist%s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out(vty, "%% mesh-group source del failed%s", VTY_NEWLINE);
}
- neigh_holdtime = atoi(argv[2]);
- neigh_dr_priority = atoi(argv[3]);
- neigh_generation_id = atoi(argv[4]);
- neigh_propagation_delay = atoi(argv[5]);
- neigh_override_interval = atoi(argv[6]);
- neigh_can_disable_join_suppression = atoi(argv[7]);
+ return result?CMD_WARNING:CMD_SUCCESS;
+}
- /*
- Tweak IP header
- */
- ip_hdr = (struct ip *) buf;
- ip_hdr->ip_p = PIM_IP_PROTO_PIM;
- ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
- ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
- ip_hdr->ip_src = neigh_addr;
- ip_hdr->ip_dst = qpim_all_pim_routers_addr;
+static int
+ip_no_msdp_mesh_group_cmd_worker(struct vty *vty, const char *mg)
+{
+ enum pim_msdp_err result;
+
+ result = pim_msdp_mg_del(mg);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_NO_MG:
+ vty_out(vty, "%% mesh-group does not exist%s", VTY_NEWLINE);
+ break;
+ default:
+ vty_out(vty, "%% mesh-group source del failed%s", VTY_NEWLINE);
+ }
- /*
- Build PIM hello message
- */
- pim_msg = buf + ip_hlen;
-
- /* Scan LINE addresses */
- for (argi = 8; argi < argc; ++argi) {
- const char *sec_str = argv[argi];
- struct in_addr sec_addr;
- result = inet_pton(AF_INET, sec_str, &sec_addr);
- if (result <= 0) {
- vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
- sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
- }
+ return result ? CMD_WARNING : CMD_SUCCESS;
+}
- vty_out(vty,
- "FIXME WRITEME consider neighbor secondary address %s%s",
- sec_str, VTY_NEWLINE);
- }
-
- pim_tlv_size = pim_hello_build_tlv(ifp->name,
- pim_msg + PIM_PIM_MIN_LEN,
- sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
- neigh_holdtime,
- neigh_dr_priority,
- neigh_generation_id,
- neigh_propagation_delay,
- neigh_override_interval,
- neigh_can_disable_join_suppression,
- 0 /* FIXME secondary address list */);
- if (pim_tlv_size < 0) {
- vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
- pim_tlv_size, VTY_NEWLINE);
- return CMD_WARNING;
+DEFUN (no_ip_msdp_mesh_group_source,
+ no_ip_msdp_mesh_group_source_cmd,
+ "no ip msdp mesh-group WORD source [A.B.C.D]",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP mesh-group source\n"
+ "mesh group name\n"
+ "mesh group source\n"
+ "mesh group local address\n")
+{
+ if (argc == 6)
+ return ip_no_msdp_mesh_group_cmd_worker(vty, argv[6]->arg);
+ else
+ return ip_no_msdp_mesh_group_source_cmd_worker(vty, argv[4]->arg);
+}
+
+static void
+print_empty_json_obj(struct vty *vty)
+{
+ json_object *json;
+ json = json_object_new_object();
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+}
+
+static void
+ip_msdp_show_mesh_group(struct vty *vty, u_char uj)
+{
+ struct listnode *mbrnode;
+ struct pim_msdp_mg_mbr *mbr;
+ struct pim_msdp_mg *mg = msdp->mg;
+ char mbr_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ char state_str[PIM_MSDP_STATE_STRLEN];
+ enum pim_msdp_peer_state state;
+ json_object *json = NULL;
+ json_object *json_mg_row = NULL;
+ json_object *json_members = NULL;
+ json_object *json_row = NULL;
+
+ if (!mg) {
+ if (uj)
+ print_empty_json_obj(vty);
+ return;
}
- pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
-
- pim_msg_build_header(pim_msg, pim_msg_size,
- PIM_MSG_TYPE_HELLO);
+ pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
+ if (uj) {
+ json = json_object_new_object();
+ /* currently there is only one mesh group but we should still make
+ * it a dict with mg-name as key */
+ json_mg_row = json_object_new_object();
+ json_object_string_add(json_mg_row, "name", mg->mesh_group_name);
+ json_object_string_add(json_mg_row, "source", src_str);
+ } else {
+ vty_out(vty, "Mesh group : %s%s", mg->mesh_group_name, VTY_NEWLINE);
+ vty_out(vty, " Source : %s%s", src_str, VTY_NEWLINE);
+ vty_out(vty, " Member State%s", VTY_NEWLINE);
+ }
- /* "receive" message */
+ for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
+ pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
+ if (mbr->mp) {
+ state = mbr->mp->state;
+ } else {
+ state = PIM_MSDP_DISABLED;
+ }
+ pim_msdp_state_dump(state, state_str, sizeof(state_str));
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "member", mbr_str);
+ json_object_string_add(json_row, "state", state_str);
+ if (!json_members) {
+ json_members = json_object_new_object();
+ json_object_object_add(json_mg_row, "members", json_members);
+ }
+ json_object_object_add(json_members, mbr_str, json_row);
+ } else {
+ vty_out(vty, " %-15s %11s%s",
+ mbr_str, state_str, VTY_NEWLINE);
+ }
+ }
- ip_msg_len = ip_hlen + pim_msg_size;
- result = pim_pim_packet(ifp, buf, ip_msg_len);
- if (result) {
- vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
- ip_msg_len, result, VTY_NEWLINE);
- return CMD_WARNING;
+ if (uj) {
+ json_object_object_add(json, mg->mesh_group_name, json_mg_row);
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
}
+}
+
+DEFUN (show_ip_msdp_mesh_group,
+ show_ip_msdp_mesh_group_cmd,
+ "show ip msdp mesh-group [json]",
+ SHOW_STR
+ IP_STR
+ MSDP_STR
+ "MSDP mesh-group information\n"
+ "JavaScript Object Notation\n")
+{
+ u_char uj = use_json(argc, argv);
+ ip_msdp_show_mesh_group(vty, uj);
return CMD_SUCCESS;
}
-DEFUN (test_pim_receive_assert,
- test_pim_receive_assert_cmd,
- "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
- "Test\n"
- "Test PIM protocol\n"
- "Test PIM message reception\n"
- "Test reception of PIM assert\n"
- "Interface\n"
- "Neighbor address\n"
- "Assert multicast group address\n"
- "Assert unicast source address\n"
- "Assert metric preference\n"
- "Assert route metric\n"
- "Assert RPT bit flag\n")
-{
- uint8_t buf[1000];
- uint8_t *buf_pastend = buf + sizeof(buf);
- uint8_t *pim_msg;
- struct ip *ip_hdr;
- size_t ip_hlen; /* ip header length in bytes */
- int ip_msg_len;
- int pim_msg_size;
- const char *neigh_str;
- struct in_addr neigh_addr;
- const char *group_str;
- struct in_addr group_addr;
- const char *source_str;
- struct in_addr source_addr;
- const char *ifname;
- struct interface *ifp;
- uint32_t assert_metric_preference;
- uint32_t assert_route_metric;
- uint32_t assert_rpt_bit_flag;
- int remain;
- int result;
-
- /* Find interface */
- ifname = argv[0];
- ifp = if_lookup_by_name(ifname);
- if (!ifp) {
- vty_out(vty, "No such interface name %s%s",
- ifname, VTY_NEWLINE);
- return CMD_WARNING;
+static void
+ip_msdp_show_peers(struct vty *vty, u_char uj)
+{
+ struct listnode *mpnode;
+ struct pim_msdp_peer *mp;
+ char peer_str[INET_ADDRSTRLEN];
+ char local_str[INET_ADDRSTRLEN];
+ char state_str[PIM_MSDP_STATE_STRLEN];
+ char timebuf[PIM_MSDP_UPTIME_STRLEN];
+ int64_t now;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty, "Peer Local State Uptime SaCnt%s", VTY_NEWLINE);
}
- /* Neighbor address */
- neigh_str = argv[1];
- result = inet_pton(AF_INET, neigh_str, &neigh_addr);
- if (result <= 0) {
- vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
- neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
+ for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ now = pim_time_monotonic_sec();
+ pim_time_uptime(timebuf, sizeof(timebuf), now - mp->uptime);
+ } else {
+ strcpy(timebuf, "-");
+ }
+ pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
+ pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
+ pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "peer", peer_str);
+ json_object_string_add(json_row, "local", local_str);
+ json_object_string_add(json_row, "state", state_str);
+ json_object_string_add(json_row, "upTime", timebuf);
+ json_object_int_add(json_row, "saCount", mp->sa_cnt);
+ json_object_object_add(json, peer_str, json_row);
+ } else {
+ vty_out(vty, "%-15s %15s %11s %8s %6d%s",
+ peer_str, local_str, state_str,
+ timebuf, mp->sa_cnt, VTY_NEWLINE);
+ }
}
- /* Group address */
- group_str = argv[2];
- result = inet_pton(AF_INET, group_str, &group_addr);
- if (result <= 0) {
- vty_out(vty, "Bad group address %s: errno=%d: %s%s",
- group_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
}
+}
- /* Source address */
- source_str = argv[3];
- result = inet_pton(AF_INET, source_str, &source_addr);
- if (result <= 0) {
- vty_out(vty, "Bad source address %s: errno=%d: %s%s",
- source_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
+static void
+ip_msdp_show_peers_detail(struct vty *vty, const char *peer, u_char uj)
+{
+ struct listnode *mpnode;
+ struct pim_msdp_peer *mp;
+ char peer_str[INET_ADDRSTRLEN];
+ char local_str[INET_ADDRSTRLEN];
+ char state_str[PIM_MSDP_STATE_STRLEN];
+ char timebuf[PIM_MSDP_UPTIME_STRLEN];
+ char katimer[PIM_MSDP_TIMER_STRLEN];
+ char crtimer[PIM_MSDP_TIMER_STRLEN];
+ char holdtimer[PIM_MSDP_TIMER_STRLEN];
+ int64_t now;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
}
- assert_metric_preference = atoi(argv[4]);
- assert_route_metric = atoi(argv[5]);
- assert_rpt_bit_flag = atoi(argv[6]);
+ for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+ pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
+ if (strcmp(peer, "detail") &&
+ strcmp(peer, peer_str))
+ continue;
- remain = buf_pastend - buf;
- if (remain < (int) sizeof(struct ip)) {
- vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%zu%s",
- remain, sizeof(struct ip), VTY_NEWLINE);
- return CMD_WARNING;
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ now = pim_time_monotonic_sec();
+ pim_time_uptime(timebuf, sizeof(timebuf), now - mp->uptime);
+ } else {
+ strcpy(timebuf, "-");
+ }
+ pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
+ pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
+ pim_time_timer_to_hhmmss(katimer, sizeof(katimer), mp->ka_timer);
+ pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer), mp->cr_timer);
+ pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer), mp->hold_timer);
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "peer", peer_str);
+ json_object_string_add(json_row, "local", local_str);
+ json_object_string_add(json_row, "meshGroupName", mp->mesh_group_name);
+ json_object_string_add(json_row, "state", state_str);
+ json_object_string_add(json_row, "upTime", timebuf);
+ json_object_string_add(json_row, "keepAliveTimer", katimer);
+ json_object_string_add(json_row, "connRetryTimer", crtimer);
+ json_object_string_add(json_row, "holdTimer", holdtimer);
+ json_object_string_add(json_row, "lastReset", mp->last_reset);
+ json_object_int_add(json_row, "connAttempts", mp->conn_attempts);
+ json_object_int_add(json_row, "establishedChanges", mp->est_flaps);
+ json_object_int_add(json_row, "saCount", mp->sa_cnt);
+ json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
+ json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
+ json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
+ json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
+ json_object_object_add(json, peer_str, json_row);
+ } else {
+ vty_out(vty, "Peer : %s%s", peer_str, VTY_NEWLINE);
+ vty_out(vty, " Local : %s%s", local_str, VTY_NEWLINE);
+ vty_out(vty, " Mesh Group : %s%s", mp->mesh_group_name, VTY_NEWLINE);
+ vty_out(vty, " State : %s%s", state_str, VTY_NEWLINE);
+ vty_out(vty, " Uptime : %s%s", timebuf, VTY_NEWLINE);
+
+ vty_out(vty, " Keepalive Timer : %s%s", katimer, VTY_NEWLINE);
+ vty_out(vty, " Conn Retry Timer : %s%s", crtimer, VTY_NEWLINE);
+ vty_out(vty, " Hold Timer : %s%s", holdtimer, VTY_NEWLINE);
+ vty_out(vty, " Last Reset : %s%s", mp->last_reset, VTY_NEWLINE);
+ vty_out(vty, " Conn Attempts : %d%s", mp->conn_attempts, VTY_NEWLINE);
+ vty_out(vty, " Established Changes : %d%s", mp->est_flaps, VTY_NEWLINE);
+ vty_out(vty, " SA Count : %d%s", mp->sa_cnt, VTY_NEWLINE);
+ vty_out(vty, " Statistics :%s", VTY_NEWLINE);
+ vty_out(vty, " Sent Rcvd%s", VTY_NEWLINE);
+ vty_out(vty, " Keepalives : %10d %10d%s",
+ mp->ka_tx_cnt, mp->ka_rx_cnt, VTY_NEWLINE);
+ vty_out(vty, " SAs : %10d %10d%s",
+ mp->sa_tx_cnt, mp->sa_rx_cnt, VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
}
- /*
- Tweak IP header
- */
- ip_hdr = (struct ip *) buf;
- ip_hdr->ip_p = PIM_IP_PROTO_PIM;
- ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
- ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
- ip_hdr->ip_src = neigh_addr;
- ip_hdr->ip_dst = qpim_all_pim_routers_addr;
-
- /*
- Build PIM assert message
- */
- pim_msg = buf + ip_hlen; /* skip ip header */
-
- pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
- group_addr, source_addr,
- assert_metric_preference,
- assert_route_metric,
- assert_rpt_bit_flag);
- if (pim_msg_size < 0) {
- vty_out(vty, "Failure building PIM assert message: size=%d%s",
- pim_msg_size, VTY_NEWLINE);
- return CMD_WARNING;
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
}
+}
- /* "receive" message */
+DEFUN (show_ip_msdp_peer_detail,
+ show_ip_msdp_peer_detail_cmd,
+ "show ip msdp peer [detail|A.B.C.D] [json]",
+ SHOW_STR
+ IP_STR
+ MSDP_STR
+ "MSDP peer information\n"
+ "Detailed output\n"
+ "peer ip address\n"
+ "JavaScript Object Notation\n")
+{
+ u_char uj = use_json(argc, argv);
+ if (uj)
+ argc--;
- ip_msg_len = ip_hlen + pim_msg_size;
- result = pim_pim_packet(ifp, buf, ip_msg_len);
- if (result) {
- vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
- ip_msg_len, result, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (argc == 4)
+ ip_msdp_show_peers_detail(vty, argv[4]->arg, uj);
+ else
+ ip_msdp_show_peers(vty, uj);
return CMD_SUCCESS;
}
-static int recv_joinprune(struct vty *vty,
- const char *argv[],
- int src_is_join)
-{
- uint8_t buf[1000];
- const uint8_t *buf_pastend = buf + sizeof(buf);
- uint8_t *pim_msg;
- uint8_t *pim_msg_curr;
- int pim_msg_size;
- struct ip *ip_hdr;
- size_t ip_hlen; /* ip header length in bytes */
- int ip_msg_len;
- uint16_t neigh_holdtime;
- const char *neigh_dst_str;
- struct in_addr neigh_dst_addr;
- const char *neigh_src_str;
- struct in_addr neigh_src_addr;
- const char *group_str;
- struct in_addr group_addr;
- const char *source_str;
- struct in_addr source_addr;
- const char *ifname;
- struct interface *ifp;
- int result;
- int remain;
- uint16_t num_joined;
- uint16_t num_pruned;
-
- /* Find interface */
- ifname = argv[0];
- ifp = if_lookup_by_name(ifname);
- if (!ifp) {
- vty_out(vty, "No such interface name %s%s",
- ifname, VTY_NEWLINE);
- return CMD_WARNING;
+static void
+ip_msdp_show_sa(struct vty *vty, u_char uj)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char rp_str[INET_ADDRSTRLEN];
+ char timebuf[PIM_MSDP_UPTIME_STRLEN];
+ char spt_str[8];
+ char local_str[8];
+ int64_t now;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty, "Source Group RP Local SPT Uptime%s", VTY_NEWLINE);
}
- neigh_holdtime = atoi(argv[1]);
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ now = pim_time_monotonic_sec();
+ pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
+ pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
+ if (sa->flags & PIM_MSDP_SAF_PEER) {
+ pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
+ if (sa->up) {
+ strcpy(spt_str, "yes");
+ } else {
+ strcpy(spt_str, "no");
+ }
+ } else {
+ strcpy(rp_str, "-");
+ strcpy(spt_str, "-");
+ }
+ if (sa->flags & PIM_MSDP_SAF_LOCAL) {
+ strcpy(local_str, "yes");
+ } else {
+ strcpy(local_str, "no");
+ }
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
- /* Neighbor destination address */
- neigh_dst_str = argv[2];
- result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
- if (result <= 0) {
- vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
- neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
- /* Neighbor source address */
- neigh_src_str = argv[3];
- result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
- if (result <= 0) {
- vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
- neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rp", rp_str);
+ json_object_string_add(json_row, "local", local_str);
+ json_object_string_add(json_row, "sptSetup", spt_str);
+ json_object_string_add(json_row, "upTime", timebuf);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty, "%-15s %15s %15s %5c %3c %8s%s",
+ src_str, grp_str, rp_str, local_str[0], spt_str[0], timebuf, VTY_NEWLINE);
+ }
}
- /* Multicast group address */
- group_str = argv[4];
- result = inet_pton(AF_INET, group_str, &group_addr);
- if (result <= 0) {
- vty_out(vty, "Bad group address %s: errno=%d: %s%s",
- group_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
- }
- /* Multicast source address */
- source_str = argv[5];
- result = inet_pton(AF_INET, source_str, &source_addr);
- if (result <= 0) {
- vty_out(vty, "Bad source address %s: errno=%d: %s%s",
- source_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
}
+}
- /*
- Tweak IP header
- */
- ip_hdr = (struct ip *) buf;
- ip_hdr->ip_p = PIM_IP_PROTO_PIM;
- ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
- ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
- ip_hdr->ip_src = neigh_src_addr;
- ip_hdr->ip_dst = qpim_all_pim_routers_addr;
+static void
+ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa, const char *src_str,
+ const char *grp_str, struct vty *vty,
+ u_char uj, json_object *json)
+{
+ char rp_str[INET_ADDRSTRLEN];
+ char peer_str[INET_ADDRSTRLEN];
+ char timebuf[PIM_MSDP_UPTIME_STRLEN];
+ char spt_str[8];
+ char local_str[8];
+ char statetimer[PIM_MSDP_TIMER_STRLEN];
+ int64_t now;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
- /*
- Build PIM message
- */
- pim_msg = buf + ip_hlen;
-
- /* skip room for pim header */
- pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
-
- remain = buf_pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
- remain,
- neigh_dst_addr);
- if (!pim_msg_curr) {
- vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
- neigh_dst_str, remain, VTY_NEWLINE);
- return CMD_WARNING;
+ now = pim_time_monotonic_sec();
+ pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
+ if (sa->flags & PIM_MSDP_SAF_PEER) {
+ pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
+ pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
+ if (sa->up) {
+ strcpy(spt_str, "yes");
+ } else {
+ strcpy(spt_str, "no");
+ }
+ } else {
+ strcpy(rp_str, "-");
+ strcpy(peer_str, "-");
+ strcpy(spt_str, "-");
}
-
- remain = buf_pastend - pim_msg_curr;
- if (remain < 4) {
- vty_out(vty, "Group will not fit: space left=%d%s",
- remain, VTY_NEWLINE);
- return CMD_WARNING;
+ if (sa->flags & PIM_MSDP_SAF_LOCAL) {
+ strcpy(local_str, "yes");
+ } else {
+ strcpy(local_str, "no");
}
+ pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer), sa->sa_state_timer);
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
- *pim_msg_curr = 0; /* reserved */
- ++pim_msg_curr;
- *pim_msg_curr = 1; /* number of groups */
- ++pim_msg_curr;
- *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- remain = buf_pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
- remain,
- group_addr);
- if (!pim_msg_curr) {
- vty_out(vty, "Failure encoding group address %s: space left=%d%s",
- group_str, remain, VTY_NEWLINE);
- return CMD_WARNING;
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rp", rp_str);
+ json_object_string_add(json_row, "local", local_str);
+ json_object_string_add(json_row, "sptSetup", spt_str);
+ json_object_string_add(json_row, "upTime", timebuf);
+ json_object_string_add(json_row, "stateTimer", statetimer);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty, "SA : %s%s", sa->sg_str, VTY_NEWLINE);
+ vty_out(vty, " RP : %s%s", rp_str, VTY_NEWLINE);
+ vty_out(vty, " Peer : %s%s", peer_str, VTY_NEWLINE);
+ vty_out(vty, " Local : %s%s", local_str, VTY_NEWLINE);
+ vty_out(vty, " SPT Setup : %s%s", spt_str, VTY_NEWLINE);
+ vty_out(vty, " Uptime : %s%s", timebuf, VTY_NEWLINE);
+ vty_out(vty, " State Timer : %s%s", statetimer, VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
}
+}
- remain = buf_pastend - pim_msg_curr;
- if (remain < 4) {
- vty_out(vty, "Sources will not fit: space left=%d%s",
- remain, VTY_NEWLINE);
- return CMD_WARNING;
+static void
+ip_msdp_show_sa_detail(struct vty *vty, u_char uj)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
}
- if (src_is_join) {
- num_joined = 1;
- num_pruned = 0;
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
+ ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
}
- else {
- num_joined = 0;
- num_pruned = 1;
- }
-
- /* number of joined sources */
- *((uint16_t *) pim_msg_curr) = htons(num_joined);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- /* number of pruned sources */
- *((uint16_t *) pim_msg_curr) = htons(num_pruned);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- remain = buf_pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
- remain,
- source_addr);
- if (!pim_msg_curr) {
- vty_out(vty, "Failure encoding source address %s: space left=%d%s",
- source_str, remain, VTY_NEWLINE);
- return CMD_WARNING;
+
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
}
+}
- /* Add PIM header */
+DEFUN (show_ip_msdp_sa_detail,
+ show_ip_msdp_sa_detail_cmd,
+ "show ip msdp sa detail [json]",
+ SHOW_STR
+ IP_STR
+ MSDP_STR
+ "MSDP active-source information\n"
+ "Detailed output\n"
+ "JavaScript Object Notation\n")
+{
+ u_char uj = use_json(argc, argv);
+ ip_msdp_show_sa_detail(vty, uj);
- pim_msg_size = pim_msg_curr - pim_msg;
+ return CMD_SUCCESS;
+}
- pim_msg_build_header(pim_msg, pim_msg_size,
- PIM_MSG_TYPE_JOIN_PRUNE);
+static void
+ip_msdp_show_sa_addr(struct vty *vty, const char *addr, u_char uj)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
- /*
- "Receive" message
- */
+ if (uj) {
+ json = json_object_new_object();
+ }
- ip_msg_len = ip_hlen + pim_msg_size;
- result = pim_pim_packet(ifp, buf, ip_msg_len);
- if (result) {
- vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
- ip_msg_len, result, VTY_NEWLINE);
- return CMD_WARNING;
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
+ if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
+ ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
+ }
}
- return CMD_SUCCESS;
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
}
-DEFUN (test_pim_receive_join,
- test_pim_receive_join_cmd,
- "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
- "Test\n"
- "Test PIM protocol\n"
- "Test PIM message reception\n"
- "Test PIM join reception from neighbor\n"
- "Interface\n"
- "Neighbor holdtime\n"
- "Upstream neighbor unicast destination address\n"
- "Downstream neighbor unicast source address\n"
- "Multicast group address\n"
- "Unicast source address\n")
-{
- return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
-}
-
-DEFUN (test_pim_receive_prune,
- test_pim_receive_prune_cmd,
- "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
- "Test\n"
- "Test PIM protocol\n"
- "Test PIM message reception\n"
- "Test PIM prune reception from neighbor\n"
- "Interface\n"
- "Neighbor holdtime\n"
- "Upstream neighbor unicast destination address\n"
- "Downstream neighbor unicast source address\n"
- "Multicast group address\n"
- "Unicast source address\n")
-{
- return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
-}
-
-DEFUN (test_pim_receive_upcall,
- test_pim_receive_upcall_cmd,
- "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
- "Test\n"
- "Test PIM protocol\n"
- "Test PIM message reception\n"
- "Test reception of kernel upcall\n"
- "NOCACHE kernel upcall\n"
- "WRONGVIF kernel upcall\n"
- "WHOLEPKT kernel upcall\n"
- "Input interface vif index\n"
- "Multicast group address\n"
- "Multicast source address\n")
+static void
+ip_msdp_show_sa_sg(struct vty *vty, const char *src, const char *grp, u_char uj)
{
- struct igmpmsg msg;
- const char *upcall_type;
- const char *group_str;
- const char *source_str;
- int result;
-
- upcall_type = argv[0];
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
- if (upcall_type[0] == 'n')
- msg.im_msgtype = IGMPMSG_NOCACHE;
- else if (upcall_type[1] == 'r')
- msg.im_msgtype = IGMPMSG_WRONGVIF;
- else if (upcall_type[1] == 'h')
- msg.im_msgtype = IGMPMSG_WHOLEPKT;
- else {
- vty_out(vty, "Unknown kernel upcall type: %s%s",
- upcall_type, VTY_NEWLINE);
- return CMD_WARNING;
+ if (uj) {
+ json = json_object_new_object();
}
- msg.im_vif = atoi(argv[1]);
-
- /* Group address */
- group_str = argv[2];
- result = inet_pton(AF_INET, group_str, &msg.im_dst);
- if (result <= 0) {
- vty_out(vty, "Bad group address %s: errno=%d: %s%s",
- group_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
+ if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
+ ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
+ }
}
- /* Source address */
- source_str = argv[3];
- result = inet_pton(AF_INET, source_str, &msg.im_src);
- if (result <= 0) {
- vty_out(vty, "Bad source address %s: errno=%d: %s%s",
- source_str, errno, safe_strerror(errno), VTY_NEWLINE);
- return CMD_WARNING;
+ if (uj) {
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
}
+}
- msg.im_mbz = 0; /* Must be zero */
-
- result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
- if (result) {
- vty_out(vty, "pim_mroute_msg(len=%zu) returned failure: %d%s",
- sizeof(msg), result, VTY_NEWLINE);
- return CMD_WARNING;
- }
+DEFUN (show_ip_msdp_sa_sg,
+ show_ip_msdp_sa_sg_cmd,
+ "show ip msdp sa [A.B.C.D] [A.B.C.D] [json]",
+ SHOW_STR
+ IP_STR
+ MSDP_STR
+ "MSDP active-source information\n"
+ "source or group ip\n"
+ "group ip\n"
+ "JavaScript Object Notation\n")
+{
+ u_char uj = use_json(argc, argv);
+ if (uj)
+ argc--;
+
+ if (argc == 5)
+ ip_msdp_show_sa_sg(vty, argv[4]->arg, argv[5]->arg, uj);
+ else if (argc == 4)
+ ip_msdp_show_sa_addr(vty, argv[4]->arg, uj);
+ else
+ ip_msdp_show_sa(vty, uj);
return CMD_SUCCESS;
}
@@ -4867,25 +5991,35 @@ void pim_cmd_init()
{
install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
+ if_cmd_init ();
+
+ install_node (&debug_node, pim_debug_config_write);
install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
install_element (CONFIG_NODE, &ip_pim_rp_cmd);
install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
+ install_element (CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
+ install_element (CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
+ install_element (CONFIG_NODE, &ip_pim_register_suppress_cmd);
+ install_element (CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
+ install_element (CONFIG_NODE, &ip_pim_joinprune_time_cmd);
+ install_element (CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
+ install_element (CONFIG_NODE, &ip_pim_keep_alive_cmd);
+ install_element (CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
+ install_element (CONFIG_NODE, &ip_pim_packets_cmd);
+ install_element (CONFIG_NODE, &no_ip_pim_packets_cmd);
install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
-#if 0
- install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
-#else
- install_element (CONFIG_NODE, &pim_interface_cmd);
-#endif
- install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
-
- install_default (INTERFACE_NODE);
+ install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
+ install_element (CONFIG_NODE, &no_ip_msdp_peer_cmd);
+
install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
+ install_element (INTERFACE_NODE, &interface_ip_igmp_version_cmd);
+ install_element (INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
@@ -4899,7 +6033,6 @@ void pim_cmd_init()
install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
- install_element (INTERFACE_NODE, &interface_ip_pim_hello_hold_cmd);
install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
// Static mroutes NEB
@@ -4910,29 +6043,25 @@ void pim_cmd_init()
install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
- install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
- install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
- install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
- install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
install_element (VIEW_NODE, &show_ip_pim_join_cmd);
- install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
- install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
+ install_element (VIEW_NODE, &show_ip_pim_state_cmd);
install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
+ install_element (VIEW_NODE, &show_ip_pim_rp_cmd);
install_element (VIEW_NODE, &show_ip_multicast_cmd);
install_element (VIEW_NODE, &show_ip_mroute_cmd);
install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
@@ -4940,99 +6069,95 @@ void pim_cmd_init()
install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
install_element (VIEW_NODE, &show_debugging_pim_cmd);
- install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
-
install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
- install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
- install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
- install_element (ENABLE_NODE, &test_pim_receive_dump_cmd);
- install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
- install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
- install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
- install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
-
install_element (ENABLE_NODE, &debug_igmp_cmd);
install_element (ENABLE_NODE, &no_debug_igmp_cmd);
- install_element (ENABLE_NODE, &undebug_igmp_cmd);
install_element (ENABLE_NODE, &debug_igmp_events_cmd);
install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
- install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
- install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
- install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
install_element (ENABLE_NODE, &debug_mroute_cmd);
+ install_element (ENABLE_NODE, &debug_mroute_detail_cmd);
install_element (ENABLE_NODE, &no_debug_mroute_cmd);
+ install_element (ENABLE_NODE, &no_debug_mroute_detail_cmd);
install_element (ENABLE_NODE, &debug_static_cmd);
install_element (ENABLE_NODE, &no_debug_static_cmd);
install_element (ENABLE_NODE, &debug_pim_cmd);
install_element (ENABLE_NODE, &no_debug_pim_cmd);
- install_element (ENABLE_NODE, &undebug_pim_cmd);
install_element (ENABLE_NODE, &debug_pim_events_cmd);
install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
- install_element (ENABLE_NODE, &undebug_pim_events_cmd);
install_element (ENABLE_NODE, &debug_pim_packets_cmd);
- install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
- install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
- install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
- install_element (ENABLE_NODE, &undebug_pim_packetdump_send_cmd);
install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
- install_element (ENABLE_NODE, &undebug_pim_packetdump_recv_cmd);
install_element (ENABLE_NODE, &debug_pim_trace_cmd);
install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
- install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
- install_element (ENABLE_NODE, &undebug_ssmpingd_cmd);
install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
- install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
+ install_element (ENABLE_NODE, &debug_msdp_cmd);
+ install_element (ENABLE_NODE, &no_debug_msdp_cmd);
+ install_element (ENABLE_NODE, &undebug_msdp_cmd);
+ install_element (ENABLE_NODE, &debug_msdp_events_cmd);
+ install_element (ENABLE_NODE, &no_debug_msdp_events_cmd);
+ install_element (ENABLE_NODE, &undebug_msdp_events_cmd);
+ install_element (ENABLE_NODE, &debug_msdp_packets_cmd);
+ install_element (ENABLE_NODE, &no_debug_msdp_packets_cmd);
+ install_element (ENABLE_NODE, &undebug_msdp_packets_cmd);
install_element (CONFIG_NODE, &debug_igmp_cmd);
install_element (CONFIG_NODE, &no_debug_igmp_cmd);
- install_element (CONFIG_NODE, &undebug_igmp_cmd);
install_element (CONFIG_NODE, &debug_igmp_events_cmd);
install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
- install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
- install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
- install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
install_element (CONFIG_NODE, &debug_mroute_cmd);
+ install_element (CONFIG_NODE, &debug_mroute_detail_cmd);
install_element (CONFIG_NODE, &no_debug_mroute_cmd);
+ install_element (CONFIG_NODE, &no_debug_mroute_detail_cmd);
install_element (CONFIG_NODE, &debug_static_cmd);
install_element (CONFIG_NODE, &no_debug_static_cmd);
install_element (CONFIG_NODE, &debug_pim_cmd);
install_element (CONFIG_NODE, &no_debug_pim_cmd);
- install_element (CONFIG_NODE, &undebug_pim_cmd);
install_element (CONFIG_NODE, &debug_pim_events_cmd);
install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
- install_element (CONFIG_NODE, &undebug_pim_events_cmd);
install_element (CONFIG_NODE, &debug_pim_packets_cmd);
- install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
- install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
- install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
install_element (CONFIG_NODE, &debug_pim_trace_cmd);
install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
- install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
- install_element (CONFIG_NODE, &undebug_ssmpingd_cmd);
install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
- install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);
+ install_element (CONFIG_NODE, &debug_msdp_cmd);
+ install_element (CONFIG_NODE, &no_debug_msdp_cmd);
+ install_element (CONFIG_NODE, &undebug_msdp_cmd);
+ install_element (CONFIG_NODE, &debug_msdp_events_cmd);
+ install_element (CONFIG_NODE, &no_debug_msdp_events_cmd);
+ install_element (CONFIG_NODE, &undebug_msdp_events_cmd);
+ install_element (CONFIG_NODE, &debug_msdp_packets_cmd);
+ install_element (CONFIG_NODE, &no_debug_msdp_packets_cmd);
+ install_element (CONFIG_NODE, &undebug_msdp_packets_cmd);
+ install_element (CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
+ install_element (CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
+ install_element (CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
+ install_element (CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
+ install_element (VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
+ install_element (VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
+ install_element (VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
+ install_element (VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
+ install_element (INTERFACE_NODE, &interface_pim_use_source_cmd);
+ install_element (INTERFACE_NODE, &interface_no_pim_use_source_cmd);
}
diff --git a/pimd/pim_cmd.h b/pimd/pim_cmd.h
index e6fbfa310c..e08cefb29b 100644
--- a/pimd/pim_cmd.h
+++ b/pimd/pim_cmd.h
@@ -47,6 +47,7 @@
#define DEBUG_PIM_PACKETS_STR "PIM protocol packets\n"
#define DEBUG_PIM_HELLO_PACKETS_STR "PIM Hello protocol packets\n"
#define DEBUG_PIM_J_P_PACKETS_STR "PIM Join/Prune protocol packets\n"
+#define DEBUG_PIM_PIM_REG_PACKETS_STR "PIM Register/Reg-Stop protocol packets\n"
#define DEBUG_PIM_PACKETDUMP_STR "PIM packet dump\n"
#define DEBUG_PIM_PACKETDUMP_SEND_STR "Dump sent packets\n"
#define DEBUG_PIM_PACKETDUMP_RECV_STR "Dump received packets\n"
@@ -57,12 +58,12 @@
#define CLEAR_IP_PIM_STR "PIM clear commands\n"
#define MROUTE_STR "IP multicast routing table\n"
#define RIB_STR "IP unicast routing table\n"
-
-#define PIM_CMD_NO "no"
-#define PIM_CMD_IP_MULTICAST_ROUTING "ip multicast-routing"
-#define PIM_CMD_IP_IGMP_QUERY_INTERVAL "ip igmp query-interval"
-#define PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME "ip igmp query-max-response-time"
-#define PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC "ip igmp query-max-response-time-dsec"
+#define CFG_MSDP_STR "Configure multicast source discovery protocol\n"
+#define MSDP_STR "MSDP information\n"
+#define DEBUG_MSDP_STR "MSDP protocol activity\n"
+#define DEBUG_MSDP_EVENTS_STR "MSDP protocol events\n"
+#define DEBUG_MSDP_INTERNAL_STR "MSDP protocol internal\n"
+#define DEBUG_MSDP_PACKETS_STR "MSDP protocol packets\n"
void pim_cmd_init(void);
diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c
index 1cd44f2539..3d7ae4ad22 100644
--- a/pimd/pim_hello.c
+++ b/pimd/pim_hello.c
@@ -37,7 +37,7 @@ static void on_trace(const char *label,
struct interface *ifp, struct in_addr src)
{
if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
zlog_debug("%s: from %s on %s",
label, src_str, ifp->name);
@@ -49,7 +49,7 @@ static void tlv_trace_bool(const char *label, const char *tlv_name,
int isset, int value)
{
if (isset) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello option from %s on interface %s: %s=%d",
label,
@@ -63,7 +63,7 @@ static void tlv_trace_uint16(const char *label, const char *tlv_name,
int isset, uint16_t value)
{
if (isset) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello option from %s on interface %s: %s=%u",
label,
@@ -77,7 +77,7 @@ static void tlv_trace_uint32(const char *label, const char *tlv_name,
int isset, uint32_t value)
{
if (isset) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello option from %s on interface %s: %s=%u",
label,
@@ -91,7 +91,7 @@ static void tlv_trace_uint32_hex(const char *label, const char *tlv_name,
int isset, uint32_t value)
{
if (isset) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello option from %s on interface %s: %s=%08x",
label,
@@ -106,7 +106,7 @@ static void tlv_trace(const char *label, const char *tlv_name,
int isset)
{
if (isset) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello option from %s on interface %s: %s",
label,
@@ -121,7 +121,7 @@ static void tlv_trace_list(const char *label, const char *tlv_name,
int isset, struct list *addr_list)
{
if (isset) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello option from %s on interface %s: %s size=%d list=%p",
label,
@@ -181,7 +181,7 @@ int pim_hello_recv(struct interface *ifp,
if (remain < PIM_TLV_MIN_SIZE) {
if (PIM_DEBUG_PIM_HELLO) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: short PIM hello TLV size=%d < min=%d from %s on interface %s",
__PRETTY_FUNCTION__,
@@ -198,7 +198,7 @@ int pim_hello_recv(struct interface *ifp,
if ((tlv_curr + option_len) > tlv_pastend) {
if (PIM_DEBUG_PIM_HELLO) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: long PIM hello TLV type=%d length=%d > left=%td from %s on interface %s",
__PRETTY_FUNCTION__,
@@ -209,7 +209,7 @@ int pim_hello_recv(struct interface *ifp,
}
if (PIM_DEBUG_PIM_HELLO) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: parse left_size=%d: PIM hello TLV type=%d length=%d from %s on %s",
__PRETTY_FUNCTION__,
@@ -267,7 +267,7 @@ int pim_hello_recv(struct interface *ifp,
break;
case PIM_MSG_OPTION_TYPE_DM_STATE_REFRESH:
if (PIM_DEBUG_PIM_HELLO) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: ignoring PIM hello dense-mode state refresh TLV option type=%d length=%d from %s on interface %s",
__PRETTY_FUNCTION__,
@@ -277,7 +277,7 @@ int pim_hello_recv(struct interface *ifp,
break;
default:
if (PIM_DEBUG_PIM_HELLO) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: ignoring unknown PIM hello TLV type=%d length=%d from %s on interface %s",
__PRETTY_FUNCTION__,
@@ -326,7 +326,7 @@ int pim_hello_recv(struct interface *ifp,
if (!PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME)) {
if (PIM_DEBUG_PIM_HELLO) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello missing holdtime from %s on interface %s",
__PRETTY_FUNCTION__,
@@ -349,10 +349,11 @@ int pim_hello_recv(struct interface *ifp,
hello_option_override_interval,
hello_option_dr_priority,
hello_option_generation_id,
- hello_option_addr_list);
+ hello_option_addr_list,
+ PIM_NEIGHBOR_SEND_DELAY);
if (!neigh) {
if (PIM_DEBUG_PIM_HELLO) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: failure creating PIM neighbor %s on interface %s",
__PRETTY_FUNCTION__,
@@ -373,15 +374,10 @@ int pim_hello_recv(struct interface *ifp,
/* GenID mismatch ? */
if (!PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID) ||
(hello_option_generation_id != neigh->generation_id)) {
-
- /* GenID changed */
-
- pim_upstream_rpf_genid_changed(neigh->source_addr);
-
/* GenID mismatch, then replace neighbor */
if (PIM_DEBUG_PIM_HELLO) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: GenId mismatch new=%08x old=%08x: replacing neighbor %s on %s",
__PRETTY_FUNCTION__,
@@ -400,10 +396,11 @@ int pim_hello_recv(struct interface *ifp,
hello_option_override_interval,
hello_option_dr_priority,
hello_option_generation_id,
- hello_option_addr_list);
+ hello_option_addr_list,
+ PIM_NEIGHBOR_SEND_NOW);
if (!neigh) {
if (PIM_DEBUG_PIM_HELLO) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: failure re-creating PIM neighbor %s on interface %s",
__PRETTY_FUNCTION__,
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index bac9692caa..7f64c9d5f2 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -25,6 +25,8 @@
#include "memory.h"
#include "prefix.h"
#include "vrf.h"
+#include "linklist.h"
+#include "plist.h"
#include "pimd.h"
#include "pim_iface.h"
@@ -38,14 +40,32 @@
#include "pim_sock.h"
#include "pim_time.h"
#include "pim_ssmpingd.h"
+#include "pim_rp.h"
struct interface *pim_regiface = NULL;
+struct list *pim_ifchannel_list = NULL;
+static int pim_iface_vif_index[MAXVIFS];
static void pim_if_igmp_join_del_all(struct interface *ifp);
-void pim_if_init()
+void
+pim_if_init (void)
{
+ int i;
+
+ for (i = 0; i < MAXVIFS; i++)
+ pim_iface_vif_index[i] = 0;
+
vrf_iflist_create(VRF_DEFAULT);
+ pim_ifchannel_list = list_new();
+ pim_ifchannel_list->cmp = (int (*)(void *, void *))pim_ifchannel_compare;
+}
+
+void
+pim_if_terminate (void)
+{
+ if (pim_ifchannel_list)
+ list_free (pim_ifchannel_list);
}
static void *if_list_clean(struct pim_interface *pim_ifp)
@@ -78,15 +98,16 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
zassert(ifp);
zassert(!ifp->info);
- pim_ifp = XMALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
+ pim_ifp = XCALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
if (!pim_ifp) {
- zlog_err("PIM XMALLOC(%zu) failure", sizeof(*pim_ifp));
+ zlog_err("PIM XCALLOC(%zu) failure", sizeof(*pim_ifp));
return 0;
}
pim_ifp->options = 0;
pim_ifp->mroute_vif_index = -1;
+ pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
pim_ifp->igmp_default_robustness_variable = IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
pim_ifp->igmp_default_query_interval = IGMP_GENERAL_QUERY_INTERVAL;
pim_ifp->igmp_query_max_response_time_dsec = IGMP_QUERY_MAX_RESPONSE_TIME_DSEC;
@@ -104,15 +125,12 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
if (igmp)
PIM_IF_DO_IGMP(pim_ifp->options);
-#if 0
- /* FIXME: Should join? */
PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options);
-#endif
- pim_ifp->igmp_join_list = 0;
- pim_ifp->igmp_socket_list = 0;
- pim_ifp->pim_neighbor_list = 0;
- pim_ifp->pim_ifchannel_list = 0;
+ pim_ifp->igmp_join_list = NULL;
+ pim_ifp->igmp_socket_list = NULL;
+ pim_ifp->pim_neighbor_list = NULL;
+ pim_ifp->pim_ifchannel_list = NULL;
pim_ifp->pim_generation_id = 0;
/* list of struct igmp_sock */
@@ -141,6 +159,7 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
return if_list_clean(pim_ifp);
}
pim_ifp->pim_ifchannel_list->del = (void (*)(void *)) pim_ifchannel_free;
+ pim_ifp->pim_ifchannel_list->cmp = (int (*)(void *, void *)) pim_ifchannel_compare;
ifp->info = pim_ifp;
@@ -164,16 +183,11 @@ void pim_if_delete(struct interface *ifp)
if (pim_ifp->igmp_join_list) {
pim_if_igmp_join_del_all(ifp);
}
- zassert(!pim_ifp->igmp_join_list);
-
- zassert(pim_ifp->igmp_socket_list);
- zassert(!listcount(pim_ifp->igmp_socket_list));
- zassert(pim_ifp->pim_neighbor_list);
- zassert(!listcount(pim_ifp->pim_neighbor_list));
+ pim_ifchannel_delete_all (ifp);
+ igmp_sock_delete_all (ifp);
- zassert(pim_ifp->pim_ifchannel_list);
- zassert(!listcount(pim_ifp->pim_ifchannel_list));
+ pim_neighbor_delete_all (ifp, "Interface removed from configuration");
if (PIM_MROUTE_IS_ENABLED) {
pim_if_del_vif(ifp);
@@ -185,7 +199,7 @@ void pim_if_delete(struct interface *ifp)
XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
- ifp->info = 0;
+ ifp->info = NULL;
}
void pim_if_update_could_assert(struct interface *ifp)
@@ -258,14 +272,10 @@ static int detect_primary_address_change(struct interface *ifp,
int force_prim_as_any,
const char *caller)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp = ifp->info;
struct in_addr new_prim_addr;
int changed;
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return 0;
-
if (force_prim_as_any)
new_prim_addr = qpim_inaddr_any;
else
@@ -274,8 +284,8 @@ static int detect_primary_address_change(struct interface *ifp,
changed = new_prim_addr.s_addr != pim_ifp->primary_address.s_addr;
if (PIM_DEBUG_ZEBRA) {
- char new_prim_str[100];
- char old_prim_str[100];
+ char new_prim_str[INET_ADDRSTRLEN];
+ char old_prim_str[INET_ADDRSTRLEN];
pim_inet4_dump("<new?>", new_prim_addr, new_prim_str, sizeof(new_prim_str));
pim_inet4_dump("<old?>", pim_ifp->primary_address, old_prim_str, sizeof(old_prim_str));
zlog_debug("%s: old=%s new=%s on interface %s: %s",
@@ -286,57 +296,230 @@ static int detect_primary_address_change(struct interface *ifp,
if (changed) {
pim_ifp->primary_address = new_prim_addr;
+ }
- if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
- return changed;
+ return changed;
+}
+
+static int pim_sec_addr_comp(const void *p1, const void *p2)
+{
+ const struct pim_secondary_addr *sec1 = p1;
+ const struct pim_secondary_addr *sec2 = p2;
+
+ if (ntohl(sec1->addr.s_addr) < ntohl(sec2->addr.s_addr))
+ return -1;
+
+ if (ntohl(sec1->addr.s_addr) > ntohl(sec2->addr.s_addr))
+ return 1;
+
+ return 0;
+}
+
+static void pim_sec_addr_free(struct pim_secondary_addr *sec_addr)
+{
+ XFREE(MTYPE_PIM_SEC_ADDR, sec_addr);
+}
+
+static struct pim_secondary_addr *
+pim_sec_addr_find(struct pim_interface *pim_ifp, struct in_addr addr)
+{
+ struct pim_secondary_addr *sec_addr;
+ struct listnode *node;
+
+ if (!pim_ifp->sec_addr_list) {
+ return NULL;
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
+ if (sec_addr->addr.s_addr == addr.s_addr) {
+ return sec_addr;
}
+ }
- pim_addr_change(ifp);
+ return NULL;
+}
+
+static void pim_sec_addr_del(struct pim_interface *pim_ifp,
+ struct pim_secondary_addr *sec_addr)
+{
+ listnode_delete(pim_ifp->sec_addr_list, sec_addr);
+ pim_sec_addr_free(sec_addr);
+}
+
+static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct in_addr addr)
+{
+ int changed = 0;
+ struct pim_secondary_addr *sec_addr;
+
+ sec_addr = pim_sec_addr_find(pim_ifp, addr);
+ if (sec_addr) {
+ sec_addr->flags &= ~PIM_SEC_ADDRF_STALE;
+ return changed;
+ }
+
+ if (!pim_ifp->sec_addr_list) {
+ pim_ifp->sec_addr_list = list_new();
+ pim_ifp->sec_addr_list->del = (void (*)(void *))pim_sec_addr_free;
+ pim_ifp->sec_addr_list->cmp = (int (*)(void *, void *))pim_sec_addr_comp;
}
+ sec_addr = XCALLOC(MTYPE_PIM_SEC_ADDR, sizeof(*sec_addr));
+ if (!sec_addr) {
+ if (list_isempty(pim_ifp->sec_addr_list)) {
+ list_free(pim_ifp->sec_addr_list);
+ pim_ifp->sec_addr_list = NULL;
+ }
+ return changed;
+ }
+
+ changed = 1;
+ sec_addr->addr = addr;
+ listnode_add_sort(pim_ifp->sec_addr_list, sec_addr);
+
return changed;
}
-static void detect_secondary_address_change(struct interface *ifp,
+static int pim_sec_addr_del_all(struct pim_interface *pim_ifp)
+{
+ int changed = 0;
+
+ if (!pim_ifp->sec_addr_list) {
+ return changed;
+ }
+ if (!list_isempty(pim_ifp->sec_addr_list)) {
+ changed = 1;
+ /* remove all nodes and free up the list itself */
+ list_delete_all_node(pim_ifp->sec_addr_list);
+ list_free(pim_ifp->sec_addr_list);
+ pim_ifp->sec_addr_list = NULL;
+ }
+
+ return changed;
+}
+
+static int pim_sec_addr_update(struct interface *ifp)
+{
+ struct pim_interface *pim_ifp = ifp->info;
+ struct connected *ifc;
+ struct listnode *node;
+ struct listnode *nextnode;
+ struct pim_secondary_addr *sec_addr;
+ int changed = 0;
+
+ if (pim_ifp->sec_addr_list) {
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
+ sec_addr->flags |= PIM_SEC_ADDRF_STALE;
+ }
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ struct prefix *p = ifc->address;
+
+ if (p->family != AF_INET) {
+ continue;
+ }
+
+ if (PIM_INADDR_IS_ANY(p->u.prefix4)) {
+ continue;
+ }
+
+ if (pim_ifp->primary_address.s_addr == p->u.prefix4.s_addr) {
+ /* don't add the primary address into the secondary address list */
+ continue;
+ }
+
+ if (pim_sec_addr_add(pim_ifp, p->u.prefix4)) {
+ changed = 1;
+ }
+ }
+
+ if (pim_ifp->sec_addr_list) {
+ /* Drop stale entries */
+ for (ALL_LIST_ELEMENTS(pim_ifp->sec_addr_list, node, nextnode, sec_addr)) {
+ if (sec_addr->flags & PIM_SEC_ADDRF_STALE) {
+ pim_sec_addr_del(pim_ifp, sec_addr);
+ changed = 1;
+ }
+ }
+
+ /* If the list went empty free it up */
+ if (list_isempty(pim_ifp->sec_addr_list)) {
+ list_free(pim_ifp->sec_addr_list);
+ pim_ifp->sec_addr_list = NULL;
+ }
+ }
+
+ return changed;
+}
+
+static int detect_secondary_address_change(struct interface *ifp,
+ int force_prim_as_any,
const char *caller)
{
+ struct pim_interface *pim_ifp = ifp->info;
+ int changed = 0;
+
+ if (force_prim_as_any) {
+ /* if primary address is being forced to zero just flush the
+ * secondary address list */
+ changed = pim_sec_addr_del_all(pim_ifp);
+ } else {
+ /* re-evaluate the secondary address list */
+ changed = pim_sec_addr_update(ifp);
+ }
+
+ return changed;
+}
+
+static void detect_address_change(struct interface *ifp,
+ int force_prim_as_any,
+ const char *caller)
+{
+ int changed = 0;
struct pim_interface *pim_ifp;
- int changed;
pim_ifp = ifp->info;
if (!pim_ifp)
return;
- changed = 1; /* true */
- if (PIM_DEBUG_ZEBRA)
- zlog_debug("FIXME T31 C15 %s: on interface %s: acting on any addr change",
- __PRETTY_FUNCTION__, ifp->name);
+ if (detect_primary_address_change(ifp, force_prim_as_any, caller)) {
+ changed = 1;
+ }
- if (!changed) {
- return;
+ if (detect_secondary_address_change(ifp, force_prim_as_any, caller)) {
+ changed = 1;
}
- if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
- return;
+
+ if (changed) {
+ if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
+ return;
+ }
+
+ pim_addr_change(ifp);
}
- pim_addr_change(ifp);
+ /* XXX: if we have unnumbered interfaces we need to run detect address
+ * address change on all of them when the lo address changes */
}
-static void detect_address_change(struct interface *ifp,
- int force_prim_as_any,
- const char *caller)
+int pim_update_source_set(struct interface *ifp, struct in_addr source)
{
- int prim_changed;
+ struct pim_interface *pim_ifp = ifp->info;
- prim_changed = detect_primary_address_change(ifp, force_prim_as_any, caller);
- if (prim_changed) {
- /* no need to detect secondary change because
- the reaction would be the same */
- return;
+ if (!pim_ifp) {
+ return PIM_IFACE_NOT_FOUND;
+ }
+
+ if (pim_ifp->update_source.s_addr == source.s_addr) {
+ return PIM_UPDATE_SOURCE_DUP;
}
- detect_secondary_address_change(ifp, caller);
+ pim_ifp->update_source = source;
+ detect_address_change(ifp, 0 /* force_prim_as_any */,
+ __PRETTY_FUNCTION__);
+
+ return PIM_SUCCESS;
}
void pim_if_addr_add(struct connected *ifc)
@@ -406,6 +589,7 @@ void pim_if_addr_add(struct connected *ifc)
if (pim_ifp->mroute_vif_index < 0) {
pim_if_add_vif(ifp);
}
+ pim_ifchannel_scan_forward_start (ifp);
}
}
@@ -496,19 +680,59 @@ void pim_if_addr_add_all(struct interface *ifp)
struct connected *ifc;
struct listnode *node;
struct listnode *nextnode;
+ int v4_addrs = 0;
+ int v6_addrs = 0;
+ struct pim_interface *pim_ifp = ifp->info;
+
/* PIM/IGMP enabled ? */
- if (!ifp->info)
+ if (!pim_ifp)
return;
for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
struct prefix *p = ifc->address;
if (p->family != AF_INET)
- continue;
+ {
+ v6_addrs++;
+ continue;
+ }
+ v4_addrs++;
pim_if_addr_add(ifc);
}
+
+ if (!v4_addrs && v6_addrs && !if_is_loopback (ifp))
+ {
+ if (PIM_IF_TEST_PIM(pim_ifp->options)) {
+
+ /* Interface has a valid primary address ? */
+ if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {
+
+ /* Interface has a valid socket ? */
+ if (pim_ifp->pim_sock_fd < 0) {
+ if (pim_sock_add(ifp)) {
+ zlog_warn("Failure creating PIM socket for interface %s",
+ ifp->name);
+ }
+ }
+
+ }
+ } /* pim */
+ }
+ if (PIM_MROUTE_IS_ENABLED) {
+ /*
+ * PIM or IGMP is enabled on interface, and there is at least one
+ * address assigned, then try to create a vif_index.
+ */
+ if (pim_ifp->mroute_vif_index < 0) {
+ pim_if_add_vif(ifp);
+ }
+ pim_ifchannel_scan_forward_start (ifp);
+ }
+
+ pim_rp_setup();
+ pim_rp_check_on_if_add(pim_ifp);
}
void pim_if_addr_del_all(struct interface *ifp)
@@ -529,6 +753,9 @@ void pim_if_addr_del_all(struct interface *ifp)
pim_if_addr_del(ifc, 1 /* force_prim_as_any=true */);
}
+
+ pim_rp_setup();
+ pim_i_am_rp_re_evaluate();
}
void pim_if_addr_del_all_igmp(struct interface *ifp)
@@ -571,17 +798,28 @@ void pim_if_addr_del_all_pim(struct interface *ifp)
}
}
-static struct in_addr find_first_nonsec_addr(struct interface *ifp)
+struct in_addr
+pim_find_primary_addr (struct interface *ifp)
{
struct connected *ifc;
struct listnode *node;
struct in_addr addr;
+ int v4_addrs = 0;
+ int v6_addrs = 0;
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (pim_ifp && PIM_INADDR_ISNOT_ANY(pim_ifp->update_source)) {
+ return pim_ifp->update_source;
+ }
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
struct prefix *p = ifc->address;
-
+
if (p->family != AF_INET)
- continue;
+ {
+ v6_addrs++;
+ continue;
+ }
if (PIM_INADDR_IS_ANY(p->u.prefix4)) {
zlog_warn("%s: null IPv4 address connected to interface %s",
@@ -589,27 +827,37 @@ static struct in_addr find_first_nonsec_addr(struct interface *ifp)
continue;
}
+ v4_addrs++;
+
if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
continue;
return p->u.prefix4;
}
+ /*
+ * If we have no v4_addrs and v6 is configured
+ * We probably are using unnumbered
+ * So let's grab the loopbacks v4 address
+ * and use that as the primary address
+ */
+ if (!v4_addrs && v6_addrs && !if_is_loopback (ifp))
+ {
+ struct interface *lo_ifp;
+ lo_ifp = if_lookup_by_name_vrf ("lo", VRF_DEFAULT);
+ if (lo_ifp)
+ return pim_find_primary_addr (lo_ifp);
+ }
+
addr.s_addr = PIM_NET_INADDR_ANY;
return addr;
}
-struct in_addr pim_find_primary_addr(struct interface *ifp)
-{
- return find_first_nonsec_addr(ifp);
-}
-
-static int pim_iface_vif_index = 0;
-
static int
pim_iface_next_vif_index (struct interface *ifp)
{
+ int i;
/*
* The pimreg vif is always going to be in index 0
* of the table.
@@ -617,8 +865,12 @@ pim_iface_next_vif_index (struct interface *ifp)
if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF)
return 0;
- pim_iface_vif_index++;
- return pim_iface_vif_index;
+ for (i = 1 ; i < MAXVIFS; i++)
+ {
+ if (pim_iface_vif_index[i] == 0)
+ return i;
+ }
+ return MAXVIFS;
}
/*
@@ -641,7 +893,7 @@ int pim_if_add_vif(struct interface *ifp)
return -1;
}
- if (ifp->ifindex < 1) {
+ if (ifp->ifindex < 0) {
zlog_warn("%s: ifindex=%d < 1 on interface %s",
__PRETTY_FUNCTION__,
ifp->ifindex, ifp->name);
@@ -678,41 +930,13 @@ int pim_if_add_vif(struct interface *ifp)
return -5;
}
- /*
- Update highest vif_index
- */
- if (pim_ifp->mroute_vif_index != PIM_OIF_PIM_REGISTER_VIF &&
- pim_ifp->mroute_vif_index > qpim_mroute_oif_highest_vif_index) {
- qpim_mroute_oif_highest_vif_index = pim_ifp->mroute_vif_index;
- }
-
+ pim_iface_vif_index[pim_ifp->mroute_vif_index] = 1;
return 0;
}
-static int iflist_find_highest_vif_index()
-{
- struct listnode *ifnode;
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- int highest_vif_index = -1;
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- pim_ifp = ifp->info;
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->mroute_vif_index > highest_vif_index) {
- highest_vif_index = pim_ifp->mroute_vif_index;
- }
- }
-
- return highest_vif_index;
-}
-
int pim_if_del_vif(struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
- int old_vif_index;
if (pim_ifp->mroute_vif_index < 1) {
zlog_warn("%s: vif_index=%d < 1 on interface %s ifindex=%d",
@@ -727,18 +951,12 @@ int pim_if_del_vif(struct interface *ifp)
}
/*
- Update highest vif_index
+ Update vif_index
*/
-
- /* save old vif_index in order to compare with highest below */
- old_vif_index = pim_ifp->mroute_vif_index;
+ pim_iface_vif_index[pim_ifp->mroute_vif_index] = 0;
pim_ifp->mroute_vif_index = -1;
- if (old_vif_index == qpim_mroute_oif_highest_vif_index) {
- qpim_mroute_oif_highest_vif_index = iflist_find_highest_vif_index();
- }
-
return 0;
}
@@ -800,9 +1018,9 @@ int pim_if_find_vifindex_by_ifindex(ifindex_t ifindex)
struct interface *ifp;
ifp = if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
- pim_ifp = ifp->info;
- if (!pim_ifp)
+ if (!ifp || !ifp->info)
return -1;
+ pim_ifp = ifp->info;
return pim_ifp->mroute_vif_index;
}
@@ -899,14 +1117,14 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
}
if (PIM_DEBUG_PIM_TRACE) {
- char addr_str[100];
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
zlog_debug("%s: neighbor not found for address %s on interface %s",
__PRETTY_FUNCTION__,
addr_str, ifp->name);
}
- return 0;
+ return NULL;
}
long pim_if_t_suppressed_msec(struct interface *ifp)
@@ -985,8 +1203,8 @@ static struct igmp_join *igmp_join_new(struct interface *ifp,
join_fd = igmp_join_sock(ifp->name, ifp->ifindex, group_addr, source_addr);
if (join_fd < 0) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
@@ -995,13 +1213,13 @@ static struct igmp_join *igmp_join_new(struct interface *ifp,
return 0;
}
- ij = XMALLOC(MTYPE_PIM_IGMP_JOIN, sizeof(*ij));
+ ij = XCALLOC(MTYPE_PIM_IGMP_JOIN, sizeof(*ij));
if (!ij) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_err("%s: XMALLOC(%zu) failure for IGMP group %s source %s on interface %s",
+ zlog_err("%s: XCALLOC(%zu) failure for IGMP group %s source %s on interface %s",
__PRETTY_FUNCTION__,
sizeof(*ij), group_str, source_str, ifp->name);
close(join_fd);
@@ -1045,8 +1263,8 @@ int pim_if_igmp_join_add(struct interface *ifp,
ij = igmp_join_find(pim_ifp->igmp_join_list, group_addr, source_addr);
if (ij) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: can't re-join existing IGMP group %s source %s on interface %s",
@@ -1057,8 +1275,8 @@ int pim_if_igmp_join_add(struct interface *ifp,
ij = igmp_join_new(ifp, group_addr, source_addr);
if (!ij) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: igmp_join_new() failure for IGMP group %s source %s on interface %s",
@@ -1068,8 +1286,8 @@ int pim_if_igmp_join_add(struct interface *ifp,
}
if (PIM_DEBUG_IGMP_EVENTS) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_debug("%s: issued static igmp join for channel (S,G)=(%s,%s) on interface %s",
@@ -1106,8 +1324,8 @@ int pim_if_igmp_join_del(struct interface *ifp,
ij = igmp_join_find(pim_ifp->igmp_join_list, group_addr, source_addr);
if (!ij) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: could not find IGMP group %s source %s on interface %s",
@@ -1117,14 +1335,13 @@ int pim_if_igmp_join_del(struct interface *ifp,
}
if (close(ij->sock_fd)) {
- int e = errno;
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: failure closing sock_fd=%d for IGMP group %s source %s on interface %s: errno=%d: %s",
__PRETTY_FUNCTION__,
- ij->sock_fd, group_str, source_str, ifp->name, e, safe_strerror(e));
+ ij->sock_fd, group_str, source_str, ifp->name, errno, safe_strerror(errno));
/* warning only */
}
listnode_delete(pim_ifp->igmp_join_list, ij);
@@ -1249,3 +1466,40 @@ void pim_if_create_pimreg (void)
pim_if_new(pim_regiface, 0, 0);
}
}
+
+int
+pim_if_connected_to_source (struct interface *ifp, struct in_addr src)
+{
+ struct listnode *cnode;
+ struct connected *c;
+ struct prefix p;
+
+ p.family = AF_INET;
+ p.u.prefix4 = src;
+ p.prefixlen = IPV4_MAX_BITLEN;
+
+ for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
+ {
+ if ((c->address->family == AF_INET) &&
+ prefix_match (CONNECTED_PREFIX (c), &p))
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+struct interface *
+pim_if_lookup_address_vrf (struct in_addr src, vrf_id_t vrf_id)
+{
+ struct listnode *ifnode;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist(vrf_id), ifnode, ifp))
+ {
+ if (pim_if_connected_to_source (ifp, src) && ifp->info)
+ return ifp;
+ }
+ return NULL;
+}
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index e56559ca46..244de598db 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -16,7 +16,7 @@
along with this program; see the file COPYING; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA
-*/
+ */
#ifndef PIM_IFACE_H
#define PIM_IFACE_H
@@ -58,12 +58,26 @@ enum pim_interface_type {
PIM_INTERFACE_SM
};
+enum pim_secondary_addr_flags {
+ PIM_SEC_ADDRF_NONE = 0,
+ PIM_SEC_ADDRF_STALE = (1 << 0)
+};
+
+struct pim_secondary_addr {
+ struct in_addr addr;
+ enum pim_secondary_addr_flags flags;
+};
+
struct pim_interface {
enum pim_interface_type itype;
uint32_t options; /* bit vector */
ifindex_t mroute_vif_index;
struct in_addr primary_address; /* remember addr to detect change */
+ struct list *sec_addr_list; /* list of struct pim_secondary_addr */
+ struct in_addr update_source; /* user can statically set the primary
+ * address of the interface */
+ int igmp_version; /* IGMP version */
int igmp_default_robustness_variable; /* IGMPv3 QRV */
int igmp_default_query_interval; /* IGMPv3 secs between general queries */
int igmp_query_max_response_time_dsec; /* IGMPv3 Max Response Time in dsecs for general queries */
@@ -106,6 +120,7 @@ struct pim_interface {
};
extern struct interface *pim_regiface;
+extern struct list *pim_ifchannel_list;
/*
if default_holdtime is set (>= 0), use it;
otherwise default_holdtime is 3.5 * hello_period
@@ -116,6 +131,7 @@ extern struct interface *pim_regiface;
((pim_ifp)->pim_default_holdtime))
void pim_if_init(void);
+void pim_if_terminate (void);
struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim);
void pim_if_delete(struct interface *ifp);
@@ -126,6 +142,8 @@ void pim_if_addr_del_all(struct interface *ifp);
void pim_if_addr_del_all_igmp(struct interface *ifp);
void pim_if_addr_del_all_pim(struct interface *ifp);
+struct interface *pim_if_lookup_address_vrf (struct in_addr src, vrf_id_t vrf_id);
+
int pim_if_add_vif(struct interface *ifp);
int pim_if_del_vif(struct interface *ifp);
void pim_if_add_vif_all(void);
@@ -166,4 +184,8 @@ void pim_if_update_join_desired(struct pim_interface *pim_ifp);
void pim_if_update_assert_tracking_desired(struct interface *ifp);
void pim_if_create_pimreg(void);
+
+int pim_if_connected_to_source (struct interface *ifp, struct in_addr src);
+int pim_update_source_set(struct interface *ifp, struct in_addr source);
+
#endif /* PIM_IFACE_H */
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 7afb7a5bdf..f0e4a3a68a 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -24,6 +24,7 @@
#include "thread.h"
#include "memory.h"
#include "if.h"
+#include "vrf.h"
#include "pimd.h"
#include "pim_str.h"
@@ -36,13 +37,100 @@
#include "pim_join.h"
#include "pim_rpf.h"
#include "pim_macro.h"
+#include "pim_oil.h"
+#include "pim_upstream.h"
-void pim_ifchannel_free(struct pim_ifchannel *ch)
+int
+pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2)
+{
+ struct pim_interface *pim_ifp1;
+ struct pim_interface *pim_ifp2;
+
+ if (ntohl(ch1->sg.grp.s_addr) < ntohl(ch2->sg.grp.s_addr))
+ return -1;
+
+ if (ntohl(ch1->sg.grp.s_addr) > ntohl(ch2->sg.grp.s_addr))
+ return 1;
+
+ if (ntohl(ch1->sg.src.s_addr) < ntohl(ch2->sg.src.s_addr))
+ return -1;
+
+ if (ntohl(ch1->sg.src.s_addr) > ntohl(ch2->sg.src.s_addr))
+ return 1;
+
+ pim_ifp1 = ch1->interface->info;
+ pim_ifp2 = ch2->interface->info;
+ if (ntohl(pim_ifp1->primary_address.s_addr) < ntohl(pim_ifp2->primary_address.s_addr))
+ return -1;
+
+ if (ntohl(pim_ifp1->primary_address.s_addr) > ntohl(pim_ifp2->primary_address.s_addr))
+ return 1;
+
+ if (pim_ifp1->mroute_vif_index < pim_ifp2->mroute_vif_index)
+ return -1;
+
+ if (pim_ifp1->mroute_vif_index > pim_ifp2->mroute_vif_index)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * A (*,G) or a (*,*) is going away
+ * remove the parent pointer from
+ * those pointing at us
+ */
+static void
+pim_ifchannel_remove_children (struct pim_ifchannel *ch)
{
- zassert(!ch->t_ifjoin_expiry_timer);
- zassert(!ch->t_ifjoin_prune_pending_timer);
- zassert(!ch->t_ifassert_timer);
+ struct pim_ifchannel *child;
+
+ if (!ch->sources)
+ return;
+
+ while (!list_isempty (ch->sources))
+ {
+ child = listnode_head (ch->sources);
+ child->parent = NULL;
+ listnode_delete (ch->sources, child);
+ }
+}
+
+/*
+ * A (*,G) or a (*,*) is being created
+ * find all the children that would point
+ * at us.
+ */
+static void
+pim_ifchannel_find_new_children (struct pim_ifchannel *ch)
+{
+ struct pim_interface *pim_ifp = ch->interface->info;
+ struct pim_ifchannel *child;
+ struct listnode *ch_node;
+
+ // Basic Sanity that we are not being silly
+ if ((ch->sg.src.s_addr != INADDR_ANY) &&
+ (ch->sg.grp.s_addr != INADDR_ANY))
+ return;
+
+ if ((ch->sg.src.s_addr == INADDR_ANY) &&
+ (ch->sg.grp.s_addr == INADDR_ANY))
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO (pim_ifp->pim_ifchannel_list, ch_node, child))
+ {
+ if ((ch->sg.grp.s_addr != INADDR_ANY) &&
+ (child->sg.grp.s_addr == ch->sg.grp.s_addr) &&
+ (child != ch))
+ {
+ child->parent = ch;
+ listnode_add_sort (ch->sources, child);
+ }
+ }
+}
+void pim_ifchannel_free(struct pim_ifchannel *ch)
+{
XFREE(MTYPE_PIM_IFCHANNEL, ch);
}
@@ -51,48 +139,91 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
struct pim_interface *pim_ifp;
pim_ifp = ch->interface->info;
- zassert(pim_ifp);
+
+ if (ch->upstream->channel_oil)
+ {
+ uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
+ if (ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+ mask = PIM_OIF_FLAG_PROTO_IGMP;
+
+ pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
+ /*
+ * Do we have any S,G's that are inheriting?
+ * Nuke from on high too.
+ */
+ if (ch->upstream->sources)
+ {
+ struct pim_upstream *child;
+ struct listnode *up_node;
+
+ for (ALL_LIST_ELEMENTS_RO (ch->upstream->sources, up_node, child))
+ pim_channel_del_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
+ }
+ }
+
+ /*
+ * When this channel is removed
+ * we need to find all our children
+ * and make sure our pointers are fixed
+ */
+ pim_ifchannel_remove_children (ch);
+
+ if (ch->sources)
+ list_delete (ch->sources);
if (ch->ifjoin_state != PIM_IFJOIN_NOINFO) {
pim_upstream_update_join_desired(ch->upstream);
}
- pim_upstream_del(ch->upstream);
+ pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__);
+ ch->upstream = NULL;
THREAD_OFF(ch->t_ifjoin_expiry_timer);
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
THREAD_OFF(ch->t_ifassert_timer);
+ if (ch->parent)
+ {
+ listnode_delete (ch->parent->sources, ch);
+ ch->parent = NULL;
+ }
/*
notice that listnode_delete() can't be moved
into pim_ifchannel_free() because the later is
called by list_delete_all_node()
*/
listnode_delete(pim_ifp->pim_ifchannel_list, ch);
+ listnode_delete(pim_ifchannel_list, ch);
pim_ifchannel_free(ch);
}
-#define IFCHANNEL_NOINFO(ch) \
- ( \
- ((ch)->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO) \
- && \
- ((ch)->ifjoin_state == PIM_IFJOIN_NOINFO) \
- && \
- ((ch)->ifassert_state == PIM_IFASSERT_NOINFO) \
- )
+void
+pim_ifchannel_delete_all (struct interface *ifp)
+{
+ struct pim_interface *pim_ifp;
+ struct listnode *ifchannel_node;
+ struct listnode *ifchannel_nextnode;
+ struct pim_ifchannel *ifchannel;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return;
+
+ for (ALL_LIST_ELEMENTS (pim_ifp->pim_ifchannel_list, ifchannel_node,
+ ifchannel_nextnode, ifchannel))
+ {
+ pim_ifchannel_delete (ifchannel);
+ }
+}
static void delete_on_noinfo(struct pim_ifchannel *ch)
{
- if (IFCHANNEL_NOINFO(ch)) {
-
- /* In NOINFO state, timers should have been cleared */
- zassert(!ch->t_ifjoin_expiry_timer);
- zassert(!ch->t_ifjoin_prune_pending_timer);
- zassert(!ch->t_ifassert_timer);
-
+ if (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO &&
+ ch->ifjoin_state == PIM_IFJOIN_NOINFO &&
+ ch->t_ifjoin_expiry_timer == NULL)
pim_ifchannel_delete(ch);
- }
+
}
void pim_ifchannel_ifjoin_switch(const char *caller,
@@ -101,6 +232,14 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
{
enum pim_ifjoin_state old_state = ch->ifjoin_state;
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug ("PIM_IFCHANNEL(%s): %s is switching from %s to %s",
+ ch->interface->name,
+ ch->sg_str,
+ pim_ifchannel_ifjoin_name (ch->ifjoin_state),
+ pim_ifchannel_ifjoin_name (new_state));
+
+
if (old_state == new_state) {
if (PIM_DEBUG_PIM_EVENTS) {
zlog_debug("%s calledby %s: non-transition on state %d (%s)",
@@ -110,25 +249,72 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
return;
}
- zassert(old_state != new_state);
-
ch->ifjoin_state = new_state;
+ if (ch->sg.src.s_addr == INADDR_ANY)
+ {
+ struct pim_upstream *up = ch->upstream;
+ struct pim_upstream *child;
+ struct listnode *up_node;
+
+ if (up)
+ {
+ if (ch->ifjoin_state == PIM_IFJOIN_NOINFO)
+ {
+ for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
+ {
+ struct channel_oil *c_oil = child->channel_oil;
+ struct pim_interface *pim_ifp = ch->interface->info;
+
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s %s: Prune(S,G)=%s from %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ child->sg_str, up->sg_str);
+ if (!c_oil)
+ continue;
+
+ if (!pim_upstream_evaluate_join_desired (child))
+ {
+ pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
+ pim_upstream_update_join_desired (child);
+ }
+
+ /*
+ * If the S,G has no if channel and the c_oil still
+ * has output here then the *,G was supplying the implied
+ * if channel. So remove it.
+ * I think this is dead code now. is it?
+ */
+ if (!ch && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
+ pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
+ }
+ }
+ if (ch->ifjoin_state == PIM_IFJOIN_JOIN)
+ {
+ for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
+ {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s %s: Join(S,G)=%s from %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ child->sg_str, up->sg_str);
+
+ if (pim_upstream_evaluate_join_desired (child))
+ {
+ pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
+ pim_upstream_update_join_desired (child);
+ }
+ }
+ }
+ }
+ }
/* Transition to/from NOINFO ? */
- if (
- (old_state == PIM_IFJOIN_NOINFO)
- ||
- (new_state == PIM_IFJOIN_NOINFO)
- ) {
+ if ((old_state == PIM_IFJOIN_NOINFO) ||
+ (new_state == PIM_IFJOIN_NOINFO)) {
if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("PIM_IFCHANNEL_%s: (S,G)=(%s,%s) on interface %s",
+ zlog_debug("PIM_IFCHANNEL_%s: (S,G)=%s on interface %s",
((new_state == PIM_IFJOIN_NOINFO) ? "DOWN" : "UP"),
- src_str, grp_str, ch->interface->name);
+ ch->sg_str, ch->interface->name);
}
/*
@@ -145,9 +331,12 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
const char *pim_ifchannel_ifjoin_name(enum pim_ifjoin_state ifjoin_state)
{
switch (ifjoin_state) {
- case PIM_IFJOIN_NOINFO: return "NOINFO";
- case PIM_IFJOIN_JOIN: return "JOIN";
- case PIM_IFJOIN_PRUNE_PENDING: return "PRUNEP";
+ case PIM_IFJOIN_NOINFO: return "NOINFO";
+ case PIM_IFJOIN_JOIN: return "JOIN";
+ case PIM_IFJOIN_PRUNE: return "PRUNE";
+ case PIM_IFJOIN_PRUNE_PENDING: return "PRUNEP";
+ case PIM_IFJOIN_PRUNE_TMP: return "PRUNET";
+ case PIM_IFJOIN_PRUNE_PENDING_TMP: return "PRUNEPT";
}
return "ifjoin_bad_state";
@@ -180,77 +369,8 @@ void reset_ifassert_state(struct pim_ifchannel *ch)
qpim_infinite_assert_metric);
}
-static struct pim_ifchannel *pim_ifchannel_new(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr)
-{
- struct pim_ifchannel *ch;
- struct pim_interface *pim_ifp;
- struct pim_upstream *up;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- up = pim_upstream_add(source_addr, group_addr, NULL);
- if (!up) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", group_addr, grp_str, sizeof(grp_str));
- zlog_err("%s: could not attach upstream (S,G)=(%s,%s) on interface %s",
- __PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
- return 0;
- }
-
- ch = XMALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch));
- if (!ch) {
- zlog_err("%s: PIM XMALLOC(%zu) failure",
- __PRETTY_FUNCTION__, sizeof(*ch));
- return 0;
- }
-
- ch->flags = 0;
- ch->upstream = up;
- ch->interface = ifp;
- ch->source_addr = source_addr;
- ch->group_addr = group_addr;
- ch->local_ifmembership = PIM_IFMEMBERSHIP_NOINFO;
-
- ch->ifjoin_state = PIM_IFJOIN_NOINFO;
- ch->t_ifjoin_expiry_timer = 0;
- ch->t_ifjoin_prune_pending_timer = 0;
- ch->ifjoin_creation = 0;
-
- ch->ifassert_my_metric = pim_macro_ch_my_assert_metric_eval(ch);
- ch->ifassert_winner_metric = pim_macro_ch_my_assert_metric_eval (ch);
-
- ch->ifassert_winner.s_addr = 0;
-
- /* Assert state */
- ch->t_ifassert_timer = 0;
- reset_ifassert_state(ch);
- if (pim_macro_ch_could_assert_eval(ch))
- PIM_IF_FLAG_SET_COULD_ASSERT(ch->flags);
- else
- PIM_IF_FLAG_UNSET_COULD_ASSERT(ch->flags);
-
- if (pim_macro_assert_tracking_desired_eval(ch))
- PIM_IF_FLAG_SET_ASSERT_TRACKING_DESIRED(ch->flags);
- else
- PIM_IF_FLAG_UNSET_ASSERT_TRACKING_DESIRED(ch->flags);
-
- /* Attach to list */
- listnode_add(pim_ifp->pim_ifchannel_list, ch);
-
- zassert(IFCHANNEL_NOINFO(ch));
-
- return ch;
-}
-
struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr)
+ struct prefix_sg *sg)
{
struct pim_interface *pim_ifp;
struct listnode *ch_node;
@@ -261,21 +381,17 @@ struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
pim_ifp = ifp->info;
if (!pim_ifp) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: (S,G)=(%s,%s): multicast not enabled on interface %s",
+ zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str,
+ pim_str_sg_dump (sg),
ifp->name);
return 0;
}
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
if (
- (source_addr.s_addr == ch->source_addr.s_addr) &&
- (group_addr.s_addr == ch->group_addr.s_addr)
+ (sg->src.s_addr == ch->sg.src.s_addr) &&
+ (sg->grp.s_addr == ch->sg.grp.s_addr)
) {
return ch;
}
@@ -291,13 +407,9 @@ static void ifmembership_set(struct pim_ifchannel *ch,
return;
if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s: (S,G)=(%s,%s) membership now is %s on interface %s",
+ zlog_debug("%s: (S,G)=%s membership now is %s on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str,
+ ch->sg_str,
membership == PIM_IFMEMBERSHIP_INCLUDE ? "INCLUDE" : "NOINFO",
ch->interface->name);
}
@@ -339,29 +451,111 @@ void pim_ifchannel_delete_on_noinfo(struct interface *ifp)
}
}
-struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr)
+/*
+ * For a given Interface, if we are given a S,G
+ * Find the *,G (If we have it).
+ * If we are passed a *,G, find the *,* ifchannel
+ * if we have it.
+ */
+static struct pim_ifchannel *
+pim_ifchannel_find_parent (struct pim_ifchannel *ch)
{
+ struct prefix_sg parent_sg = ch->sg;
+ struct pim_ifchannel *parent = NULL;
+
+ // (S,G)
+ if ((parent_sg.src.s_addr != INADDR_ANY) &&
+ (parent_sg.grp.s_addr != INADDR_ANY))
+ {
+ parent_sg.src.s_addr = INADDR_ANY;
+ parent = pim_ifchannel_find (ch->interface, &parent_sg);
+
+ if (parent)
+ listnode_add (parent->sources, ch);
+ return parent;
+ }
+
+ return NULL;
+}
+
+struct pim_ifchannel *
+pim_ifchannel_add(struct interface *ifp,
+ struct prefix_sg *sg, int flags)
+{
+ struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
- char src_str[100];
- char grp_str[100];
+ struct pim_upstream *up;
- ch = pim_ifchannel_find(ifp, source_addr, group_addr);
+ ch = pim_ifchannel_find(ifp, sg);
if (ch)
return ch;
- ch = pim_ifchannel_new(ifp, source_addr, group_addr);
- if (ch)
- return ch;
-
- pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: pim_ifchannel_new() failure for (S,G)=(%s,%s) on interface %s",
- __PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ pim_ifp = ifp->info;
- return 0;
+ up = pim_upstream_add(sg, NULL, flags, __PRETTY_FUNCTION__);
+ if (!up) {
+ zlog_err("%s: could not attach upstream (S,G)=%s on interface %s",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump (sg), ifp->name);
+ return NULL;
+ }
+
+ ch = XCALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch));
+ if (!ch) {
+ zlog_warn("%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s",
+ __PRETTY_FUNCTION__,
+ up->sg_str, ifp->name);
+
+ pim_upstream_del (up, __PRETTY_FUNCTION__);
+ return NULL;
+ }
+
+ ch->flags = 0;
+ ch->upstream = up;
+ ch->interface = ifp;
+ ch->sg = *sg;
+ pim_str_sg_set (sg, ch->sg_str);
+ ch->parent = pim_ifchannel_find_parent (ch);
+ if (ch->sg.src.s_addr == INADDR_ANY)
+ {
+ ch->sources = list_new ();
+ ch->sources->cmp = (int (*)(void *, void *))pim_ifchannel_compare;
+ }
+ else
+ ch->sources = NULL;
+
+ pim_ifchannel_find_new_children (ch);
+ ch->local_ifmembership = PIM_IFMEMBERSHIP_NOINFO;
+
+ ch->ifjoin_state = PIM_IFJOIN_NOINFO;
+ ch->t_ifjoin_expiry_timer = NULL;
+ ch->t_ifjoin_prune_pending_timer = NULL;
+ ch->ifjoin_creation = 0;
+
+ ch->ifassert_my_metric = pim_macro_ch_my_assert_metric_eval(ch);
+ ch->ifassert_winner_metric = pim_macro_ch_my_assert_metric_eval (ch);
+
+ ch->ifassert_winner.s_addr = 0;
+
+ /* Assert state */
+ ch->t_ifassert_timer = NULL;
+ ch->ifassert_state = PIM_IFASSERT_NOINFO;
+ reset_ifassert_state(ch);
+ if (pim_macro_ch_could_assert_eval(ch))
+ PIM_IF_FLAG_SET_COULD_ASSERT(ch->flags);
+ else
+ PIM_IF_FLAG_UNSET_COULD_ASSERT(ch->flags);
+
+ if (pim_macro_assert_tracking_desired_eval(ch))
+ PIM_IF_FLAG_SET_ASSERT_TRACKING_DESIRED(ch->flags);
+ else
+ PIM_IF_FLAG_UNSET_ASSERT_TRACKING_DESIRED(ch->flags);
+
+ /* Attach to list */
+ listnode_add_sort(pim_ifp->pim_ifchannel_list, ch);
+ listnode_add_sort(pim_ifchannel_list, ch);
+
+ return ch;
}
static void ifjoin_to_noinfo(struct pim_ifchannel *ch)
@@ -375,13 +569,9 @@ static int on_ifjoin_expiry_timer(struct thread *t)
{
struct pim_ifchannel *ch;
- zassert(t);
ch = THREAD_ARG(t);
- zassert(ch);
- ch->t_ifjoin_expiry_timer = 0;
-
- zassert(ch->ifjoin_state == PIM_IFJOIN_JOIN);
+ ch->t_ifjoin_expiry_timer = NULL;
ifjoin_to_noinfo(ch);
/* ch may have been deleted */
@@ -389,64 +579,37 @@ static int on_ifjoin_expiry_timer(struct thread *t)
return 0;
}
-static void prune_echo(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr)
-{
- struct pim_interface *pim_ifp;
- struct in_addr neigh_dst_addr;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- neigh_dst_addr = pim_ifp->primary_address;
-
- if (PIM_DEBUG_PIM_EVENTS) {
- char source_str[100];
- char group_str[100];
- char neigh_dst_str[100];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<neigh?>", neigh_dst_addr, neigh_dst_str, sizeof(neigh_dst_str));
- zlog_debug("%s: sending PruneEcho(S,G)=(%s,%s) to upstream=%s on interface %s",
- __PRETTY_FUNCTION__, source_str, group_str, neigh_dst_str, ifp->name);
- }
-
- pim_joinprune_send(ifp, neigh_dst_addr, source_addr, group_addr,
- 0 /* boolean: send_join=false (prune) */);
-}
-
static int on_ifjoin_prune_pending_timer(struct thread *t)
{
struct pim_ifchannel *ch;
int send_prune_echo; /* boolean */
struct interface *ifp;
struct pim_interface *pim_ifp;
- struct in_addr ch_source;
- struct in_addr ch_group;
- zassert(t);
ch = THREAD_ARG(t);
- zassert(ch);
-
- ch->t_ifjoin_prune_pending_timer = 0;
- zassert(ch->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING);
+ ch->t_ifjoin_prune_pending_timer = NULL;
- /* Send PruneEcho(S,G) ? */
- ifp = ch->interface;
- pim_ifp = ifp->info;
- send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
-
- /* Save (S,G) */
- ch_source = ch->source_addr;
- ch_group = ch->group_addr;
+ if (ch->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING)
+ {
+ /* Send PruneEcho(S,G) ? */
+ ifp = ch->interface;
+ pim_ifp = ifp->info;
+ send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
- ifjoin_to_noinfo(ch);
- /* from here ch may have been deleted */
+ ifjoin_to_noinfo(ch);
+ /* from here ch may have been deleted */
- if (send_prune_echo)
- prune_echo(ifp, ch_source, ch_group);
+ if (send_prune_echo)
+ pim_joinprune_send (ifp, pim_ifp->primary_address,
+ ch->upstream, 0);
+ }
+ else
+ {
+ zlog_warn("%s: IFCHANNEL%s Prune Pending Timer Popped while in %s state",
+ __PRETTY_FUNCTION__, pim_str_sg_dump (&ch->sg),
+ pim_ifchannel_ifjoin_name (ch->ifjoin_state));
+ }
return 0;
}
@@ -454,15 +617,14 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
static void check_recv_upstream(int is_join,
struct interface *recv_ifp,
struct in_addr upstream,
- struct in_addr source_addr,
- struct in_addr group_addr,
+ struct prefix_sg *sg,
uint8_t source_flags,
int holdtime)
{
struct pim_upstream *up;
/* Upstream (S,G) in Joined state ? */
- up = pim_upstream_find(source_addr, group_addr);
+ up = pim_upstream_find(sg);
if (!up)
return;
if (up->join_state != PIM_UPSTREAM_JOINED)
@@ -470,31 +632,23 @@ static void check_recv_upstream(int is_join,
/* Upstream (S,G) in Joined state */
- if (PIM_INADDR_IS_ANY(up->rpf.rpf_addr)) {
+ if (pim_rpf_addr_is_inaddr_any(&up->rpf)) {
/* RPF'(S,G) not found */
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s %s: RPF'(%s,%s) not found",
+ zlog_warn("%s %s: RPF'%s not found",
__FILE__, __PRETTY_FUNCTION__,
- src_str, grp_str);
+ up->sg_str);
return;
}
/* upstream directed to RPF'(S,G) ? */
- if (upstream.s_addr != up->rpf.rpf_addr.s_addr) {
- char src_str[100];
- char grp_str[100];
- char up_str[100];
- char rpf_str[100];
- pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", group_addr, grp_str, sizeof(grp_str));
+ if (upstream.s_addr != up->rpf.rpf_addr.u.prefix4.s_addr) {
+ char up_str[INET_ADDRSTRLEN];
+ char rpf_str[PREFIX_STRLEN];
pim_inet4_dump("<up?>", upstream, up_str, sizeof(up_str));
- pim_inet4_dump("<rpf?>", up->rpf.rpf_addr, rpf_str, sizeof(rpf_str));
- zlog_warn("%s %s: (S,G)=(%s,%s) upstream=%s not directed to RPF'(S,G)=%s on interface %s",
+ pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_str, sizeof(rpf_str));
+ zlog_warn("%s %s: (S,G)=%s upstream=%s not directed to RPF'(S,G)=%s on interface %s",
__FILE__, __PRETTY_FUNCTION__,
- src_str, grp_str,
+ up->sg_str,
up_str, rpf_str, recv_ifp->name);
return;
}
@@ -502,7 +656,7 @@ static void check_recv_upstream(int is_join,
if (is_join) {
/* Join(S,G) to RPF'(S,G) */
- pim_upstream_join_suppress(up, up->rpf.rpf_addr, holdtime);
+ pim_upstream_join_suppress(up, up->rpf.rpf_addr.u.prefix4, holdtime);
return;
}
@@ -512,26 +666,25 @@ static void check_recv_upstream(int is_join,
if (source_flags & PIM_WILDCARD_BIT_MASK) {
/* Prune(*,G) to RPF'(S,G) */
pim_upstream_join_timer_decrease_to_t_override("Prune(*,G)",
- up, up->rpf.rpf_addr);
+ up, up->rpf.rpf_addr.u.prefix4);
return;
}
/* Prune(S,G,rpt) to RPF'(S,G) */
pim_upstream_join_timer_decrease_to_t_override("Prune(S,G,rpt)",
- up, up->rpf.rpf_addr);
+ up, up->rpf.rpf_addr.u.prefix4);
return;
}
/* Prune(S,G) to RPF'(S,G) */
pim_upstream_join_timer_decrease_to_t_override("Prune(S,G)", up,
- up->rpf.rpf_addr);
+ up->rpf.rpf_addr.u.prefix4);
}
static int nonlocal_upstream(int is_join,
struct interface *recv_ifp,
struct in_addr upstream,
- struct in_addr source_addr,
- struct in_addr group_addr,
+ struct prefix_sg *sg,
uint8_t source_flags,
uint16_t holdtime)
{
@@ -543,17 +696,13 @@ static int nonlocal_upstream(int is_join,
is_local = (upstream.s_addr == recv_pim_ifp->primary_address.s_addr);
- if (PIM_DEBUG_PIM_TRACE) {
- char up_str[100];
- char src_str[100];
- char grp_str[100];
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ char up_str[INET_ADDRSTRLEN];
pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
- pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: recv %s (S,G)=(%s,%s) to %s upstream=%s on %s",
+ zlog_warn("%s: recv %s (S,G)=%s to %s upstream=%s on %s",
__PRETTY_FUNCTION__,
is_join ? "join" : "prune",
- src_str, grp_str,
+ pim_str_sg_dump (sg),
is_local ? "local" : "non-local",
up_str, recv_ifp->name);
}
@@ -565,7 +714,7 @@ static int nonlocal_upstream(int is_join,
Since recv upstream addr was not directed to our primary
address, check if we should react to it in any way.
*/
- check_recv_upstream(is_join, recv_ifp, upstream, source_addr, group_addr,
+ check_recv_upstream(is_join, recv_ifp, upstream, sg,
source_flags, holdtime);
return 1; /* non-local */
@@ -574,8 +723,7 @@ static int nonlocal_upstream(int is_join,
void pim_ifchannel_join_add(struct interface *ifp,
struct in_addr neigh_addr,
struct in_addr upstream,
- struct in_addr source_addr,
- struct in_addr group_addr,
+ struct prefix_sg *sg,
uint8_t source_flags,
uint16_t holdtime)
{
@@ -583,11 +731,11 @@ void pim_ifchannel_join_add(struct interface *ifp,
struct pim_ifchannel *ch;
if (nonlocal_upstream(1 /* join */, ifp, upstream,
- source_addr, group_addr, source_flags, holdtime)) {
+ sg, source_flags, holdtime)) {
return;
}
- ch = pim_ifchannel_add(ifp, source_addr, group_addr);
+ ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM);
if (!ch)
return;
@@ -608,15 +756,11 @@ void pim_ifchannel_join_add(struct interface *ifp,
address of the join message is our primary address.
*/
if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
- char src_str[100];
- char grp_str[100];
- char neigh_str[100];
- pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", group_addr, grp_str, sizeof(grp_str));
+ char neigh_str[INET_ADDRSTRLEN];
pim_inet4_dump("<neigh?>", neigh_addr, neigh_str, sizeof(neigh_str));
- zlog_warn("%s: Assert Loser recv Join(%s,%s) from %s on %s",
+ zlog_warn("%s: Assert Loser recv Join%s from %s on %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, neigh_str, ifp->name);
+ ch->sg_str, neigh_str, ifp->name);
assert_action_a5(ch);
}
@@ -628,6 +772,7 @@ void pim_ifchannel_join_add(struct interface *ifp,
case PIM_IFJOIN_NOINFO:
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
if (pim_macro_chisin_oiflist(ch)) {
+ pim_upstream_inherited_olist (ch->upstream);
pim_forward_start(ch);
}
break;
@@ -660,16 +805,26 @@ void pim_ifchannel_join_add(struct interface *ifp,
}
THREAD_OFF(ch->t_ifjoin_expiry_timer);
break;
+ case PIM_IFJOIN_PRUNE:
+ if (source_flags & PIM_ENCODE_RPT_BIT)
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
+ break;
case PIM_IFJOIN_PRUNE_PENDING:
- zassert(!ch->t_ifjoin_expiry_timer);
- zassert(ch->t_ifjoin_prune_pending_timer);
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
+ if (source_flags & PIM_ENCODE_RPT_BIT)
+ {
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
+ }
+ else
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
+ break;
+ case PIM_IFJOIN_PRUNE_TMP:
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING_TMP:
break;
}
- zassert(!IFCHANNEL_NOINFO(ch));
-
if (holdtime != 0xFFFF) {
THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
on_ifjoin_expiry_timer,
@@ -679,66 +834,113 @@ void pim_ifchannel_join_add(struct interface *ifp,
void pim_ifchannel_prune(struct interface *ifp,
struct in_addr upstream,
- struct in_addr source_addr,
- struct in_addr group_addr,
+ struct prefix_sg *sg,
uint8_t source_flags,
uint16_t holdtime)
{
struct pim_ifchannel *ch;
+ struct pim_interface *pim_ifp;
int jp_override_interval_msec;
if (nonlocal_upstream(0 /* prune */, ifp, upstream,
- source_addr, group_addr, source_flags, holdtime)) {
+ sg, source_flags, holdtime)) {
return;
}
- ch = pim_ifchannel_add(ifp, source_addr, group_addr);
+ ch = pim_ifchannel_find (ifp, sg);
+ if (!ch && !(source_flags & PIM_ENCODE_RPT_BIT))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: Received prune with no relevant ifchannel %s(%s) state: %d",
+ __PRETTY_FUNCTION__, ifp->name, pim_str_sg_dump (sg), source_flags);
+ return;
+ }
+
+ ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM);
if (!ch)
return;
+ pim_ifp = ifp->info;
+
switch (ch->ifjoin_state) {
case PIM_IFJOIN_NOINFO:
+ if (source_flags & PIM_ENCODE_RPT_BIT)
+ {
+ PIM_IF_FLAG_SET_S_G_RPT(ch->flags);
+ ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
+ if (listcount(pim_ifp->pim_neighbor_list) > 1)
+ jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
+ else
+ jp_override_interval_msec = 0; /* schedule to expire immediately */
+ /* If we called ifjoin_prune() directly instead, care should
+ be taken not to use "ch" afterwards since it would be
+ deleted. */
+
+ THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ THREAD_TIMER_MSEC_ON(master, ch->t_ifjoin_prune_pending_timer,
+ on_ifjoin_prune_pending_timer,
+ ch, jp_override_interval_msec);
+ THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
+ on_ifjoin_expiry_timer,
+ ch, holdtime);
+ }
+ break;
case PIM_IFJOIN_PRUNE_PENDING:
/* nothing to do */
break;
case PIM_IFJOIN_JOIN:
- {
- struct pim_interface *pim_ifp;
-
- pim_ifp = ifp->info;
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
- zassert(ch->t_ifjoin_expiry_timer);
- zassert(!ch->t_ifjoin_prune_pending_timer);
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_PRUNE_PENDING);
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
-
- pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_PRUNE_PENDING);
-
- if (listcount(pim_ifp->pim_neighbor_list) > 1) {
- jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
+ if (listcount(pim_ifp->pim_neighbor_list) > 1)
+ jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
+ else
+ jp_override_interval_msec = 0; /* schedule to expire immediately */
+ /* If we called ifjoin_prune() directly instead, care should
+ be taken not to use "ch" afterwards since it would be
+ deleted. */
+ THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ THREAD_TIMER_MSEC_ON(master, ch->t_ifjoin_prune_pending_timer,
+ on_ifjoin_prune_pending_timer,
+ ch, jp_override_interval_msec);
+ break;
+ case PIM_IFJOIN_PRUNE:
+ if (source_flags & PIM_ENCODE_RPT_BIT)
+ {
+ THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
+ on_ifjoin_expiry_timer,
+ ch, holdtime);
}
- else {
- jp_override_interval_msec = 0; /* schedule to expire immediately */
- /* If we called ifjoin_prune() directly instead, care should
- be taken not to use "ch" afterwards since it would be
- deleted. */
+ break;
+ case PIM_IFJOIN_PRUNE_TMP:
+ if (source_flags & PIM_ENCODE_RPT_BIT)
+ {
+ ch->ifjoin_state = PIM_IFJOIN_PRUNE;
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
+ on_ifjoin_expiry_timer,
+ ch, holdtime);
+ }
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING_TMP:
+ if (source_flags & PIM_ENCODE_RPT_BIT)
+ {
+ ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
+ on_ifjoin_expiry_timer,
+ ch, holdtime);
}
-
- THREAD_TIMER_MSEC_ON(master, ch->t_ifjoin_prune_pending_timer,
- on_ifjoin_prune_pending_timer,
- ch, jp_override_interval_msec);
-
- zassert(!ch->t_ifjoin_expiry_timer);
- zassert(ch->t_ifjoin_prune_pending_timer);
- }
break;
}
-
}
-void pim_ifchannel_local_membership_add(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr)
+int
+pim_ifchannel_local_membership_add(struct interface *ifp,
+ struct prefix_sg *sg)
{
struct pim_ifchannel *ch;
struct pim_interface *pim_ifp;
@@ -746,23 +948,43 @@ void pim_ifchannel_local_membership_add(struct interface *ifp,
/* PIM enabled on interface? */
pim_ifp = ifp->info;
if (!pim_ifp)
- return;
+ return 0;
if (!PIM_IF_TEST_PIM(pim_ifp->options))
- return;
+ return 0;
- ch = pim_ifchannel_add(ifp, source_addr, group_addr);
+ ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP);
if (!ch) {
- return;
+ return 0;
}
ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE);
- zassert(!IFCHANNEL_NOINFO(ch));
+ if (sg->src.s_addr == INADDR_ANY)
+ {
+ struct pim_upstream *up = pim_upstream_find (sg);
+ struct pim_upstream *child;
+ struct listnode *up_node;
+
+ for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
+ {
+ if (PIM_DEBUG_EVENTS)
+ zlog_debug("%s %s: IGMP (S,G)=%s(%s) from %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ child->sg_str, ifp->name, up->sg_str);
+
+ if (pim_upstream_evaluate_join_desired (child))
+ {
+ pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
+ pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
+ }
+ }
+ }
+
+ return 1;
}
void pim_ifchannel_local_membership_del(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr)
+ struct prefix_sg *sg)
{
struct pim_ifchannel *ch;
struct pim_interface *pim_ifp;
@@ -774,12 +996,41 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
if (!PIM_IF_TEST_PIM(pim_ifp->options))
return;
- ch = pim_ifchannel_find(ifp, source_addr, group_addr);
+ ch = pim_ifchannel_find(ifp, sg);
if (!ch)
return;
ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO);
+ if (sg->src.s_addr == INADDR_ANY)
+ {
+ struct pim_upstream *up = pim_upstream_find (sg);
+ struct pim_upstream *child;
+ struct listnode *up_node;
+
+ for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
+ {
+ struct channel_oil *c_oil = child->channel_oil;
+ struct pim_ifchannel *chchannel = pim_ifchannel_find (ifp, &child->sg);
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (PIM_DEBUG_EVENTS)
+ zlog_debug("%s %s: Prune(S,G)=%s(%s) from %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ up->sg_str, ifp->name, child->sg_str);
+
+ if (c_oil && !pim_upstream_evaluate_join_desired (child))
+ pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
+
+ /*
+ * If the S,G has no if channel and the c_oil still
+ * has output here then the *,G was supplying the implied
+ * if channel. So remove it.
+ */
+ if (!chchannel && c_oil && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
+ pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
+ }
+ }
delete_on_noinfo(ch);
}
@@ -792,10 +1043,10 @@ void pim_ifchannel_update_could_assert(struct pim_ifchannel *ch)
return;
if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ch->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", ch->sg.grp, grp_str, sizeof(grp_str));
zlog_debug("%s: CouldAssert(%s,%s,%s) changed from %d to %d",
__PRETTY_FUNCTION__,
src_str, grp_str, ch->interface->name,
@@ -834,12 +1085,12 @@ void pim_ifchannel_update_my_assert_metric(struct pim_ifchannel *ch)
return;
if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- char old_addr_str[100];
- char new_addr_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char old_addr_str[INET_ADDRSTRLEN];
+ char new_addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ch->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", ch->sg.grp, grp_str, sizeof(grp_str));
pim_inet4_dump("<old_addr?>", ch->ifassert_my_metric.ip_address, old_addr_str, sizeof(old_addr_str));
pim_inet4_dump("<new_addr?>", my_metric_new.ip_address, new_addr_str, sizeof(new_addr_str));
zlog_debug("%s: my_assert_metric(%s,%s,%s) changed from %u,%u,%u,%s to %u,%u,%u,%s",
@@ -872,10 +1123,10 @@ void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch)
return;
if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ch->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", ch->sg.grp, grp_str, sizeof(grp_str));
zlog_debug("%s: AssertTrackingDesired(%s,%s,%s) changed from %d to %d",
__PRETTY_FUNCTION__,
src_str, grp_str, ch->interface->name,
@@ -895,3 +1146,88 @@ void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch)
}
}
}
+
+/*
+ * If we have a new pim interface, check to
+ * see if any of the pre-existing channels have
+ * their upstream out that way and turn on forwarding
+ * for that ifchannel then.
+ */
+void
+pim_ifchannel_scan_forward_start (struct interface *new_ifp)
+{
+ struct listnode *ifnode;
+ struct interface *ifp;
+ struct pim_interface *new_pim_ifp = new_ifp->info;
+
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
+ {
+ struct pim_interface *loop_pim_ifp = ifp->info;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+
+ if (!loop_pim_ifp)
+ continue;
+
+ if (new_pim_ifp == loop_pim_ifp)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO (loop_pim_ifp->pim_ifchannel_list, ch_node, ch))
+ {
+ if (ch->ifjoin_state == PIM_IFJOIN_JOIN)
+ {
+ struct pim_upstream *up = ch->upstream;
+ if ((!up->channel_oil) &&
+ (up->rpf.source_nexthop.interface == new_ifp))
+ pim_forward_start (ch);
+ }
+ }
+ }
+}
+
+/*
+ * Downstream per-interface (S,G,rpt) state machine
+ * states that we need to move (S,G,rpt) items
+ * into different states at the start of the
+ * reception of a *,G join as well, when
+ * we get End of Message
+ */
+void
+pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom)
+{
+ struct pim_ifchannel *child;
+ struct listnode *ch_node;
+
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug ("%s: %s %s eom: %d", __PRETTY_FUNCTION__,
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state),
+ ch->sg_str, eom);
+ if (!ch->sources)
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO (ch->sources, ch_node, child))
+ {
+ if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
+ continue;
+
+ switch (child->ifjoin_state)
+ {
+ case PIM_IFJOIN_NOINFO:
+ case PIM_IFJOIN_JOIN:
+ break;
+ case PIM_IFJOIN_PRUNE:
+ if (!eom)
+ child->ifjoin_state = PIM_IFJOIN_PRUNE_TMP;
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING:
+ if (!eom)
+ child->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING_TMP;
+ break;
+ case PIM_IFJOIN_PRUNE_TMP:
+ case PIM_IFJOIN_PRUNE_PENDING_TMP:
+ if (eom)
+ child->ifjoin_state = PIM_IFJOIN_NOINFO;
+ break;
+ }
+ }
+}
diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h
index ce753222ee..a3dc0e9d83 100644
--- a/pimd/pim_ifchannel.h
+++ b/pimd/pim_ifchannel.h
@@ -24,6 +24,7 @@
#include <zebra.h>
#include "if.h"
+#include "prefix.h"
#include "pim_upstream.h"
@@ -35,7 +36,10 @@ enum pim_ifmembership {
enum pim_ifjoin_state {
PIM_IFJOIN_NOINFO,
PIM_IFJOIN_JOIN,
- PIM_IFJOIN_PRUNE_PENDING
+ PIM_IFJOIN_PRUNE,
+ PIM_IFJOIN_PRUNE_PENDING,
+ PIM_IFJOIN_PRUNE_TMP,
+ PIM_IFJOIN_PRUNE_PENDING_TMP,
};
enum pim_ifassert_state {
@@ -67,11 +71,21 @@ struct pim_assert_metric {
#define PIM_IF_FLAG_UNSET_ASSERT_TRACKING_DESIRED(flags) ((flags) &= ~PIM_IF_FLAG_MASK_ASSERT_TRACKING_DESIRED)
/*
+ * Flat to tell us if the ifchannel is (S,G,rpt)
+ */
+#define PIM_IF_FLAG_MASK_S_G_RPT (1 << 2)
+#define PIM_IF_FLAG_TEST_S_G_RPT(flags) ((flags) & PIM_IF_FLAG_MASK_S_G_RPT)
+#define PIM_IF_FLAG_SET_S_G_RPT(flags) ((flags) |= PIM_IF_FLAG_MASK_S_G_RPT)
+#define PIM_IF_FLAG_UNSET_S_G_RPT(flags) ((flags) &= ~PIM_IF_FLAG_MASK_S_G_RPT)
+
+/*
Per-interface (S,G) state
*/
struct pim_ifchannel {
- struct in_addr source_addr; /* (S,G) source key */
- struct in_addr group_addr; /* (S,G) group key */
+ struct pim_ifchannel *parent;
+ struct list *sources;
+ struct prefix_sg sg;
+ char sg_str[PIM_SG_LEN];
struct interface *interface; /* backpointer to interface */
uint32_t flags;
@@ -98,33 +112,28 @@ struct pim_ifchannel {
void pim_ifchannel_free(struct pim_ifchannel *ch);
void pim_ifchannel_delete(struct pim_ifchannel *ch);
+void pim_ifchannel_delete_all (struct interface *ifp);
void pim_ifchannel_membership_clear(struct interface *ifp);
void pim_ifchannel_delete_on_noinfo(struct interface *ifp);
struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr);
+ struct prefix_sg *sg);
struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr);
+ struct prefix_sg *sg, int flags);
void pim_ifchannel_join_add(struct interface *ifp,
struct in_addr neigh_addr,
struct in_addr upstream,
- struct in_addr source_addr,
- struct in_addr group_addr,
+ struct prefix_sg *sg,
uint8_t source_flags,
uint16_t holdtime);
void pim_ifchannel_prune(struct interface *ifp,
struct in_addr upstream,
- struct in_addr source_addr,
- struct in_addr group_addr,
+ struct prefix_sg *sg,
uint8_t source_flags,
uint16_t holdtime);
-void pim_ifchannel_local_membership_add(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr);
+int pim_ifchannel_local_membership_add(struct interface *ifp,
+ struct prefix_sg *sg);
void pim_ifchannel_local_membership_del(struct interface *ifp,
- struct in_addr source_addr,
- struct in_addr group_addr);
+ struct prefix_sg *sg);
void pim_ifchannel_ifjoin_switch(const char *caller,
struct pim_ifchannel *ch,
@@ -140,4 +149,8 @@ void pim_ifchannel_update_could_assert(struct pim_ifchannel *ch);
void pim_ifchannel_update_my_assert_metric(struct pim_ifchannel *ch);
void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch);
+void pim_ifchannel_scan_forward_start (struct interface *new_ifp);
+void pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom);
+
+int pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2);
#endif /* PIM_IFCHANNEL_H */
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index ef1b3cbac0..24b9e54ea5 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -26,6 +26,7 @@
#include "pimd.h"
#include "pim_igmp.h"
+#include "pim_igmpv2.h"
#include "pim_igmpv3.h"
#include "pim_iface.h"
#include "pim_sock.h"
@@ -35,34 +36,31 @@
#include "pim_time.h"
#include "pim_zebra.h"
-#define IGMP_GRP_REC_TYPE_MODE_IS_INCLUDE (1)
-#define IGMP_GRP_REC_TYPE_MODE_IS_EXCLUDE (2)
-#define IGMP_GRP_REC_TYPE_CHANGE_TO_INCLUDE_MODE (3)
-#define IGMP_GRP_REC_TYPE_CHANGE_TO_EXCLUDE_MODE (4)
-#define IGMP_GRP_REC_TYPE_ALLOW_NEW_SOURCES (5)
-#define IGMP_GRP_REC_TYPE_BLOCK_OLD_SOURCES (6)
-
static void group_timer_off(struct igmp_group *group);
-static int igmp_sock_open(struct in_addr ifaddr, ifindex_t ifindex, uint32_t pim_options)
+/* This socket is used for TXing IGMP packets only, IGMP RX happens
+ * in pim_mroute_msg()
+ */
+static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp, uint32_t pim_options)
{
int fd;
int join = 0;
struct in_addr group;
- fd = pim_socket_mcast(IPPROTO_IGMP, ifaddr, ifindex, 1 /* loop=true */);
+ fd = pim_socket_mcast(IPPROTO_IGMP, ifaddr, ifp, 1);
+
if (fd < 0)
return -1;
if (PIM_IF_TEST_IGMP_LISTEN_ALLROUTERS(pim_options)) {
if (inet_aton(PIM_ALL_ROUTERS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifindex))
- ++join;
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex))
+ ++join;
}
else {
zlog_warn("%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
- PIM_ALL_ROUTERS, errno, safe_strerror(errno));
+ __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
+ PIM_ALL_ROUTERS, errno, safe_strerror(errno));
}
}
@@ -71,29 +69,29 @@ static int igmp_sock_open(struct in_addr ifaddr, ifindex_t ifindex, uint32_t pim
IGMP routers must receive general queries for querier election.
*/
if (inet_aton(PIM_ALL_SYSTEMS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifindex))
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex))
++join;
}
else {
zlog_warn("%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
- PIM_ALL_SYSTEMS, errno, safe_strerror(errno));
+ __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
+ PIM_ALL_SYSTEMS, errno, safe_strerror(errno));
}
if (inet_aton(PIM_ALL_IGMP_ROUTERS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifindex)) {
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex)) {
++join;
}
}
else {
zlog_warn("%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
- PIM_ALL_IGMP_ROUTERS, errno, safe_strerror(errno));
+ __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
+ PIM_ALL_IGMP_ROUTERS, errno, safe_strerror(errno));
}
if (!join) {
zlog_err("IGMP socket fd=%d could not join any group on interface address %s",
- fd, inet_ntoa(ifaddr));
+ fd, inet_ntoa(ifaddr));
close(fd);
fd = -1;
}
@@ -154,22 +152,20 @@ static int pim_igmp_other_querier_expire(struct thread *t)
{
struct igmp_sock *igmp;
- zassert(t);
igmp = THREAD_ARG(t);
- zassert(igmp);
zassert(igmp->t_other_querier_timer);
zassert(!igmp->t_igmp_query_timer);
if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
zlog_debug("%s: Querier %s resuming",
__PRETTY_FUNCTION__,
ifaddr_str);
}
- igmp->t_other_querier_timer = 0;
+ igmp->t_other_querier_timer = NULL;
/*
We are the current querier, then
@@ -198,7 +194,7 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
*/
if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
zlog_debug("Querier %s resetting TIMER event for Other-Querier-Present",
ifaddr_str);
@@ -210,7 +206,7 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
else {
/*
We are the current querier, then stop sending general queries:
- igmp->t_igmp_query_timer = 0;
+ igmp->t_igmp_query_timer = NULL;
*/
pim_igmp_general_query_off(igmp);
}
@@ -241,7 +237,7 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
pim_ifp->igmp_query_max_response_time_dsec);
if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
zlog_debug("Querier %s scheduling %ld.%03ld sec TIMER event for Other-Querier-Present",
ifaddr_str,
@@ -260,7 +256,7 @@ void pim_igmp_other_querier_timer_off(struct igmp_sock *igmp)
if (PIM_DEBUG_IGMP_TRACE) {
if (igmp->t_other_querier_timer) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
zlog_debug("IGMP querier %s fd=%d cancelling other-querier-present TIMER event on %s",
ifaddr_str, igmp->fd, igmp->interface->name);
@@ -270,31 +266,27 @@ void pim_igmp_other_querier_timer_off(struct igmp_sock *igmp)
zassert(!igmp->t_other_querier_timer);
}
-static int recv_igmp_query(struct igmp_sock *igmp, int query_version,
- int max_resp_code,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
+static int
+igmp_recv_query(struct igmp_sock *igmp, int query_version,
+ int max_resp_code,
+ struct in_addr from, const char *from_str,
+ char *igmp_msg, int igmp_msg_len)
{
struct interface *ifp;
struct pim_interface *pim_ifp;
- uint8_t resv_s_qrv = 0;
- uint8_t s_flag = 0;
- uint8_t qrv = 0;
struct in_addr group_addr;
uint16_t recv_checksum;
uint16_t checksum;
- int i;
- //group_addr = *(struct in_addr *)(igmp_msg + 4);
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
ifp = igmp->interface;
pim_ifp = ifp->info;
- recv_checksum = *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET);
+ recv_checksum = *(uint16_t *) (igmp_msg + IGMP_CHECKSUM_OFFSET);
/* for computing checksum */
- *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0;
+ *(uint16_t *) (igmp_msg + IGMP_CHECKSUM_OFFSET) = 0;
checksum = in_cksum(igmp_msg, igmp_msg_len);
if (checksum != recv_checksum) {
@@ -303,12 +295,33 @@ static int recv_igmp_query(struct igmp_sock *igmp, int query_version,
return -1;
}
+ /* RFC 3376 defines some guidelines on operating in backwards compatibility
+ * with older versions of IGMP but there are some gaps in the logic:
+ *
+ * - once we drop from say version 3 to version 2 we will never go back to
+ * version 3 even if the node that TXed an IGMP v2 query upgrades to v3
+ *
+ * - The node with the lowest IP is the querier so we will only know to drop
+ * from v3 to v2 if the node that is the querier is also the one that is
+ * running igmp v2. If a non-querier only supports igmp v2 we will have
+ * no way of knowing.
+ *
+ * For now we will simplify things and inform the user that they need to
+ * configure all PIM routers to use the same version of IGMP.
+ */
+ if (query_version != pim_ifp->igmp_version) {
+ zlog_warn("Recv IGMP query v%d from %s on %s but we are using v%d, please "
+ "configure all PIM routers on this subnet to use the same "
+ "IGMP version",
+ query_version, from_str, ifp->name, pim_ifp->igmp_version);
+ return 0;
+ }
+
if (PIM_DEBUG_IGMP_PACKETS) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- zlog_debug("Recv IGMP query v%d from %s on %s: size=%d checksum=%x group=%s",
- query_version, from_str, ifp->name,
- igmp_msg_len, checksum, group_str);
+ zlog_debug("Recv IGMP query v%d from %s on %s for group %s",
+ query_version, from_str, ifp->name, group_str);
}
/*
@@ -320,9 +333,9 @@ static int recv_igmp_query(struct igmp_sock *igmp, int query_version,
elected querier.
*/
if (ntohl(from.s_addr) < ntohl(igmp->ifaddr.s_addr)) {
-
+
if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
zlog_debug("%s: local address %s (%u) lost querier election to %s (%u)",
ifp->name,
@@ -333,272 +346,11 @@ static int recv_igmp_query(struct igmp_sock *igmp, int query_version,
pim_igmp_other_querier_timer_on(igmp);
}
+ /* IGMP version 3 is the only one where we process the RXed query */
if (query_version == 3) {
- /*
- RFC 3376: 4.1.6. QRV (Querier's Robustness Variable)
-
- Routers adopt the QRV value from the most recently received Query
- as their own [Robustness Variable] value, unless that most
- recently received QRV was zero, in which case the receivers use
- the default [Robustness Variable] value specified in section 8.1
- or a statically configured value.
- */
- resv_s_qrv = igmp_msg[8];
- qrv = 7 & resv_s_qrv;
- igmp->querier_robustness_variable = qrv ? qrv : pim_ifp->igmp_default_robustness_variable;
+ igmp_v3_recv_query(igmp, from_str, igmp_msg);
}
- /*
- RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
-
- Multicast routers that are not the current querier adopt the QQI
- value from the most recently received Query as their own [Query
- Interval] value, unless that most recently received QQI was zero,
- in which case the receiving routers use the default.
- */
- if (igmp->t_other_querier_timer && query_version == 3) {
- /* other querier present */
- uint8_t qqic;
- uint16_t qqi;
- qqic = igmp_msg[9];
- qqi = igmp_msg_decode8to16(qqic);
- igmp->querier_query_interval = qqi ? qqi : pim_ifp->igmp_default_query_interval;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[100];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("Querier %s new query interval is %s QQI=%u sec (recv QQIC=%02x from %s)",
- ifaddr_str,
- qqi ? "recv-non-default" : "default",
- igmp->querier_query_interval,
- qqic,
- from_str);
- }
- }
-
- /*
- RFC 3376: 6.6.1. Timer Updates
-
- When a router sends or receives a query with a clear Suppress
- Router-Side Processing flag, it must update its timers to reflect
- the correct timeout values for the group or sources being queried.
-
- General queries don't trigger timer update.
- */
- if (query_version == 3) {
- s_flag = (1 << 3) & resv_s_qrv;
- }
- else {
- /* Neither V1 nor V2 have this field. Pimd should really go into
- * a compatibility mode here and run as V2 (or V1) but it doesn't
- * so for now, lets just set the flag to suppress these timer updates.
- */
- s_flag = 1;
- }
-
- if (!s_flag) {
- /* s_flag is clear */
-
- if (PIM_INADDR_IS_ANY(group_addr)) {
- /* this is a general query */
-
- /* log that general query should have the s_flag set */
- zlog_warn("General IGMP query v%d from %s on %s: Suppress Router-Side Processing flag is clear",
- query_version, from_str, ifp->name);
- }
- else {
- struct igmp_group *group;
-
- /* this is a non-general query: perform timer updates */
-
- group = find_group_by_addr(igmp, group_addr);
- if (group) {
- int recv_num_sources = ntohs(*(uint16_t *)(igmp_msg + IGMP_V3_NUMSOURCES_OFFSET));
-
- /*
- RFC 3376: 6.6.1. Timer Updates
- Query Q(G,A): Source Timer for sources in A are lowered to LMQT
- Query Q(G): Group Timer is lowered to LMQT
- */
- if (recv_num_sources < 1) {
- /* Query Q(G): Group Timer is lowered to LMQT */
-
- igmp_group_timer_lower_to_lmqt(group);
- }
- else {
- /* Query Q(G,A): Source Timer for sources in A are lowered to LMQT */
-
- /* Scan sources in query and lower their timers to LMQT */
- struct in_addr *sources = (struct in_addr *)(igmp_msg + IGMP_V3_SOURCES_OFFSET);
- for (i = 0; i < recv_num_sources; ++i) {
- //struct in_addr src_addr = sources[i];
- //struct igmp_source *src = igmp_find_source_by_addr(group, src_addr);
- struct in_addr src_addr;
- struct igmp_source *src;
- memcpy(&src_addr, sources + i, sizeof(struct in_addr));
- src = igmp_find_source_by_addr(group, src_addr);
- if (src) {
- igmp_source_timer_lower_to_lmqt(src);
- }
- }
- }
-
- }
- else {
- char group_str[100];
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- zlog_warn("IGMP query v%d from %s on %s: could not find group %s for timer update",
- query_version, from_str, ifp->name, group_str);
- }
- }
- } /* s_flag is clear: timer updates */
-
- return 0;
-}
-
-static int igmp_v3_report(struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
-{
- uint16_t recv_checksum;
- uint16_t checksum;
- int num_groups;
- uint8_t *group_record;
- uint8_t *report_pastend = (uint8_t *) igmp_msg + igmp_msg_len;
- struct interface *ifp = igmp->interface;
- int i;
- int local_ncb = 0;
-
- if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {
- zlog_warn("Recv IGMP report v3 from %s on %s: size=%d shorter than minimum=%d",
- from_str, ifp->name, igmp_msg_len, IGMP_V3_MSG_MIN_SIZE);
- return -1;
- }
-
- recv_checksum = *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET);
-
- /* for computing checksum */
- *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0;
-
- checksum = in_cksum(igmp_msg, igmp_msg_len);
- if (checksum != recv_checksum) {
- zlog_warn("Recv IGMP report v3 from %s on %s: checksum mismatch: received=%x computed=%x",
- from_str, ifp->name, recv_checksum, checksum);
- return -1;
- }
-
- num_groups = ntohs(*(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET));
- if (num_groups < 1) {
- zlog_warn("Recv IGMP report v3 from %s on %s: missing group records",
- from_str, ifp->name);
- return -1;
- }
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- zlog_debug("Recv IGMP report v3 from %s on %s: size=%d checksum=%x groups=%d",
- from_str, ifp->name, igmp_msg_len, checksum, num_groups);
- }
-
- group_record = (uint8_t *) igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
-
- /* Scan groups */
- for (i = 0; i < num_groups; ++i) {
- struct in_addr rec_group;
- uint8_t *sources;
- uint8_t *src;
- int rec_type;
- int rec_auxdatalen;
- int rec_num_sources;
- int j;
- struct prefix lncb;
- struct prefix g;
-
- if ((group_record + IGMP_V3_GROUP_RECORD_MIN_SIZE) > report_pastend) {
- zlog_warn("Recv IGMP report v3 from %s on %s: group record beyond report end",
- from_str, ifp->name);
- return -1;
- }
-
- rec_type = group_record[IGMP_V3_GROUP_RECORD_TYPE_OFFSET];
- rec_auxdatalen = group_record[IGMP_V3_GROUP_RECORD_AUXDATALEN_OFFSET];
- rec_num_sources = ntohs(* (uint16_t *) (group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET));
-
- //rec_group = *(struct in_addr *)(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET);
- memcpy(&rec_group, group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, sizeof(struct in_addr));
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- zlog_debug("Recv IGMP report v3 from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%s",
- from_str, ifp->name, i, rec_type, rec_auxdatalen, rec_num_sources, inet_ntoa(rec_group));
- }
-
- /* Scan sources */
-
- sources = group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET;
-
- for (j = 0, src = sources; j < rec_num_sources; ++j, src += 4) {
-
- if ((src + 4) > report_pastend) {
- zlog_warn("Recv IGMP report v3 from %s on %s: group source beyond report end",
- from_str, ifp->name);
- return -1;
- }
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- char src_str[200];
-
- if (!inet_ntop(AF_INET, src, src_str , sizeof(src_str)))
- sprintf(src_str, "<source?>");
-
- zlog_debug("Recv IGMP report v3 from %s on %s: record=%d group=%s source=%s",
- from_str, ifp->name, i, inet_ntoa(rec_group), src_str);
- }
- } /* for (sources) */
-
-
- lncb.family = AF_INET;
- lncb.u.prefix4.s_addr = 0x000000E0;
- lncb.prefixlen = 24;
-
- g.family = AF_INET;
- g.u.prefix4 = rec_group;
- g.prefixlen = 32;
- /*
- * If we receive a igmp report with the group in 224.0.0.0/24
- * then we should ignore it
- */
- if (prefix_match(&lncb, &g))
- local_ncb = 1;
-
- if (!local_ncb)
- switch (rec_type) {
- case IGMP_GRP_REC_TYPE_MODE_IS_INCLUDE:
- igmpv3_report_isin(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- case IGMP_GRP_REC_TYPE_MODE_IS_EXCLUDE:
- igmpv3_report_isex(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- case IGMP_GRP_REC_TYPE_CHANGE_TO_INCLUDE_MODE:
- igmpv3_report_toin(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- case IGMP_GRP_REC_TYPE_CHANGE_TO_EXCLUDE_MODE:
- igmpv3_report_toex(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- case IGMP_GRP_REC_TYPE_ALLOW_NEW_SOURCES:
- igmpv3_report_allow(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- case IGMP_GRP_REC_TYPE_BLOCK_OLD_SOURCES:
- igmpv3_report_block(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- default:
- zlog_warn("Recv IGMP report v3 from %s on %s: unknown record type: type=%d",
- from_str, ifp->name, rec_type);
- }
-
- group_record += 8 + (rec_num_sources << 2) + (rec_auxdatalen << 2);
- local_ncb = 0;
-
- } /* for (group records) */
-
return 0;
}
@@ -606,73 +358,17 @@ static void on_trace(const char *label,
struct interface *ifp, struct in_addr from)
{
if (PIM_DEBUG_IGMP_TRACE) {
- char from_str[100];
+ char from_str[INET_ADDRSTRLEN];
pim_inet4_dump("<from?>", from, from_str, sizeof(from_str));
zlog_debug("%s: from %s on %s",
label, from_str, ifp->name);
}
}
-static int igmp_v2_report(struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
-{
- struct interface *ifp = igmp->interface;
- struct igmp_group *group;
- struct in_addr group_addr;
-
- on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
-
- if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
- zlog_warn("Recv IGMP report v2 from %s on %s: size=%d other than correct=%d",
- from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
- return -1;
- }
-
- if (PIM_DEBUG_IGMP_TRACE) {
- zlog_warn("%s %s: FIXME WRITEME",
- __FILE__, __PRETTY_FUNCTION__);
- }
-
- //group_addr = *(struct in_addr *)(igmp_msg + 4);
- memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
-
- /* non-existant group is created as INCLUDE {empty} */
- group = igmp_add_group_by_addr(igmp, group_addr);
- if (!group) {
- return -1;
- }
-
- group->last_igmp_v2_report_dsec = pim_time_monotonic_dsec();
-
- return 0;
-}
-
-static int igmp_v2_leave(struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
-{
- struct interface *ifp = igmp->interface;
-
- on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
-
- if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
- zlog_warn("Recv IGMP leave v2 from %s on %s: size=%d other than correct=%d",
- from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
- return -1;
- }
-
- if (PIM_DEBUG_IGMP_TRACE) {
- zlog_warn("%s %s: FIXME WRITEME",
- __FILE__, __PRETTY_FUNCTION__);
- }
-
- return 0;
-}
-
-static int igmp_v1_report(struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
+static int
+igmp_v1_recv_report (struct igmp_sock *igmp,
+ struct in_addr from, const char *from_str,
+ char *igmp_msg, int igmp_msg_len)
{
struct interface *ifp = igmp->interface;
struct igmp_group *group;
@@ -691,7 +387,6 @@ static int igmp_v1_report(struct igmp_sock *igmp,
__FILE__, __PRETTY_FUNCTION__);
}
- //group_addr = *(struct in_addr *)(igmp_msg + 4);
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
/* non-existant group is created as INCLUDE {empty} */
@@ -712,8 +407,8 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
char *igmp_msg;
int igmp_msg_len;
int msg_type;
- char from_str[100];
- char to_str[100];
+ char from_str[INET_ADDRSTRLEN];
+ char to_str[INET_ADDRSTRLEN];
if (len < sizeof(*ip_hdr)) {
zlog_warn("IGMP packet size=%zu shorter than minimum=%zu",
@@ -790,26 +485,26 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
return -1;
}
- return recv_igmp_query(igmp, query_version, max_resp_code,
+ return igmp_recv_query(igmp, query_version, max_resp_code,
ip_hdr->ip_src, from_str,
igmp_msg, igmp_msg_len);
}
case PIM_IGMP_V3_MEMBERSHIP_REPORT:
- return igmp_v3_report(igmp, ip_hdr->ip_src, from_str,
- igmp_msg, igmp_msg_len);
+ return igmp_v3_recv_report(igmp, ip_hdr->ip_src, from_str,
+ igmp_msg, igmp_msg_len);
case PIM_IGMP_V2_MEMBERSHIP_REPORT:
- return igmp_v2_report(igmp, ip_hdr->ip_src, from_str,
- igmp_msg, igmp_msg_len);
+ return igmp_v2_recv_report(igmp, ip_hdr->ip_src, from_str,
+ igmp_msg, igmp_msg_len);
case PIM_IGMP_V1_MEMBERSHIP_REPORT:
- return igmp_v1_report(igmp, ip_hdr->ip_src, from_str,
- igmp_msg, igmp_msg_len);
+ return igmp_v1_recv_report(igmp, ip_hdr->ip_src, from_str,
+ igmp_msg, igmp_msg_len);
case PIM_IGMP_V2_LEAVE_GROUP:
- return igmp_v2_leave(igmp, ip_hdr->ip_src, from_str,
- igmp_msg, igmp_msg_len);
+ return igmp_v2_recv_leave(igmp, ip_hdr->ip_src, from_str,
+ igmp_msg, igmp_msg_len);
}
zlog_warn("Ignoring unsupported IGMP message type: %d", msg_type);
@@ -825,9 +520,6 @@ void pim_igmp_general_query_on(struct igmp_sock *igmp)
int startup_mode;
int query_interval;
- zassert(igmp);
- zassert(igmp->interface);
-
/*
Since this socket is starting as querier,
there should not exist a timer for other-querier-present.
@@ -841,20 +533,31 @@ void pim_igmp_general_query_on(struct igmp_sock *igmp)
The Startup Query Interval is the interval between General Queries
sent by a Querier on startup. Default: 1/4 the Query Interval.
+ The first one should be sent out immediately instead of 125/4
+ seconds from now.
*/
startup_mode = igmp->startup_query_count > 0;
if (startup_mode) {
- --igmp->startup_query_count;
+ /*
+ * If this is the first time we are sending a query on a
+ * newly configured igmp interface send it out in 1 second
+ * just to give the entire world a tiny bit of time to settle
+ * else the query interval is:
+ * query_interval = pim_ifp->igmp_default_query_interval >> 2;
+ */
+ if (igmp->startup_query_count == igmp->querier_robustness_variable)
+ query_interval = 1;
+ else
+ query_interval = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
- /* query_interval = pim_ifp->igmp_default_query_interval >> 2; */
- query_interval = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
+ --igmp->startup_query_count;
}
else {
query_interval = igmp->querier_query_interval;
}
if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
zlog_debug("Querier %s scheduling %d-second (%s) TIMER event for IGMP query on fd=%d",
ifaddr_str,
@@ -862,8 +565,7 @@ void pim_igmp_general_query_on(struct igmp_sock *igmp)
startup_mode ? "startup" : "non-startup",
igmp->fd);
}
- igmp->t_igmp_query_timer = 0;
- zassert(!igmp->t_igmp_query_timer);
+ igmp->t_igmp_query_timer = NULL;
THREAD_TIMER_ON(master, igmp->t_igmp_query_timer,
pim_igmp_general_query,
igmp, query_interval);
@@ -875,35 +577,39 @@ void pim_igmp_general_query_off(struct igmp_sock *igmp)
if (PIM_DEBUG_IGMP_TRACE) {
if (igmp->t_igmp_query_timer) {
- char ifaddr_str[100];
+ char ifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
zlog_debug("IGMP querier %s fd=%d cancelling query TIMER event on %s",
ifaddr_str, igmp->fd, igmp->interface->name);
}
}
THREAD_OFF(igmp->t_igmp_query_timer);
- zassert(!igmp->t_igmp_query_timer);
}
/* Issue IGMP general query */
static int pim_igmp_general_query(struct thread *t)
{
- char query_buf[PIM_IGMP_BUFSIZE_WRITE];
struct igmp_sock *igmp;
struct in_addr dst_addr;
struct in_addr group_addr;
struct pim_interface *pim_ifp;
-
- zassert(t);
+ int query_buf_size;
igmp = THREAD_ARG(t);
- zassert(igmp);
zassert(igmp->interface);
zassert(igmp->interface->info);
pim_ifp = igmp->interface->info;
+ if (pim_ifp->igmp_version == 3) {
+ query_buf_size = PIM_IGMP_BUFSIZE_WRITE;
+ } else {
+ query_buf_size = IGMP_V12_MSG_SIZE;
+ }
+
+ char query_buf[query_buf_size];
+
/*
RFC3376: 4.1.12. IP Destination Addresses for Queries
@@ -917,8 +623,8 @@ static int pim_igmp_general_query(struct thread *t)
group_addr.s_addr = PIM_NET_INADDR_ANY;
if (PIM_DEBUG_IGMP_TRACE) {
- char querier_str[100];
- char dst_str[100];
+ char querier_str[INET_ADDRSTRLEN];
+ char dst_str[INET_ADDRSTRLEN];
pim_inet4_dump("<querier?>", igmp->ifaddr, querier_str,
sizeof(querier_str));
pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
@@ -926,124 +632,25 @@ static int pim_igmp_general_query(struct thread *t)
querier_str, dst_str, igmp->interface->name);
}
- pim_igmp_send_membership_query(0 /* igmp_group */,
- igmp->fd,
- igmp->interface->name,
- query_buf,
- sizeof(query_buf),
- 0 /* num_sources */,
- dst_addr,
- group_addr,
- pim_ifp->igmp_query_max_response_time_dsec,
- 1 /* s_flag: always set for general queries */,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
+ igmp_send_query (pim_ifp->igmp_version,
+ 0 /* igmp_group */,
+ igmp->fd,
+ igmp->interface->name,
+ query_buf,
+ sizeof(query_buf),
+ 0 /* num_sources */,
+ dst_addr,
+ group_addr,
+ pim_ifp->igmp_query_max_response_time_dsec,
+ 1 /* s_flag: always set for general queries */,
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
pim_igmp_general_query_on(igmp);
return 0;
}
-static int pim_igmp_read(struct thread *t);
-
-static void igmp_read_on(struct igmp_sock *igmp)
-{
- zassert(igmp);
-
- if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
- zlog_debug("Scheduling READ event on IGMP socket fd=%d",
- igmp->fd);
- }
- igmp->t_igmp_read = 0;
- zassert(!igmp->t_igmp_read);
- THREAD_READ_ON(master, igmp->t_igmp_read, pim_igmp_read, igmp, igmp->fd);
-}
-
-static int pim_igmp_read(struct thread *t)
-{
- struct igmp_sock *igmp;
- int fd;
- struct sockaddr_in from;
- struct sockaddr_in to;
- socklen_t fromlen = sizeof(from);
- socklen_t tolen = sizeof(to);
- uint8_t buf[PIM_IGMP_BUFSIZE_READ];
- int len;
- ifindex_t ifindex = -1;
- int result = -1; /* defaults to bad */
-
- zassert(t);
-
- igmp = THREAD_ARG(t);
-
- zassert(igmp);
-
- fd = THREAD_FD(t);
-
- zassert(fd == igmp->fd);
-
- len = pim_socket_recvfromto(fd, buf, sizeof(buf),
- &from, &fromlen,
- &to, &tolen,
- &ifindex);
- if (len < 0) {
- zlog_warn("Failure receiving IP IGMP packet on fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- goto done;
- }
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- char from_str[100];
- char to_str[100];
-
- if (!inet_ntop(AF_INET, &from.sin_addr, from_str, sizeof(from_str)))
- sprintf(from_str, "<from?>");
- if (!inet_ntop(AF_INET, &to.sin_addr, to_str, sizeof(to_str)))
- sprintf(to_str, "<to?>");
-
- zlog_debug("Recv IP IGMP pkt size=%d from %s to %s on fd=%d on ifindex=%d (sock_ifindex=%d)",
- len, from_str, to_str, fd, ifindex, igmp->interface->ifindex);
- }
-
-#ifdef PIM_CHECK_RECV_IFINDEX_SANITY
- /* ifindex sanity check */
- if (ifindex != igmp->interface->ifindex) {
- char from_str[100];
- char to_str[100];
- struct interface *ifp;
-
- if (!inet_ntop(AF_INET, &from.sin_addr, from_str , sizeof(from_str)))
- sprintf(from_str, "<from?>");
- if (!inet_ntop(AF_INET, &to.sin_addr, to_str , sizeof(to_str)))
- sprintf(to_str, "<to?>");
-
- ifp = if_lookup_by_index(ifindex);
- if (ifp) {
- zassert(ifindex == ifp->ifindex);
- }
-
-#ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH
- zlog_warn("Interface mismatch: recv IGMP pkt from %s to %s on fd=%d: recv_ifindex=%d (%s) sock_ifindex=%d (%s)",
- from_str, to_str, fd,
- ifindex, ifp ? ifp->name : "<if-notfound>",
- igmp->interface->ifindex, igmp->interface->name);
-#endif
- goto done;
- }
-#endif
-
- if (pim_igmp_packet(igmp, (char *)buf, len)) {
- goto done;
- }
-
- result = 0; /* good */
-
- done:
- igmp_read_on(igmp);
-
- return result;
-}
-
static void sock_close(struct igmp_sock *igmp)
{
pim_igmp_other_querier_timer_off(igmp);
@@ -1057,7 +664,6 @@ static void sock_close(struct igmp_sock *igmp)
}
}
THREAD_OFF(igmp->t_igmp_read);
- zassert(!igmp->t_igmp_read);
if (close(igmp->fd)) {
zlog_err("Failure closing IGMP socket %s fd=%d on interface %s: errno=%d: %s",
@@ -1106,7 +712,7 @@ static void igmp_group_delete(struct igmp_group *group)
struct igmp_source *src;
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("Deleting IGMP group %s from socket %d interface %s",
group_str,
@@ -1168,6 +774,22 @@ void igmp_sock_delete(struct igmp_sock *igmp)
igmp_sock_free(igmp);
}
+void
+igmp_sock_delete_all (struct interface *ifp)
+{
+ struct pim_interface *pim_ifp;
+ struct listnode *igmp_node, *igmp_nextnode;
+ struct igmp_sock *igmp;
+
+ pim_ifp = ifp->info;
+
+ for (ALL_LIST_ELEMENTS (pim_ifp->igmp_socket_list, igmp_node,
+ igmp_nextnode, igmp))
+ {
+ igmp_sock_delete(igmp);
+ }
+}
+
static struct igmp_sock *igmp_sock_new(int fd,
struct in_addr ifaddr,
struct interface *ifp)
@@ -1182,9 +804,9 @@ static struct igmp_sock *igmp_sock_new(int fd,
fd, inet_ntoa(ifaddr), ifp->name);
}
- igmp = XMALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp));
+ igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp));
if (!igmp) {
- zlog_warn("%s %s: XMALLOC() failure",
+ zlog_warn("%s %s: XCALLOC() failure",
__FILE__, __PRETTY_FUNCTION__);
return 0;
}
@@ -1200,9 +822,9 @@ static struct igmp_sock *igmp_sock_new(int fd,
igmp->fd = fd;
igmp->interface = ifp;
igmp->ifaddr = ifaddr;
- igmp->t_igmp_read = 0;
- igmp->t_igmp_query_timer = 0;
- igmp->t_other_querier_timer = 0; /* no other querier present */
+ igmp->t_igmp_read = NULL;
+ igmp->t_igmp_query_timer = NULL;
+ igmp->t_other_querier_timer = NULL; /* no other querier present */
igmp->querier_robustness_variable = pim_ifp->igmp_default_robustness_variable;
igmp->sock_creation = pim_time_monotonic_sec();
@@ -1212,13 +834,63 @@ static struct igmp_sock *igmp_sock_new(int fd,
igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
*/
igmp_startup_mode_on(igmp);
-
- igmp_read_on(igmp);
pim_igmp_general_query_on(igmp);
return igmp;
}
+static void igmp_read_on (struct igmp_sock *igmp);
+
+static int
+pim_igmp_read (struct thread *t)
+{
+ uint8_t buf[10000];
+ struct igmp_sock *igmp = (struct igmp_sock *)THREAD_ARG(t);
+ struct sockaddr_in from;
+ struct sockaddr_in to;
+ socklen_t fromlen = sizeof(from);
+ socklen_t tolen = sizeof(to);
+ ifindex_t ifindex = -1;
+ int cont = 1;
+ int len;
+
+ while (cont)
+ {
+ len = pim_socket_recvfromto(igmp->fd, buf, sizeof(buf),
+ &from, &fromlen,
+ &to, &tolen,
+ &ifindex);
+ if (len < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ {
+ cont = 0;
+ break;
+ }
+ goto done;
+ }
+ }
+
+ done:
+ igmp_read_on(igmp);
+ return 0;
+}
+
+static void
+igmp_read_on (struct igmp_sock *igmp)
+{
+
+ if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
+ zlog_debug("Scheduling READ event on IGMP socket fd=%d",
+ igmp->fd);
+ }
+ igmp->t_igmp_read = NULL;
+ THREAD_READ_ON(master, igmp->t_igmp_read, pim_igmp_read, igmp, igmp->fd);
+
+}
+
struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
struct in_addr ifaddr,
struct interface *ifp)
@@ -1229,7 +901,7 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
pim_ifp = ifp->info;
- fd = igmp_sock_open(ifaddr, ifp->ifindex, pim_ifp->options);
+ fd = igmp_sock_open(ifaddr, ifp, pim_ifp->options);
if (fd < 0) {
zlog_warn("Could not open IGMP socket for %s on %s",
inet_ntoa(ifaddr), ifp->name);
@@ -1244,6 +916,8 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
return 0;
}
+ igmp_read_on (igmp);
+
listnode_add(igmp_sock_list, igmp);
#ifdef IGMP_SOCK_DUMP
@@ -1271,12 +945,10 @@ static int igmp_group_timer(struct thread *t)
{
struct igmp_group *group;
- zassert(t);
group = THREAD_ARG(t);
- zassert(group);
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("%s: Timer for group %s on interface %s",
__PRETTY_FUNCTION__,
@@ -1315,7 +987,7 @@ static void group_timer_off(struct igmp_group *group)
return;
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("Cancelling TIMER event for group %s on %s",
group_str, group->group_igmp_sock->interface->name);
@@ -1331,7 +1003,7 @@ void igmp_group_timer_on(struct igmp_group *group,
group_timer_off(group);
if (PIM_DEBUG_IGMP_EVENTS) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("Scheduling %ld.%03ld sec TIMER event for group %s on %s",
interval_msec / 1000,
@@ -1377,6 +1049,19 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
return group;
}
+ if (!pim_is_group_224_4 (group_addr))
+ {
+ zlog_warn("%s: Group Specified is not part of 224.0.0.0/4",
+ __PRETTY_FUNCTION__);
+ return NULL;
+ }
+
+ if (pim_is_group_224_0_0_0_24 (group_addr))
+ {
+ zlog_warn("%s: Group specified is part of 224.0.0.0/24",
+ __PRETTY_FUNCTION__);
+ return NULL;
+ }
/*
Non-existant group is created as INCLUDE {empty}:
@@ -1390,11 +1075,11 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
of INCLUDE and an empty source list.
*/
- group = XMALLOC(MTYPE_PIM_IGMP_GROUP, sizeof(*group));
+ group = XCALLOC(MTYPE_PIM_IGMP_GROUP, sizeof(*group));
if (!group) {
- zlog_warn("%s %s: XMALLOC() failure",
+ zlog_warn("%s %s: XCALLOC() failure",
__FILE__, __PRETTY_FUNCTION__);
- return 0; /* error, not found, could not create */
+ return NULL; /* error, not found, could not create */
}
group->group_source_list = list_new();
@@ -1402,7 +1087,7 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
zlog_warn("%s %s: list_new() failure",
__FILE__, __PRETTY_FUNCTION__);
XFREE(MTYPE_PIM_IGMP_GROUP, group); /* discard group */
- return 0; /* error, not found, could not initialize */
+ return NULL; /* error, not found, could not initialize */
}
group->group_source_list->del = (void (*)(void *)) igmp_source_free;
@@ -1414,6 +1099,7 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
group->last_igmp_v1_report_dsec = -1;
group->last_igmp_v2_report_dsec = -1;
group->group_creation = pim_time_monotonic_sec();
+ group->igmp_version = IGMP_DEFAULT_VERSION;
/* initialize new group as INCLUDE {empty} */
group->group_filtermode_isexcl = 0; /* 0=INCLUDE, 1=EXCLUDE */
@@ -1421,7 +1107,7 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
listnode_add(igmp->igmp_group_list, group);
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("Creating new IGMP group %s on socket %d interface %s",
group_str, igmp->fd, igmp->interface->name);
@@ -1442,3 +1128,32 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
return group;
}
+
+void
+igmp_send_query (int igmp_version,
+ struct igmp_group *group,
+ int fd,
+ const char *ifname,
+ char *query_buf,
+ int query_buf_size,
+ int num_sources,
+ struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec,
+ uint8_t s_flag,
+ uint8_t querier_robustness_variable,
+ uint16_t querier_query_interval)
+{
+ if (igmp_version == 3) {
+ igmp_v3_send_query (group, fd, ifname, query_buf,
+ query_buf_size, num_sources,
+ dst_addr, group_addr,
+ query_max_response_time_dsec, s_flag,
+ querier_robustness_variable,
+ querier_query_interval);
+ } else if (igmp_version == 2) {
+ igmp_v2_send_query (group, fd, ifname, query_buf,
+ dst_addr, group_addr,
+ query_max_response_time_dsec);
+ }
+}
diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h
index eb0377ce8c..802f1ba471 100644
--- a/pimd/pim_igmp.h
+++ b/pimd/pim_igmp.h
@@ -51,6 +51,7 @@
#define IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET (2)
#define IGMP_V3_GROUP_RECORD_GROUP_OFFSET (4)
#define IGMP_V3_GROUP_RECORD_SOURCE_OFFSET (8)
+#define IGMP_CHECKSUM_OFFSET (2)
/* RFC 3376: 8.1. Robustness Variable - Default: 2 */
#define IGMP_DEFAULT_ROBUSTNESS_VARIABLE (2)
@@ -64,6 +65,8 @@
/* RFC 3376: 8.8. Last Member Query Interval - Default: 10 deciseconds */
#define IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC (10)
+#define IGMP_DEFAULT_VERSION (3)
+
struct igmp_join {
struct in_addr group_addr;
struct in_addr source_addr;
@@ -97,7 +100,7 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
struct interface *ifp);
void igmp_sock_delete(struct igmp_sock *igmp);
void igmp_sock_free(struct igmp_sock *igmp);
-
+void igmp_sock_delete_all (struct interface *ifp);
int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len);
void pim_igmp_general_query_on(struct igmp_sock *igmp);
@@ -151,6 +154,9 @@ struct igmp_group {
since sources have their counters) */
int group_specific_query_retransmit_count;
+ /* compatibility mode - igmp v1, v2 or v3 */
+ int igmp_version;
+
struct in_addr group_addr;
int group_filtermode_isexcl; /* 0=INCLUDE, 1=EXCLUDE */
struct list *group_source_list; /* list of struct igmp_source */
@@ -175,4 +181,18 @@ void igmp_group_timer_on(struct igmp_group *group,
struct igmp_source *
source_new (struct igmp_group *group,
struct in_addr src_addr);
+
+void igmp_send_query(int igmp_version,
+ struct igmp_group *group,
+ int fd,
+ const char *ifname,
+ char *query_buf,
+ int query_buf_size,
+ int num_sources,
+ struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec,
+ uint8_t s_flag,
+ uint8_t querier_robustness_variable,
+ uint16_t querier_query_interval);
#endif /* PIM_IGMP_H */
diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c
new file mode 100644
index 0000000000..ee4aa7bd9d
--- /dev/null
+++ b/pimd/pim_igmpv2.c
@@ -0,0 +1,190 @@
+/*
+ * PIM for Quagga
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Daniel Walton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include "zebra.h"
+
+#include "pimd.h"
+#include "pim_igmp.h"
+#include "pim_igmpv2.h"
+#include "pim_igmpv3.h"
+#include "pim_str.h"
+#include "pim_time.h"
+#include "pim_util.h"
+
+
+static void
+on_trace (const char *label,
+ struct interface *ifp, struct in_addr from)
+{
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char from_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<from?>", from, from_str, sizeof(from_str));
+ zlog_debug("%s: from %s on %s",
+ label, from_str, ifp->name);
+ }
+}
+
+void
+igmp_v2_send_query (struct igmp_group *group,
+ int fd,
+ const char *ifname,
+ char *query_buf,
+ struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec)
+{
+ ssize_t msg_size = 8;
+ uint8_t max_resp_code;
+ ssize_t sent;
+ struct sockaddr_in to;
+ socklen_t tolen;
+ uint16_t checksum;
+
+ /* max_resp_code must be non-zero else this will look like an IGMP v1 query */
+ max_resp_code = igmp_msg_encode16to8(query_max_response_time_dsec);
+ zassert(max_resp_code > 0);
+
+ query_buf[0] = PIM_IGMP_MEMBERSHIP_QUERY;
+ query_buf[1] = max_resp_code;
+ *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = 0; /* for computing checksum */
+ memcpy(query_buf+4, &group_addr, sizeof(struct in_addr));
+
+ checksum = in_cksum(query_buf, msg_size);
+ *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = checksum;
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
+ pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
+ zlog_debug("Send IGMPv2 QUERY to %s on %s for group %s",
+ dst_str, ifname, group_str);
+ }
+
+ memset(&to, 0, sizeof(to));
+ to.sin_family = AF_INET;
+ to.sin_addr = dst_addr;
+ tolen = sizeof(to);
+
+ sent = sendto(fd, query_buf, msg_size, MSG_DONTWAIT,
+ (struct sockaddr *)&to, tolen);
+ if (sent != (ssize_t) msg_size) {
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
+ pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
+ if (sent < 0) {
+ zlog_warn("Send IGMPv2 QUERY failed due to %s on %s: group=%s msg_size=%zd: errno=%d: %s",
+ dst_str, ifname, group_str, msg_size, errno, safe_strerror(errno));
+ }
+ else {
+ zlog_warn("Send IGMPv2 QUERY failed due to %s on %s: group=%s msg_size=%zd: sent=%zd",
+ dst_str, ifname, group_str, msg_size, sent);
+ }
+ return;
+ }
+}
+
+int
+igmp_v2_recv_report (struct igmp_sock *igmp,
+ struct in_addr from, const char *from_str,
+ char *igmp_msg, int igmp_msg_len)
+{
+ struct interface *ifp = igmp->interface;
+ struct in_addr group_addr;
+ char group_str[INET_ADDRSTRLEN];
+
+ on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
+
+ if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
+ zlog_warn("Recv IGMPv2 REPORT from %s on %s: size=%d other than correct=%d",
+ from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
+ return -1;
+ }
+
+ memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ pim_inet4_dump("<dst?>", group_addr, group_str, sizeof(group_str));
+ zlog_debug("Recv IGMPv2 REPORT from %s on %s for %s",
+ from_str, ifp->name, group_str);
+ }
+
+ /*
+ * RFC 3376
+ * 7.3.2. In the Presence of Older Version Group Members
+ *
+ * When Group Compatibility Mode is IGMPv2, a router internally
+ * translates the following IGMPv2 messages for that group to their
+ * IGMPv3 equivalents:
+ *
+ * IGMPv2 Message IGMPv3 Equivalent
+ * -------------- -----------------
+ * Report IS_EX( {} )
+ * Leave TO_IN( {} )
+ */
+ igmpv3_report_isex (igmp, from, group_addr, 0, NULL, 1);
+
+ return 0;
+}
+
+int
+igmp_v2_recv_leave (struct igmp_sock *igmp,
+ struct in_addr from, const char *from_str,
+ char *igmp_msg, int igmp_msg_len)
+{
+ struct interface *ifp = igmp->interface;
+ struct in_addr group_addr;
+ char group_str[INET_ADDRSTRLEN];
+
+ on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
+
+ if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
+ zlog_warn("Recv IGMPv2 LEAVE from %s on %s: size=%d other than correct=%d",
+ from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
+ return -1;
+ }
+
+ memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ pim_inet4_dump("<dst?>", group_addr, group_str, sizeof(group_str));
+ zlog_debug("Recv IGMPv2 LEAVE from %s on %s for %s",
+ from_str, ifp->name, group_str);
+ }
+
+ /*
+ * RFC 3376
+ * 7.3.2. In the Presence of Older Version Group Members
+ *
+ * When Group Compatibility Mode is IGMPv2, a router internally
+ * translates the following IGMPv2 messages for that group to their
+ * IGMPv3 equivalents:
+ *
+ * IGMPv2 Message IGMPv3 Equivalent
+ * -------------- -----------------
+ * Report IS_EX( {} )
+ * Leave TO_IN( {} )
+ */
+ igmpv3_report_toin (igmp, from, group_addr, 0, NULL);
+
+ return 0;
+}
diff --git a/pimd/pim_igmpv2.h b/pimd/pim_igmpv2.h
new file mode 100644
index 0000000000..10a2477724
--- /dev/null
+++ b/pimd/pim_igmpv2.h
@@ -0,0 +1,41 @@
+/*
+ * PIM for Quagga
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Daniel Walton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef PIM_IGMPV2_H
+#define PIM_IGMPV2_H
+
+void igmp_v2_send_query (struct igmp_group *group,
+ int fd,
+ const char *ifname,
+ char *query_buf,
+ struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec);
+
+int igmp_v2_recv_report (struct igmp_sock *igmp,
+ struct in_addr from, const char *from_str,
+ char *igmp_msg, int igmp_msg_len);
+
+int igmp_v2_recv_leave (struct igmp_sock *igmp,
+ struct in_addr from, const char *from_str,
+ char *igmp_msg, int igmp_msg_len);
+
+#endif /* PIM_IGMPV2_H */
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index bdaf2bb270..f7a6cbd0ce 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -46,8 +46,8 @@ static void on_trace(const char *label,
int num_sources, struct in_addr *sources)
{
if (PIM_DEBUG_IGMP_TRACE) {
- char from_str[100];
- char group_str[100];
+ char from_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<from?>", from, from_str, sizeof(from_str));
pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
@@ -57,50 +57,6 @@ static void on_trace(const char *label,
}
}
-int igmp_group_compat_mode(const struct igmp_sock *igmp,
- const struct igmp_group *group)
-{
- struct pim_interface *pim_ifp;
- int64_t now_dsec;
- long older_host_present_interval_dsec;
-
- zassert(igmp);
- zassert(igmp->interface);
- zassert(igmp->interface->info);
-
- pim_ifp = igmp->interface->info;
-
- /*
- RFC 3376: 8.13. Older Host Present Interval
-
- This value MUST be ((the Robustness Variable) times (the Query
- Interval)) plus (one Query Response Interval).
-
- older_host_present_interval_dsec = \
- igmp->querier_robustness_variable * \
- 10 * igmp->querier_query_interval + \
- pim_ifp->query_max_response_time_dsec;
- */
- older_host_present_interval_dsec =
- PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec);
-
- now_dsec = pim_time_monotonic_dsec();
- if (now_dsec < 1) {
- /* broken timer logged by pim_time_monotonic_dsec() */
- return 3;
- }
-
- if ((now_dsec - group->last_igmp_v1_report_dsec) < older_host_present_interval_dsec)
- return 1; /* IGMPv1 */
-
- if ((now_dsec - group->last_igmp_v2_report_dsec) < older_host_present_interval_dsec)
- return 2; /* IGMPv2 */
-
- return 3; /* IGMPv3 */
-}
-
void igmp_group_reset_gmi(struct igmp_group *group)
{
long group_membership_interval_msec;
@@ -132,7 +88,7 @@ void igmp_group_reset_gmi(struct igmp_group *group)
pim_ifp->igmp_query_max_response_time_dsec);
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("Resetting group %s timer to GMI=%ld.%03ld sec on %s",
group_str,
@@ -158,15 +114,13 @@ static int igmp_source_timer(struct thread *t)
struct igmp_source *source;
struct igmp_group *group;
- zassert(t);
source = THREAD_ARG(t);
- zassert(source);
group = source->source_group;
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
zlog_debug("%s: Source timer expired for group %s source %s on %s",
@@ -176,7 +130,7 @@ static int igmp_source_timer(struct thread *t)
}
zassert(source->t_source_timer);
- source->t_source_timer = 0;
+ source->t_source_timer = NULL;
/*
RFC 3376: 6.3. IGMPv3 Source-Specific Forwarding Rules
@@ -230,8 +184,8 @@ static void source_timer_off(struct igmp_group *group,
return;
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
zlog_debug("Cancelling TIMER event for group %s source %s on %s",
@@ -250,8 +204,8 @@ static void igmp_source_timer_on(struct igmp_group *group,
source_timer_off(group, source);
if (PIM_DEBUG_IGMP_EVENTS) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
zlog_debug("Scheduling %ld.%03ld sec TIMER event for group %s source %s on %s",
@@ -291,8 +245,8 @@ void igmp_source_reset_gmi(struct igmp_sock *igmp,
pim_ifp->igmp_query_max_response_time_dsec);
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
@@ -383,7 +337,7 @@ static void source_channel_oil_detach(struct igmp_source *source)
{
if (source->source_channel_oil) {
pim_channel_oil_del(source->source_channel_oil);
- source->source_channel_oil = 0;
+ source->source_channel_oil = NULL;
}
}
@@ -398,8 +352,8 @@ void igmp_source_delete(struct igmp_source *source)
group = source->source_group;
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
zlog_debug("Deleting IGMP source %s for group %s from socket %d interface %s",
@@ -413,8 +367,8 @@ void igmp_source_delete(struct igmp_source *source)
/* sanity check that forwarding has been disabled */
if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
zlog_warn("%s: forwarding=ON(!) IGMP source %s for group %s from socket %d interface %s",
@@ -483,8 +437,8 @@ source_new (struct igmp_group *group,
struct igmp_source *src;
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", src_addr, source_str, sizeof(source_str));
zlog_debug("Creating new IGMP source %s for group %s on socket %d interface %s",
@@ -493,9 +447,9 @@ source_new (struct igmp_group *group,
group->group_igmp_sock->interface->name);
}
- src = XMALLOC(MTYPE_PIM_IGMP_GROUP_SOURCE, sizeof(*src));
+ src = XCALLOC(MTYPE_PIM_IGMP_GROUP_SOURCE, sizeof(*src));
if (!src) {
- zlog_warn("%s %s: XMALLOC() failure",
+ zlog_warn("%s %s: XCALLOC() failure",
__FILE__, __PRETTY_FUNCTION__);
return 0; /* error, not found, could not create */
}
@@ -646,8 +600,10 @@ static void isex_excl(struct igmp_group *group,
struct in_addr star = { .s_addr = INADDR_ANY };
source = igmp_find_source_by_addr (group, star);
if (source)
- IGMP_SOURCE_DONT_DELETE(source->source_flags);
- igmp_source_reset_gmi (group->group_igmp_sock, group, source);
+ {
+ IGMP_SOURCE_DONT_DELETE(source->source_flags);
+ igmp_source_reset_gmi (group->group_igmp_sock, group, source);
+ }
}
/* E.5: delete all sources marked with deletion flag: (X-A) and (Y-A) */
@@ -702,7 +658,8 @@ static void isex_incl(struct igmp_group *group,
void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from,
struct in_addr group_addr,
- int num_sources, struct in_addr *sources)
+ int num_sources, struct in_addr *sources,
+ int from_igmp_v2_report)
{
struct interface *ifp = igmp->interface;
struct igmp_group *group;
@@ -716,6 +673,10 @@ void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from,
return;
}
+ /* So we can display how we learned the group in our show command output */
+ if (from_igmp_v2_report)
+ group->igmp_version = 2;
+
if (group->group_filtermode_isexcl) {
/* EXCLUDE mode */
isex_excl(group, num_sources, sources);
@@ -932,6 +893,16 @@ static void toex_excl(struct igmp_group *group,
/* clear off SEND flag from all known sources (X,Y) */
source_clear_send_flag(group->group_source_list);
+ if (num_sources == 0)
+ {
+ struct igmp_source *source;
+ struct in_addr any = { .s_addr = INADDR_ANY };
+
+ source = igmp_find_source_by_addr (group, any);
+ if (source)
+ IGMP_SOURCE_DONT_DELETE(source->source_flags);
+ }
+
/* scan received sources (A) */
for (i = 0; i < num_sources; ++i) {
struct igmp_source *source;
@@ -1037,17 +1008,25 @@ void igmpv3_report_allow(struct igmp_sock *igmp, struct in_addr from,
*/
static void group_retransmit_group(struct igmp_group *group)
{
- char query_buf[PIM_IGMP_BUFSIZE_WRITE];
struct igmp_sock *igmp;
struct pim_interface *pim_ifp;
long lmqc; /* Last Member Query Count */
long lmqi_msec; /* Last Member Query Interval */
long lmqt_msec; /* Last Member Query Time */
int s_flag;
+ int query_buf_size;
igmp = group->group_igmp_sock;
pim_ifp = igmp->interface->info;
+ if (pim_ifp->igmp_version == 3) {
+ query_buf_size = PIM_IGMP_BUFSIZE_WRITE;
+ } else {
+ query_buf_size = IGMP_V12_MSG_SIZE;
+ }
+
+ char query_buf[query_buf_size];
+
lmqc = igmp->querier_robustness_variable;
lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
lmqt_msec = lmqc * lmqi_msec;
@@ -1062,7 +1041,7 @@ static void group_retransmit_group(struct igmp_group *group)
s_flag = igmp_group_timer_remain_msec(group) > lmqt_msec;
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("retransmit_group_specific_query: group %s on %s: s_flag=%d count=%d",
group_str, igmp->interface->name, s_flag,
@@ -1077,18 +1056,19 @@ static void group_retransmit_group(struct igmp_group *group)
interest.
*/
- pim_igmp_send_membership_query(group,
- igmp->fd,
- igmp->interface->name,
- query_buf,
- sizeof(query_buf),
- 0 /* num_sources_tosend */,
- group->group_addr /* dst_addr */,
- group->group_addr /* group_addr */,
- pim_ifp->igmp_specific_query_max_response_time_dsec,
- s_flag,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
+ igmp_send_query(pim_ifp->igmp_version,
+ group,
+ igmp->fd,
+ igmp->interface->name,
+ query_buf,
+ sizeof(query_buf),
+ 0 /* num_sources_tosend */,
+ group->group_addr /* dst_addr */,
+ group->group_addr /* group_addr */,
+ pim_ifp->igmp_specific_query_max_response_time_dsec,
+ s_flag,
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
}
/*
@@ -1123,9 +1103,6 @@ static int group_retransmit_sources(struct igmp_group *group,
struct igmp_source *src;
int num_retransmit_sources_left = 0;
- query_buf1_max_sources = (sizeof(query_buf1) - IGMP_V3_SOURCES_OFFSET) >> 2;
- query_buf2_max_sources = (sizeof(query_buf2) - IGMP_V3_SOURCES_OFFSET) >> 2;
-
source_addr1 = (struct in_addr *)(query_buf1 + IGMP_V3_SOURCES_OFFSET);
source_addr2 = (struct in_addr *)(query_buf2 + IGMP_V3_SOURCES_OFFSET);
@@ -1163,7 +1140,7 @@ static int group_retransmit_sources(struct igmp_group *group,
num_sources_tosend2 = source_addr2 - (struct in_addr *)(query_buf2 + IGMP_V3_SOURCES_OFFSET);
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("retransmit_grp&src_specific_query: group %s on %s: srcs_with_sflag=%d srcs_wo_sflag=%d will_send_sflag=%d retransmit_src_left=%d",
group_str, igmp->interface->name,
@@ -1183,7 +1160,7 @@ static int group_retransmit_sources(struct igmp_group *group,
query_buf1_max_sources = (sizeof(query_buf1) - IGMP_V3_SOURCES_OFFSET) >> 2;
if (num_sources_tosend1 > query_buf1_max_sources) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_warn("%s: group %s on %s: s_flag=1 unable to fit %d sources into buf_size=%zu (max_sources=%d)",
__PRETTY_FUNCTION__, group_str, igmp->interface->name,
@@ -1198,19 +1175,19 @@ static int group_retransmit_sources(struct igmp_group *group,
interest.
*/
- pim_igmp_send_membership_query(group,
- igmp->fd,
- igmp->interface->name,
- query_buf1,
- sizeof(query_buf1),
- num_sources_tosend1,
- group->group_addr,
- group->group_addr,
- pim_ifp->igmp_specific_query_max_response_time_dsec,
- 1 /* s_flag */,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
-
+ igmp_send_query(pim_ifp->igmp_version,
+ group,
+ igmp->fd,
+ igmp->interface->name,
+ query_buf1,
+ sizeof(query_buf1),
+ num_sources_tosend1,
+ group->group_addr,
+ group->group_addr,
+ pim_ifp->igmp_specific_query_max_response_time_dsec,
+ 1 /* s_flag */,
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
}
} /* send_with_sflag_set */
@@ -1225,7 +1202,7 @@ static int group_retransmit_sources(struct igmp_group *group,
query_buf2_max_sources = (sizeof(query_buf2) - IGMP_V3_SOURCES_OFFSET) >> 2;
if (num_sources_tosend2 > query_buf2_max_sources) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_warn("%s: group %s on %s: s_flag=0 unable to fit %d sources into buf_size=%zu (max_sources=%d)",
__PRETTY_FUNCTION__, group_str, igmp->interface->name,
@@ -1240,19 +1217,19 @@ static int group_retransmit_sources(struct igmp_group *group,
interest.
*/
- pim_igmp_send_membership_query(group,
- igmp->fd,
- igmp->interface->name,
- query_buf2,
- sizeof(query_buf2),
- num_sources_tosend2,
- group->group_addr,
- group->group_addr,
- pim_ifp->igmp_specific_query_max_response_time_dsec,
- 0 /* s_flag */,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
-
+ igmp_send_query(pim_ifp->igmp_version,
+ group,
+ igmp->fd,
+ igmp->interface->name,
+ query_buf2,
+ sizeof(query_buf2),
+ num_sources_tosend2,
+ group->group_addr,
+ group->group_addr,
+ pim_ifp->igmp_specific_query_max_response_time_dsec,
+ 0 /* s_flag */,
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
}
}
@@ -1265,12 +1242,10 @@ static int igmp_group_retransmit(struct thread *t)
int num_retransmit_sources_left;
int send_with_sflag_set; /* boolean */
- zassert(t);
group = THREAD_ARG(t);
- zassert(group);
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("group_retransmit_timer: group %s on %s",
group_str, group->group_igmp_sock->interface->name);
@@ -1300,7 +1275,7 @@ static int igmp_group_retransmit(struct thread *t)
num_retransmit_sources_left = group_retransmit_sources(group,
send_with_sflag_set);
- group->t_group_query_retransmit_timer = 0;
+ group->t_group_query_retransmit_timer = NULL;
/*
Keep group retransmit timer running if there is any retransmit
@@ -1336,7 +1311,7 @@ static void group_retransmit_timer_on(struct igmp_group *group)
lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("Scheduling %ld.%03ld sec retransmit timer for group %s on %s",
lmqi_msec / 1000,
@@ -1565,7 +1540,7 @@ void igmp_group_timer_lower_to_lmqt(struct igmp_group *group)
lmqt_msec = PIM_IGMP_LMQT_MSEC(lmqi_dsec, lmqc); /* lmqt_msec = (100 * lmqi_dsec) * lmqc */
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
zlog_debug("%s: group %s on %s: LMQC=%d LMQI=%d dsec LMQT=%d msec",
__PRETTY_FUNCTION__,
@@ -1600,8 +1575,8 @@ void igmp_source_timer_lower_to_lmqt(struct igmp_source *source)
lmqt_msec = PIM_IGMP_LMQT_MSEC(lmqi_dsec, lmqc); /* lmqt_msec = (100 * lmqi_dsec) * lmqc */
if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
zlog_debug("%s: group %s source %s on %s: LMQC=%d LMQI=%d dsec LMQT=%d msec",
@@ -1613,32 +1588,19 @@ void igmp_source_timer_lower_to_lmqt(struct igmp_source *source)
igmp_source_timer_on(group, source, lmqt_msec);
}
-/*
- Copy sources to message:
-
- struct in_addr *sources = (struct in_addr *)(query_buf + IGMP_V3_SOURCES_OFFSET);
- if (num_sources > 0) {
- struct listnode *node;
- struct igmp_source *src;
- int i = 0;
-
- for (ALL_LIST_ELEMENTS_RO(source_list, node, src)) {
- sources[i++] = src->source_addr;
- }
- }
-*/
-void pim_igmp_send_membership_query(struct igmp_group *group,
- int fd,
- const char *ifname,
- char *query_buf,
- int query_buf_size,
- int num_sources,
- struct in_addr dst_addr,
- struct in_addr group_addr,
- int query_max_response_time_dsec,
- uint8_t s_flag,
- uint8_t querier_robustness_variable,
- uint16_t querier_query_interval)
+void
+igmp_v3_send_query (struct igmp_group *group,
+ int fd,
+ const char *ifname,
+ char *query_buf,
+ int query_buf_size,
+ int num_sources,
+ struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec,
+ uint8_t s_flag,
+ uint8_t querier_robustness_variable,
+ uint16_t querier_query_interval)
{
ssize_t msg_size;
uint8_t max_resp_code;
@@ -1678,7 +1640,7 @@ void pim_igmp_send_membership_query(struct igmp_group *group,
query_buf[0] = PIM_IGMP_MEMBERSHIP_QUERY;
query_buf[1] = max_resp_code;
- *(uint16_t *)(query_buf + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
+ *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = 0; /* for computing checksum */
memcpy(query_buf+4, &group_addr, sizeof(struct in_addr));
query_buf[8] = (s_flag << 3) | querier_robustness_variable;
@@ -1686,18 +1648,17 @@ void pim_igmp_send_membership_query(struct igmp_group *group,
*(uint16_t *)(query_buf + IGMP_V3_NUMSOURCES_OFFSET) = htons(num_sources);
checksum = in_cksum(query_buf, msg_size);
- *(uint16_t *)(query_buf + IGMP_V3_CHECKSUM_OFFSET) = checksum;
+ *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = checksum;
if (PIM_DEBUG_IGMP_PACKETS) {
- char dst_str[100];
- char group_str[100];
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: to %s on %s: group=%s sources=%d msg_size=%zd s_flag=%x QRV=%u QQI=%u QQIC=%02x checksum=%x",
- __PRETTY_FUNCTION__,
- dst_str, ifname, group_str, num_sources,
- msg_size, s_flag, querier_robustness_variable,
- querier_query_interval, qqic, checksum);
+ zlog_debug("Send IGMPv3 query to %s on %s for group %s, sources=%d msg_size=%zd s_flag=%x QRV=%u QQI=%u QQIC=%02x",
+ dst_str, ifname, group_str,
+ num_sources, msg_size, s_flag, querier_robustness_variable,
+ querier_query_interval, qqic);
}
memset(&to, 0, sizeof(to));
@@ -1708,22 +1669,17 @@ void pim_igmp_send_membership_query(struct igmp_group *group,
sent = sendto(fd, query_buf, msg_size, MSG_DONTWAIT,
(struct sockaddr *)&to, tolen);
if (sent != (ssize_t) msg_size) {
- int e = errno;
- char dst_str[100];
- char group_str[100];
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
if (sent < 0) {
- zlog_warn("%s: sendto() failure to %s on %s: group=%s msg_size=%zd: errno=%d: %s",
- __PRETTY_FUNCTION__,
- dst_str, ifname, group_str, msg_size,
- e, safe_strerror(e));
+ zlog_warn("Send IGMPv3 query failed due to %s on %s: group=%s msg_size=%zd: errno=%d: %s",
+ dst_str, ifname, group_str, msg_size, errno, safe_strerror(errno));
}
else {
- zlog_warn("%s: sendto() partial to %s on %s: group=%s msg_size=%zd: sent=%zd",
- __PRETTY_FUNCTION__,
- dst_str, ifname, group_str,
- msg_size, sent);
+ zlog_warn("Send IGMPv3 query failed due to %s on %s: group=%s msg_size=%zd: sent=%zd",
+ dst_str, ifname, group_str, msg_size, sent);
}
return;
}
@@ -1742,8 +1698,8 @@ void pim_igmp_send_membership_query(struct igmp_group *group,
if (!s_flag) {
/* general query? */
if (PIM_INADDR_IS_ANY(group_addr)) {
- char dst_str[100];
- char group_str[100];
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
zlog_warn("%s: to %s on %s: group=%s sources=%d: s_flag is clear for general query!",
@@ -1751,5 +1707,268 @@ void pim_igmp_send_membership_query(struct igmp_group *group,
dst_str, ifname, group_str, num_sources);
}
}
+}
+
+void
+igmp_v3_recv_query (struct igmp_sock *igmp, const char *from_str, char *igmp_msg)
+{
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct in_addr group_addr;
+ uint8_t resv_s_qrv = 0;
+ uint8_t s_flag = 0;
+ uint8_t qrv = 0;
+ int i;
+
+ memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
+ ifp = igmp->interface;
+ pim_ifp = ifp->info;
+
+ /*
+ * RFC 3376: 4.1.6. QRV (Querier's Robustness Variable)
+ *
+ * Routers adopt the QRV value from the most recently received Query
+ * as their own [Robustness Variable] value, unless that most
+ * recently received QRV was zero, in which case the receivers use
+ * the default [Robustness Variable] value specified in section 8.1
+ * or a statically configured value.
+ */
+ resv_s_qrv = igmp_msg[8];
+ qrv = 7 & resv_s_qrv;
+ igmp->querier_robustness_variable = qrv ? qrv : pim_ifp->igmp_default_robustness_variable;
+
+ /*
+ * RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
+ *
+ * Multicast routers that are not the current querier adopt the QQI
+ * value from the most recently received Query as their own [Query
+ * Interval] value, unless that most recently received QQI was zero,
+ * in which case the receiving routers use the default.
+ */
+ if (igmp->t_other_querier_timer) {
+ /* other querier present */
+ uint8_t qqic;
+ uint16_t qqi;
+ qqic = igmp_msg[9];
+ qqi = igmp_msg_decode8to16(qqic);
+ igmp->querier_query_interval = qqi ? qqi : pim_ifp->igmp_default_query_interval;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
+ zlog_debug("Querier %s new query interval is %s QQI=%u sec (recv QQIC=%02x from %s)",
+ ifaddr_str,
+ qqi ? "recv-non-default" : "default",
+ igmp->querier_query_interval,
+ qqic,
+ from_str);
+ }
+ }
+
+ /*
+ * RFC 3376: 6.6.1. Timer Updates
+ *
+ * When a router sends or receives a query with a clear Suppress
+ * Router-Side Processing flag, it must update its timers to reflect
+ * the correct timeout values for the group or sources being queried.
+ *
+ * General queries don't trigger timer update.
+ */
+ s_flag = (1 << 3) & resv_s_qrv;
+
+ if (!s_flag) {
+ /* s_flag is clear */
+
+ if (PIM_INADDR_IS_ANY(group_addr)) {
+ /* this is a general query */
+ /* log that general query should have the s_flag set */
+ zlog_warn("General IGMP query v3 from %s on %s: Suppress Router-Side Processing flag is clear",
+ from_str, ifp->name);
+ } else {
+ struct igmp_group *group;
+
+ /* this is a non-general query: perform timer updates */
+
+ group = find_group_by_addr(igmp, group_addr);
+ if (group) {
+ int recv_num_sources = ntohs(*(uint16_t *)(igmp_msg + IGMP_V3_NUMSOURCES_OFFSET));
+
+ /*
+ * RFC 3376: 6.6.1. Timer Updates
+ * Query Q(G,A): Source Timer for sources in A are lowered to LMQT
+ * Query Q(G): Group Timer is lowered to LMQT
+ */
+ if (recv_num_sources < 1) {
+ /* Query Q(G): Group Timer is lowered to LMQT */
+
+ igmp_group_timer_lower_to_lmqt(group);
+ } else {
+ /* Query Q(G,A): Source Timer for sources in A are lowered to LMQT */
+
+ /* Scan sources in query and lower their timers to LMQT */
+ struct in_addr *sources = (struct in_addr *)(igmp_msg + IGMP_V3_SOURCES_OFFSET);
+ for (i = 0; i < recv_num_sources; ++i) {
+ struct in_addr src_addr;
+ struct igmp_source *src;
+ memcpy(&src_addr, sources + i, sizeof(struct in_addr));
+ src = igmp_find_source_by_addr(group, src_addr);
+ if (src) {
+ igmp_source_timer_lower_to_lmqt(src);
+ }
+ }
+ }
+ } else {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
+ zlog_warn("IGMP query v3 from %s on %s: could not find group %s for timer update",
+ from_str, ifp->name, group_str);
+ }
+ }
+ } /* s_flag is clear: timer updates */
+}
+
+int
+igmp_v3_recv_report (struct igmp_sock *igmp,
+ struct in_addr from, const char *from_str,
+ char *igmp_msg, int igmp_msg_len)
+{
+ uint16_t recv_checksum;
+ uint16_t checksum;
+ int num_groups;
+ uint8_t *group_record;
+ uint8_t *report_pastend = (uint8_t *) igmp_msg + igmp_msg_len;
+ struct interface *ifp = igmp->interface;
+ int i;
+ int local_ncb = 0;
+
+ if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {
+ zlog_warn("Recv IGMP report v3 from %s on %s: size=%d shorter than minimum=%d",
+ from_str, ifp->name, igmp_msg_len, IGMP_V3_MSG_MIN_SIZE);
+ return -1;
+ }
+
+ recv_checksum = *(uint16_t *) (igmp_msg + IGMP_CHECKSUM_OFFSET);
+
+ /* for computing checksum */
+ *(uint16_t *) (igmp_msg + IGMP_CHECKSUM_OFFSET) = 0;
+
+ checksum = in_cksum(igmp_msg, igmp_msg_len);
+ if (checksum != recv_checksum) {
+ zlog_warn("Recv IGMP report v3 from %s on %s: checksum mismatch: received=%x computed=%x",
+ from_str, ifp->name, recv_checksum, checksum);
+ return -1;
+ }
+ num_groups = ntohs(*(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET));
+ if (num_groups < 1) {
+ zlog_warn("Recv IGMP report v3 from %s on %s: missing group records",
+ from_str, ifp->name);
+ return -1;
+ }
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ zlog_debug("Recv IGMP report v3 from %s on %s: size=%d checksum=%x groups=%d",
+ from_str, ifp->name, igmp_msg_len, checksum, num_groups);
+ }
+
+ group_record = (uint8_t *) igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
+
+ /* Scan groups */
+ for (i = 0; i < num_groups; ++i) {
+ struct in_addr rec_group;
+ uint8_t *sources;
+ uint8_t *src;
+ int rec_type;
+ int rec_auxdatalen;
+ int rec_num_sources;
+ int j;
+ struct prefix lncb;
+ struct prefix g;
+
+ if ((group_record + IGMP_V3_GROUP_RECORD_MIN_SIZE) > report_pastend) {
+ zlog_warn("Recv IGMP report v3 from %s on %s: group record beyond report end",
+ from_str, ifp->name);
+ return -1;
+ }
+
+ rec_type = group_record[IGMP_V3_GROUP_RECORD_TYPE_OFFSET];
+ rec_auxdatalen = group_record[IGMP_V3_GROUP_RECORD_AUXDATALEN_OFFSET];
+ rec_num_sources = ntohs(* (uint16_t *) (group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET));
+
+ memcpy(&rec_group, group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, sizeof(struct in_addr));
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ zlog_debug("Recv IGMP report v3 from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%s",
+ from_str, ifp->name, i, rec_type, rec_auxdatalen, rec_num_sources, inet_ntoa(rec_group));
+ }
+
+ /* Scan sources */
+
+ sources = group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET;
+
+ for (j = 0, src = sources; j < rec_num_sources; ++j, src += 4) {
+
+ if ((src + 4) > report_pastend) {
+ zlog_warn("Recv IGMP report v3 from %s on %s: group source beyond report end",
+ from_str, ifp->name);
+ return -1;
+ }
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ char src_str[200];
+
+ if (!inet_ntop(AF_INET, src, src_str , sizeof(src_str)))
+ sprintf(src_str, "<source?>");
+
+ zlog_debug("Recv IGMP report v3 from %s on %s: record=%d group=%s source=%s",
+ from_str, ifp->name, i, inet_ntoa(rec_group), src_str);
+ }
+ } /* for (sources) */
+
+
+ lncb.family = AF_INET;
+ lncb.u.prefix4.s_addr = 0x000000E0;
+ lncb.prefixlen = 24;
+
+ g.family = AF_INET;
+ g.u.prefix4 = rec_group;
+ g.prefixlen = 32;
+ /*
+ * If we receive a igmp report with the group in 224.0.0.0/24
+ * then we should ignore it
+ */
+ if (prefix_match(&lncb, &g))
+ local_ncb = 1;
+
+ if (!local_ncb)
+ switch (rec_type) {
+ case IGMP_GRP_REC_TYPE_MODE_IS_INCLUDE:
+ igmpv3_report_isin(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
+ break;
+ case IGMP_GRP_REC_TYPE_MODE_IS_EXCLUDE:
+ igmpv3_report_isex(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources, 0);
+ break;
+ case IGMP_GRP_REC_TYPE_CHANGE_TO_INCLUDE_MODE:
+ igmpv3_report_toin(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
+ break;
+ case IGMP_GRP_REC_TYPE_CHANGE_TO_EXCLUDE_MODE:
+ igmpv3_report_toex(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
+ break;
+ case IGMP_GRP_REC_TYPE_ALLOW_NEW_SOURCES:
+ igmpv3_report_allow(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
+ break;
+ case IGMP_GRP_REC_TYPE_BLOCK_OLD_SOURCES:
+ igmpv3_report_block(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
+ break;
+ default:
+ zlog_warn("Recv IGMP report v3 from %s on %s: unknown record type: type=%d",
+ from_str, ifp->name, rec_type);
+ }
+
+ group_record += 8 + (rec_num_sources << 2) + (rec_auxdatalen << 2);
+ local_ncb = 0;
+
+ } /* for (group records) */
+
+ return 0;
}
diff --git a/pimd/pim_igmpv3.h b/pimd/pim_igmpv3.h
index db7895f9be..3a4a81d97e 100644
--- a/pimd/pim_igmpv3.h
+++ b/pimd/pim_igmpv3.h
@@ -30,6 +30,13 @@
#define IGMP_V3_NUMSOURCES_OFFSET (10)
#define IGMP_V3_SOURCES_OFFSET (12)
+#define IGMP_GRP_REC_TYPE_MODE_IS_INCLUDE (1)
+#define IGMP_GRP_REC_TYPE_MODE_IS_EXCLUDE (2)
+#define IGMP_GRP_REC_TYPE_CHANGE_TO_INCLUDE_MODE (3)
+#define IGMP_GRP_REC_TYPE_CHANGE_TO_EXCLUDE_MODE (4)
+#define IGMP_GRP_REC_TYPE_ALLOW_NEW_SOURCES (5)
+#define IGMP_GRP_REC_TYPE_BLOCK_OLD_SOURCES (6)
+
/* GMI: Group Membership Interval */
#define PIM_IGMP_GMI_MSEC(qrv,qqi,qri_dsec) ((qrv) * (1000 * (qqi)) + 100 * (qri_dsec))
@@ -54,15 +61,13 @@ void igmp_source_free(struct igmp_source *source);
void igmp_source_delete(struct igmp_source *source);
void igmp_source_delete_expired(struct list *source_list);
-int igmp_group_compat_mode(const struct igmp_sock *igmp,
- const struct igmp_group *group);
-
void igmpv3_report_isin(struct igmp_sock *igmp, struct in_addr from,
struct in_addr group_addr,
int num_sources, struct in_addr *sources);
void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from,
struct in_addr group_addr,
- int num_sources, struct in_addr *sources);
+ int num_sources, struct in_addr *sources,
+ int from_igmp_v2_report);
void igmpv3_report_toin(struct igmp_sock *igmp, struct in_addr from,
struct in_addr group_addr,
int num_sources, struct in_addr *sources);
@@ -82,17 +87,24 @@ void igmp_source_timer_lower_to_lmqt(struct igmp_source *source);
struct igmp_source *igmp_find_source_by_addr(struct igmp_group *group,
struct in_addr src_addr);
-void pim_igmp_send_membership_query(struct igmp_group *group,
- int fd,
- const char *ifname,
- char *query_buf,
- int query_buf_size,
- int num_sources,
- struct in_addr dst_addr,
- struct in_addr group_addr,
- int query_max_response_time_dsec,
- uint8_t s_flag,
- uint8_t querier_robustness_variable,
- uint16_t querier_query_interval);
+void igmp_v3_send_query (struct igmp_group *group,
+ int fd,
+ const char *ifname,
+ char *query_buf,
+ int query_buf_size,
+ int num_sources,
+ struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec,
+ uint8_t s_flag,
+ uint8_t querier_robustness_variable,
+ uint16_t querier_query_interval);
+
+void igmp_v3_recv_query (struct igmp_sock *igmp, const char *from_str,
+ char *igmp_msg);
+
+int igmp_v3_recv_report (struct igmp_sock *igmp,
+ struct in_addr from, const char *from_str,
+ char *igmp_msg, int igmp_msg_len);
#endif /* PIM_IGMPV3_H */
diff --git a/pimd/pim_join.c b/pimd/pim_join.c
index 6a5fb851d6..028f77f532 100644
--- a/pimd/pim_join.c
+++ b/pimd/pim_join.c
@@ -23,6 +23,8 @@
#include "log.h"
#include "prefix.h"
#include "if.h"
+#include "vty.h"
+#include "plist.h"
#include "pimd.h"
#include "pim_str.h"
@@ -30,15 +32,19 @@
#include "pim_msg.h"
#include "pim_pim.h"
#include "pim_join.h"
+#include "pim_oil.h"
#include "pim_iface.h"
#include "pim_hello.h"
#include "pim_ifchannel.h"
+#include "pim_rpf.h"
+#include "pim_rp.h"
-static void on_trace(const char *label,
- struct interface *ifp, struct in_addr src)
+static void
+on_trace (const char *label,
+ struct interface *ifp, struct in_addr src)
{
if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
zlog_debug("%s: from %s on %s",
label, src_str, ifp->name);
@@ -49,58 +55,81 @@ static void recv_join(struct interface *ifp,
struct pim_neighbor *neigh,
uint16_t holdtime,
struct in_addr upstream,
- struct in_addr group,
- struct in_addr source,
+ struct prefix_sg *sg,
uint8_t source_flags)
{
if (PIM_DEBUG_PIM_TRACE) {
- char up_str[100];
- char src_str[100];
- char grp_str[100];
- char neigh_str[100];
+ char up_str[INET_ADDRSTRLEN];
+ char neigh_str[INET_ADDRSTRLEN];
pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
- pim_inet4_dump("<src?>", source, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", group, grp_str, sizeof(grp_str));
pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, sizeof(neigh_str));
- zlog_warn("%s: join (S,G)=(%s,%s) rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
+ zlog_warn("%s: join (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
__PRETTY_FUNCTION__,
- src_str, grp_str,
+ pim_str_sg_dump (sg),
source_flags & PIM_RPT_BIT_MASK,
source_flags & PIM_WILDCARD_BIT_MASK,
up_str, holdtime, neigh_str, ifp->name);
}
-
+
+ /*
+ * If the RPT and WC are set it's a (*,G)
+ * and the source is the RP
+ */
+ if ((source_flags & PIM_RPT_BIT_MASK) &&
+ (source_flags & PIM_WILDCARD_BIT_MASK))
+ {
+ struct pim_rpf *rp = RP (sg->grp);
+
+ /*
+ * If the RP sent in the message is not
+ * our RP for the group, drop the message
+ */
+ if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
+ return;
+
+ sg->src.s_addr = INADDR_ANY;
+ }
+
/* Restart join expiry timer */
pim_ifchannel_join_add(ifp, neigh->source_addr, upstream,
- source, group, source_flags, holdtime);
+ sg, source_flags, holdtime);
+
}
static void recv_prune(struct interface *ifp,
struct pim_neighbor *neigh,
uint16_t holdtime,
struct in_addr upstream,
- struct in_addr group,
- struct in_addr source,
+ struct prefix_sg *sg,
uint8_t source_flags)
{
if (PIM_DEBUG_PIM_TRACE) {
- char up_str[100];
- char src_str[100];
- char grp_str[100];
- char neigh_str[100];
+ char up_str[INET_ADDRSTRLEN];
+ char neigh_str[INET_ADDRSTRLEN];
pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
- pim_inet4_dump("<src?>", source, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", group, grp_str, sizeof(grp_str));
pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, sizeof(neigh_str));
- zlog_warn("%s: prune (S,G)=(%s,%s) rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
+ zlog_warn("%s: prune (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
__PRETTY_FUNCTION__,
- src_str, grp_str,
+ pim_str_sg_dump (sg),
source_flags & PIM_RPT_BIT_MASK,
source_flags & PIM_WILDCARD_BIT_MASK,
up_str, holdtime, neigh_str, ifp->name);
}
-
- pim_ifchannel_prune(ifp, upstream, source, group, source_flags, holdtime);
+
+ if ((source_flags & PIM_RPT_BIT_MASK) &&
+ (source_flags & PIM_WILDCARD_BIT_MASK))
+ {
+ struct pim_rpf *rp = RP (sg->grp);
+
+ // Ignoring Prune *,G's at the moment.
+ if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
+ return;
+
+ sg->src.s_addr = INADDR_ANY;
+ }
+
+ pim_ifchannel_prune(ifp, upstream, sg, source_flags, holdtime);
+
}
int pim_joinprune_recv(struct interface *ifp,
@@ -117,8 +146,6 @@ int pim_joinprune_recv(struct interface *ifp,
int remain;
int group;
- on_trace(__PRETTY_FUNCTION__, ifp, src_addr);
-
buf = tlv_buf;
pastend = tlv_buf + tlv_buf_size;
@@ -128,7 +155,7 @@ int pim_joinprune_recv(struct interface *ifp,
addr_offset = pim_parse_addr_ucast (&msg_upstream_addr,
buf, pastend - buf);
if (addr_offset < 1) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
__PRETTY_FUNCTION__,
@@ -141,8 +168,8 @@ int pim_joinprune_recv(struct interface *ifp,
Check upstream address family
*/
if (msg_upstream_addr.family != AF_INET) {
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
+ if (PIM_DEBUG_PIM_J_P) {
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: ignoring join/prune directed to unexpected addr family=%d from %s on %s",
__PRETTY_FUNCTION__,
@@ -153,7 +180,7 @@ int pim_joinprune_recv(struct interface *ifp,
remain = pastend - buf;
if (remain < 4) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: short join/prune message buffer for group list: size=%d minimum=%d from %s on %s",
__PRETTY_FUNCTION__,
@@ -168,28 +195,29 @@ int pim_joinprune_recv(struct interface *ifp,
++buf;
++buf;
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
- char upstream_str[100];
+ if (PIM_DEBUG_PIM_J_P) {
+ char src_str[INET_ADDRSTRLEN];
+ char upstream_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
upstream_str, sizeof(upstream_str));
- zlog_warn("%s: join/prune upstream=%s groups=%d holdtime=%d from %s on %s",
- __PRETTY_FUNCTION__,
- upstream_str, msg_num_groups, msg_holdtime,
- src_str, ifp->name);
+ zlog_debug ("%s: join/prune upstream=%s groups=%d holdtime=%d from %s on %s",
+ __PRETTY_FUNCTION__,
+ upstream_str, msg_num_groups, msg_holdtime,
+ src_str, ifp->name);
}
/* Scan groups */
for (group = 0; group < msg_num_groups; ++group) {
- struct prefix msg_group_addr;
- struct prefix msg_source_addr;
+ struct prefix_sg sg;
uint8_t msg_source_flags;
uint16_t msg_num_joined_sources;
uint16_t msg_num_pruned_sources;
int source;
+ struct pim_ifchannel *ch = NULL;
- addr_offset = pim_parse_addr_group (&msg_group_addr,
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ addr_offset = pim_parse_addr_group (&sg,
buf, pastend - buf);
if (addr_offset < 1) {
return -5;
@@ -198,7 +226,7 @@ int pim_joinprune_recv(struct interface *ifp,
remain = pastend - buf;
if (remain < 4) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: short join/prune buffer for source list: size=%d minimum=%d from %s on %s",
__PRETTY_FUNCTION__,
@@ -211,25 +239,25 @@ int pim_joinprune_recv(struct interface *ifp,
msg_num_pruned_sources = ntohs(*(const uint16_t *) buf);
buf += 2;
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
- char upstream_str[100];
- char group_str[100];
+ if (PIM_DEBUG_PIM_J_P) {
+ char src_str[INET_ADDRSTRLEN];
+ char upstream_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
upstream_str, sizeof(upstream_str));
- pim_inet4_dump("<grp?>", msg_group_addr.u.prefix4,
+ pim_inet4_dump("<grp?>", sg.grp,
group_str, sizeof(group_str));
- zlog_warn("%s: join/prune upstream=%s group=%s/%d join_src=%d prune_src=%d from %s on %s",
+ zlog_warn("%s: join/prune upstream=%s group=%s/32 join_src=%d prune_src=%d from %s on %s",
__PRETTY_FUNCTION__,
- upstream_str, group_str, msg_group_addr.prefixlen,
+ upstream_str, group_str,
msg_num_joined_sources, msg_num_pruned_sources,
src_str, ifp->name);
}
/* Scan joined sources */
for (source = 0; source < msg_num_joined_sources; ++source) {
- addr_offset = pim_parse_addr_source (&msg_source_addr,
+ addr_offset = pim_parse_addr_source (&sg,
&msg_source_flags,
buf, pastend - buf);
if (addr_offset < 1) {
@@ -240,14 +268,20 @@ int pim_joinprune_recv(struct interface *ifp,
recv_join(ifp, neigh, msg_holdtime,
msg_upstream_addr.u.prefix4,
- msg_group_addr.u.prefix4,
- msg_source_addr.u.prefix4,
+ &sg,
msg_source_flags);
+
+ if (sg.src.s_addr == INADDR_ANY)
+ {
+ ch = pim_ifchannel_find (ifp, &sg);
+ if (ch)
+ pim_ifchannel_set_star_g_join_state (ch, 0);
+ }
}
/* Scan pruned sources */
for (source = 0; source < msg_num_pruned_sources; ++source) {
- addr_offset = pim_parse_addr_source (&msg_source_addr,
+ addr_offset = pim_parse_addr_source (&sg,
&msg_source_flags,
buf, pastend - buf);
if (addr_offset < 1) {
@@ -258,11 +292,12 @@ int pim_joinprune_recv(struct interface *ifp,
recv_prune(ifp, neigh, msg_holdtime,
msg_upstream_addr.u.prefix4,
- msg_group_addr.u.prefix4,
- msg_source_addr.u.prefix4,
+ &sg,
msg_source_flags);
}
-
+ if (ch)
+ pim_ifchannel_set_star_g_join_state (ch, 1);
+ ch = NULL;
} /* scan groups */
return 0;
@@ -270,16 +305,14 @@ int pim_joinprune_recv(struct interface *ifp,
int pim_joinprune_send(struct interface *ifp,
struct in_addr upstream_addr,
- struct in_addr source_addr,
- struct in_addr group_addr,
+ struct pim_upstream *up,
int send_join)
{
struct pim_interface *pim_ifp;
- uint8_t pim_msg[1000];
- const uint8_t *pastend = pim_msg + sizeof(pim_msg);
- uint8_t *pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN; /* room for pim header */
+ uint8_t pim_msg[9000];
int pim_msg_size;
- int remain;
+
+ on_trace (__PRETTY_FUNCTION__, ifp, upstream_addr);
zassert(ifp);
@@ -292,31 +325,23 @@ int pim_joinprune_send(struct interface *ifp,
return -1;
}
- if (PIM_DEBUG_PIM_TRACE) {
- char source_str[100];
- char group_str[100];
- char dst_str[100];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
+ if (PIM_DEBUG_PIM_J_P) {
+ char dst_str[INET_ADDRSTRLEN];
pim_inet4_dump("<dst?>", upstream_addr, dst_str, sizeof(dst_str));
- zlog_debug("%s: sending %s(S,G)=(%s,%s) to upstream=%s on interface %s",
+ zlog_debug("%s: sending %s(S,G)=%s to upstream=%s on interface %s",
__PRETTY_FUNCTION__,
send_join ? "Join" : "Prune",
- source_str, group_str, dst_str, ifp->name);
+ up->sg_str, dst_str, ifp->name);
}
if (PIM_INADDR_IS_ANY(upstream_addr)) {
- if (PIM_DEBUG_PIM_TRACE) {
- char source_str[100];
- char group_str[100];
- char dst_str[100];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
+ if (PIM_DEBUG_PIM_J_P) {
+ char dst_str[INET_ADDRSTRLEN];
pim_inet4_dump("<dst?>", upstream_addr, dst_str, sizeof(dst_str));
- zlog_debug("%s: %s(S,G)=(%s,%s): upstream=%s is myself on interface %s",
+ zlog_debug("%s: %s(S,G)=%s: upstream=%s is myself on interface %s",
__PRETTY_FUNCTION__,
send_join ? "Join" : "Prune",
- source_str, group_str, dst_str, ifp->name);
+ up->sg_str, dst_str, ifp->name);
}
return 0;
}
@@ -335,83 +360,14 @@ int pim_joinprune_send(struct interface *ifp,
/*
Build PIM message
*/
+ pim_msg_size = pim_msg_join_prune_encode (pim_msg, 9000, send_join,
+ up, upstream_addr, PIM_JP_HOLDTIME);
- remain = pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
- remain,
- upstream_addr);
- if (!pim_msg_curr) {
- char dst_str[100];
- pim_inet4_dump("<dst?>", upstream_addr, dst_str, sizeof(dst_str));
- zlog_warn("%s: failure encoding destination address %s: space left=%d",
- __PRETTY_FUNCTION__, dst_str, remain);
- return -3;
- }
-
- remain = pastend - pim_msg_curr;
- if (remain < 4) {
- zlog_warn("%s: group will not fit: space left=%d",
- __PRETTY_FUNCTION__, remain);
- return -4;
- }
-
- *pim_msg_curr = 0; /* reserved */
- ++pim_msg_curr;
- *pim_msg_curr = 1; /* number of groups */
- ++pim_msg_curr;
- *((uint16_t *) pim_msg_curr) = htons(PIM_JP_HOLDTIME);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- remain = pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
- remain,
- group_addr);
- if (!pim_msg_curr) {
- char group_str[100];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- zlog_warn("%s: failure encoding group address %s: space left=%d",
- __PRETTY_FUNCTION__, group_str, remain);
- return -5;
- }
-
- remain = pastend - pim_msg_curr;
- if (remain < 4) {
- zlog_warn("%s: sources will not fit: space left=%d",
- __PRETTY_FUNCTION__, remain);
- return -6;
- }
-
- /* number of joined sources */
- *((uint16_t *) pim_msg_curr) = htons(send_join ? 1 : 0);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- /* number of pruned sources */
- *((uint16_t *) pim_msg_curr) = htons(send_join ? 0 : 1);
- ++pim_msg_curr;
- ++pim_msg_curr;
-
- remain = pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
- remain,
- source_addr);
- if (!pim_msg_curr) {
- char source_str[100];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: failure encoding source address %s: space left=%d",
- __PRETTY_FUNCTION__, source_str, remain);
- return -7;
- }
-
- /* Add PIM header */
-
- pim_msg_size = pim_msg_curr - pim_msg;
-
- pim_msg_build_header(pim_msg, pim_msg_size,
- PIM_MSG_TYPE_JOIN_PRUNE);
+ if (pim_msg_size < 0)
+ return pim_msg_size;
if (pim_msg_send(pim_ifp->pim_sock_fd,
+ pim_ifp->primary_address,
qpim_all_pim_routers_addr,
pim_msg,
pim_msg_size,
diff --git a/pimd/pim_join.h b/pimd/pim_join.h
index dcdca00359..1eeeef756f 100644
--- a/pimd/pim_join.h
+++ b/pimd/pim_join.h
@@ -34,8 +34,7 @@ int pim_joinprune_recv(struct interface *ifp,
int pim_joinprune_send(struct interface *ifp,
struct in_addr upstream_addr,
- struct in_addr source_addr,
- struct in_addr group_addr,
+ struct pim_upstream *up,
int send_join);
#endif /* PIM_JOIN_H */
diff --git a/pimd/pim_macro.c b/pimd/pim_macro.c
index 622bef4439..127e0f6252 100644
--- a/pimd/pim_macro.c
+++ b/pimd/pim_macro.c
@@ -21,22 +21,39 @@
#include <zebra.h>
#include "log.h"
+#include "prefix.h"
+#include "vty.h"
+#include "plist.h"
-#include "pim_macro.h"
#include "pimd.h"
-#include "pim_str.h"
+#include "pim_macro.h"
#include "pim_iface.h"
#include "pim_ifchannel.h"
+#include "pim_rp.h"
/*
DownstreamJPState(S,G,I) is the per-interface state machine for
receiving (S,G) Join/Prune messages.
- DownstreamJPState(S,G,I) is either Join or Prune-Pending ?
+ DownstreamJPState(S,G,I) is either Join or Prune-Pending
+ DownstreamJPState(*,G,I) is either Join or Prune-Pending
*/
static int downstream_jpstate_isjoined(const struct pim_ifchannel *ch)
{
- return ch->ifjoin_state != PIM_IFJOIN_NOINFO;
+ switch (ch->ifjoin_state)
+ {
+ case PIM_IFJOIN_NOINFO:
+ case PIM_IFJOIN_PRUNE:
+ case PIM_IFJOIN_PRUNE_TMP:
+ case PIM_IFJOIN_PRUNE_PENDING_TMP:
+ return 0;
+ break;
+ case PIM_IFJOIN_JOIN:
+ case PIM_IFJOIN_PRUNE_PENDING:
+ return 1;
+ break;
+ }
+ return 0;
}
/*
@@ -100,13 +117,9 @@ int pim_macro_ch_lost_assert(const struct pim_ifchannel *ch)
ifp = ch->interface;
if (!ifp) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: (S,G)=(%s,%s): null interface",
+ zlog_warn("%s: (S,G)=%s: null interface",
__PRETTY_FUNCTION__,
- src_str, grp_str);
+ ch->sg_str);
return 0; /* false */
}
@@ -116,13 +129,9 @@ int pim_macro_ch_lost_assert(const struct pim_ifchannel *ch)
pim_ifp = ifp->info;
if (!pim_ifp) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: (S,G)=(%s,%s): multicast not enabled on interface %s",
+ zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ ch->sg_str, ifp->name);
return 0; /* false */
}
@@ -157,13 +166,9 @@ int pim_macro_chisin_pim_include(const struct pim_ifchannel *ch)
struct pim_interface *pim_ifp = ch->interface->info;
if (!pim_ifp) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: (S,G)=(%s,%s): multicast not enabled on interface %s",
+ zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ch->interface->name);
+ ch->sg_str, ch->interface->name);
return 0; /* false */
}
@@ -225,13 +230,8 @@ int pim_macro_ch_could_assert_eval(const struct pim_ifchannel *ch)
ifp = ch->interface;
if (!ifp) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: (S,G)=(%s,%s): null interface",
- __PRETTY_FUNCTION__,
- src_str, grp_str);
+ zlog_warn("%s: (S,G)=%s: null interface",
+ __PRETTY_FUNCTION__, ch->sg_str);
return 0; /* false */
}
@@ -350,7 +350,7 @@ static int pim_macro_chisin_inherited_olist(const struct pim_ifchannel *ch)
*/
int pim_macro_chisin_oiflist(const struct pim_ifchannel *ch)
{
- if (ch->upstream->join_state != PIM_UPSTREAM_JOINED) {
+ if (ch->upstream->join_state == PIM_UPSTREAM_NOTJOINED) {
/* oiflist is NULL */
return 0; /* false */
}
@@ -386,25 +386,15 @@ int pim_macro_assert_tracking_desired_eval(const struct pim_ifchannel *ch)
ifp = ch->interface;
if (!ifp) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: (S,G)=(%s,%s): null interface",
- __PRETTY_FUNCTION__,
- src_str, grp_str);
+ zlog_warn("%s: (S,G)=%s: null interface",
+ __PRETTY_FUNCTION__, ch->sg_str);
return 0; /* false */
}
pim_ifp = ifp->info;
if (!pim_ifp) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: (S,G)=(%s,%s): multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- src_str, grp_str, ch->interface->name);
+ zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ch->interface->name);
return 0; /* false */
}
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index e4aa2de594..2e81ac53fd 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -44,10 +44,9 @@
#include "pim_version.h"
#include "pim_signals.h"
#include "pim_zebra.h"
-
-#ifdef PIM_ZCLIENT_DEBUG
-extern int zclient_debug;
-#endif
+#include "pim_msdp.h"
+#include "pim_iface.h"
+#include "pim_rp.h"
extern struct host host;
@@ -78,6 +77,7 @@ zebra_capabilities_t _caps_p [] =
ZCAP_NET_ADMIN,
ZCAP_SYS_ADMIN,
ZCAP_NET_RAW,
+ ZCAP_BIND,
};
/* pimd privileges to run with */
@@ -113,18 +113,9 @@ Daemon which manages PIM.\n\n\
-P, --vty_port Set vty's port number\n\
--vty_socket Override vty socket path\n\
-v, --version Print program version\n\
-"
-
-#ifdef PIM_ZCLIENT_DEBUG
-"\
--Z, --debug_zclient Enable zclient debugging\n\
-"
-#endif
-
-"\
-h, --help Display this help and exit\n\
\n\
-Report bugs to %s\n", progname, PIMD_BUG_ADDRESS);
+Report bugs to %s\n", progname, PACKAGE_BUGREPORT);
}
exit (status);
@@ -189,11 +180,6 @@ int main(int argc, char** argv, char** envp) {
print_version(progname);
exit (0);
break;
-#ifdef PIM_ZCLIENT_DEBUG
- case 'Z':
- zclient_debug = 1;
- break;
-#endif
case 'h':
usage (0);
break;
@@ -218,8 +204,12 @@ int main(int argc, char** argv, char** envp) {
vrf_init ();
access_list_init();
prefix_list_init ();
+ prefix_list_add_hook (pim_rp_prefix_list_update);
+ prefix_list_delete_hook (pim_rp_prefix_list_update);
+
pim_route_map_init ();
pim_init();
+ pim_msdp_init (master);
/*
* Initialize zclient "update" and "lookup" sockets
@@ -266,11 +256,6 @@ int main(int argc, char** argv, char** envp) {
PIM_DO_DEBUG_ZEBRA;
#endif
-#ifdef PIM_ZCLIENT_DEBUG
- zlog_notice("PIM_ZCLIENT_DEBUG: zclient debugging is supported, mode is %s (see option -Z)",
- zclient_debug ? "ON" : "OFF");
-#endif
-
#ifdef PIM_CHECK_RECV_IFINDEX_SANITY
zlog_notice("PIM_CHECK_RECV_IFINDEX_SANITY: will match sock/recv ifindex");
#ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH
@@ -282,12 +267,6 @@ int main(int argc, char** argv, char** envp) {
zlog_notice("PIM_UNEXPECTED_KERNEL_UPCALL: report unexpected kernel upcall");
#endif
-#ifdef HAVE_CLOCK_MONOTONIC
- zlog_notice("HAVE_CLOCK_MONOTONIC");
-#else
- zlog_notice("!HAVE_CLOCK_MONOTONIC");
-#endif
-
while (thread_fetch(master, &thread))
thread_call(&thread);
diff --git a/pimd/pim_memory.c b/pimd/pim_memory.c
index 6014725020..ccd0fa81ac 100644
--- a/pimd/pim_memory.c
+++ b/pimd/pim_memory.c
@@ -39,3 +39,11 @@ DEFINE_MTYPE(PIMD, PIM_UPSTREAM, "PIM upstream (S,G) state")
DEFINE_MTYPE(PIMD, PIM_SSMPINGD, "PIM sspimgd socket")
DEFINE_MTYPE(PIMD, PIM_STATIC_ROUTE, "PIM Static Route")
DEFINE_MTYPE(PIMD, PIM_BR, "PIM Bridge Router info")
+DEFINE_MTYPE(PIMD, PIM_RP, "PIM RP info")
+DEFINE_MTYPE(PIMD, PIM_FILTER_NAME, "PIM RP filter info")
+DEFINE_MTYPE(PIMD, PIM_MSDP_PEER, "PIM MSDP peer")
+DEFINE_MTYPE(PIMD, PIM_MSDP_MG_NAME, "PIM MSDP mesh-group name")
+DEFINE_MTYPE(PIMD, PIM_MSDP_SA, "PIM MSDP source-active cache")
+DEFINE_MTYPE(PIMD, PIM_MSDP_MG, "PIM MSDP mesh group")
+DEFINE_MTYPE(PIMD, PIM_MSDP_MG_MBR, "PIM MSDP mesh group mbr")
+DEFINE_MTYPE(PIMD, PIM_SEC_ADDR, "PIM secondary address")
diff --git a/pimd/pim_memory.h b/pimd/pim_memory.h
index 81841e58b6..b6b9b23239 100644
--- a/pimd/pim_memory.h
+++ b/pimd/pim_memory.h
@@ -38,5 +38,13 @@ DECLARE_MTYPE(PIM_UPSTREAM)
DECLARE_MTYPE(PIM_SSMPINGD)
DECLARE_MTYPE(PIM_STATIC_ROUTE)
DECLARE_MTYPE(PIM_BR)
+DECLARE_MTYPE(PIM_RP)
+DECLARE_MTYPE(PIM_FILTER_NAME)
+DECLARE_MTYPE(PIM_MSDP_PEER)
+DECLARE_MTYPE(PIM_MSDP_MG_NAME)
+DECLARE_MTYPE(PIM_MSDP_SA)
+DECLARE_MTYPE(PIM_MSDP_MG)
+DECLARE_MTYPE(PIM_MSDP_MG_MBR)
+DECLARE_MTYPE(PIM_SEC_ADDR)
#endif /* _QUAGGA_PIM_MEMORY_H */
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index 3fbed88800..b1cdaf9b95 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -23,8 +23,11 @@
#include "privs.h"
#include "if.h"
#include "prefix.h"
+#include "vty.h"
+#include "plist.h"
#include "pimd.h"
+#include "pim_rpf.h"
#include "pim_mroute.h"
#include "pim_oil.h"
#include "pim_str.h"
@@ -34,9 +37,11 @@
#include "pim_rp.h"
#include "pim_oil.h"
#include "pim_register.h"
+#include "pim_ifchannel.h"
+#include "pim_zlookup.h"
/* GLOBAL VARS */
-extern struct zebra_privs_t pimd_privs;
+static struct thread *qpim_mroute_socket_reader = NULL;
static void mroute_read_on(void);
@@ -45,62 +50,75 @@ static int pim_mroute_set(int fd, int enable)
int err;
int opt = enable ? MRT_INIT : MRT_DONE;
socklen_t opt_len = sizeof(opt);
+ int rcvbuf = 1024 * 1024 * 8;
+ long flags;
err = setsockopt(fd, IPPROTO_IP, opt, &opt, opt_len);
if (err) {
- int e = errno;
zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,%s=%d): errno=%d: %s",
__FILE__, __PRETTY_FUNCTION__,
- fd, enable ? "MRT_INIT" : "MRT_DONE", opt, e, safe_strerror(e));
- errno = e;
+ fd, enable ? "MRT_INIT" : "MRT_DONE", opt, errno, safe_strerror(errno));
return -1;
}
-#if 0
- zlog_info("%s %s: setsockopt(fd=%d,IPPROTO_IP,MRT_INIT,opt=%d): ok",
- __FILE__, __PRETTY_FUNCTION__,
- fd, opt);
-#endif
-
- return 0;
-}
-
-static int
-pim_mroute_connected_to_source (struct interface *ifp, struct in_addr src)
-{
- struct listnode *cnode;
- struct connected *c;
- struct prefix p;
-
- p.family = AF_INET;
- p.u.prefix4 = src;
- p.prefixlen = IPV4_MAX_BITLEN;
+ err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+ if (err) {
+ zlog_warn("%s: failure: setsockopt(fd=%d, SOL_SOCKET, %d): errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, rcvbuf, errno, safe_strerror(errno));
+ }
- for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
+ flags = fcntl(fd, F_GETFL, 0);
+ if (flags < 0)
+ {
+ zlog_warn("Could not get flags on socket fd:%d %d %s",
+ fd, errno, safe_strerror(errno));
+ close (fd);
+ return -1;
+ }
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
{
- if ((c->address->family == AF_INET) &&
- prefix_match (CONNECTED_PREFIX (c), &p))
- {
- return 1;
- }
+ zlog_warn("Could not set O_NONBLOCK on socket fd:%d %d %s",
+ fd, errno, safe_strerror(errno));
+ close(fd);
+ return -1;
}
+ if (enable)
+ {
+#if defined linux
+ int upcalls = IGMPMSG_WRVIFWHOLE;
+ opt = MRT_PIM;
+
+ err = setsockopt (fd, IPPROTO_IP, opt, &upcalls, sizeof (upcalls));
+ if (err)
+ {
+ zlog_warn ("Failure to register for VIFWHOLE and WRONGVIF upcalls %d %s",
+ errno, safe_strerror (errno));
+ return -1;
+ }
+#else
+ zlog_warn ("PIM-SM will not work properly on this platform, until the ability to receive the WRVIFWHOLE upcall");
+#endif
+ }
+
return 0;
}
-static const char *igmpmsgtype2str[IGMPMSG_WHOLEPKT + 1] = {
+static const char *igmpmsgtype2str[IGMPMSG_WRVIFWHOLE + 1] = {
"<unknown_upcall?>",
"NOCACHE",
"WRONGVIF",
- "WHOLEPKT", };
+ "WHOLEPKT",
+ "WRVIFWHOLE" };
static int
-pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg,
- const char *src_str, const char *grp_str)
+pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg)
{
struct pim_interface *pim_ifp = ifp->info;
struct pim_upstream *up;
struct pim_rpf *rpg;
+ struct prefix_sg sg;
+ struct channel_oil *oil;
rpg = RP(msg->im_dst);
/*
@@ -108,108 +126,132 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg
* the Interface type is SSM we don't need to
* do anything here
*/
- if ((rpg->rpf_addr.s_addr == INADDR_NONE) ||
+ if ((pim_rpf_addr_is_inaddr_none (rpg)) ||
(!pim_ifp) ||
(!(PIM_I_am_DR(pim_ifp))) ||
(pim_ifp->itype == PIM_INTERFACE_SSM))
- return 0;
+ {
+ if (PIM_DEBUG_MROUTE_DETAIL)
+ zlog_debug ("%s: Interface is not configured correctly to handle incoming packet: Could be !DR, !pim_ifp, !SM, !RP",
+ __PRETTY_FUNCTION__);
+ return 0;
+ }
/*
* If we've received a multicast packet that isn't connected to
* us
*/
- if (!pim_mroute_connected_to_source (ifp, msg->im_src))
+ if (!pim_if_connected_to_source (ifp, msg->im_src))
{
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("%s: Received incoming packet that does originate on our seg",
+ if (PIM_DEBUG_MROUTE_DETAIL)
+ zlog_debug ("%s: Received incoming packet that doesn't originate on our seg",
__PRETTY_FUNCTION__);
return 0;
}
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: Adding a Route for %s from %s for WHOLEPKT consumption",
- __PRETTY_FUNCTION__, grp_str, src_str);
- }
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = msg->im_src;
+ sg.grp = msg->im_dst;
- up = pim_upstream_add(msg->im_src, msg->im_dst, ifp);
- if (!up) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: Failure to add upstream information for (%s,%s)",
+ oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index);
+ if (!oil) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: Failure to add channel oil for %s",
__PRETTY_FUNCTION__,
- src_str, grp_str);
+ pim_str_sg_dump (&sg));
}
return 0;
}
- pim_upstream_keep_alive_timer_start (up, PIM_KEEPALIVE_PERIOD);
-
- up->channel_oil = pim_channel_oil_add(msg->im_dst,
- msg->im_src,
- pim_ifp->mroute_vif_index);
- if (!up->channel_oil) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: Failure to add channel oil for (%s,%s)",
+ up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__);
+ if (!up) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: Failure to add upstream information for %s",
__PRETTY_FUNCTION__,
- src_str, grp_str);
+ pim_str_sg_dump (&sg));
}
return 0;
}
- up->channel_oil->cc.pktcnt++;
- pim_channel_add_oif(up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_SOURCE);
+ /*
+ * I moved this debug till after the actual add because
+ * I want to take advantage of the up->sg_str being filled in.
+ */
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: Adding a Route %s for WHOLEPKT consumption",
+ __PRETTY_FUNCTION__, up->sg_str);
+ }
+
+ PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
+ pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
+
+ up->channel_oil = oil;
+ up->channel_oil->cc.pktcnt++;
+ PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
+ pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+ up->join_state = PIM_UPSTREAM_JOINED;
return 0;
}
static int
-pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const char *buf,
- const char *src_str, const char *grp_str)
+pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const char *buf)
{
struct pim_interface *pim_ifp;
- struct in_addr group;
- struct in_addr src;
+ struct prefix_sg sg;
struct pim_rpf *rpg;
const struct ip *ip_hdr;
struct pim_upstream *up;
ip_hdr = (const struct ip *)buf;
- src = ip_hdr->ip_src;
- group = ip_hdr->ip_dst;
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = ip_hdr->ip_src;
+ sg.grp = ip_hdr->ip_dst;
- up = pim_upstream_find(src, group);
+ up = pim_upstream_find(&sg);
if (!up) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: Unable to find upstream channel WHOLEPKT(%s,%s)",
- __PRETTY_FUNCTION__, src_str, grp_str);
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ zlog_debug("%s: Unable to find upstream channel WHOLEPKT%s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
}
return 0;
}
pim_ifp = up->rpf.source_nexthop.interface->info;
- rpg = RP(group);
+ rpg = RP(sg.grp);
- if ((rpg->rpf_addr.s_addr == INADDR_NONE) ||
+ if ((pim_rpf_addr_is_inaddr_none (rpg)) ||
(!pim_ifp) ||
(!(PIM_I_am_DR(pim_ifp))) ||
(pim_ifp->itype == PIM_INTERFACE_SSM)) {
- if (PIM_DEBUG_PIM_TRACE) {
+ if (PIM_DEBUG_MROUTE) {
zlog_debug("%s: Failed Check send packet", __PRETTY_FUNCTION__);
}
return 0;
}
- pim_register_send((const struct ip *)(buf + sizeof(struct ip)), rpg);
+ /*
+ * If we've received a register suppress
+ */
+ if (!up->t_rs_timer)
+ pim_register_send((uint8_t *)buf + sizeof(struct ip),
+ ntohs (ip_hdr->ip_len) - sizeof (struct ip),
+ pim_ifp->primary_address, rpg, 0, up);
return 0;
}
static int
-pim_mroute_msg_wrongvif (int fd, struct interface *ifp, const struct igmpmsg *msg,
- const char *src_str, const char *grp_str)
+pim_mroute_msg_wrongvif (int fd, struct interface *ifp, const struct igmpmsg *msg)
{
struct pim_ifchannel *ch;
struct pim_interface *pim_ifp;
+ struct prefix_sg sg;
+
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = msg->im_src;
+ sg.grp = msg->im_dst;
/*
Send Assert(S,G) on iif as response to WRONGVIF kernel upcall.
@@ -223,32 +265,39 @@ pim_mroute_msg_wrongvif (int fd, struct interface *ifp, const struct igmpmsg *ms
*/
if (!ifp) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) could not find input interface for input_vif_index=%d",
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug("%s: WRONGVIF (S,G)=%s could not find input interface for input_vif_index=%d",
__PRETTY_FUNCTION__,
- src_str, grp_str, msg->im_vif);
- }
+ pim_str_sg_dump (&sg), msg->im_vif);
return -1;
}
pim_ifp = ifp->info;
if (!pim_ifp) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) multicast not enabled on interface %s",
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug("%s: WRONGVIF (S,G)=%s multicast not enabled on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
- }
+ pim_str_sg_dump (&sg), ifp->name);
return -2;
}
- ch = pim_ifchannel_find(ifp, msg->im_src, msg->im_dst);
+ ch = pim_ifchannel_find(ifp, &sg);
if (!ch) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) could not find channel on interface %s",
+ struct prefix_sg star_g = sg;
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug("%s: WRONGVIF (S,G)=%s could not find channel on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ pim_str_sg_dump(&sg), ifp->name);
+
+ star_g.src.s_addr = INADDR_ANY;
+ ch = pim_ifchannel_find(ifp, &star_g);
+ if (!ch) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug("%s: WRONGVIF (*,G)=%s could not find channel on interface %s",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&star_g), ifp->name);
+ return -3;
}
- return -3;
}
/*
@@ -266,28 +315,28 @@ pim_mroute_msg_wrongvif (int fd, struct interface *ifp, const struct igmpmsg *ms
*/
if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) channel is not on Assert NoInfo state for interface %s",
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: WRONGVIF (S,G)=%s channel is not on Assert NoInfo state for interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ ch->sg_str, ifp->name);
}
return -4;
}
if (!PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) interface %s is not downstream for channel",
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: WRONGVIF (S,G)=%s interface %s is not downstream for channel",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ ch->sg_str, ifp->name);
}
return -5;
}
if (assert_action_a1(ch)) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) assert_action_a1 failure on interface %s",
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: WRONGVIF (S,G)=%s assert_action_a1 failure on interface %s",
__PRETTY_FUNCTION__,
- src_str, grp_str, ifp->name);
+ ch->sg_str, ifp->name);
}
return -6;
}
@@ -295,107 +344,250 @@ pim_mroute_msg_wrongvif (int fd, struct interface *ifp, const struct igmpmsg *ms
return 0;
}
+static int
+pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
+{
+ const struct ip *ip_hdr = (const struct ip *)buf;
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct pim_upstream *up;
+ //struct prefix_sg star_g;
+ struct prefix_sg sg;
+ struct channel_oil *oil;
+
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = ip_hdr->ip_src;
+ sg.grp = ip_hdr->ip_dst;
+
+ ch = pim_ifchannel_find(ifp, &sg);
+ if (ch)
+ {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug ("WRVIFWHOLE (S,G)=%s found ifchannel on interface %s",
+ ch->sg_str, ifp->name);
+ return -1;
+ }
+#if 0
+ star_g = sg;
+ star_g.src.s_addr = INADDR_ANY;
+ ch = pim_ifchannel_find(ifp, &star_g);
+ if (ch)
+ {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug ("WRVIFWHOLE (*,G)=%s found ifchannel on interface %s",
+ pim_str_sg_dump (&star_g), ifp->name);
+ return -1;
+ }
+#endif
+
+ up = pim_upstream_find (&sg);
+ if (up)
+ {
+ struct pim_nexthop source;
+ struct pim_rpf *rpf = RP (sg.grp);
+ if (!rpf || !rpf->source_nexthop.interface)
+ return 0;
+
+ pim_ifp = rpf->source_nexthop.interface->info;
+
+ memset (&source, 0, sizeof (source));
+ /*
+ * If we are the fhr that means we are getting a callback during
+ * the pimreg period, so I believe we can ignore this packet
+ */
+ if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
+ {
+ //No if channel, but upstream we are at the RP.
+ if (pim_nexthop_lookup (&source, up->upstream_register, 0) == 0)
+ pim_register_stop_send(source.interface, &sg, pim_ifp->primary_address, up->upstream_register);
+ if (!up->channel_oil)
+ up->channel_oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index);
+ pim_upstream_inherited_olist (up);
+ if (!up->channel_oil->installed)
+ pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__);
+ pim_upstream_set_sptbit (up, ifp);
+ }
+ else
+ {
+ if (I_am_RP (up->sg.grp))
+ {
+ if (pim_nexthop_lookup (&source, up->upstream_register, 0) == 0)
+ pim_register_stop_send(source.interface, &sg, pim_ifp->primary_address, up->upstream_register);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ }
+ pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
+ pim_upstream_inherited_olist (up);
+ pim_mroute_msg_wholepkt (fd, ifp, buf);
+ }
+ return 0;
+ }
+
+ pim_ifp = ifp->info;
+ oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index);
+ if (!oil->installed)
+ pim_mroute_add (oil, __PRETTY_FUNCTION__);
+ if (pim_if_connected_to_source (ifp, sg.src))
+ {
+ up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__);
+ if (!up)
+ {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug ("%s: WRONGVIF%s unable to create upstream on interface",
+ pim_str_sg_dump (&sg), ifp->name);
+ return -2;
+ }
+ PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
+ pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
+ up->channel_oil = oil;
+ up->channel_oil->cc.pktcnt++;
+ pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+ up->join_state = PIM_UPSTREAM_JOINED;
+ pim_upstream_inherited_olist (up);
+
+ // Send the packet to the RP
+ pim_mroute_msg_wholepkt (fd, ifp, buf);
+ }
+
+ return 0;
+}
+
int pim_mroute_msg(int fd, const char *buf, int buf_size)
{
struct interface *ifp;
+ struct pim_interface *pim_ifp;
const struct ip *ip_hdr;
const struct igmpmsg *msg;
- char src_str[100] = "<src?>";
- char grp_str[100] = "<grp?>";
+ char ip_src_str[INET_ADDRSTRLEN] = "";
+ char ip_dst_str[INET_ADDRSTRLEN] = "";
+ char src_str[INET_ADDRSTRLEN] = "<src?>";
+ char grp_str[INET_ADDRSTRLEN] = "<grp?>";
+ struct in_addr ifaddr;
+ struct igmp_sock *igmp;
ip_hdr = (const struct ip *) buf;
- /* kernel upcall must have protocol=0 */
- if (ip_hdr->ip_p) {
- /* this is not a kernel upcall */
- if (PIM_DEBUG_PIM_TRACE) {
- pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ip_hdr->ip_dst, grp_str, sizeof(grp_str));
- zlog_debug("%s: not a kernel upcall proto=%d src: %s dst: %s msg_size=%d",
- __PRETTY_FUNCTION__, ip_hdr->ip_p, src_str, grp_str, buf_size);
+ if (ip_hdr->ip_p == IPPROTO_IGMP) {
+
+ /* We have the IP packet but we do not know which interface this packet was
+ * received on. Find the interface that is on the same subnet as the source
+ * of the IP packet.
+ */
+ ifp = pim_if_lookup_address_vrf (ip_hdr->ip_src, VRF_DEFAULT);
+
+ if (!ifp) {
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, ip_src_str, sizeof(ip_src_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst, ip_dst_str, sizeof(ip_dst_str));
+
+ zlog_warn("%s: igmp kernel upcall could not find usable interface for %s -> %s",
+ __PRETTY_FUNCTION__,
+ ip_src_str,
+ ip_dst_str);
+ }
+ return 0;
}
- return 0;
- }
+ pim_ifp = ifp->info;
+ ifaddr = pim_find_primary_addr(ifp);
+ igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list, ifaddr);
- msg = (const struct igmpmsg *) buf;
-
- ifp = pim_if_find_by_vif_index(msg->im_vif);
-
- if (PIM_DEBUG_PIM_TRACE) {
- pim_inet4_dump("<src?>", msg->im_src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", msg->im_dst, grp_str, sizeof(grp_str));
- zlog_warn("%s: kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d",
- __PRETTY_FUNCTION__,
- igmpmsgtype2str[msg->im_msgtype],
- msg->im_msgtype,
- ip_hdr->ip_p,
- fd,
- src_str,
- grp_str,
- ifp ? ifp->name : "<ifname?>",
- msg->im_vif);
- }
+ if (PIM_DEBUG_MROUTE) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, ip_src_str, sizeof(ip_src_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst, ip_dst_str, sizeof(ip_dst_str));
- switch (msg->im_msgtype) {
- case IGMPMSG_WRONGVIF:
- return pim_mroute_msg_wrongvif(fd, ifp, msg, src_str, grp_str);
- break;
- case IGMPMSG_NOCACHE:
- return pim_mroute_msg_nocache(fd, ifp, msg, src_str, grp_str);
- break;
- case IGMPMSG_WHOLEPKT:
- return pim_mroute_msg_wholepkt(fd, ifp, (const char *)msg, src_str, grp_str);
- break;
- default:
- break;
- }
+ zlog_warn("%s: igmp kernel upcall on %s(%p) for %s -> %s",
+ __PRETTY_FUNCTION__, ifp->name, igmp, ip_src_str, ip_dst_str);
+ }
+ if (igmp)
+ pim_igmp_packet(igmp, (char *)buf, buf_size);
- return 0;
-}
+ } else if (ip_hdr->ip_p) {
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", ip_hdr->ip_dst, grp_str, sizeof(grp_str));
+ zlog_debug("%s: no kernel upcall proto=%d src: %s dst: %s msg_size=%d",
+ __PRETTY_FUNCTION__, ip_hdr->ip_p, src_str, grp_str, buf_size);
+ }
-static int mroute_read_msg(int fd)
-{
- const int msg_min_size = MAX(sizeof(struct ip), sizeof(struct igmpmsg));
- char buf[1000];
- int rd;
+ } else {
+ msg = (const struct igmpmsg *) buf;
- if (((int) sizeof(buf)) < msg_min_size) {
- zlog_err("%s: fd=%d: buf size=%zu lower than msg_min=%d",
- __PRETTY_FUNCTION__, fd, sizeof(buf), msg_min_size);
- return -1;
- }
+ ifp = pim_if_find_by_vif_index(msg->im_vif);
- rd = read(fd, buf, sizeof(buf));
- if (rd < 0) {
- zlog_warn("%s: failure reading fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
- return -2;
- }
+ if (!ifp)
+ return 0;
+ if (PIM_DEBUG_MROUTE) {
+ pim_inet4_dump("<src?>", msg->im_src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", msg->im_dst, grp_str, sizeof(grp_str));
+ zlog_warn("%s: pim kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d size=%d",
+ __PRETTY_FUNCTION__,
+ igmpmsgtype2str[msg->im_msgtype],
+ msg->im_msgtype,
+ ip_hdr->ip_p,
+ fd,
+ src_str,
+ grp_str,
+ ifp->name,
+ msg->im_vif, buf_size);
+ }
- if (rd < msg_min_size) {
- zlog_warn("%s: short message reading fd=%d: read=%d msg_min=%d",
- __PRETTY_FUNCTION__, fd, rd, msg_min_size);
- return -3;
+ switch (msg->im_msgtype) {
+ case IGMPMSG_WRONGVIF:
+ return pim_mroute_msg_wrongvif(fd, ifp, msg);
+ break;
+ case IGMPMSG_NOCACHE:
+ return pim_mroute_msg_nocache(fd, ifp, msg);
+ break;
+ case IGMPMSG_WHOLEPKT:
+ return pim_mroute_msg_wholepkt(fd, ifp, (const char *)msg);
+ break;
+ case IGMPMSG_WRVIFWHOLE:
+ return pim_mroute_msg_wrvifwhole (fd, ifp, (const char *)msg);
+ break;
+ default:
+ break;
+ }
}
- return pim_mroute_msg(fd, buf, rd);
+ return 0;
}
static int mroute_read(struct thread *t)
{
+ static long long count;
+ char buf[10000];
+ int result = 0;
+ int cont = 1;
int fd;
- int result;
-
- zassert(t);
- zassert(!THREAD_ARG(t));
+ int rd;
fd = THREAD_FD(t);
- zassert(fd == qpim_mroute_socket_fd);
-
- result = mroute_read_msg(fd);
+ while (cont)
+ {
+ rd = read(fd, buf, sizeof(buf));
+ if (rd < 0) {
+ if (errno == EINTR)
+ continue;
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ {
+ cont = 0;
+ break;
+ }
+ if (PIM_DEBUG_MROUTE)
+ zlog_warn("%s: failure reading fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
+ goto done;
+ }
+
+ result = pim_mroute_msg(fd, buf, rd);
+
+ count++;
+ if (count % qpim_packet_process == 0)
+ cont = 0;
+ }
/* Keep reading */
- qpim_mroute_socket_reader = 0;
+ done:
+ qpim_mroute_socket_reader = NULL;
mroute_read_on();
return result;
@@ -450,8 +642,6 @@ int pim_mroute_socket_enable()
qpim_mroute_socket_creation = pim_time_monotonic_sec();
mroute_read_on();
- zassert(PIM_MROUTE_IS_ENABLED);
-
return 0;
}
@@ -475,8 +665,6 @@ int pim_mroute_socket_disable()
mroute_read_off();
qpim_mroute_socket_fd = -1;
- zassert(PIM_MROUTE_IS_DISABLED);
-
return 0;
}
@@ -521,16 +709,14 @@ int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr, unsigned ch
err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_VIF, (void*) &vc, sizeof(vc));
if (err) {
- char ifaddr_str[100];
- int e = errno;
+ char ifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", ifaddr, ifaddr_str, sizeof(ifaddr_str));
zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_VIF,vif_index=%d,ifaddr=%s,flag=%d): errno=%d: %s",
__FILE__, __PRETTY_FUNCTION__,
qpim_mroute_socket_fd, ifp->ifindex, ifaddr_str, flags,
- e, safe_strerror(e));
- errno = e;
+ errno, safe_strerror(errno));
return -2;
}
@@ -553,22 +739,21 @@ int pim_mroute_del_vif(int vif_index)
err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_VIF, (void*) &vc, sizeof(vc));
if (err) {
- int e = errno;
zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_VIF,vif_index=%d): errno=%d: %s",
__FILE__, __PRETTY_FUNCTION__,
qpim_mroute_socket_fd, vif_index,
- e, safe_strerror(e));
- errno = e;
+ errno, safe_strerror(errno));
return -2;
}
return 0;
}
-int pim_mroute_add(struct channel_oil *c_oil)
+int pim_mroute_add(struct channel_oil *c_oil, const char *name)
{
int err;
int orig = 0;
+ int orig_iif_vif = 0;
qpim_mroute_add_last = pim_time_monotonic_sec();
++qpim_mroute_add_events;
@@ -589,27 +774,54 @@ int pim_mroute_add(struct channel_oil *c_oil)
c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = 1;
}
+ /*
+ * If we have an unresolved cache entry for the S,G
+ * it is owned by the pimreg for the incoming IIF
+ * So set pimreg as the IIF temporarily to cause
+ * the packets to be forwarded. Then set it
+ * to the correct IIF afterwords.
+ */
+ if (!c_oil->installed && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY &&
+ c_oil->oil.mfcc_parent != 0)
+ {
+ orig_iif_vif = c_oil->oil.mfcc_parent;
+ c_oil->oil.mfcc_parent = 0;
+ }
err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
&c_oil->oil, sizeof(c_oil->oil));
+ if (!err && !c_oil->installed && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY &&
+ orig_iif_vif != 0)
+ {
+ c_oil->oil.mfcc_parent = orig_iif_vif;
+ err = setsockopt (qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
+ &c_oil->oil, sizeof (c_oil->oil));
+ }
+
if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = orig;
if (err) {
- int e = errno;
zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_MFC): errno=%d: %s",
__FILE__, __PRETTY_FUNCTION__,
qpim_mroute_socket_fd,
- e, safe_strerror(e));
- errno = e;
+ errno, safe_strerror(errno));
return -2;
}
+ if (PIM_DEBUG_MROUTE)
+ {
+ char buf[1000];
+ zlog_debug("%s(%s), Added Route: %s",
+ __PRETTY_FUNCTION__, name,
+ pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
+ }
+
c_oil->installed = 1;
return 0;
}
-int pim_mroute_del (struct channel_oil *c_oil)
+int pim_mroute_del (struct channel_oil *c_oil, const char *name)
{
int err;
@@ -624,15 +836,22 @@ int pim_mroute_del (struct channel_oil *c_oil)
err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_MFC, &c_oil->oil, sizeof(c_oil->oil));
if (err) {
- int e = errno;
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_MFC): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- qpim_mroute_socket_fd,
- e, safe_strerror(e));
- errno = e;
+ if (PIM_DEBUG_MROUTE)
+ zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_MFC): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ qpim_mroute_socket_fd,
+ errno, safe_strerror(errno));
return -2;
}
+ if (PIM_DEBUG_MROUTE)
+ {
+ char buf[1000];
+ zlog_debug("%s(%s), Deleted Route: %s",
+ __PRETTY_FUNCTION__, name,
+ pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
+ }
+
c_oil->installed = 0;
return 0;
@@ -643,28 +862,46 @@ pim_mroute_update_counters (struct channel_oil *c_oil)
{
struct sioc_sg_req sgreq;
- memset (&sgreq, 0, sizeof(sgreq));
- sgreq.src = c_oil->oil.mfcc_origin;
- sgreq.grp = c_oil->oil.mfcc_mcastgrp;
-
c_oil->cc.oldpktcnt = c_oil->cc.pktcnt;
c_oil->cc.oldbytecnt = c_oil->cc.bytecnt;
c_oil->cc.oldwrong_if = c_oil->cc.wrong_if;
+ if (!c_oil->installed)
+ {
+ c_oil->cc.lastused = 100 * qpim_keep_alive_time;
+ if (PIM_DEBUG_MROUTE)
+ {
+ struct prefix_sg sg;
+
+ sg.src = c_oil->oil.mfcc_origin;
+ sg.grp = c_oil->oil.mfcc_mcastgrp;
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug("Channel(%s) is not installed no need to collect data from kernel",
+ pim_str_sg_dump (&sg));
+ }
+ return;
+ }
+
+ memset (&sgreq, 0, sizeof(sgreq));
+ sgreq.src = c_oil->oil.mfcc_origin;
+ sgreq.grp = c_oil->oil.mfcc_mcastgrp;
+
+ pim_zlookup_sg_statistics (c_oil);
if (ioctl (qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq))
{
- char group_str[100];
- char source_str[100];
-
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-
- zlog_warn ("ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s,%s): errno=%d: %s",
- (unsigned long)SIOCGETSGCNT,
- source_str,
- group_str,
- errno,
- safe_strerror(errno));
+ if (PIM_DEBUG_MROUTE)
+ {
+ struct prefix_sg sg;
+
+ sg.src = c_oil->oil.mfcc_origin;
+ sg.grp = c_oil->oil.mfcc_mcastgrp;
+
+ zlog_warn ("ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s): errno=%d: %s",
+ (unsigned long)SIOCGETSGCNT,
+ pim_str_sg_dump (&sg),
+ errno,
+ safe_strerror(errno));
+ }
return;
}
diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h
index f385ce09f4..3c15c800da 100644
--- a/pimd/pim_mroute.h
+++ b/pimd/pim_mroute.h
@@ -157,6 +157,10 @@ struct igmpmsg
#endif
#endif
+#ifndef IGMPMSG_WRVIFWHOLE
+#define IGMPMSG_WRVIFWHOLE 4 /* For PIM processing */
+#endif
+
/*
Above: from <linux/mroute.h>
*/
@@ -167,8 +171,8 @@ int pim_mroute_socket_disable(void);
int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr, unsigned char flags);
int pim_mroute_del_vif(int vif_index);
-int pim_mroute_add(struct channel_oil *c_oil);
-int pim_mroute_del(struct channel_oil *c_oil);
+int pim_mroute_add(struct channel_oil *c_oil, const char *name);
+int pim_mroute_del(struct channel_oil *c_oil, const char *name);
int pim_mroute_msg(int fd, const char *buf, int buf_size);
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
new file mode 100644
index 0000000000..93141f39de
--- /dev/null
+++ b/pimd/pim_msdp.c
@@ -0,0 +1,1606 @@
+/*
+ * IP MSDP for Quagga
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include <lib/hash.h>
+#include <lib/jhash.h>
+#include <lib/log.h>
+#include <lib/prefix.h>
+#include <lib/sockunion.h>
+#include <lib/stream.h>
+#include <lib/thread.h>
+#include <lib/vty.h>
+#include <lib/plist.h>
+
+#include "pimd.h"
+#include "pim_cmd.h"
+#include "pim_memory.h"
+#include "pim_iface.h"
+#include "pim_rp.h"
+#include "pim_str.h"
+#include "pim_time.h"
+#include "pim_upstream.h"
+
+#include "pim_msdp.h"
+#include "pim_msdp_packet.h"
+#include "pim_msdp_socket.h"
+
+struct pim_msdp pim_msdp, *msdp = &pim_msdp;
+
+static void pim_msdp_peer_listen(struct pim_msdp_peer *mp);
+static void pim_msdp_peer_cr_timer_setup(struct pim_msdp_peer *mp, bool start);
+static void pim_msdp_peer_ka_timer_setup(struct pim_msdp_peer *mp, bool start);
+static void pim_msdp_peer_hold_timer_setup(struct pim_msdp_peer *mp, bool start);
+static void pim_msdp_peer_free(struct pim_msdp_peer *mp);
+static void pim_msdp_enable(void);
+static void pim_msdp_sa_adv_timer_setup(bool start);
+static void pim_msdp_sa_deref(struct pim_msdp_sa *sa, enum pim_msdp_sa_flags flags);
+static int pim_msdp_mg_mbr_comp(const void *p1, const void *p2);
+static void pim_msdp_mg_mbr_free(struct pim_msdp_mg_mbr *mbr);
+static void pim_msdp_mg_mbr_do_del(struct pim_msdp_mg *mg, struct pim_msdp_mg_mbr *mbr);
+
+/************************ SA cache management ******************************/
+static void
+pim_msdp_sa_timer_expiry_log(struct pim_msdp_sa *sa, const char *timer_str)
+{
+ zlog_debug("MSDP SA %s %s timer expired", sa->sg_str, timer_str);
+}
+
+/* RFC-3618:Sec-5.1 - global active source advertisement timer */
+static int
+pim_msdp_sa_adv_timer_cb(struct thread *t)
+{
+ msdp->sa_adv_timer = NULL;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA advertisment timer expired");
+ }
+
+ pim_msdp_sa_adv_timer_setup(true /* start */);
+ pim_msdp_pkt_sa_tx();
+ return 0;
+}
+static void
+pim_msdp_sa_adv_timer_setup(bool start)
+{
+ THREAD_OFF(msdp->sa_adv_timer);
+ if (start) {
+ THREAD_TIMER_ON(msdp->master, msdp->sa_adv_timer,
+ pim_msdp_sa_adv_timer_cb, NULL, PIM_MSDP_SA_ADVERTISMENT_TIME);
+ }
+}
+
+/* RFC-3618:Sec-5.3 - SA cache state timer */
+static int
+pim_msdp_sa_state_timer_cb(struct thread *t)
+{
+ struct pim_msdp_sa *sa;
+
+ sa = THREAD_ARG(t);
+ sa->sa_state_timer = NULL;
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_sa_timer_expiry_log(sa, "state");
+ }
+
+ pim_msdp_sa_deref(sa, PIM_MSDP_SAF_PEER);
+ return 0;
+}
+static void
+pim_msdp_sa_state_timer_setup(struct pim_msdp_sa *sa, bool start)
+{
+ THREAD_OFF(sa->sa_state_timer);
+ if (start) {
+ THREAD_TIMER_ON(msdp->master, sa->sa_state_timer,
+ pim_msdp_sa_state_timer_cb, sa, PIM_MSDP_SA_HOLD_TIME);
+ }
+}
+
+static void
+pim_msdp_sa_upstream_del(struct pim_msdp_sa *sa)
+{
+ struct pim_upstream *up = sa->up;
+ if (!up) {
+ return;
+ }
+
+ sa->up = NULL;
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags)) {
+ PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(up->flags);
+ sa->flags |= PIM_MSDP_SAF_UP_DEL_IN_PROG;
+ pim_upstream_del(up, __PRETTY_FUNCTION__);
+ sa->flags &= ~PIM_MSDP_SAF_UP_DEL_IN_PROG;
+ }
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s de-referenced SPT", sa->sg_str);
+ }
+}
+
+static bool
+pim_msdp_sa_upstream_add_ok(struct pim_msdp_sa *sa, struct pim_upstream *xg_up)
+{
+ if (!(sa->flags & PIM_MSDP_SAF_PEER)) {
+ /* SA should have been rxed from a peer */
+ return false;
+ }
+ /* check if we are RP */
+ if (!I_am_RP(sa->sg.grp)) {
+ return false;
+ }
+
+ /* check if we have a (*, G) with a non-empty immediate OIL */
+ if (!xg_up) {
+ struct prefix_sg sg;
+
+ memset(&sg, 0, sizeof(sg));
+ sg.grp = sa->sg.grp;
+
+ xg_up = pim_upstream_find(&sg);
+ }
+ if (!xg_up || (xg_up->join_state != PIM_UPSTREAM_JOINED)) {
+ /* join desired will be true for such (*, G) entries so we will
+ * just look at join_state and let the PIM state machine do the rest of
+ * the magic */
+ return false;
+ }
+
+ return true;
+}
+
+/* Upstream add evaluation needs to happen everytime -
+ * 1. Peer reference is added or removed.
+ * 2. The RP for a group changes.
+ * 3. joinDesired for the associated (*, G) changes
+ * 4. associated (*, G) is removed - this seems like a bit redundant
+ * (considering #4); but just in case an entry gets nuked without
+ * upstream state transition
+ * */
+static void
+pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa,
+ struct pim_upstream *xg_up, const char *ctx)
+{
+ struct pim_upstream *up;
+
+ if (!pim_msdp_sa_upstream_add_ok(sa, xg_up)) {
+ pim_msdp_sa_upstream_del(sa);
+ return;
+ }
+
+ if (sa->up) {
+ /* nothing to do */
+ return;
+ }
+
+ up = pim_upstream_find(&sa->sg);
+ if (up && (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags))) {
+ /* somehow we lost track of the upstream ptr? best log it */
+ sa->up = up;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s SPT reference missing", sa->sg_str);
+ }
+ return;
+ }
+
+ /* RFC3618: "RP triggers a (S, G) join event towards the data source
+ * as if a JP message was rxed addressed to the RP itself." */
+ up = pim_upstream_add(&sa->sg, NULL /* iif */,
+ PIM_UPSTREAM_FLAG_MASK_SRC_MSDP,
+ __PRETTY_FUNCTION__);
+
+ sa->up = up;
+ if (up) {
+ /* update inherited oil */
+ pim_upstream_inherited_olist(up);
+ /* should we also start the kat in parallel? we will need it when the
+ * SA ages out */
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s referenced SPT", sa->sg_str);
+ }
+ } else {
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s SPT reference failed", sa->sg_str);
+ }
+ }
+}
+
+/* release all mem associated with a sa */
+static void
+pim_msdp_sa_free(struct pim_msdp_sa *sa)
+{
+ XFREE(MTYPE_PIM_MSDP_SA, sa);
+}
+
+static struct pim_msdp_sa *
+pim_msdp_sa_new(struct prefix_sg *sg, struct in_addr rp)
+{
+ struct pim_msdp_sa *sa;
+
+ sa = XCALLOC(MTYPE_PIM_MSDP_SA, sizeof(*sa));
+ if (!sa) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure",
+ __PRETTY_FUNCTION__, sizeof(*sa));
+ return NULL;
+ }
+
+ sa->sg = *sg;
+ pim_str_sg_set(sg, sa->sg_str);
+ sa->rp = rp;
+ sa->uptime = pim_time_monotonic_sec();
+
+ /* insert into misc tables for easy access */
+ sa = hash_get(msdp->sa_hash, sa, hash_alloc_intern);
+ if (!sa) {
+ zlog_err("%s: PIM hash get failure", __PRETTY_FUNCTION__);
+ pim_msdp_sa_free(sa);
+ return NULL;
+ }
+ listnode_add_sort(msdp->sa_list, sa);
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s created", sa->sg_str);
+ }
+
+ return sa;
+}
+
+static struct pim_msdp_sa *
+pim_msdp_sa_find(struct prefix_sg *sg)
+{
+ struct pim_msdp_sa lookup;
+
+ lookup.sg = *sg;
+ return hash_lookup(msdp->sa_hash, &lookup);
+}
+
+static struct pim_msdp_sa *
+pim_msdp_sa_add(struct prefix_sg *sg, struct in_addr rp)
+{
+ struct pim_msdp_sa *sa;
+
+ sa = pim_msdp_sa_find(sg);
+ if (sa) {
+ return sa;
+ }
+
+ return pim_msdp_sa_new(sg, rp);
+}
+
+static void
+pim_msdp_sa_del(struct pim_msdp_sa * sa)
+{
+ /* this is somewhat redundant - still want to be careful not to leave
+ * stale upstream references */
+ pim_msdp_sa_upstream_del(sa);
+
+ /* stop timers */
+ pim_msdp_sa_state_timer_setup(sa, false /* start */);
+
+ /* remove the entry from various tables */
+ listnode_delete(msdp->sa_list, sa);
+ hash_release(msdp->sa_hash, sa);
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s deleted", sa->sg_str);
+ }
+
+ /* free up any associated memory */
+ pim_msdp_sa_free(sa);
+}
+
+static void
+pim_msdp_sa_peer_ip_set(struct pim_msdp_sa *sa, struct pim_msdp_peer *mp, struct in_addr rp)
+{
+ struct pim_msdp_peer *old_mp;
+
+ /* optimize the "no change" case as it will happen
+ * frequently/periodically */
+ if (mp && (sa->peer.s_addr == mp->peer.s_addr)) {
+ return;
+ }
+
+ /* any time the peer ip changes also update the rp address */
+ if (PIM_INADDR_ISNOT_ANY(sa->peer)) {
+ old_mp = pim_msdp_peer_find(sa->peer);
+ if (old_mp && old_mp->sa_cnt) {
+ --old_mp->sa_cnt;
+ }
+ }
+
+ if (mp) {
+ ++mp->sa_cnt;
+ sa->peer = mp->peer;
+ } else {
+ sa->peer.s_addr = PIM_NET_INADDR_ANY;
+ }
+ sa->rp = rp;
+}
+
+/* When a local active-source is removed there is no way to withdraw the
+ * source from peers. We will simply remove it from the SA cache so it will
+ * not be sent in supsequent SA updates. Peers will consequently timeout the
+ * SA.
+ * Similarly a "peer-added" SA is never explicitly deleted. It is simply
+ * aged out overtime if not seen in the SA updates from the peers.
+ * XXX: should we provide a knob to drop entries learnt from a peer when the
+ * peer goes down? */
+static void
+pim_msdp_sa_deref(struct pim_msdp_sa *sa, enum pim_msdp_sa_flags flags)
+{
+ bool update_up = false;
+
+ if ((sa->flags &PIM_MSDP_SAF_LOCAL)) {
+ if (flags & PIM_MSDP_SAF_LOCAL) {
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s local reference removed", sa->sg_str);
+ }
+ if (msdp->local_cnt)
+ --msdp->local_cnt;
+ }
+ }
+
+ if ((sa->flags &PIM_MSDP_SAF_PEER)) {
+ if (flags & PIM_MSDP_SAF_PEER) {
+ struct in_addr rp;
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s peer reference removed", sa->sg_str);
+ }
+ pim_msdp_sa_state_timer_setup(sa, false /* start */);
+ rp.s_addr = INADDR_ANY;
+ pim_msdp_sa_peer_ip_set(sa, NULL /* mp */, rp);
+ /* if peer ref was removed we need to remove the msdp reference on the
+ * msdp entry */
+ update_up = true;
+ }
+ }
+
+ sa->flags &= ~flags;
+ if (update_up) {
+ pim_msdp_sa_upstream_update(sa, NULL /* xg_up */, "sa-deref");
+ }
+
+ if (!(sa->flags & PIM_MSDP_SAF_REF)) {
+ pim_msdp_sa_del(sa);
+ }
+}
+
+void
+pim_msdp_sa_ref(struct pim_msdp_peer *mp, struct prefix_sg *sg,
+ struct in_addr rp)
+{
+ struct pim_msdp_sa *sa;
+
+ sa = pim_msdp_sa_add(sg, rp);
+ if (!sa) {
+ return;
+ }
+
+ /* reference it */
+ if (mp) {
+ if (!(sa->flags & PIM_MSDP_SAF_PEER)) {
+ sa->flags |= PIM_MSDP_SAF_PEER;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s added by peer", sa->sg_str);
+ }
+ }
+ pim_msdp_sa_peer_ip_set(sa, mp, rp);
+ /* start/re-start the state timer to prevent cache expiry */
+ pim_msdp_sa_state_timer_setup(sa, true /* start */);
+ /* We re-evaluate SA "SPT-trigger" everytime we hear abt it from a
+ * peer. XXX: If this becomes too much of a periodic overhead we
+ * can make it event based */
+ pim_msdp_sa_upstream_update(sa, NULL /* xg_up */, "peer-ref");
+ } else {
+ if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
+ sa->flags |= PIM_MSDP_SAF_LOCAL;
+ ++msdp->local_cnt;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s added locally", sa->sg_str);
+ }
+ /* send an immediate SA update to peers */
+ pim_msdp_pkt_sa_tx_one(sa);
+ }
+ sa->flags &= ~PIM_MSDP_SAF_STALE;
+ }
+}
+
+/* The following criteria must be met to originate an SA from the MSDP
+ * speaker -
+ * 1. KAT must be running i.e. source is active.
+ * 2. We must be RP for the group.
+ * 3. Source must be registrable to the RP (this is where the RFC is vague
+ * and especially ambiguous in CLOS networks; with anycast RP all sources
+ * are potentially registrable to all RPs in the domain). We assume #3 is
+ * satisfied if -
+ * a. We are also the FHR-DR for the source (OR)
+ * b. We rxed a pim register (null or data encapsulated) within the last
+ * (3 * (1.5 * register_suppression_timer))).
+ */
+static bool
+pim_msdp_sa_local_add_ok(struct pim_upstream *up)
+{
+ if (!(msdp->flags & PIM_MSDPF_ENABLE)) {
+ return false;
+ }
+
+ if (!up->t_ka_timer) {
+ /* stream is not active */
+ return false;
+ }
+
+ if (!I_am_RP(up->sg.grp)) {
+ /* we are not RP for the group */
+ return false;
+ }
+
+ /* we are the FHR-DR for this stream or we are RP and have seen registers
+ * from a FHR for this source */
+ if (PIM_UPSTREAM_FLAG_TEST_FHR(up->flags) || up->t_msdp_reg_timer) {
+ return true;
+ }
+
+ return false;
+}
+
+static void
+pim_msdp_sa_local_add(struct prefix_sg *sg)
+{
+ struct in_addr rp;
+ rp.s_addr = 0;
+ pim_msdp_sa_ref(NULL /* mp */, sg, rp);
+}
+
+void
+pim_msdp_sa_local_del(struct prefix_sg *sg)
+{
+ struct pim_msdp_sa *sa;
+
+ sa = pim_msdp_sa_find(sg);
+ if (sa) {
+ pim_msdp_sa_deref(sa, PIM_MSDP_SAF_LOCAL);
+ }
+}
+
+/* we need to be very cautious with this API as SA del too can trigger an
+ * upstream del and we will get stuck in a simple loop */
+static void
+pim_msdp_sa_local_del_on_up_del(struct prefix_sg *sg)
+{
+ struct pim_msdp_sa *sa;
+
+ sa = pim_msdp_sa_find(sg);
+ if (sa) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP local sa %s del on up del", sa->sg_str);
+ }
+
+ /* if there is no local reference escape */
+ if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP local sa %s del; no local ref", sa->sg_str);
+ }
+ return;
+ }
+
+ if (sa->flags & PIM_MSDP_SAF_UP_DEL_IN_PROG) {
+ /* MSDP is the one that triggered the upstream del. if this happens
+ * we most certainly have a bug in the PIM upstream state machine. We
+ * will not have a local reference unless the KAT is running. And if the
+ * KAT is running there MUST be an additional source-stream reference to
+ * the flow. Accounting for such cases requires lot of changes; perhaps
+ * address this in the next release? - XXX */
+ zlog_err("MSDP sa %s SPT teardown is causing the local entry to be removed", sa->sg_str);
+ return;
+ }
+
+ /* we are dropping the sa on upstream del we should not have an
+ * upstream reference */
+ if (sa->up) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP local sa %s del; up non-NULL", sa->sg_str);
+ }
+ sa->up = NULL;
+ }
+ pim_msdp_sa_deref(sa, PIM_MSDP_SAF_LOCAL);
+ }
+}
+
+/* Local SA qualification needs to be re-evaluated when -
+ * 1. KAT is started or stopped
+ * 2. on RP changes
+ * 3. Whenever FHR status changes for a (S,G) - XXX - currently there
+ * is no clear path to transition an entry out of "MASK_FHR" need
+ * to discuss this with Donald. May result in some strangeness if the
+ * FHR is also the RP.
+ * 4. When msdp_reg timer is started or stopped
+ */
+void
+pim_msdp_sa_local_update(struct pim_upstream *up)
+{
+ if (pim_msdp_sa_local_add_ok(up)) {
+ pim_msdp_sa_local_add(&up->sg);
+ } else {
+ pim_msdp_sa_local_del(&up->sg);
+ }
+}
+
+static void
+pim_msdp_sa_local_setup(void)
+{
+ struct pim_upstream *up;
+ struct listnode *up_node;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, up_node, up)) {
+ pim_msdp_sa_local_update(up);
+ }
+}
+
+/* whenever the RP changes we need to re-evaluate the "local" SA-cache */
+/* XXX: needs to be tested */
+void
+pim_msdp_i_am_rp_changed(void)
+{
+ struct listnode *sanode;
+ struct listnode *nextnode;
+ struct pim_msdp_sa *sa;
+
+ if (!(msdp->flags & PIM_MSDPF_ENABLE)) {
+ /* if the feature is not enabled do nothing */
+ return;
+ }
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP i_am_rp changed");
+ }
+
+ /* mark all local entries as stale */
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ if (sa->flags & PIM_MSDP_SAF_LOCAL) {
+ sa->flags |= PIM_MSDP_SAF_STALE;
+ }
+ }
+
+ /* re-setup local SA entries */
+ pim_msdp_sa_local_setup();
+
+ for (ALL_LIST_ELEMENTS(msdp->sa_list, sanode, nextnode, sa)) {
+ /* purge stale SA entries */
+ if (sa->flags & PIM_MSDP_SAF_STALE) {
+ /* clear the stale flag; the entry may be kept even after
+ * "local-deref" */
+ sa->flags &= ~PIM_MSDP_SAF_STALE;
+ /* sa_deref can end up freeing the sa; so don't access contents after */
+ pim_msdp_sa_deref(sa, PIM_MSDP_SAF_LOCAL);
+ } else {
+ /* if the souce is still active check if we can influence SPT */
+ pim_msdp_sa_upstream_update(sa, NULL /* xg_up */, "rp-change");
+ }
+ }
+}
+
+/* We track the join state of (*, G) entries. If G has sources in the SA-cache
+ * we need to setup or teardown SPT when the JoinDesired status changes for
+ * (*, G) */
+void
+pim_msdp_up_join_state_changed(struct pim_upstream *xg_up)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP join state changed for %s", xg_up->sg_str);
+ }
+
+ /* If this is not really an XG entry just move on */
+ if ((xg_up->sg.src.s_addr != INADDR_ANY) ||
+ (xg_up->sg.grp.s_addr == INADDR_ANY)) {
+ return;
+ }
+
+ /* XXX: Need to maintain SAs per-group to avoid all this unnecessary
+ * walking */
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ if (sa->sg.grp.s_addr != xg_up->sg.grp.s_addr) {
+ continue;
+ }
+ pim_msdp_sa_upstream_update(sa, xg_up, "up-jp-change");
+ }
+}
+
+static void
+pim_msdp_up_xg_del(struct prefix_sg *sg)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP %s del", pim_str_sg_dump(sg));
+ }
+
+ /* If this is not really an XG entry just move on */
+ if ((sg->src.s_addr != INADDR_ANY) ||
+ (sg->grp.s_addr == INADDR_ANY)) {
+ return;
+ }
+
+ /* XXX: Need to maintain SAs per-group to avoid all this unnecessary
+ * walking */
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ if (sa->sg.grp.s_addr != sg->grp.s_addr) {
+ continue;
+ }
+ pim_msdp_sa_upstream_update(sa, NULL /* xg */, "up-jp-change");
+ }
+}
+
+void
+pim_msdp_up_del(struct prefix_sg *sg)
+{
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP up %s del", pim_str_sg_dump(sg));
+ }
+ if (sg->src.s_addr == INADDR_ANY) {
+ pim_msdp_up_xg_del(sg);
+ } else {
+ pim_msdp_sa_local_del_on_up_del(sg);
+ }
+}
+
+/* sa hash and peer list helpers */
+static unsigned int
+pim_msdp_sa_hash_key_make(void *p)
+{
+ struct pim_msdp_sa *sa = p;
+
+ return (jhash_2words(sa->sg.src.s_addr, sa->sg.grp.s_addr, 0));
+}
+
+static int
+pim_msdp_sa_hash_eq(const void *p1, const void *p2)
+{
+ const struct pim_msdp_sa *sa1 = p1;
+ const struct pim_msdp_sa *sa2 = p2;
+
+ return ((sa1->sg.src.s_addr == sa2->sg.src.s_addr) &&
+ (sa1->sg.grp.s_addr == sa2->sg.grp.s_addr));
+}
+
+static int
+pim_msdp_sa_comp(const void *p1, const void *p2)
+{
+ const struct pim_msdp_sa *sa1 = p1;
+ const struct pim_msdp_sa *sa2 = p2;
+
+ if (ntohl(sa1->sg.grp.s_addr) < ntohl(sa2->sg.grp.s_addr))
+ return -1;
+
+ if (ntohl(sa1->sg.grp.s_addr) > ntohl(sa2->sg.grp.s_addr))
+ return 1;
+
+ if (ntohl(sa1->sg.src.s_addr) < ntohl(sa2->sg.src.s_addr))
+ return -1;
+
+ if (ntohl(sa1->sg.src.s_addr) > ntohl(sa2->sg.src.s_addr))
+ return 1;
+
+ return 0;
+}
+
+/* RFC-3618:Sec-10.1.3 - Peer-RPF forwarding */
+/* XXX: this can use a bit of refining and extensions */
+bool
+pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp)
+{
+ if (mp->peer.s_addr == rp.s_addr) {
+ return true;
+ }
+
+ return false;
+}
+
+/************************ Peer session management **************************/
+char *
+pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf, int buf_size)
+{
+ switch (state) {
+ case PIM_MSDP_DISABLED:
+ snprintf(buf, buf_size, "%s", "disabled");
+ break;
+ case PIM_MSDP_INACTIVE:
+ snprintf(buf, buf_size, "%s", "inactive");
+ break;
+ case PIM_MSDP_LISTEN:
+ snprintf(buf, buf_size, "%s", "listen");
+ break;
+ case PIM_MSDP_CONNECTING:
+ snprintf(buf, buf_size, "%s", "connecting");
+ break;
+ case PIM_MSDP_ESTABLISHED:
+ snprintf(buf, buf_size, "%s", "established");
+ break;
+ default:
+ snprintf(buf, buf_size, "unk-%d", state);
+ }
+ return buf;
+}
+
+char *
+pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size, bool long_format)
+{
+ char peer_str[INET_ADDRSTRLEN];
+ char local_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
+ if (long_format) {
+ pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
+ snprintf(buf, buf_size, "MSDP peer %s local %s mg %s",
+ peer_str, local_str, mp->mesh_group_name);
+ } else {
+ snprintf(buf, buf_size, "MSDP peer %s", peer_str);
+ }
+
+ return buf;
+}
+
+static void
+pim_msdp_peer_state_chg_log(struct pim_msdp_peer *mp)
+{
+ char state_str[PIM_MSDP_STATE_STRLEN];
+
+ pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
+ zlog_debug("MSDP peer %s state chg to %s", mp->key_str, state_str);
+}
+
+/* MSDP Connection State Machine actions (defined in RFC-3618:Sec-11.2) */
+/* 11.2.A2: active peer - start connect retry timer; when the timer fires
+ * a tcp connection will be made */
+static void
+pim_msdp_peer_connect(struct pim_msdp_peer *mp)
+{
+ mp->state = PIM_MSDP_CONNECTING;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
+
+ pim_msdp_peer_cr_timer_setup(mp, true /* start */);
+}
+
+/* 11.2.A3: passive peer - just listen for connections */
+static void
+pim_msdp_peer_listen(struct pim_msdp_peer *mp)
+{
+ mp->state = PIM_MSDP_LISTEN;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
+
+ /* this is interntionally asymmetric i.e. we set up listen-socket when the
+ * first listening peer is configured; but don't bother tearing it down when
+ * all the peers go down */
+ pim_msdp_sock_listen();
+}
+
+/* 11.2.A4 and 11.2.A5: transition active or passive peer to
+ * established state */
+void
+pim_msdp_peer_established(struct pim_msdp_peer *mp)
+{
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ ++mp->est_flaps;
+ }
+
+ mp->state = PIM_MSDP_ESTABLISHED;
+ mp->uptime = pim_time_monotonic_sec();
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
+
+ /* stop retry timer on active peers */
+ pim_msdp_peer_cr_timer_setup(mp, false /* start */);
+
+ /* send KA; start KA and hold timers */
+ pim_msdp_pkt_ka_tx(mp);
+ pim_msdp_peer_ka_timer_setup(mp, true /* start */);
+ pim_msdp_peer_hold_timer_setup(mp, true /* start */);
+
+ pim_msdp_pkt_sa_tx_to_one_peer(mp);
+
+ PIM_MSDP_PEER_WRITE_ON(mp);
+ PIM_MSDP_PEER_READ_ON(mp);
+}
+
+/* 11.2.A6, 11.2.A7 and 11.2.A8: shutdown the peer tcp connection */
+void
+pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state)
+{
+ if (chg_state) {
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ ++mp->est_flaps;
+ }
+ mp->state = PIM_MSDP_INACTIVE;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
+ }
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_peer_stop_tcp_conn", mp->key_str);
+ }
+ /* stop read and write threads */
+ PIM_MSDP_PEER_READ_OFF(mp);
+ PIM_MSDP_PEER_WRITE_OFF(mp);
+
+ /* reset buffers */
+ mp->packet_size = 0;
+ if (mp->ibuf)
+ stream_reset(mp->ibuf);
+ if (mp->obuf)
+ stream_fifo_clean(mp->obuf);
+
+ /* stop all peer timers */
+ pim_msdp_peer_ka_timer_setup(mp, false /* start */);
+ pim_msdp_peer_cr_timer_setup(mp, false /* start */);
+ pim_msdp_peer_hold_timer_setup(mp, false /* start */);
+
+ /* close connection */
+ if (mp->fd >= 0) {
+ close(mp->fd);
+ mp->fd = -1;
+ }
+}
+
+/* RFC-3618:Sec-5.6 - stop the peer tcp connection and startover */
+void
+pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str)
+{
+ if (PIM_DEBUG_EVENTS) {
+ zlog_debug("MSDP peer %s tcp reset %s", mp->key_str, rc_str);
+ snprintf(mp->last_reset, sizeof(mp->last_reset), "%s", rc_str);
+ }
+
+ /* close the connection and transition to listening or connecting */
+ pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
+ if (PIM_MSDP_PEER_IS_LISTENER(mp)) {
+ pim_msdp_peer_listen(mp);
+ } else {
+ pim_msdp_peer_connect(mp);
+ }
+}
+
+static void
+pim_msdp_peer_timer_expiry_log(struct pim_msdp_peer *mp, const char *timer_str)
+{
+ zlog_debug("MSDP peer %s %s timer expired", mp->key_str, timer_str);
+}
+
+/* RFC-3618:Sec-5.4 - peer hold timer */
+static int
+pim_msdp_peer_hold_timer_cb(struct thread *t)
+{
+ struct pim_msdp_peer *mp;
+
+ mp = THREAD_ARG(t);
+ mp->hold_timer = NULL;
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_timer_expiry_log(mp, "hold");
+ }
+
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ return 0;
+ }
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
+ pim_msdp_peer_reset_tcp_conn(mp, "ht-expired");
+ return 0;
+}
+static void
+pim_msdp_peer_hold_timer_setup(struct pim_msdp_peer *mp, bool start)
+{
+ THREAD_OFF(mp->hold_timer);
+ if (start) {
+ THREAD_TIMER_ON(msdp->master, mp->hold_timer,
+ pim_msdp_peer_hold_timer_cb, mp, PIM_MSDP_PEER_HOLD_TIME);
+ }
+}
+
+
+/* RFC-3618:Sec-5.5 - peer keepalive timer */
+static int
+pim_msdp_peer_ka_timer_cb(struct thread *t)
+{
+ struct pim_msdp_peer *mp;
+
+ mp = THREAD_ARG(t);
+ mp->ka_timer = NULL;
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_timer_expiry_log(mp, "ka");
+ }
+
+ pim_msdp_pkt_ka_tx(mp);
+ pim_msdp_peer_ka_timer_setup(mp, true /* start */);
+ return 0;
+}
+static void
+pim_msdp_peer_ka_timer_setup(struct pim_msdp_peer *mp, bool start)
+{
+ THREAD_OFF(mp->ka_timer);
+ if (start) {
+ THREAD_TIMER_ON(msdp->master, mp->ka_timer,
+ pim_msdp_peer_ka_timer_cb, mp, PIM_MSDP_PEER_KA_TIME);
+ }
+}
+
+static void
+pim_msdp_peer_active_connect(struct pim_msdp_peer *mp)
+{
+ int rc;
+ ++mp->conn_attempts;
+ rc = pim_msdp_sock_connect(mp);
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_peer_active_connect: %d", mp->key_str, rc);
+ }
+
+ switch (rc) {
+ case connect_error:
+ case -1:
+ /* connect failed restart the connect-retry timer */
+ pim_msdp_peer_cr_timer_setup(mp, true /* start */);
+ break;
+
+ case connect_success:
+ /* connect was sucessful move to established */
+ pim_msdp_peer_established(mp);
+ break;
+
+ case connect_in_progress:
+ /* for NB content we need to wait till sock is readable or
+ * writeable */
+ PIM_MSDP_PEER_WRITE_ON(mp);
+ PIM_MSDP_PEER_READ_ON(mp);
+ /* also restart connect-retry timer to reset the socket if connect is
+ * not sucessful */
+ pim_msdp_peer_cr_timer_setup(mp, true /* start */);
+ break;
+ }
+}
+
+/* RFC-3618:Sec-5.6 - connection retry on active peer */
+static int
+pim_msdp_peer_cr_timer_cb(struct thread *t)
+{
+ struct pim_msdp_peer *mp;
+
+ mp = THREAD_ARG(t);
+ mp->cr_timer = NULL;
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_timer_expiry_log(mp, "connect-retry");
+ }
+
+ if (mp->state != PIM_MSDP_CONNECTING || PIM_MSDP_PEER_IS_LISTENER(mp)) {
+ return 0;
+ }
+
+ pim_msdp_peer_active_connect(mp);
+ return 0;
+}
+static void
+pim_msdp_peer_cr_timer_setup(struct pim_msdp_peer *mp, bool start)
+{
+ THREAD_OFF(mp->cr_timer);
+ if (start) {
+ THREAD_TIMER_ON(msdp->master, mp->cr_timer,
+ pim_msdp_peer_cr_timer_cb, mp, PIM_MSDP_PEER_CONNECT_RETRY_TIME);
+ }
+}
+
+/* if a valid packet is rxed from the peer we can restart hold timer */
+void
+pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp)
+{
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ pim_msdp_peer_hold_timer_setup(mp, true /* start */);
+ }
+}
+
+/* if a valid packet is txed to the peer we can restart ka timer and avoid
+ * unnecessary ka noise in the network */
+void
+pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp)
+{
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ pim_msdp_peer_ka_timer_setup(mp, true /* start */);
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP ka timer restart on pkt tx to %s", mp->key_str);
+ }
+ }
+}
+
+static void pim_msdp_addr2su(union sockunion *su, struct in_addr addr)
+{
+ sockunion_init(su);
+ su->sin.sin_addr = addr;
+ su->sin.sin_family = AF_INET;
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+ su->sin.sin_len = sizeof(struct sockaddr_in);
+#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
+}
+
+/* 11.2.A1: create a new peer and transition state to listen or connecting */
+static enum pim_msdp_err
+pim_msdp_peer_new(struct in_addr peer_addr, struct in_addr local_addr,
+ const char *mesh_group_name, struct pim_msdp_peer **mp_p)
+{
+ struct pim_msdp_peer *mp;
+
+ pim_msdp_enable();
+
+ mp = XCALLOC(MTYPE_PIM_MSDP_PEER, sizeof(*mp));
+ if (!mp) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure",
+ __PRETTY_FUNCTION__, sizeof(*mp));
+ return PIM_MSDP_ERR_OOM;
+ }
+
+ mp->peer = peer_addr;
+ pim_inet4_dump("<peer?>", mp->peer, mp->key_str, sizeof(mp->key_str));
+ pim_msdp_addr2su(&mp->su_peer, mp->peer);
+ mp->local = local_addr;
+ /* XXX: originator_id setting needs to move to the mesh group */
+ msdp->originator_id = local_addr;
+ pim_msdp_addr2su(&mp->su_local, mp->local);
+ mp->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
+ mp->state = PIM_MSDP_INACTIVE;
+ mp->fd = -1;
+ strcpy(mp->last_reset, "-");
+ /* higher IP address is listener */
+ if (ntohl(mp->local.s_addr) > ntohl(mp->peer.s_addr)) {
+ mp->flags |= PIM_MSDP_PEERF_LISTENER;
+ }
+
+ /* setup packet buffers */
+ mp->ibuf = stream_new(PIM_MSDP_MAX_PACKET_SIZE);
+ mp->obuf = stream_fifo_new();
+
+ /* insert into misc tables for easy access */
+ mp = hash_get(msdp->peer_hash, mp, hash_alloc_intern);
+ listnode_add_sort(msdp->peer_list, mp);
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP peer %s created", mp->key_str);
+
+ pim_msdp_peer_state_chg_log(mp);
+ }
+
+ /* fireup the connect state machine */
+ if (PIM_MSDP_PEER_IS_LISTENER(mp)) {
+ pim_msdp_peer_listen(mp);
+ } else {
+ pim_msdp_peer_connect(mp);
+ }
+ if (mp_p) {
+ *mp_p = mp;
+ }
+ return PIM_MSDP_ERR_NONE;
+}
+
+struct pim_msdp_peer *
+pim_msdp_peer_find(struct in_addr peer_addr)
+{
+ struct pim_msdp_peer lookup;
+
+ lookup.peer = peer_addr;
+ return hash_lookup(msdp->peer_hash, &lookup);
+}
+
+/* add peer configuration if it doesn't already exist */
+enum pim_msdp_err
+pim_msdp_peer_add(struct in_addr peer_addr, struct in_addr local_addr,
+ const char *mesh_group_name, struct pim_msdp_peer **mp_p)
+{
+ struct pim_msdp_peer *mp;
+
+ if (mp_p) {
+ *mp_p = NULL;
+ }
+
+ if (peer_addr.s_addr == local_addr.s_addr) {
+ /* skip session setup if config is invalid */
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ char peer_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<peer?>", peer_addr, peer_str, sizeof(peer_str));
+ zlog_debug("%s add skipped as DIP=SIP", peer_str);
+ }
+ return PIM_MSDP_ERR_SIP_EQ_DIP;
+ }
+
+ mp = pim_msdp_peer_find(peer_addr);
+ if (mp) {
+ if (mp_p) {
+ *mp_p = mp;
+ }
+ return PIM_MSDP_ERR_PEER_EXISTS;
+ }
+
+ return pim_msdp_peer_new(peer_addr, local_addr, mesh_group_name, mp_p);
+}
+
+/* release all mem associated with a peer */
+static void
+pim_msdp_peer_free(struct pim_msdp_peer *mp)
+{
+ if (mp->ibuf) {
+ stream_free(mp->ibuf);
+ }
+
+ if (mp->obuf) {
+ stream_fifo_free(mp->obuf);
+ }
+
+ if (mp->mesh_group_name) {
+ XFREE(MTYPE_PIM_MSDP_MG_NAME, mp->mesh_group_name);
+ }
+ XFREE(MTYPE_PIM_MSDP_PEER, mp);
+}
+
+/* delete the peer config */
+static enum pim_msdp_err
+pim_msdp_peer_do_del(struct pim_msdp_peer *mp)
+{
+ /* stop the tcp connection and shutdown all timers */
+ pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
+
+ /* remove the session from various tables */
+ listnode_delete(msdp->peer_list, mp);
+ hash_release(msdp->peer_hash, mp);
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP peer %s deleted", mp->key_str);
+ }
+
+ /* free up any associated memory */
+ pim_msdp_peer_free(mp);
+
+ return PIM_MSDP_ERR_NONE;
+}
+
+enum pim_msdp_err
+pim_msdp_peer_del(struct in_addr peer_addr)
+{
+ struct pim_msdp_peer *mp;
+
+ mp = pim_msdp_peer_find(peer_addr);
+ if (!mp) {
+ return PIM_MSDP_ERR_NO_PEER;
+ }
+
+ return pim_msdp_peer_do_del(mp);
+}
+
+/* peer hash and peer list helpers */
+static unsigned int
+pim_msdp_peer_hash_key_make(void *p)
+{
+ struct pim_msdp_peer *mp = p;
+ return (jhash_1word(mp->peer.s_addr, 0));
+}
+
+static int
+pim_msdp_peer_hash_eq(const void *p1, const void *p2)
+{
+ const struct pim_msdp_peer *mp1 = p1;
+ const struct pim_msdp_peer *mp2 = p2;
+
+ return (mp1->peer.s_addr == mp2->peer.s_addr);
+}
+
+static int
+pim_msdp_peer_comp(const void *p1, const void *p2)
+{
+ const struct pim_msdp_peer *mp1 = p1;
+ const struct pim_msdp_peer *mp2 = p2;
+
+ if (ntohl(mp1->peer.s_addr) < ntohl(mp2->peer.s_addr))
+ return -1;
+
+ if (ntohl(mp1->peer.s_addr) > ntohl(mp2->peer.s_addr))
+ return 1;
+
+ return 0;
+}
+
+/************************** Mesh group management **************************/
+static void
+pim_msdp_mg_free(struct pim_msdp_mg *mg)
+{
+ /* If the mesh-group has valid member or src_ip don't delete it */
+ if (!mg || mg->mbr_cnt || (mg->src_ip.s_addr != INADDR_ANY)) {
+ return;
+ }
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP mesh-group %s deleted", mg->mesh_group_name);
+ }
+ if (mg->mesh_group_name)
+ XFREE(MTYPE_PIM_MSDP_MG_NAME, mg->mesh_group_name);
+
+ if (mg->mbr_list)
+ list_free(mg->mbr_list);
+
+ XFREE(MTYPE_PIM_MSDP_MG, mg);
+ msdp->mg = NULL;
+}
+
+static struct pim_msdp_mg *
+pim_msdp_mg_new(const char *mesh_group_name)
+{
+ struct pim_msdp_mg *mg;
+
+ mg = XCALLOC(MTYPE_PIM_MSDP_MG, sizeof(*mg));
+ if (!mg) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure",
+ __PRETTY_FUNCTION__, sizeof(*mg));
+ return NULL;
+ }
+
+ mg->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
+ mg->mbr_list = list_new();
+ mg->mbr_list->del = (void (*)(void *))pim_msdp_mg_mbr_free;
+ mg->mbr_list->cmp = (int (*)(void *, void *))pim_msdp_mg_mbr_comp;
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP mesh-group %s created", mg->mesh_group_name);
+ }
+ return mg;
+}
+
+enum pim_msdp_err
+pim_msdp_mg_del(const char *mesh_group_name)
+{
+ struct pim_msdp_mg *mg = msdp->mg;
+ struct pim_msdp_mg_mbr *mbr;
+
+ if (!mg || strcmp(mg->mesh_group_name, mesh_group_name)) {
+ return PIM_MSDP_ERR_NO_MG;
+ }
+
+ /* delete all the mesh-group members */
+ while (!list_isempty(mg->mbr_list)) {
+ mbr = listnode_head(mg->mbr_list);
+ pim_msdp_mg_mbr_do_del(mg, mbr);
+ }
+
+ /* clear src ip */
+ mg->src_ip.s_addr = INADDR_ANY;
+
+ /* free up the mesh-group */
+ pim_msdp_mg_free(mg);
+ return PIM_MSDP_ERR_NONE;
+}
+
+static enum pim_msdp_err
+pim_msdp_mg_add(const char *mesh_group_name)
+{
+ if (msdp->mg) {
+ if (!strcmp(msdp->mg->mesh_group_name, mesh_group_name)) {
+ return PIM_MSDP_ERR_NONE;
+ }
+ /* currently only one mesh-group can exist at a time */
+ return PIM_MSDP_ERR_MAX_MESH_GROUPS;
+ }
+
+ msdp->mg = pim_msdp_mg_new(mesh_group_name);
+ if (!msdp->mg) {
+ return PIM_MSDP_ERR_OOM;
+ }
+
+ return PIM_MSDP_ERR_NONE;
+}
+
+static int
+pim_msdp_mg_mbr_comp(const void *p1, const void *p2)
+{
+ const struct pim_msdp_mg_mbr *mbr1 = p1;
+ const struct pim_msdp_mg_mbr *mbr2 = p2;
+
+ if (ntohl(mbr1->mbr_ip.s_addr) < ntohl(mbr2->mbr_ip.s_addr))
+ return -1;
+
+ if (ntohl(mbr1->mbr_ip.s_addr) > ntohl(mbr2->mbr_ip.s_addr))
+ return 1;
+
+ return 0;
+}
+
+static void
+pim_msdp_mg_mbr_free(struct pim_msdp_mg_mbr *mbr)
+{
+ XFREE(MTYPE_PIM_MSDP_MG_MBR, mbr);
+}
+
+static struct pim_msdp_mg_mbr *
+pim_msdp_mg_mbr_find(struct in_addr mbr_ip)
+{
+ struct pim_msdp_mg_mbr *mbr;
+ struct listnode *mbr_node;
+
+ if (!msdp->mg) {
+ return NULL;
+ }
+ /* we can move this to a hash but considering that number of peers in
+ * a mesh-group that seems like bit of an overkill */
+ for (ALL_LIST_ELEMENTS_RO(msdp->mg->mbr_list, mbr_node, mbr)) {
+ if (mbr->mbr_ip.s_addr == mbr_ip.s_addr) {
+ return mbr;
+ }
+ }
+ return mbr;
+}
+
+enum pim_msdp_err
+pim_msdp_mg_mbr_add(const char *mesh_group_name, struct in_addr mbr_ip)
+{
+ int rc;
+ struct pim_msdp_mg_mbr *mbr;
+ struct pim_msdp_mg *mg;
+
+ rc = pim_msdp_mg_add(mesh_group_name);
+ if (rc != PIM_MSDP_ERR_NONE) {
+ return rc;
+ }
+
+ mg = msdp->mg;
+ mbr = pim_msdp_mg_mbr_find(mbr_ip);
+ if (mbr) {
+ return PIM_MSDP_ERR_MG_MBR_EXISTS;
+ }
+
+ mbr = XCALLOC(MTYPE_PIM_MSDP_MG_MBR, sizeof(*mbr));
+ if (!mbr) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure",
+ __PRETTY_FUNCTION__, sizeof(*mbr));
+ /* if there are no references to the mg free it */
+ pim_msdp_mg_free(mg);
+ return PIM_MSDP_ERR_OOM;
+ }
+ mbr->mbr_ip = mbr_ip;
+ listnode_add_sort(mg->mbr_list, mbr);
+
+ /* if valid SIP has been configured add peer session */
+ if (mg->src_ip.s_addr != INADDR_ANY) {
+ pim_msdp_peer_add(mbr_ip, mg->src_ip, mesh_group_name,
+ &mbr->mp);
+ }
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ char ip_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<mbr?>", mbr->mbr_ip, ip_str, sizeof(ip_str));
+ zlog_debug("MSDP mesh-group %s mbr %s created", mg->mesh_group_name, ip_str);
+ }
+ ++mg->mbr_cnt;
+ return PIM_MSDP_ERR_NONE;
+}
+
+static void
+pim_msdp_mg_mbr_do_del(struct pim_msdp_mg *mg, struct pim_msdp_mg_mbr *mbr)
+{
+ /* Delete active peer session if any */
+ if (mbr->mp) {
+ pim_msdp_peer_do_del(mbr->mp);
+ }
+
+ listnode_delete(mg->mbr_list, mbr);
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ char ip_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<mbr?>", mbr->mbr_ip, ip_str, sizeof(ip_str));
+ zlog_debug("MSDP mesh-group %s mbr %s deleted", mg->mesh_group_name, ip_str);
+ }
+ pim_msdp_mg_mbr_free(mbr);
+ if (mg->mbr_cnt) {
+ --mg->mbr_cnt;
+ }
+}
+
+enum pim_msdp_err
+pim_msdp_mg_mbr_del(const char *mesh_group_name, struct in_addr mbr_ip)
+{
+ struct pim_msdp_mg_mbr *mbr;
+ struct pim_msdp_mg *mg = msdp->mg;
+
+ if (!mg || strcmp(mg->mesh_group_name, mesh_group_name)) {
+ return PIM_MSDP_ERR_NO_MG;
+ }
+
+ mbr = pim_msdp_mg_mbr_find(mbr_ip);
+ if (!mbr) {
+ return PIM_MSDP_ERR_NO_MG_MBR;
+ }
+
+ pim_msdp_mg_mbr_do_del(mg, mbr);
+ /* if there are no references to the mg free it */
+ pim_msdp_mg_free(mg);
+
+ return PIM_MSDP_ERR_NONE;
+}
+
+static void
+pim_msdp_mg_src_do_del(void)
+{
+ struct pim_msdp_mg_mbr *mbr;
+ struct listnode *mbr_node;
+ struct pim_msdp_mg *mg = msdp->mg;
+
+ /* SIP is being removed - tear down all active peer sessions */
+ for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbr_node, mbr)) {
+ if (mbr->mp) {
+ pim_msdp_peer_do_del(mbr->mp);
+ mbr->mp = NULL;
+ }
+ }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP mesh-group %s src cleared", mg->mesh_group_name);
+ }
+}
+
+enum pim_msdp_err
+pim_msdp_mg_src_del(const char *mesh_group_name)
+{
+ struct pim_msdp_mg *mg = msdp->mg;
+
+ if (!mg || strcmp(mg->mesh_group_name, mesh_group_name)) {
+ return PIM_MSDP_ERR_NO_MG;
+ }
+
+ if (mg->src_ip.s_addr != INADDR_ANY) {
+ mg->src_ip.s_addr = INADDR_ANY;
+ pim_msdp_mg_src_do_del();
+ /* if there are no references to the mg free it */
+ pim_msdp_mg_free(mg);
+ }
+ return PIM_MSDP_ERR_NONE;
+}
+
+enum pim_msdp_err
+pim_msdp_mg_src_add(const char *mesh_group_name, struct in_addr src_ip)
+{
+ int rc;
+ struct pim_msdp_mg_mbr *mbr;
+ struct listnode *mbr_node;
+ struct pim_msdp_mg *mg;
+
+ if (src_ip.s_addr == INADDR_ANY) {
+ pim_msdp_mg_src_del(mesh_group_name);
+ return PIM_MSDP_ERR_NONE;
+ }
+
+ rc = pim_msdp_mg_add(mesh_group_name);
+ if (rc != PIM_MSDP_ERR_NONE) {
+ return rc;
+ }
+
+ mg = msdp->mg;
+ if (mg->src_ip.s_addr != INADDR_ANY) {
+ pim_msdp_mg_src_do_del();
+ }
+ mg->src_ip = src_ip;
+
+ for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbr_node, mbr)) {
+ pim_msdp_peer_add(mbr->mbr_ip, mg->src_ip, mesh_group_name,
+ &mbr->mp);
+ }
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ char ip_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", mg->src_ip, ip_str, sizeof(ip_str));
+ zlog_debug("MSDP mesh-group %s src %s set", mg->mesh_group_name, ip_str);
+ }
+ return PIM_MSDP_ERR_NONE;
+}
+
+/*********************** MSDP feature APIs *********************************/
+int
+pim_msdp_config_write(struct vty *vty)
+{
+ struct listnode *mbrnode;
+ struct pim_msdp_mg_mbr *mbr;
+ struct pim_msdp_mg *mg = msdp->mg;
+ char mbr_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ int count = 0;
+
+ if (!mg) {
+ return count;
+ }
+
+ if (mg->src_ip.s_addr != INADDR_ANY) {
+ pim_inet4_dump("<src?>", mg->src_ip, src_str, sizeof(src_str));
+ vty_out(vty, "ip msdp mesh-group %s source %s%s",
+ mg->mesh_group_name, src_str, VTY_NEWLINE);
+ ++count;
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
+ pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
+ vty_out(vty, "ip msdp mesh-group %s member %s%s",
+ mg->mesh_group_name, mbr_str, VTY_NEWLINE);
+ ++count;
+ }
+ return count;
+}
+
+/* Enable feature including active/periodic timers etc. on the first peer
+ * config. Till then MSDP should just stay quiet. */
+static void
+pim_msdp_enable(void)
+{
+ if (msdp->flags & PIM_MSDPF_ENABLE) {
+ /* feature is already enabled */
+ return;
+ }
+ msdp->flags |= PIM_MSDPF_ENABLE;
+ msdp->work_obuf = stream_new(PIM_MSDP_MAX_PACKET_SIZE);
+ pim_msdp_sa_adv_timer_setup(true /* start */);
+ /* setup sa cache based on local sources */
+ pim_msdp_sa_local_setup();
+}
+
+/* MSDP init */
+void
+pim_msdp_init(struct thread_master *master)
+{
+ msdp->master = master;
+
+ msdp->peer_hash = hash_create(pim_msdp_peer_hash_key_make,
+ pim_msdp_peer_hash_eq);
+ msdp->peer_list = list_new();
+ msdp->peer_list->del = (void (*)(void *))pim_msdp_peer_free;
+ msdp->peer_list->cmp = (int (*)(void *, void *))pim_msdp_peer_comp;
+
+ msdp->sa_hash = hash_create(pim_msdp_sa_hash_key_make,
+ pim_msdp_sa_hash_eq);
+ msdp->sa_list = list_new();
+ msdp->sa_list->del = (void (*)(void *))pim_msdp_sa_free;
+ msdp->sa_list->cmp = (int (*)(void *, void *))pim_msdp_sa_comp;
+}
+
+/* counterpart to MSDP init; XXX: unused currently */
+void
+pim_msdp_exit(void)
+{
+ /* XXX: stop listener and delete all peer sessions */
+
+ if (msdp->peer_hash) {
+ hash_free(msdp->peer_hash);
+ msdp->peer_hash = NULL;
+ }
+
+ if (msdp->peer_list) {
+ list_free(msdp->peer_list);
+ msdp->peer_list = NULL;
+ }
+}
diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h
new file mode 100644
index 0000000000..33c1d88a45
--- /dev/null
+++ b/pimd/pim_msdp.h
@@ -0,0 +1,233 @@
+/*
+ * IP MSDP for Quagga
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#ifndef PIM_MSDP_H
+#define PIM_MSDP_H
+
+enum pim_msdp_peer_state {
+ PIM_MSDP_DISABLED,
+ PIM_MSDP_INACTIVE,
+ PIM_MSDP_LISTEN,
+ PIM_MSDP_CONNECTING,
+ PIM_MSDP_ESTABLISHED
+};
+
+/* SA and KA TLVs are processed; rest ignored */
+enum pim_msdp_tlv {
+ PIM_MSDP_V4_SOURCE_ACTIVE = 1,
+ PIM_MSDP_V4_SOURCE_ACTIVE_REQUEST,
+ PIM_MSDP_V4_SOURCE_ACTIVE_RESPONSE,
+ PIM_MSDP_KEEPALIVE,
+ PIM_MSDP_RESERVED,
+ PIM_MSDP_TRACEROUTE_PROGRESS,
+ PIM_MSDP_TRACEROUTE_REPLY,
+};
+
+/* MSDP error codes */
+enum pim_msdp_err {
+ PIM_MSDP_ERR_NONE = 0,
+ PIM_MSDP_ERR_OOM = -1,
+ PIM_MSDP_ERR_PEER_EXISTS = -2,
+ PIM_MSDP_ERR_MAX_MESH_GROUPS = -3,
+ PIM_MSDP_ERR_NO_PEER = -4,
+ PIM_MSDP_ERR_MG_MBR_EXISTS = -5,
+ PIM_MSDP_ERR_NO_MG = -6,
+ PIM_MSDP_ERR_NO_MG_MBR = -7,
+ PIM_MSDP_ERR_SIP_EQ_DIP = -8,
+};
+
+#define PIM_MSDP_STATE_STRLEN 16
+#define PIM_MSDP_UPTIME_STRLEN 80
+#define PIM_MSDP_TIMER_STRLEN 12
+#define PIM_MSDP_TCP_PORT 639
+#define PIM_MSDP_SOCKET_SNDBUF_SIZE 65536
+
+enum pim_msdp_sa_flags {
+ PIM_MSDP_SAF_NONE = 0,
+ /* There are two cases where we can pickup an active source locally -
+ * 1. We are RP and got a source-register from the FHR
+ * 2. We are RP and FHR and learnt a new directly connected source on a
+ * DR interface */
+ PIM_MSDP_SAF_LOCAL = (1 << 0),
+ /* We got this in the MSDP SA TLV from a peer (and this passed peer-RPF
+ * checks) */
+ PIM_MSDP_SAF_PEER = (1 << 1),
+ PIM_MSDP_SAF_REF = (PIM_MSDP_SAF_LOCAL | PIM_MSDP_SAF_PEER),
+ PIM_MSDP_SAF_STALE = (1 << 2), /* local entries can get kicked out on
+ * misc pim events such as RP change */
+ PIM_MSDP_SAF_UP_DEL_IN_PROG = (1 << 3)
+};
+
+struct pim_msdp_sa {
+ struct prefix_sg sg;
+ char sg_str[PIM_SG_LEN];
+ struct in_addr rp; /* Last RP address associated with this SA */
+ struct in_addr peer; /* last peer from who we heard this SA */
+ enum pim_msdp_sa_flags flags;
+
+ /* rfc-3618 is missing default value for SA-hold-down-Period. pulled
+ * this number from industry-standards */
+#define PIM_MSDP_SA_HOLD_TIME ((3*60)+30)
+ struct thread *sa_state_timer; // 5.6
+ int64_t uptime;
+
+ struct pim_upstream *up;
+};
+
+enum pim_msdp_peer_flags {
+ PIM_MSDP_PEERF_NONE = 0,
+ PIM_MSDP_PEERF_LISTENER = (1 << 0),
+#define PIM_MSDP_PEER_IS_LISTENER(mp) (mp->flags & PIM_MSDP_PEERF_LISTENER)
+ PIM_MSDP_PEERF_SA_JUST_SENT = (1 << 1)
+};
+
+struct pim_msdp_peer {
+ /* configuration */
+ struct in_addr local;
+ struct in_addr peer;
+ char *mesh_group_name;
+ char key_str[INET_ADDRSTRLEN];
+
+ /* state */
+ enum pim_msdp_peer_state state;
+ enum pim_msdp_peer_flags flags;
+
+ /* TCP socket info */
+ union sockunion su_local;
+ union sockunion su_peer;
+ int fd;
+
+ /* protocol timers */
+#define PIM_MSDP_PEER_HOLD_TIME 75
+ struct thread *hold_timer; // 5.4
+#define PIM_MSDP_PEER_KA_TIME 60
+ struct thread *ka_timer; // 5.5
+#define PIM_MSDP_PEER_CONNECT_RETRY_TIME 30
+ struct thread *cr_timer; // 5.6
+
+ /* packet thread and buffers */
+ uint32_t packet_size;
+ struct stream *ibuf;
+ struct stream_fifo *obuf;
+ struct thread *t_read;
+ struct thread *t_write;
+
+ /* stats */
+ uint32_t conn_attempts;
+ uint32_t est_flaps;
+ uint32_t sa_cnt; /* number of SAs attributed to this peer */
+#define PIM_MSDP_PEER_LAST_RESET_STR 20
+ char last_reset[PIM_MSDP_PEER_LAST_RESET_STR];
+
+ /* packet stats */
+ uint32_t ka_tx_cnt;
+ uint32_t sa_tx_cnt;
+ uint32_t ka_rx_cnt;
+ uint32_t sa_rx_cnt;
+ uint32_t unk_rx_cnt;
+
+ /* timestamps */
+ int64_t uptime;
+};
+
+struct pim_msdp_mg_mbr {
+ struct in_addr mbr_ip;
+ struct pim_msdp_peer *mp;
+};
+
+/* PIM MSDP mesh-group */
+struct pim_msdp_mg {
+ char *mesh_group_name;
+ struct in_addr src_ip;
+ uint32_t mbr_cnt;
+ struct list *mbr_list;
+};
+
+enum pim_msdp_flags {
+ PIM_MSDPF_NONE = 0,
+ PIM_MSDPF_ENABLE = (1 << 0),
+ PIM_MSDPF_LISTENER = (1 << 1)
+};
+
+struct pim_msdp_listener {
+ int fd;
+ union sockunion su;
+ struct thread *thread;
+};
+
+struct pim_msdp {
+ enum pim_msdp_flags flags;
+ struct thread_master *master;
+ struct pim_msdp_listener listener;
+ uint32_t rejected_accepts;
+
+ /* MSDP peer info */
+ struct hash *peer_hash;
+ struct list *peer_list;
+
+ /* MSDP active-source info */
+#define PIM_MSDP_SA_ADVERTISMENT_TIME 60
+ struct thread *sa_adv_timer; // 5.6
+ struct hash *sa_hash;
+ struct list *sa_list;
+ uint32_t local_cnt;
+
+ /* keep a scratch pad for building SA TLVs */
+ struct stream *work_obuf;
+
+ struct in_addr originator_id;
+
+ /* currently only one mesh-group is supported - so just stash it here */
+ struct pim_msdp_mg *mg;
+};
+
+#define PIM_MSDP_PEER_READ_ON(mp) THREAD_READ_ON(msdp->master, mp->t_read, pim_msdp_read, mp, mp->fd);
+#define PIM_MSDP_PEER_WRITE_ON(mp) THREAD_WRITE_ON(msdp->master, mp->t_write, pim_msdp_write, mp, mp->fd);
+
+#define PIM_MSDP_PEER_READ_OFF(mp) THREAD_READ_OFF(mp->t_read)
+#define PIM_MSDP_PEER_WRITE_OFF(mp) THREAD_WRITE_OFF(mp->t_write)
+
+extern struct pim_msdp *msdp;
+void pim_msdp_init(struct thread_master *master);
+void pim_msdp_exit(void);
+enum pim_msdp_err pim_msdp_peer_add(struct in_addr peer, struct in_addr local, const char *mesh_group_name, struct pim_msdp_peer **mp_p);
+enum pim_msdp_err pim_msdp_peer_del(struct in_addr peer_addr);
+char *pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf, int buf_size);
+struct pim_msdp_peer *pim_msdp_peer_find(struct in_addr peer_addr);
+void pim_msdp_peer_established(struct pim_msdp_peer *mp);
+void pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp);
+void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state);
+void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str);
+int pim_msdp_write(struct thread *thread);
+char *pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size, bool long_format);
+int pim_msdp_config_write(struct vty *vty);
+void pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp);
+void pim_msdp_sa_ref(struct pim_msdp_peer *mp, struct prefix_sg *sg, struct in_addr rp);
+void pim_msdp_sa_local_update(struct pim_upstream *up);
+void pim_msdp_sa_local_del(struct prefix_sg *sg);
+void pim_msdp_i_am_rp_changed(void);
+bool pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp);
+void pim_msdp_up_join_state_changed(struct pim_upstream *xg_up);
+void pim_msdp_up_del(struct prefix_sg *sg);
+enum pim_msdp_err pim_msdp_mg_mbr_add(const char *mesh_group_name, struct in_addr mbr_ip);
+enum pim_msdp_err pim_msdp_mg_mbr_del(const char *mesh_group_name, struct in_addr mbr_ip);
+enum pim_msdp_err pim_msdp_mg_src_del(const char *mesh_group_name);
+enum pim_msdp_err pim_msdp_mg_src_add(const char *mesh_group_name, struct in_addr src_ip);
+enum pim_msdp_err pim_msdp_mg_del(const char *mesh_group_name);
+#endif
diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c
new file mode 100644
index 0000000000..fbf34cd91c
--- /dev/null
+++ b/pimd/pim_msdp_packet.c
@@ -0,0 +1,696 @@
+/*
+ * IP MSDP packet helper
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#include <zebra.h>
+
+#include <lib/log.h>
+#include <lib/network.h>
+#include <lib/stream.h>
+#include <lib/thread.h>
+#include <lib/vty.h>
+
+#include "pimd.h"
+#include "pim_str.h"
+
+#include "pim_msdp.h"
+#include "pim_msdp_packet.h"
+#include "pim_msdp_socket.h"
+
+static char *
+pim_msdp_pkt_type_dump(enum pim_msdp_tlv type, char *buf, int buf_size)
+{
+ switch (type) {
+ case PIM_MSDP_V4_SOURCE_ACTIVE:
+ snprintf(buf, buf_size, "%s", "SA");
+ break;
+ case PIM_MSDP_V4_SOURCE_ACTIVE_REQUEST:
+ snprintf(buf, buf_size, "%s", "SA_REQ");
+ break;
+ case PIM_MSDP_V4_SOURCE_ACTIVE_RESPONSE:
+ snprintf(buf, buf_size, "%s", "SA_RESP");
+ break;
+ case PIM_MSDP_KEEPALIVE:
+ snprintf(buf, buf_size, "%s", "KA");
+ break;
+ case PIM_MSDP_RESERVED:
+ snprintf(buf, buf_size, "%s", "RSVD");
+ break;
+ case PIM_MSDP_TRACEROUTE_PROGRESS:
+ snprintf(buf, buf_size, "%s", "TRACE_PROG");
+ break;
+ case PIM_MSDP_TRACEROUTE_REPLY:
+ snprintf(buf, buf_size, "%s", "TRACE_REPLY");
+ break;
+ default:
+ snprintf(buf, buf_size, "UNK-%d", type);
+ }
+ return buf;
+}
+
+static void
+pim_msdp_pkt_sa_dump_one(struct stream *s)
+{
+ struct prefix_sg sg;
+
+ /* just throw away the three reserved bytes */
+ stream_get3(s);
+ /* throw away the prefix length also */
+ stream_getc(s);
+
+ memset(&sg, 0, sizeof (struct prefix_sg));
+ sg.grp.s_addr = stream_get_ipv4(s);
+ sg.src.s_addr = stream_get_ipv4(s);
+
+ zlog_debug(" sg %s", pim_str_sg_dump(&sg));
+}
+
+static void
+pim_msdp_pkt_sa_dump(struct stream *s)
+{
+ int entry_cnt;
+ int i;
+ struct in_addr rp; /* Last RP address associated with this SA */
+
+ entry_cnt = stream_getc(s);
+ rp.s_addr = stream_get_ipv4(s);
+
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ char rp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<rp?>", rp, rp_str, sizeof(rp_str));
+ zlog_debug(" entry_cnt %d rp %s", entry_cnt, rp_str);
+ }
+
+ /* dump SAs */
+ for (i = 0; i < entry_cnt; ++i) {
+ pim_msdp_pkt_sa_dump_one(s);
+ }
+}
+
+static void
+pim_msdp_pkt_dump(struct pim_msdp_peer *mp, int type, int len, bool rx,
+ struct stream *s)
+{
+ char type_str[PIM_MSDP_PKT_TYPE_STRLEN];
+
+ pim_msdp_pkt_type_dump(type, type_str, sizeof(type_str));
+
+ zlog_debug("MSDP peer %s pkt %s type %s len %d",
+ mp->key_str, rx?"rx":"tx", type_str, len);
+
+ if (!s) {
+ return;
+ }
+
+ switch(type) {
+ case PIM_MSDP_V4_SOURCE_ACTIVE:
+ pim_msdp_pkt_sa_dump(s);
+ break;
+ default:;
+ }
+}
+
+/* Check file descriptor whether connect is established. */
+static void
+pim_msdp_connect_check(struct pim_msdp_peer *mp)
+{
+ int status;
+ socklen_t slen;
+ int ret;
+
+ if (mp->state != PIM_MSDP_CONNECTING) {
+ /* if we are here it means we are not in a connecting or established state
+ * for now treat this as a fatal error */
+ pim_msdp_peer_reset_tcp_conn(mp, "invalid-state");
+ return;
+ }
+
+ PIM_MSDP_PEER_READ_OFF(mp);
+ PIM_MSDP_PEER_WRITE_OFF(mp);
+
+ /* Check file descriptor. */
+ slen = sizeof(status);
+ ret = getsockopt(mp->fd, SOL_SOCKET, SO_ERROR, (void *)&status, &slen);
+
+ /* If getsockopt is fail, this is fatal error. */
+ if (ret < 0) {
+ zlog_err("can't get sockopt for nonblocking connect");
+ pim_msdp_peer_reset_tcp_conn(mp, "connect-failed");
+ return;
+ }
+
+ /* When status is 0 then TCP connection is established. */
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_connect_check %s", mp->key_str, status?"fail":"success");
+ }
+ if (status == 0) {
+ pim_msdp_peer_established(mp);
+ } else {
+ pim_msdp_peer_reset_tcp_conn(mp, "connect-failed");
+ }
+}
+
+static void
+pim_msdp_pkt_delete(struct pim_msdp_peer *mp)
+{
+ stream_free(stream_fifo_pop(mp->obuf));
+}
+
+static void
+pim_msdp_pkt_add(struct pim_msdp_peer *mp, struct stream *s)
+{
+ stream_fifo_push(mp->obuf, s);
+}
+
+static void
+pim_msdp_write_proceed_actions(struct pim_msdp_peer *mp)
+{
+ if (stream_fifo_head(mp->obuf)) {
+ PIM_MSDP_PEER_WRITE_ON(mp);
+ }
+}
+
+int
+pim_msdp_write(struct thread *thread)
+{
+ struct pim_msdp_peer *mp;
+ struct stream *s;
+ int num;
+ enum pim_msdp_tlv type;
+ int len;
+ int work_cnt = 0;
+ int work_max_cnt = 100;
+
+ mp = THREAD_ARG(thread);
+ mp->t_write = NULL;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_write", mp->key_str);
+ }
+ if (mp->fd < 0) {
+ return -1;
+ }
+
+ /* check if TCP connection is established */
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ pim_msdp_connect_check(mp);
+ return 0;
+ }
+
+ s = stream_fifo_head(mp->obuf);
+ if (!s) {
+ pim_msdp_write_proceed_actions(mp);
+ return 0;
+ }
+
+ sockopt_cork(mp->fd, 1);
+
+ /* Nonblocking write until TCP output buffer is full */
+ do
+ {
+ int writenum;
+
+ /* Number of bytes to be sent */
+ writenum = stream_get_endp(s) - stream_get_getp(s);
+
+ /* Call write() system call */
+ num = write(mp->fd, STREAM_PNT(s), writenum);
+ if (num < 0) {
+ /* write failed either retry needed or error */
+ if (ERRNO_IO_RETRY(errno)) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_write io retry", mp->key_str);
+ }
+ break;
+ }
+
+ pim_msdp_peer_reset_tcp_conn(mp, "pkt-tx-failed");
+ return 0;
+ }
+
+ if (num != writenum) {
+ /* Partial write */
+ stream_forward_getp(s, num);
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_partial_write", mp->key_str);
+ }
+ break;
+ }
+
+ /* Retrieve msdp packet type. */
+ stream_set_getp(s,0);
+ type = stream_getc(s);
+ len = stream_getw(s);
+ switch (type)
+ {
+ case PIM_MSDP_KEEPALIVE:
+ mp->ka_tx_cnt++;
+ break;
+ case PIM_MSDP_V4_SOURCE_ACTIVE:
+ mp->sa_tx_cnt++;
+ break;
+ default:;
+ }
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ pim_msdp_pkt_dump(mp, type, len, false /*rx*/, s);
+ }
+
+ /* packet sent delete it. */
+ pim_msdp_pkt_delete(mp);
+
+ ++work_cnt;
+ /* may need to pause if we have done too much work in this
+ * loop */
+ if (work_cnt >= work_max_cnt) {
+ break;
+ }
+ } while ((s = stream_fifo_head(mp->obuf)) != NULL);
+ pim_msdp_write_proceed_actions(mp);
+
+ sockopt_cork(mp->fd, 0);
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_write wrote %d packets", mp->key_str, work_cnt);
+ }
+
+ return 0;
+}
+
+static void
+pim_msdp_pkt_send(struct pim_msdp_peer *mp, struct stream *s)
+{
+ /* Add packet to the end of list. */
+ pim_msdp_pkt_add(mp, s);
+
+ PIM_MSDP_PEER_WRITE_ON(mp);
+}
+
+void
+pim_msdp_pkt_ka_tx(struct pim_msdp_peer *mp)
+{
+ struct stream *s;
+
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ /* don't tx anything unless a session is established */
+ return;
+ }
+ s = stream_new(PIM_MSDP_KA_TLV_MAX_SIZE);
+ stream_putc(s, PIM_MSDP_KEEPALIVE);
+ stream_putw(s, PIM_MSDP_KA_TLV_MAX_SIZE);
+
+ pim_msdp_pkt_send(mp, s);
+}
+
+static void
+pim_msdp_pkt_sa_push_to_one_peer(struct pim_msdp_peer *mp)
+{
+ struct stream *s;
+
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ /* don't tx anything unless a session is established */
+ return;
+ }
+ s = stream_dup(msdp->work_obuf);
+ if (s) {
+ pim_msdp_pkt_send(mp, s);
+ mp->flags |= PIM_MSDP_PEERF_SA_JUST_SENT;
+ }
+}
+
+/* push the stream into the obuf fifo of all the peers */
+static void
+pim_msdp_pkt_sa_push(struct pim_msdp_peer *mp)
+{
+ struct listnode *mpnode;
+
+ if (mp) {
+ pim_msdp_pkt_sa_push_to_one_peer(mp);
+ } else {
+ for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_pkt_sa_push", mp->key_str);
+ }
+ pim_msdp_pkt_sa_push_to_one_peer(mp);
+ }
+ }
+}
+
+static int
+pim_msdp_pkt_sa_fill_hdr(int local_cnt)
+{
+ int curr_tlv_ecnt;
+
+ stream_reset(msdp->work_obuf);
+ curr_tlv_ecnt = local_cnt>PIM_MSDP_SA_MAX_ENTRY_CNT?PIM_MSDP_SA_MAX_ENTRY_CNT:local_cnt;
+ local_cnt -= curr_tlv_ecnt;
+ stream_putc(msdp->work_obuf, PIM_MSDP_V4_SOURCE_ACTIVE);
+ stream_putw(msdp->work_obuf, PIM_MSDP_SA_ENTRY_CNT2SIZE(curr_tlv_ecnt));
+ stream_putc(msdp->work_obuf, curr_tlv_ecnt);
+ stream_put_ipv4(msdp->work_obuf, msdp->originator_id.s_addr);
+
+ return local_cnt;
+}
+
+static void
+pim_msdp_pkt_sa_fill_one(struct pim_msdp_sa *sa)
+{
+ stream_put3(msdp->work_obuf, 0 /* reserved */);
+ stream_putc(msdp->work_obuf, 32 /* sprefix len */);
+ stream_put_ipv4(msdp->work_obuf, sa->sg.grp.s_addr);
+ stream_put_ipv4(msdp->work_obuf, sa->sg.src.s_addr);
+}
+
+static void
+pim_msdp_pkt_sa_gen(struct pim_msdp_peer *mp)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ int sa_count;
+ int local_cnt = msdp->local_cnt;
+
+ sa_count = 0;
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug(" sa gen %d", local_cnt);
+ }
+
+ local_cnt = pim_msdp_pkt_sa_fill_hdr(local_cnt);
+
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
+ /* current implementation of MSDP is for anycast i.e. full mesh. so
+ * no re-forwarding of SAs that we learnt from other peers */
+ continue;
+ }
+ /* add sa into scratch pad */
+ pim_msdp_pkt_sa_fill_one(sa);
+ ++sa_count;
+ if (sa_count >= PIM_MSDP_SA_MAX_ENTRY_CNT) {
+ pim_msdp_pkt_sa_push(mp);
+ /* reset headers */
+ sa_count = 0;
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug(" sa gen for remainder %d", local_cnt);
+ }
+ local_cnt = pim_msdp_pkt_sa_fill_hdr(local_cnt);
+ }
+ }
+
+ if (sa_count) {
+ pim_msdp_pkt_sa_push(mp);
+ }
+ return;
+}
+
+static void
+pim_msdp_pkt_sa_tx_done(void)
+{
+ struct listnode *mpnode;
+ struct pim_msdp_peer *mp;
+
+ /* if SA were sent to the peers we restart ka timer and avoid
+ * unnecessary ka noise */
+ for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+ if (mp->flags & PIM_MSDP_PEERF_SA_JUST_SENT) {
+ mp->flags &= ~PIM_MSDP_PEERF_SA_JUST_SENT;
+ pim_msdp_peer_pkt_txed(mp);
+ }
+ }
+}
+
+void
+pim_msdp_pkt_sa_tx(void)
+{
+ pim_msdp_pkt_sa_gen(NULL /* mp */);
+ pim_msdp_pkt_sa_tx_done();
+}
+
+void
+pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa)
+{
+ pim_msdp_pkt_sa_fill_hdr(1 /* cnt */);
+ pim_msdp_pkt_sa_fill_one(sa);
+ pim_msdp_pkt_sa_push(NULL);
+ pim_msdp_pkt_sa_tx_done();
+}
+
+/* when a connection is first established we push all SAs immediately */
+void
+pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp)
+{
+ pim_msdp_pkt_sa_gen(mp);
+ pim_msdp_pkt_sa_tx_done();
+}
+
+static void
+pim_msdp_pkt_rxed_with_fatal_error(struct pim_msdp_peer *mp)
+{
+ pim_msdp_peer_reset_tcp_conn(mp, "invalid-pkt-rx");
+}
+
+static void
+pim_msdp_pkt_ka_rx(struct pim_msdp_peer *mp, int len)
+{
+ mp->ka_rx_cnt++;
+ if (len != PIM_MSDP_KA_TLV_MAX_SIZE) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return;
+ }
+ pim_msdp_peer_pkt_rxed(mp);
+}
+
+static void
+pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
+{
+ int prefix_len;
+ struct prefix_sg sg;
+
+ /* just throw away the three reserved bytes */
+ stream_get3(mp->ibuf);
+ prefix_len = stream_getc(mp->ibuf);
+
+ memset(&sg, 0, sizeof (struct prefix_sg));
+ sg.grp.s_addr = stream_get_ipv4(mp->ibuf);
+ sg.src.s_addr = stream_get_ipv4(mp->ibuf);
+
+ if (prefix_len != 32) {
+ /* ignore SA update if the prefix length is not 32 */
+ zlog_err("rxed sa update with invalid prefix length %d", prefix_len);
+ return;
+ }
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ zlog_debug(" sg %s", pim_str_sg_dump(&sg));
+ }
+ pim_msdp_sa_ref(mp, &sg, rp);
+}
+
+static void
+pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len)
+{
+ int entry_cnt;
+ int i;
+ struct in_addr rp; /* Last RP address associated with this SA */
+
+ mp->sa_rx_cnt++;
+
+ if (len < PIM_MSDP_SA_TLV_MIN_SIZE) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return;
+ }
+
+ entry_cnt = stream_getc(mp->ibuf);
+ /* some vendors include the actual multicast data in the tlv (at the end).
+ * we will ignore such data. in the future we may consider pushing it down
+ * the RPT */
+ if (len < PIM_MSDP_SA_ENTRY_CNT2SIZE(entry_cnt)) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return;
+ }
+ rp.s_addr = stream_get_ipv4(mp->ibuf);
+
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ char rp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<rp?>", rp, rp_str, sizeof(rp_str));
+ zlog_debug(" entry_cnt %d rp %s", entry_cnt, rp_str);
+ }
+
+ if (!pim_msdp_peer_rpf_check(mp, rp)) {
+ /* if peer-RPF check fails don't process the packet any further */
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ zlog_debug(" peer RPF check failed");
+ }
+ return;
+ }
+
+ pim_msdp_peer_pkt_rxed(mp);
+
+ /* update SA cache */
+ for (i = 0; i < entry_cnt; ++i) {
+ pim_msdp_pkt_sa_rx_one(mp, rp);
+ }
+}
+
+static void
+pim_msdp_pkt_rx(struct pim_msdp_peer *mp)
+{
+ enum pim_msdp_tlv type;
+ int len;
+
+ /* re-read type and len */
+ type = stream_getc_from(mp->ibuf, 0);
+ len = stream_getw_from(mp->ibuf, 1);
+ if (len < PIM_MSDP_HEADER_SIZE) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return;
+ }
+
+ if (len > PIM_MSDP_SA_TLV_MAX_SIZE) {
+ /* if tlv size if greater than max just ignore the tlv */
+ return;
+ }
+
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ pim_msdp_pkt_dump(mp, type, len, true /*rx*/, NULL /*s*/);
+ }
+
+ switch(type) {
+ case PIM_MSDP_KEEPALIVE:
+ pim_msdp_pkt_ka_rx(mp, len);
+ break;
+ case PIM_MSDP_V4_SOURCE_ACTIVE:
+ mp->sa_rx_cnt++;
+ pim_msdp_pkt_sa_rx(mp, len);
+ break;
+ default:
+ mp->unk_rx_cnt++;
+ }
+}
+
+/* pim msdp read utility function. */
+static int
+pim_msdp_read_packet(struct pim_msdp_peer *mp)
+{
+ int nbytes;
+ int readsize;
+ int old_endp;
+ int new_endp;
+
+ old_endp = stream_get_endp(mp->ibuf);
+ readsize = mp->packet_size - old_endp;
+ if (!readsize) {
+ return 0;
+ }
+
+ /* Read packet from fd */
+ nbytes = stream_read_try(mp->ibuf, mp->fd, readsize);
+ new_endp = stream_get_endp(mp->ibuf);
+ if (nbytes < 0) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s read failed %d", mp->key_str, nbytes);
+ }
+ if (nbytes == -2) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_read io retry old_end: %d new_end: %d", mp->key_str, old_endp, new_endp);
+ }
+ /* transient error retry */
+ return -1;
+ }
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return -1;
+ }
+
+ if (!nbytes) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s read failed %d", mp->key_str, nbytes);
+ }
+ pim_msdp_peer_reset_tcp_conn(mp, "peer-down");
+ return -1;
+ }
+
+ /* We read partial packet. */
+ if (stream_get_endp(mp->ibuf) != mp->packet_size) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s read partial len %d old_endp %d new_endp %d", mp->key_str, mp->packet_size, old_endp, new_endp);
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+pim_msdp_read(struct thread *thread)
+{
+ struct pim_msdp_peer *mp;
+ int rc;
+ uint32_t len;
+
+ mp = THREAD_ARG(thread);
+ mp->t_read = NULL;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_read", mp->key_str);
+ }
+
+ if (mp->fd < 0) {
+ return -1;
+ }
+
+ /* check if TCP connection is established */
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ pim_msdp_connect_check(mp);
+ return 0;
+ }
+
+ PIM_MSDP_PEER_READ_ON(mp);
+
+ if (!mp->packet_size) {
+ mp->packet_size = PIM_MSDP_HEADER_SIZE;
+ }
+
+ if (stream_get_endp(mp->ibuf) < PIM_MSDP_HEADER_SIZE) {
+ /* start by reading the TLV header */
+ rc = pim_msdp_read_packet(mp);
+ if (rc < 0) {
+ goto pim_msdp_read_end;
+ }
+
+ /* Find TLV type and len */
+ stream_getc(mp->ibuf);
+ len = stream_getw(mp->ibuf);
+ if (len < PIM_MSDP_HEADER_SIZE) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ goto pim_msdp_read_end;
+ }
+ /* read complete TLV */
+ mp->packet_size = len;
+ }
+
+ rc = pim_msdp_read_packet(mp);
+ if (rc < 0) {
+ goto pim_msdp_read_end;
+ }
+
+ pim_msdp_pkt_rx(mp);
+
+ /* reset input buffers and get ready for the next packet */
+ mp->packet_size = 0;
+ stream_reset(mp->ibuf);
+
+pim_msdp_read_end:
+ return 0;
+}
diff --git a/pimd/pim_msdp_packet.h b/pimd/pim_msdp_packet.h
new file mode 100644
index 0000000000..f6fcfee6bb
--- /dev/null
+++ b/pimd/pim_msdp_packet.h
@@ -0,0 +1,72 @@
+/*
+ * IP MSDP packet helpers
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#ifndef PIM_MSDP_PACKET_H
+#define PIM_MSDP_PACKET_H
+
+/* type and length of a single tlv can be consider packet header */
+#define PIM_MSDP_HEADER_SIZE 3
+
+/* Keepalive TLV
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| 4 | 3 |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+#define PIM_MSDP_KA_TLV_MAX_SIZE PIM_MSDP_HEADER_SIZE
+
+/* Source-Active TLV (x=8, y=12xEntryCount)
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| 1 | x + y | Entry Count |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| RP Address |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| Reserved | Sprefix Len | \
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ \
+| Group Address | ) z
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /
+| Source Address | /
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+#define PIM_MSDP_SA_TLV_MAX_SIZE 9192
+#define PIM_MSDP_SA_X_SIZE 8
+#define PIM_MSDP_SA_ONE_ENTRY_SIZE 12
+#define PIM_MSDP_SA_Y_SIZE(entry_cnt) (PIM_MSDP_SA_ONE_ENTRY_SIZE * entry_cnt)
+#define PIM_MSDP_SA_ENTRY_CNT2SIZE(entry_cnt) (PIM_MSDP_SA_X_SIZE +\
+ PIM_MSDP_SA_Y_SIZE(entry_cnt))
+/* SA TLV has to have atleast only one entry in it so x=8 + y=12 */
+#define PIM_MSDP_SA_TLV_MIN_SIZE PIM_MSDP_SA_ENTRY_CNT2SIZE(1)
+/* XXX: theoretically we can fix a max of 255 but that may result in packet
+ * fragmentation */
+#define PIM_MSDP_SA_MAX_ENTRY_CNT 120
+
+#define PIM_MSDP_MAX_PACKET_SIZE max(PIM_MSDP_SA_TLV_MAX_SIZE, PIM_MSDP_KA_TLV_MAX_SIZE)
+
+#define PIM_MSDP_PKT_TYPE_STRLEN 16
+
+void pim_msdp_pkt_ka_tx(struct pim_msdp_peer *mp);
+int pim_msdp_read(struct thread *thread);
+void pim_msdp_pkt_sa_tx(void);
+void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa);
+void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp);
+
+#endif
diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c
new file mode 100644
index 0000000000..805e812cae
--- /dev/null
+++ b/pimd/pim_msdp_socket.c
@@ -0,0 +1,227 @@
+/*
+ * IP MSDP socket management
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include <lib/log.h>
+#include <lib/network.h>
+#include <lib/sockunion.h>
+#include <lib/thread.h>
+#include <lib/vty.h>
+
+#include "pimd.h"
+
+#include "pim_msdp.h"
+#include "pim_msdp_socket.h"
+
+/* increase socket send buffer size */
+static void
+pim_msdp_update_sock_send_buffer_size (int fd)
+{
+ int size = PIM_MSDP_SOCKET_SNDBUF_SIZE;
+ int optval;
+ socklen_t optlen = sizeof(optval);
+
+ if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) < 0) {
+ zlog_err("getsockopt of SO_SNDBUF failed %s\n", safe_strerror(errno));
+ return;
+ }
+
+ if (optval < size) {
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0) {
+ zlog_err("Couldn't increase send buffer: %s\n", safe_strerror(errno));
+ }
+ }
+}
+
+/* passive peer socket accept */
+static int
+pim_msdp_sock_accept(struct thread *thread)
+{
+ union sockunion su;
+ struct pim_msdp_listener *listener = THREAD_ARG(thread);
+ int accept_sock;
+ int msdp_sock;
+ struct pim_msdp_peer *mp;
+ char buf[SU_ADDRSTRLEN];
+
+ sockunion_init(&su);
+
+ /* re-register accept thread */
+ accept_sock = THREAD_FD(thread);
+ if (accept_sock < 0) {
+ zlog_err ("accept_sock is negative value %d", accept_sock);
+ return -1;
+ }
+ listener->thread = thread_add_read(master, pim_msdp_sock_accept,
+ listener, accept_sock);
+
+ /* accept client connection. */
+ msdp_sock = sockunion_accept(accept_sock, &su);
+ if (msdp_sock < 0) {
+ zlog_err ("pim_msdp_sock_accept failed (%s)", safe_strerror (errno));
+ return -1;
+ }
+
+ /* see if have peer config for this */
+ mp = pim_msdp_peer_find(su.sin.sin_addr);
+ if (!mp || !PIM_MSDP_PEER_IS_LISTENER(mp)) {
+ ++msdp->rejected_accepts;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_err("msdp peer connection refused from %s",
+ sockunion2str(&su, buf, SU_ADDRSTRLEN));
+ }
+ close(msdp_sock);
+ return -1;
+ }
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s accept success%s", mp->key_str, mp->fd>=0?"(dup)":"");
+ }
+
+ /* if we have an existing connection we need to kill that one
+ * with this one */
+ if (mp->fd >= 0) {
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_err("msdp peer new connection from %s stop old connection",
+ sockunion2str(&su, buf, SU_ADDRSTRLEN));
+ }
+ pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
+ }
+ mp->fd = msdp_sock;
+ set_nonblocking(mp->fd);
+ pim_msdp_update_sock_send_buffer_size(mp->fd);
+ pim_msdp_peer_established(mp);
+ return 0;
+}
+
+/* global listener for the MSDP well know TCP port */
+int
+pim_msdp_sock_listen(void)
+{
+ int sock;
+ int socklen;
+ struct sockaddr_in sin;
+ int rc;
+ struct pim_msdp_listener *listener = &msdp->listener;
+
+ if (msdp->flags & PIM_MSDPF_LISTENER) {
+ /* listener already setup */
+ return 0;
+ }
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ zlog_err ("socket: %s", safe_strerror (errno));
+ return sock;
+ }
+
+ memset(&sin, 0, sizeof(struct sockaddr_in));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(PIM_MSDP_TCP_PORT);
+ socklen = sizeof(struct sockaddr_in);
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+ sin.sin_len = socklen;
+#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
+
+ sockopt_reuseaddr(sock);
+ sockopt_reuseport(sock);
+
+ if (pimd_privs.change(ZPRIVS_RAISE)) {
+ zlog_err ("pim_msdp_socket: could not raise privs, %s",
+ safe_strerror (errno));
+ }
+
+ /* bind to well known TCP port */
+ rc = bind(sock, (struct sockaddr *)&sin, socklen);
+
+ if (pimd_privs.change(ZPRIVS_LOWER)) {
+ zlog_err ("pim_msdp_socket: could not lower privs, %s",
+ safe_strerror (errno));
+ }
+
+ if (rc < 0) {
+ zlog_err ("pim_msdp_socket bind to port %d: %s", ntohs(sin.sin_port), safe_strerror (errno));
+ close(sock);
+ return rc;
+ }
+
+ rc = listen(sock, 3 /* backlog */);
+ if (rc < 0) {
+ zlog_err ("pim_msdp_socket listen: %s", safe_strerror (errno));
+ close(sock);
+ return rc;
+ }
+
+ /* add accept thread */
+ listener->fd = sock;
+ memcpy(&listener->su, &sin, socklen);
+ listener->thread = thread_add_read(msdp->master, pim_msdp_sock_accept, listener, sock);
+
+ msdp->flags |= PIM_MSDPF_LISTENER;
+ return 0;
+}
+
+/* active peer socket setup */
+int
+pim_msdp_sock_connect(struct pim_msdp_peer *mp)
+{
+ int rc;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s attempt connect%s", mp->key_str, mp->fd<0?"":"(dup)");
+ }
+
+ /* if we have an existing connection we need to kill that one
+ * with this one */
+ if (mp->fd >= 0) {
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_err("msdp duplicate connect to %s nuke old connection", mp->key_str);
+ }
+ pim_msdp_peer_stop_tcp_conn(mp, false /* chg_state */);
+ }
+
+ /* Make socket for the peer. */
+ mp->fd = sockunion_socket(&mp->su_peer);
+ if (mp->fd < 0) {
+ zlog_err ("pim_msdp_socket socket failure: %s", safe_strerror (errno));
+ return -1;
+ }
+
+ set_nonblocking(mp->fd);
+
+ /* Set socket send buffer size */
+ pim_msdp_update_sock_send_buffer_size(mp->fd);
+ sockopt_reuseaddr(mp->fd);
+ sockopt_reuseport(mp->fd);
+
+ /* source bind */
+ rc = sockunion_bind(mp->fd, &mp->su_local, 0, &mp->su_local);
+ if (rc < 0) {
+ zlog_err ("pim_msdp_socket connect bind failure: %s", safe_strerror (errno));
+ close(mp->fd);
+ mp->fd = -1;
+ return rc;
+ }
+
+ /* Connect to the remote mp. */
+ return (sockunion_connect(mp->fd, &mp->su_peer, htons(PIM_MSDP_TCP_PORT), 0));
+}
+
diff --git a/pimd/pim_msdp_socket.h b/pimd/pim_msdp_socket.h
new file mode 100644
index 0000000000..bf3d12ad2c
--- /dev/null
+++ b/pimd/pim_msdp_socket.h
@@ -0,0 +1,25 @@
+/*
+ * IP MSDP socket management for Quagga
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#ifndef PIM_MSDP_SOCKET_H
+#define PIM_MSDP_SOCKET_H
+
+int pim_msdp_sock_listen(void);
+int pim_msdp_sock_connect(struct pim_msdp_peer *mp);
+#endif
diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c
index 9d0fc0ad8f..7ea7b1ad82 100644
--- a/pimd/pim_msg.c
+++ b/pimd/pim_msg.c
@@ -21,11 +21,20 @@
#include <zebra.h>
#include "if.h"
+#include "log.h"
+#include "prefix.h"
+#include "vty.h"
+#include "plist.h"
#include "pimd.h"
+#include "pim_vty.h"
#include "pim_pim.h"
#include "pim_msg.h"
#include "pim_util.h"
+#include "pim_str.h"
+#include "pim_iface.h"
+#include "pim_rp.h"
+#include "pim_rpf.h"
void pim_msg_build_header(uint8_t *pim_msg, int pim_msg_size,
uint8_t pim_msg_type)
@@ -86,9 +95,9 @@ uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf,
return buf + ENCODED_IPV4_GROUP_SIZE;
}
-uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf,
- int buf_size,
- struct in_addr addr)
+uint8_t *
+pim_msg_addr_encode_ipv4_source(uint8_t *buf, int buf_size,
+ struct in_addr addr, uint8_t bits)
{
const int ENCODED_IPV4_SOURCE_SIZE = 8;
@@ -98,9 +107,172 @@ uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf,
buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */
buf[1] = '\0'; /* native encoding */
- buf[2] = 4; /* reserved = 0 | S bit = 1 | W bit = 0 | R bit = 0 */
+ buf[2] = bits;
buf[3] = 32; /* mask len */
memcpy(buf+4, &addr, sizeof(struct in_addr));
return buf + ENCODED_IPV4_SOURCE_SIZE;
}
+
+int
+pim_msg_join_prune_encode (uint8_t *buf, int buf_size, int is_join,
+ struct pim_upstream *up,
+ struct in_addr upstream, int holdtime)
+{
+ uint8_t *pim_msg = buf;
+ uint8_t *pim_msg_curr = buf + PIM_MSG_HEADER_LEN;
+ uint8_t *end = buf + buf_size;
+ uint16_t *prunes = NULL;
+ uint16_t *joins = NULL;
+ struct in_addr stosend;
+ uint8_t bits;
+ int remain;
+
+ remain = end - pim_msg_curr;
+ pim_msg_curr = pim_msg_addr_encode_ipv4_ucast (pim_msg_curr, buf_size - PIM_MSG_HEADER_LEN, upstream);
+ if (!pim_msg_curr) {
+ char dst_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", upstream, dst_str, sizeof(dst_str));
+ zlog_warn("%s: failure encoding destination address %s: space left=%d",
+ __PRETTY_FUNCTION__, dst_str, remain);
+ return -3;
+ }
+
+ remain = end - pim_msg_curr;
+ if (remain < 4) {
+ zlog_warn("%s: group will not fit: space left=%d",
+ __PRETTY_FUNCTION__, remain);
+ return -4;
+ }
+
+ *pim_msg_curr = 0; /* reserved */
+ ++pim_msg_curr;
+ *pim_msg_curr = 1; /* number of groups */
+ ++pim_msg_curr;
+
+ *((uint16_t *) pim_msg_curr) = htons(holdtime);
+ ++pim_msg_curr;
+ ++pim_msg_curr;
+
+ remain = end - pim_msg_curr;
+ pim_msg_curr = pim_msg_addr_encode_ipv4_group (pim_msg_curr, remain,
+ up->sg.grp);
+ if (!pim_msg_curr) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", up->sg.grp, group_str, sizeof(group_str));
+ zlog_warn("%s: failure encoding group address %s: space left=%d",
+ __PRETTY_FUNCTION__, group_str, remain);
+ return -5;
+ }
+
+ remain = end - pim_msg_curr;
+ if (remain < 4) {
+ zlog_warn("%s: sources will not fit: space left=%d",
+ __PRETTY_FUNCTION__, remain);
+ return -6;
+ }
+
+ /* number of joined sources */
+ joins = (uint16_t *)pim_msg_curr;
+ *joins = htons(is_join ? 1 : 0);
+ ++pim_msg_curr;
+ ++pim_msg_curr;
+
+ /* number of pruned sources */
+ prunes = (uint16_t *)pim_msg_curr;
+ *prunes = htons(is_join ? 0 : 1);
+ ++pim_msg_curr;
+ ++pim_msg_curr;
+
+ remain = end - pim_msg_curr;
+ if (up->sg.src.s_addr == INADDR_ANY)
+ {
+ struct pim_rpf *rpf = pim_rp_g (up->sg.grp);
+ bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT | PIM_ENCODE_RPT_BIT;
+ stosend = rpf->rpf_addr.u.prefix4;
+ }
+ else
+ {
+ bits = PIM_ENCODE_SPARSE_BIT;
+ stosend = up->sg.src;
+ }
+ pim_msg_curr = pim_msg_addr_encode_ipv4_source (pim_msg_curr, remain, stosend, bits);
+ if (!pim_msg_curr) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", up->sg.src, source_str, sizeof(source_str));
+ zlog_warn("%s: failure encoding source address %s: space left=%d",
+ __PRETTY_FUNCTION__, source_str, remain);
+ return -7;
+ }
+ remain = pim_msg_curr - pim_msg;
+
+ /*
+ * This is not implemented correctly at this point in time
+ * Make it stop.
+ */
+#if 0
+ if (up->sg.src.s_addr == INADDR_ANY)
+ {
+ struct pim_upstream *child;
+ struct listnode *up_node;
+ int send_prune = 0;
+
+ zlog_debug ("%s: Considering (%s) children for (S,G,rpt) prune",
+ __PRETTY_FUNCTION__, up->sg_str);
+ for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
+ {
+ if (child->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
+ {
+ if (!pim_rpf_is_same(&up->rpf, &child->rpf))
+ {
+ send_prune = 1;
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug ("%s: SPT Bit and RPF'(%s) != RPF'(S,G): Add Prune (%s,rpt) to compound message",
+ __PRETTY_FUNCTION__, up->sg_str, child->sg_str);
+ }
+ else
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug ("%s: SPT Bit and RPF'(%s) == RPF'(S,G): Not adding Prune for (%s,rpt)",
+ __PRETTY_FUNCTION__, up->sg_str, child->sg_str);
+ }
+ else if (pim_upstream_is_sg_rpt (child))
+ {
+ if (pim_upstream_empty_inherited_olist (child))
+ {
+ send_prune = 1;
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug ("%s: inherited_olist(%s,rpt) is NULL, Add Prune to compound message",
+ __PRETTY_FUNCTION__, child->sg_str);
+ }
+ else if (!pim_rpf_is_same (&up->rpf, &child->rpf))
+ {
+ send_prune = 1;
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug ("%s: RPF'(%s) != RPF'(%s,rpt), Add Prune to compound message",
+ __PRETTY_FUNCTION__, up->sg_str, child->sg_str);
+ }
+ else
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug ("%s: RPF'(%s) == RPF'(%s,rpt), Do not add Prune to compound message",
+ __PRETTY_FUNCTION__, up->sg_str, child->sg_str);
+ }
+ else
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug ("%s: SPT bit is not set for (%s)",
+ __PRETTY_FUNCTION__, child->sg_str);
+ if (send_prune)
+ {
+ pim_msg_curr = pim_msg_addr_encode_ipv4_source (pim_msg_curr, remain,
+ child->sg.src,
+ PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_RPT_BIT);
+ remain = pim_msg_curr - pim_msg;
+ *prunes = htons(ntohs(*prunes) + 1);
+ send_prune = 0;
+ }
+ }
+ }
+#endif
+ pim_msg_build_header (pim_msg, remain, PIM_MSG_TYPE_JOIN_PRUNE);
+
+ return remain;
+}
diff --git a/pimd/pim_msg.h b/pimd/pim_msg.h
index 96a89659e6..5229f85c72 100644
--- a/pimd/pim_msg.h
+++ b/pimd/pim_msg.h
@@ -43,8 +43,17 @@ uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf,
uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf,
int buf_size,
struct in_addr addr);
+
+#define PIM_ENCODE_SPARSE_BIT 0x04
+#define PIM_ENCODE_WC_BIT 0x02
+#define PIM_ENCODE_RPT_BIT 0x01
uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf,
int buf_size,
- struct in_addr addr);
+ struct in_addr addr,
+ uint8_t bits);
+
+int pim_msg_join_prune_encode (uint8_t *buf, int buf_size, int is_join,
+ struct pim_upstream *up,
+ struct in_addr upstream, int holdtime);
#endif /* PIM_MSG_H */
diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c
index 04792eb35e..346b911157 100644
--- a/pimd/pim_neighbor.c
+++ b/pimd/pim_neighbor.c
@@ -24,6 +24,8 @@
#include "prefix.h"
#include "memory.h"
#include "if.h"
+#include "vty.h"
+#include "plist.h"
#include "pimd.h"
#include "pim_neighbor.h"
@@ -33,6 +35,8 @@
#include "pim_pim.h"
#include "pim_upstream.h"
#include "pim_ifchannel.h"
+#include "pim_rp.h"
+#include "pim_zebra.h"
static void dr_election_by_addr(struct interface *ifp)
{
@@ -125,8 +129,8 @@ int pim_if_dr_election(struct interface *ifp)
if (old_dr_addr.s_addr != pim_ifp->pim_dr_addr.s_addr) {
if (PIM_DEBUG_PIM_EVENTS) {
- char dr_old_str[100];
- char dr_new_str[100];
+ char dr_old_str[INET_ADDRSTRLEN];
+ char dr_new_str[INET_ADDRSTRLEN];
pim_inet4_dump("<old_dr?>", old_dr_addr, dr_old_str, sizeof(dr_old_str));
pim_inet4_dump("<new_dr?>", pim_ifp->pim_dr_addr, dr_new_str, sizeof(dr_new_str));
zlog_debug("%s: DR was %s now is %s on interface %s",
@@ -207,20 +211,18 @@ static int on_neighbor_timer(struct thread *t)
struct interface *ifp;
char msg[100];
- zassert(t);
neigh = THREAD_ARG(t);
- zassert(neigh);
ifp = neigh->interface;
if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
zlog_debug("Expired %d sec holdtime for neighbor %s on interface %s",
neigh->holdtime, src_str, ifp->name);
}
- neigh->t_expire_timer = 0;
+ neigh->t_expire_timer = NULL;
snprintf(msg, sizeof(msg), "%d-sec holdtime expired", neigh->holdtime);
pim_neighbor_delete(ifp, neigh, msg);
@@ -237,26 +239,11 @@ static int on_neighbor_timer(struct thread *t)
return 0;
}
-static void neighbor_timer_off(struct pim_neighbor *neigh)
-{
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- if (neigh->t_expire_timer) {
- char src_str[100];
- pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
- zlog_debug("%s: cancelling timer for neighbor %s on %s",
- __PRETTY_FUNCTION__,
- src_str, neigh->interface->name);
- }
- }
- THREAD_OFF(neigh->t_expire_timer);
- zassert(!neigh->t_expire_timer);
-}
-
void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime)
{
neigh->holdtime = holdtime;
- neighbor_timer_off(neigh);
+ THREAD_OFF(neigh->t_expire_timer);
/*
0xFFFF is request for no holdtime
@@ -266,7 +253,7 @@ void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime)
}
if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
zlog_debug("%s: starting %u sec timer for neighbor %s on %s",
__PRETTY_FUNCTION__,
@@ -290,15 +277,15 @@ static struct pim_neighbor *pim_neighbor_new(struct interface *ifp,
{
struct pim_interface *pim_ifp;
struct pim_neighbor *neigh;
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
zassert(ifp);
pim_ifp = ifp->info;
zassert(pim_ifp);
- neigh = XMALLOC(MTYPE_PIM_NEIGHBOR, sizeof(*neigh));
+ neigh = XCALLOC(MTYPE_PIM_NEIGHBOR, sizeof(*neigh));
if (!neigh) {
- zlog_err("%s: PIM XMALLOC(%zu) failure",
+ zlog_err("%s: PIM XCALLOC(%zu) failure",
__PRETTY_FUNCTION__, sizeof(*neigh));
return 0;
}
@@ -311,10 +298,18 @@ static struct pim_neighbor *pim_neighbor_new(struct interface *ifp,
neigh->dr_priority = dr_priority;
neigh->generation_id = generation_id;
neigh->prefix_list = addr_list;
- neigh->t_expire_timer = 0;
+ neigh->t_expire_timer = NULL;
neigh->interface = ifp;
pim_neighbor_timer_reset(neigh, holdtime);
+ /*
+ * The pim_ifstat_hello_sent variable is used to decide if
+ * we should expedite a hello out the interface. If we
+ * establish a new neighbor, we unfortunately need to
+ * reset the value so that we can know to hurry up and
+ * hello
+ */
+ pim_ifp->pim_ifstat_hello_sent = 0;
pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
@@ -391,7 +386,8 @@ struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
struct pim_neighbor *neigh;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ if (!pim_ifp)
+ return NULL;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) {
if (source_addr.s_addr == neigh->source_addr.s_addr) {
@@ -399,7 +395,35 @@ struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
}
}
- return 0;
+ return NULL;
+}
+
+/*
+ * Find the *one* interface out
+ * this interface. If more than
+ * one return NULL
+ */
+struct pim_neighbor *
+pim_neighbor_find_if (struct interface *ifp)
+{
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp || pim_ifp->pim_neighbor_list->count != 1)
+ return NULL;
+
+ return listnode_head (pim_ifp->pim_neighbor_list);
+}
+
+/* rpf info associated with an upstream entry needs to be re-evaluated
+ * when an RPF neighbor comes or goes */
+static void
+pim_neighbor_rpf_update(void)
+{
+ /* XXX: for the time being piggyback on the timer used on rib changes
+ * to scan and update the rpf nexthop. This is expensive processing
+ * and we should be able to optimize neighbor changes differently than
+ * nexthop changes. */
+ sched_rpf_cache_refresh();
}
struct pim_neighbor *pim_neighbor_add(struct interface *ifp,
@@ -410,7 +434,8 @@ struct pim_neighbor *pim_neighbor_add(struct interface *ifp,
uint16_t override_interval,
uint32_t dr_priority,
uint32_t generation_id,
- struct list *addr_list)
+ struct list *addr_list,
+ int send_hello_now)
{
struct pim_interface *pim_ifp;
struct pim_neighbor *neigh;
@@ -449,9 +474,22 @@ struct pim_neighbor *pim_neighbor_add(struct interface *ifp,
message with a new GenID is received from an existing neighbor, a
new Hello message should be sent on this interface after a
randomized delay between 0 and Triggered_Hello_Delay.
+
+ This is a bit silly to do it that way. If I get a new
+ genid we need to send the hello *now* because we've
+ lined up a bunch of join/prune messages to go out the
+ interface.
*/
- pim_hello_restart_triggered(neigh->interface);
+ if (send_hello_now)
+ pim_hello_restart_now (ifp);
+ else
+ pim_hello_restart_triggered(neigh->interface);
+
+ pim_upstream_find_new_rpf();
+ pim_rp_setup ();
+
+ pim_neighbor_rpf_update();
return neigh;
}
@@ -508,7 +546,7 @@ void pim_neighbor_delete(struct interface *ifp,
const char *delete_message)
{
struct pim_interface *pim_ifp;
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_ifp = ifp->info;
zassert(pim_ifp);
@@ -517,7 +555,7 @@ void pim_neighbor_delete(struct interface *ifp,
zlog_info("PIM NEIGHBOR DOWN: neighbor %s on interface %s: %s",
src_str, ifp->name, delete_message);
- neighbor_timer_off(neigh);
+ THREAD_OFF(neigh->t_expire_timer);
pim_if_assert_on_neighbor_down(ifp, neigh->source_addr);
@@ -564,6 +602,8 @@ void pim_neighbor_delete(struct interface *ifp,
listnode_delete(pim_ifp->pim_neighbor_list, neigh);
pim_neighbor_free(neigh);
+
+ pim_neighbor_rpf_update();
}
void pim_neighbor_delete_all(struct interface *ifp,
@@ -646,9 +686,9 @@ static void delete_from_neigh_addr(struct interface *ifp,
{
struct prefix *p = pim_neighbor_find_secondary(neigh, addr->u.prefix4);
if (p) {
- char addr_str[100];
- char this_neigh_str[100];
- char other_neigh_str[100];
+ char addr_str[INET_ADDRSTRLEN];
+ char this_neigh_str[INET_ADDRSTRLEN];
+ char other_neigh_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr->u.prefix4, addr_str, sizeof(addr_str));
pim_inet4_dump("<neigh1?>", neigh_addr, this_neigh_str, sizeof(this_neigh_str));
diff --git a/pimd/pim_neighbor.h b/pimd/pim_neighbor.h
index e023a7f1ef..211eda25c7 100644
--- a/pimd/pim_neighbor.h
+++ b/pimd/pim_neighbor.h
@@ -25,6 +25,7 @@
#include "if.h"
#include "linklist.h"
+#include "prefix.h"
#include "pim_tlv.h"
@@ -46,6 +47,12 @@ void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime);
void pim_neighbor_free(struct pim_neighbor *neigh);
struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
struct in_addr source_addr);
+
+struct pim_neighbor *pim_neighbor_find_if (struct interface *ifp);
+
+
+#define PIM_NEIGHBOR_SEND_DELAY 0
+#define PIM_NEIGHBOR_SEND_NOW 1
struct pim_neighbor *pim_neighbor_add(struct interface *ifp,
struct in_addr source_addr,
pim_hello_options hello_options,
@@ -54,7 +61,8 @@ struct pim_neighbor *pim_neighbor_add(struct interface *ifp,
uint16_t override_interval,
uint32_t dr_priority,
uint32_t generation_id,
- struct list *addr_list);
+ struct list *addr_list,
+ int send_hello_now);
void pim_neighbor_delete(struct interface *ifp,
struct pim_neighbor *neigh,
const char *delete_message);
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index ebbc6e19f9..4c5eff4883 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -24,6 +24,8 @@
#include "memory.h"
#include "linklist.h"
#include "if.h"
+#include "hash.h"
+#include "jhash.h"
#include "pimd.h"
#include "pim_oil.h"
@@ -31,104 +33,187 @@
#include "pim_iface.h"
#include "pim_time.h"
+struct list *pim_channel_oil_list = NULL;
+struct hash *pim_channel_oil_hash = NULL;
+
+char *
+pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size)
+{
+ struct prefix_sg sg;
+ int i;
+
+ memset (buf, 0, size);
+ sg.src = c_oil->oil.mfcc_origin;
+ sg.grp = c_oil->oil.mfcc_mcastgrp;
+ sprintf(buf, "%s IIF: %d, OIFS: ",
+ pim_str_sg_dump (&sg), c_oil->oil.mfcc_parent);
+
+ for (i = 0 ; i < MAXVIFS ; i++)
+ {
+ if (c_oil->oil.mfcc_ttls[i] != 0)
+ {
+ char buf1[10];
+ sprintf(buf1, "%d ", i);
+ strcat(buf, buf1);
+ }
+ }
+
+ return buf;
+}
+
+static int
+pim_channel_oil_compare (struct channel_oil *c1, struct channel_oil *c2)
+{
+ if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) < ntohl(c2->oil.mfcc_mcastgrp.s_addr))
+ return -1;
+
+ if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) > ntohl(c2->oil.mfcc_mcastgrp.s_addr))
+ return 1;
+
+ if (ntohl(c1->oil.mfcc_origin.s_addr) < ntohl(c2->oil.mfcc_origin.s_addr))
+ return -1;
+
+ if (ntohl(c1->oil.mfcc_origin.s_addr) > ntohl(c2->oil.mfcc_origin.s_addr))
+ return 1;
+
+ return 0;
+}
+
+static int
+pim_oil_equal (const void *arg1, const void *arg2)
+{
+ const struct channel_oil *c1 = (const struct channel_oil *)arg1;
+ const struct channel_oil *c2 = (const struct channel_oil *)arg2;
+
+ if ((c1->oil.mfcc_mcastgrp.s_addr == c2->oil.mfcc_mcastgrp.s_addr) &&
+ (c1->oil.mfcc_origin.s_addr == c2->oil.mfcc_origin.s_addr))
+ return 1;
+
+ return 0;
+}
+
+static unsigned int
+pim_oil_hash_key (void *arg)
+{
+ struct channel_oil *oil = (struct channel_oil *)arg;
+
+ return jhash_2words (oil->oil.mfcc_mcastgrp.s_addr, oil->oil.mfcc_origin.s_addr, 0);
+}
+
+void
+pim_oil_init (void)
+{
+ pim_channel_oil_hash = hash_create_size (8192, pim_oil_hash_key,
+ pim_oil_equal);
+
+ pim_channel_oil_list = list_new();
+ if (!pim_channel_oil_list) {
+ zlog_err("%s %s: failure: channel_oil_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return;
+ }
+ pim_channel_oil_list->del = (void (*)(void *)) pim_channel_oil_free;
+ pim_channel_oil_list->cmp = (int (*)(void *, void *)) pim_channel_oil_compare;
+}
+
+void
+pim_oil_terminate (void)
+{
+ if (pim_channel_oil_list)
+ list_free(pim_channel_oil_list);
+ pim_channel_oil_list = NULL;
+
+ if (pim_channel_oil_hash)
+ hash_free (pim_channel_oil_hash);
+ pim_channel_oil_hash = NULL;
+}
+
void pim_channel_oil_free(struct channel_oil *c_oil)
{
XFREE(MTYPE_PIM_CHANNEL_OIL, c_oil);
}
-static void pim_channel_oil_delete(struct channel_oil *c_oil)
+static void
+pim_del_channel_oil (struct channel_oil *c_oil)
{
/*
notice that listnode_delete() can't be moved
into pim_channel_oil_free() because the later is
called by list_delete_all_node()
*/
- listnode_delete(qpim_channel_oil_list, c_oil);
+ listnode_delete(pim_channel_oil_list, c_oil);
+ hash_release (pim_channel_oil_hash, c_oil);
pim_channel_oil_free(c_oil);
}
-static struct channel_oil *channel_oil_new(struct in_addr group_addr,
- struct in_addr source_addr,
- int input_vif_index)
+static struct channel_oil *
+pim_add_channel_oil (struct prefix_sg *sg,
+ int input_vif_index)
{
struct channel_oil *c_oil;
- struct interface *ifp_in;
+ struct interface *ifp;
- ifp_in = pim_if_find_by_vif_index(input_vif_index);
- if (!ifp_in) {
+ ifp = pim_if_find_by_vif_index(input_vif_index);
+ if (!ifp) {
/* warning only */
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: (S,G)=(%s,%s) could not find input interface for input_vif_index=%d",
+ zlog_warn("%s: (S,G)=%s could not find input interface for input_vif_index=%d",
__PRETTY_FUNCTION__,
- source_str, group_str, input_vif_index);
+ pim_str_sg_dump (sg), input_vif_index);
}
c_oil = XCALLOC(MTYPE_PIM_CHANNEL_OIL, sizeof(*c_oil));
if (!c_oil) {
zlog_err("PIM XCALLOC(%zu) failure", sizeof(*c_oil));
- return 0;
+ return NULL;
}
- c_oil->oil.mfcc_mcastgrp = group_addr;
- c_oil->oil.mfcc_origin = source_addr;
+ c_oil->oil.mfcc_mcastgrp = sg->grp;
+ c_oil->oil.mfcc_origin = sg->src;
+ c_oil = hash_get (pim_channel_oil_hash, c_oil, hash_alloc_intern);
+
c_oil->oil.mfcc_parent = input_vif_index;
c_oil->oil_ref_count = 1;
c_oil->installed = 0;
- zassert(c_oil->oil_size == 0);
+ listnode_add_sort(pim_channel_oil_list, c_oil);
return c_oil;
}
-static struct channel_oil *pim_add_channel_oil(struct in_addr group_addr,
- struct in_addr source_addr,
- int input_vif_index)
+static struct channel_oil *pim_find_channel_oil(struct prefix_sg *sg)
{
- struct channel_oil *c_oil;
+ struct channel_oil *c_oil = NULL;
+ struct channel_oil lookup;
- c_oil = channel_oil_new(group_addr, source_addr, input_vif_index);
- if (!c_oil) {
- zlog_warn("PIM XCALLOC(%zu) failure", sizeof(*c_oil));
- return 0;
- }
+ lookup.oil.mfcc_mcastgrp = sg->grp;
+ lookup.oil.mfcc_origin = sg->src;
- listnode_add(qpim_channel_oil_list, c_oil);
+ c_oil = hash_lookup (pim_channel_oil_hash, &lookup);
return c_oil;
}
-static struct channel_oil *pim_find_channel_oil(struct in_addr group_addr,
- struct in_addr source_addr)
-{
- struct listnode *node;
- struct channel_oil *c_oil;
-
- for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
- if ((group_addr.s_addr == c_oil->oil.mfcc_mcastgrp.s_addr) &&
- (source_addr.s_addr == c_oil->oil.mfcc_origin.s_addr))
- return c_oil;
- }
-
- return 0;
-}
-
-struct channel_oil *pim_channel_oil_add(struct in_addr group_addr,
- struct in_addr source_addr,
+struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
int input_vif_index)
{
struct channel_oil *c_oil;
- c_oil = pim_find_channel_oil(group_addr, source_addr);
+ c_oil = pim_find_channel_oil(sg);
if (c_oil) {
+ if (c_oil->oil.mfcc_parent != input_vif_index)
+ {
+ c_oil->oil_inherited_rescan = 1;
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug ("%s: Existing channel oil %s points to %d, modifying to point at %d",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(sg), c_oil->oil.mfcc_parent, input_vif_index);
+ }
+ c_oil->oil.mfcc_parent = input_vif_index;
++c_oil->oil_ref_count;
return c_oil;
}
- return pim_add_channel_oil(group_addr, source_addr, input_vif_index);
+ return pim_add_channel_oil(sg, input_vif_index);
}
void pim_channel_oil_del(struct channel_oil *c_oil)
@@ -136,10 +221,96 @@ void pim_channel_oil_del(struct channel_oil *c_oil)
--c_oil->oil_ref_count;
if (c_oil->oil_ref_count < 1) {
- pim_channel_oil_delete(c_oil);
+ pim_del_channel_oil(c_oil);
+ }
+}
+
+int
+pim_channel_del_oif (struct channel_oil *channel_oil,
+ struct interface *oif,
+ uint32_t proto_mask)
+{
+ struct pim_interface *pim_ifp;
+
+ zassert (channel_oil);
+ zassert (oif);
+
+ pim_ifp = oif->info;
+
+ /*
+ * Don't do anything if we've been asked to remove a source
+ * that is not actually on it.
+ */
+ if (!(channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask))
+ {
+ if (PIM_DEBUG_MROUTE)
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_debug("%s %s: no existing protocol mask %u(%u) for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ proto_mask, channel_oil->oif_flags[pim_ifp->mroute_vif_index],
+ oif->name, pim_ifp->mroute_vif_index,
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
+ return 0;
+ }
+
+ channel_oil->oif_flags[pim_ifp->mroute_vif_index] &= ~proto_mask;
+
+ if (channel_oil->oif_flags[pim_ifp->mroute_vif_index])
+ {
+ if (PIM_DEBUG_MROUTE)
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_debug("%s %s: other protocol masks remain for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ oif->name, pim_ifp->mroute_vif_index,
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
+ return 0;
+ }
+
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = 0;
+
+ if (pim_mroute_add (channel_oil, __PRETTY_FUNCTION__)) {
+ if (PIM_DEBUG_MROUTE)
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_debug("%s %s: could not remove output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ oif->name, pim_ifp->mroute_vif_index,
+ source_str, group_str);
+ }
+ return -1;
}
+
+ if (PIM_DEBUG_MROUTE)
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d",
+ __FILE__, __PRETTY_FUNCTION__,
+ source_str, group_str,
+ proto_mask, oif->name, pim_ifp->mroute_vif_index);
+ }
+
+ return 0;
}
+
int pim_channel_add_oif(struct channel_oil *channel_oil,
struct interface *oif,
uint32_t proto_mask)
@@ -147,21 +318,18 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
struct pim_interface *pim_ifp;
int old_ttl;
- zassert(channel_oil);
+ /*
+ * If we've gotten here we've gone bad, but let's
+ * not take down pim
+ */
+ if (!channel_oil)
+ {
+ zlog_warn ("Attempt to Add OIF for non-existent channel oil");
+ return -1;
+ }
pim_ifp = oif->info;
- if (PIM_DEBUG_MROUTE) {
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str,
- proto_mask, oif->name, pim_ifp->mroute_vif_index);
- }
-
#ifdef PIM_ENFORCE_LOOPFREE_MFC
/*
Prevent creating MFC entry with OIF=IIF.
@@ -175,10 +343,11 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
TODO T22.
*/
if (pim_ifp->mroute_vif_index == channel_oil->oil.mfcc_parent) {
+ channel_oil->oil_inherited_rescan = 1;
if (PIM_DEBUG_MROUTE)
{
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
zlog_debug("%s %s: refusing protocol mask %u request for IIF=OIF=%s (vif_index=%d) for channel (S,G)=(%s,%s)",
@@ -195,8 +364,8 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask) {
if (PIM_DEBUG_MROUTE)
{
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
zlog_debug("%s %s: existing protocol mask %u requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
@@ -209,25 +378,26 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
}
/* Allow other protocol to request subscription of same interface to
- channel (S,G) multiple times, by silently ignoring further
- requests */
+ * channel (S,G), we need to note this information
+ */
if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & PIM_OIF_FLAG_PROTO_ANY) {
+ channel_oil->oif_creation[pim_ifp->mroute_vif_index] = pim_time_monotonic_sec();
+ channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
/* Check the OIF really exists before returning, and only log
warning otherwise */
if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) {
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- proto_mask, oif->name, pim_ifp->mroute_vif_index,
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
- source_str, group_str);
- }
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_warn("%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ proto_mask, oif->name, pim_ifp->mroute_vif_index,
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
}
return 0;
@@ -238,8 +408,8 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
if (old_ttl > 0) {
if (PIM_DEBUG_MROUTE)
{
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
zlog_debug("%s %s: interface %s (vif_index=%d) is existing output for channel (S,G)=(%s,%s)",
@@ -252,11 +422,11 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = PIM_MROUTE_MIN_TTL;
- if (pim_mroute_add(channel_oil)) {
+ if (pim_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
if (PIM_DEBUG_MROUTE)
{
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
zlog_debug("%s %s: could not add output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)",
@@ -274,8 +444,8 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
if (PIM_DEBUG_MROUTE) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d: DONE",
@@ -286,3 +456,24 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
return 0;
}
+
+int
+pim_channel_oil_empty (struct channel_oil *c_oil)
+{
+ static uint32_t zero[MAXVIFS];
+ static int inited = 0;
+
+ if (!c_oil)
+ return 1;
+ /*
+ * Not sure that this is necessary, but I would rather ensure
+ * that this works.
+ */
+ if (!inited)
+ {
+ memset(&zero, 0, sizeof(uint32_t) * MAXVIFS);
+ inited = 1;
+ }
+
+ return !memcmp(c_oil->oif_flags, zero, MAXVIFS * sizeof(uint32_t));
+}
diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h
index 540acce3a3..e90cd5fc19 100644
--- a/pimd/pim_oil.h
+++ b/pimd/pim_oil.h
@@ -29,13 +29,16 @@
* IGMP - Learned from IGMP
* PIM - Learned from PIM
* SOURCE - Learned from Source multicast packet received
+ * STAR - Inherited
*/
#define PIM_OIF_FLAG_PROTO_IGMP (1 << 0)
#define PIM_OIF_FLAG_PROTO_PIM (1 << 1)
-#define PIM_OIF_FLAG_PROTO_SOURCE (2 << 1)
+#define PIM_OIF_FLAG_PROTO_SOURCE (1 << 2)
+#define PIM_OIF_FLAG_PROTO_STAR (1 << 3)
#define PIM_OIF_FLAG_PROTO_ANY (PIM_OIF_FLAG_PROTO_IGMP | \
PIM_OIF_FLAG_PROTO_PIM | \
- PIM_OIF_FLAG_PROTO_SOURCE)
+ PIM_OIF_FLAG_PROTO_SOURCE | \
+ PIM_OIF_FLAG_PROTO_STAR)
/*
* We need a pimreg vif id from the kernel.
@@ -45,12 +48,13 @@
* Don't come running to me if this assumption is bad,
* fix it.
*/
-#define PIM_OIF_PIM_REGISTER_VIF (MAXVIFS - 1)
-#define PIM_MAX_USABLE_VIFS (MAXVIFS - 2)
+#define PIM_OIF_PIM_REGISTER_VIF 0
+#define PIM_MAX_USABLE_VIFS (MAXVIFS - 1)
struct channel_counts
{
+ unsigned long long lastused;
unsigned long pktcnt;
unsigned long oldpktcnt;
unsigned long bytecnt;
@@ -69,6 +73,7 @@ struct channel_counts
struct channel_oil {
struct mfcctl oil;
int installed;
+ int oil_inherited_rescan;
int oil_size;
int oil_ref_count;
time_t oif_creation[MAXVIFS];
@@ -76,14 +81,24 @@ struct channel_oil {
struct channel_counts cc;
};
+extern struct list *pim_channel_oil_list;
+
+void pim_oil_init (void);
+void pim_oil_terminate (void);
+
void pim_channel_oil_free(struct channel_oil *c_oil);
-struct channel_oil *pim_channel_oil_add(struct in_addr group_addr,
- struct in_addr source_addr,
+struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
int input_vif_index);
void pim_channel_oil_del(struct channel_oil *c_oil);
int pim_channel_add_oif(struct channel_oil *c_oil,
struct interface *oif,
uint32_t proto_mask);
+int pim_channel_del_oif (struct channel_oil *c_oil,
+ struct interface *oif,
+ uint32_t proto_mask);
+
+int pim_channel_oil_empty (struct channel_oil *c_oil);
+char *pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size);
#endif /* PIM_OIL_H */
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index 0f41a43315..f727d3e627 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -44,6 +44,25 @@ static int on_pim_hello_send(struct thread *t);
static int pim_hello_send(struct interface *ifp,
uint16_t holdtime);
+static
+const char *pim_pim_msgtype2str (enum pim_msg_type type)
+{
+ switch (type)
+ {
+ case PIM_MSG_TYPE_HELLO: return "HELLO";
+ case PIM_MSG_TYPE_REGISTER: return "REGISTER";
+ case PIM_MSG_TYPE_REG_STOP: return "REGSTOP";
+ case PIM_MSG_TYPE_JOIN_PRUNE: return "JOINPRUNE";
+ case PIM_MSG_TYPE_BOOTSTRAP: return "BOOT";
+ case PIM_MSG_TYPE_ASSERT: return "ASSERT";
+ case PIM_MSG_TYPE_GRAFT: return "GRAFT";
+ case PIM_MSG_TYPE_GRAFT_ACK: return "GACK";
+ case PIM_MSG_TYPE_CANDIDATE: return "CANDIDATE";
+ }
+
+ return "UNKNOWN";
+}
+
static void sock_close(struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
@@ -70,7 +89,10 @@ static void sock_close(struct interface *ifp)
pim_ifp->pim_sock_fd, ifp->name);
}
- if (close(pim_ifp->pim_sock_fd)) {
+ /*
+ * If the fd is already deleted no need to do anything here
+ */
+ if (pim_ifp->pim_sock_fd > 0 && close(pim_ifp->pim_sock_fd)) {
zlog_warn("Failure closing PIM socket fd=%d on interface %s: errno=%d: %s",
pim_ifp->pim_sock_fd, ifp->name,
errno, safe_strerror(errno));
@@ -78,11 +100,6 @@ static void sock_close(struct interface *ifp)
pim_ifp->pim_sock_fd = -1;
pim_ifp->pim_sock_creation = 0;
-
- zassert(pim_ifp->pim_sock_fd < 0);
- zassert(!pim_ifp->t_pim_sock_read);
- zassert(!pim_ifp->t_pim_hello_timer);
- zassert(!pim_ifp->pim_sock_creation);
}
void pim_sock_delete(struct interface *ifp, const char *delete_message)
@@ -114,67 +131,53 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len)
{
struct ip *ip_hdr;
size_t ip_hlen; /* ip header length in bytes */
- char src_str[100];
- char dst_str[100];
+ char src_str[INET_ADDRSTRLEN];
+ char dst_str[INET_ADDRSTRLEN];
uint8_t *pim_msg;
int pim_msg_len;
uint8_t pim_version;
- uint8_t pim_type;
+ enum pim_msg_type pim_type;
uint16_t pim_checksum; /* received checksum */
uint16_t checksum; /* computed checksum */
struct pim_neighbor *neigh;
- if (!ifp->info) {
- zlog_warn("%s: PIM not enabled on interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- return -1;
- }
-
if (len < sizeof(*ip_hdr)) {
- zlog_warn("PIM packet size=%zu shorter than minimum=%zu",
- len, sizeof(*ip_hdr));
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("PIM packet size=%zu shorter than minimum=%zu",
+ len, sizeof(*ip_hdr));
return -1;
}
ip_hdr = (struct ip *) buf;
-
- pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, sizeof(src_str));
- pim_inet4_dump("<dst?>", ip_hdr->ip_dst, dst_str, sizeof(dst_str));
-
ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
- if (PIM_DEBUG_PIM_PACKETS) {
- zlog_debug("Recv IP packet from %s to %s on %s: size=%zu ip_header_size=%zu ip_proto=%d",
- src_str, dst_str, ifp->name, len, ip_hlen, ip_hdr->ip_p);
- }
-
if (ip_hdr->ip_p != PIM_IP_PROTO_PIM) {
- zlog_warn("IP packet protocol=%d is not PIM=%d",
- ip_hdr->ip_p, PIM_IP_PROTO_PIM);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("IP packet protocol=%d is not PIM=%d",
+ ip_hdr->ip_p, PIM_IP_PROTO_PIM);
return -1;
}
if (ip_hlen < PIM_IP_HEADER_MIN_LEN) {
- zlog_warn("IP packet header size=%zu shorter than minimum=%d",
- ip_hlen, PIM_IP_HEADER_MIN_LEN);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("IP packet header size=%zu shorter than minimum=%d",
+ ip_hlen, PIM_IP_HEADER_MIN_LEN);
return -1;
}
if (ip_hlen > PIM_IP_HEADER_MAX_LEN) {
- zlog_warn("IP packet header size=%zu greater than maximum=%d",
- ip_hlen, PIM_IP_HEADER_MAX_LEN);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("IP packet header size=%zu greater than maximum=%d",
+ ip_hlen, PIM_IP_HEADER_MAX_LEN);
return -1;
}
pim_msg = buf + ip_hlen;
pim_msg_len = len - ip_hlen;
- if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
- pim_pkt_dump(__PRETTY_FUNCTION__, pim_msg, pim_msg_len);
- }
-
if (pim_msg_len < PIM_PIM_MIN_LEN) {
- zlog_warn("PIM message size=%d shorter than minimum=%d",
- pim_msg_len, PIM_PIM_MIN_LEN);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("PIM message size=%d shorter than minimum=%d",
+ pim_msg_len, PIM_PIM_MIN_LEN);
return -1;
}
@@ -182,8 +185,9 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len)
pim_type = PIM_MSG_HDR_GET_TYPE(pim_msg);
if (pim_version != PIM_PROTO_VERSION) {
- zlog_warn("Ignoring PIM pkt from %s with unsupported version: %d",
- ifp->name, pim_version);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("Ignoring PIM pkt from %s with unsupported version: %d",
+ ifp->name, pim_version);
return -1;
}
@@ -195,71 +199,79 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len)
checksum = in_cksum(pim_msg, pim_msg_len);
if (checksum != pim_checksum) {
- zlog_warn("Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x",
- ifp->name, pim_checksum, checksum);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x",
+ ifp->name, pim_checksum, checksum);
return -1;
}
if (PIM_DEBUG_PIM_PACKETS) {
- zlog_debug("Recv PIM packet from %s to %s on %s: ttl=%d pim_version=%d pim_type=%d pim_msg_size=%d checksum=%x",
- src_str, dst_str, ifp->name, ip_hdr->ip_ttl,
- pim_version, pim_type, pim_msg_len, checksum);
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, sizeof(src_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst, dst_str, sizeof(dst_str));
+ zlog_debug("Recv PIM %s packet from %s to %s on %s: ttl=%d pim_version=%d pim_msg_size=%d checksum=%x",
+ pim_pim_msgtype2str (pim_type), src_str, dst_str, ifp->name,
+ ip_hdr->ip_ttl, pim_version, pim_msg_len, checksum);
+ if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
+ pim_pkt_dump(__PRETTY_FUNCTION__, pim_msg, pim_msg_len);
+ }
}
- if (pim_type == PIM_MSG_TYPE_REG_STOP ||
- pim_type == PIM_MSG_TYPE_BOOTSTRAP ||
- pim_type == PIM_MSG_TYPE_GRAFT ||
- pim_type == PIM_MSG_TYPE_GRAFT_ACK ||
- pim_type == PIM_MSG_TYPE_CANDIDATE)
+ switch (pim_type)
{
+ case PIM_MSG_TYPE_HELLO:
+ return pim_hello_recv (ifp,
+ ip_hdr->ip_src,
+ pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ case PIM_MSG_TYPE_REGISTER:
+ return pim_register_recv (ifp,
+ ip_hdr->ip_dst,
+ ip_hdr->ip_src,
+ pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ case PIM_MSG_TYPE_REG_STOP:
+ return pim_register_stop_recv (pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ case PIM_MSG_TYPE_JOIN_PRUNE:
+ neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
+ if (!neigh) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ pim_type, src_str, ifp->name);
+ return -1;
+ }
+ pim_neighbor_timer_reset(neigh, neigh->holdtime);
+ return pim_joinprune_recv(ifp, neigh,
+ ip_hdr->ip_src,
+ pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ case PIM_MSG_TYPE_ASSERT:
+ neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
+ if (!neigh) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ pim_type, src_str, ifp->name);
+ return -1;
+ }
+ pim_neighbor_timer_reset(neigh, neigh->holdtime);
+ return pim_assert_recv(ifp, neigh,
+ ip_hdr->ip_src,
+ pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ default:
if (PIM_DEBUG_PIM_PACKETS) {
zlog_debug("Recv PIM packet type %d which is not currently understood",
pim_type);
}
return -1;
}
-
- if (pim_type == PIM_MSG_TYPE_HELLO) {
- return pim_hello_recv(ifp,
- ip_hdr->ip_src,
- pim_msg + PIM_MSG_HEADER_LEN,
- pim_msg_len - PIM_MSG_HEADER_LEN);
- } else if (pim_type == PIM_MSG_TYPE_REGISTER) {
- return pim_register_recv(ifp,
- ip_hdr->ip_dst,
- ip_hdr->ip_src,
- pim_msg + PIM_MSG_HEADER_LEN,
- pim_msg_len - PIM_MSG_HEADER_LEN);
- }
-
- neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
- if (!neigh) {
- zlog_warn("%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
- __FILE__, __PRETTY_FUNCTION__,
- pim_type, src_str, ifp->name);
- return -1;
- }
-
- switch (pim_type) {
- case PIM_MSG_TYPE_JOIN_PRUNE:
- return pim_joinprune_recv(ifp, neigh,
- ip_hdr->ip_src,
- pim_msg + PIM_MSG_HEADER_LEN,
- pim_msg_len - PIM_MSG_HEADER_LEN);
- break;
- case PIM_MSG_TYPE_ASSERT:
- return pim_assert_recv(ifp, neigh,
- ip_hdr->ip_src,
- pim_msg + PIM_MSG_HEADER_LEN,
- pim_msg_len - PIM_MSG_HEADER_LEN);
- break;
- default:
- zlog_warn("%s %s: unsupported PIM message type=%d from %s on %s",
- __FILE__, __PRETTY_FUNCTION__,
- pim_type, src_str, ifp->name);
- break;
- }
-
return -1;
}
@@ -278,80 +290,73 @@ static int pim_sock_read(struct thread *t)
int len;
ifindex_t ifindex = -1;
int result = -1; /* defaults to bad */
-
- zassert(t);
+ static long long count = 0;
+ int cont = 1;
ifp = THREAD_ARG(t);
- zassert(ifp);
-
fd = THREAD_FD(t);
pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- zassert(fd == pim_ifp->pim_sock_fd);
-
- len = pim_socket_recvfromto(fd, buf, sizeof(buf),
- &from, &fromlen,
- &to, &tolen,
- &ifindex);
- if (len < 0) {
- zlog_warn("Failure receiving IP PIM packet on fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- goto done;
- }
-
- if (PIM_DEBUG_PIM_PACKETS) {
- char from_str[100];
- char to_str[100];
-
- if (!inet_ntop(AF_INET, &from.sin_addr, from_str, sizeof(from_str)))
- sprintf(from_str, "<from?>");
- if (!inet_ntop(AF_INET, &to.sin_addr, to_str, sizeof(to_str)))
- sprintf(to_str, "<to?>");
-
- zlog_debug("Recv IP PIM pkt size=%d from %s to %s on fd=%d on ifindex=%d (sock_ifindex=%d)",
- len, from_str, to_str, fd, ifindex, ifp->ifindex);
- }
- if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
- pim_pkt_dump(__PRETTY_FUNCTION__, buf, len);
- }
+ while (cont)
+ {
+ len = pim_socket_recvfromto(fd, buf, sizeof(buf),
+ &from, &fromlen,
+ &to, &tolen,
+ &ifindex);
+ if (len < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ {
+ cont = 0;
+ break;
+ }
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug ("Received errno: %d %s", errno, safe_strerror (errno));
+ goto done;
+ }
#ifdef PIM_CHECK_RECV_IFINDEX_SANITY
- /* ifindex sanity check */
- if (ifindex != (int) ifp->ifindex) {
- char from_str[100];
- char to_str[100];
- struct interface *recv_ifp;
-
- if (!inet_ntop(AF_INET, &from.sin_addr, from_str , sizeof(from_str)))
- sprintf(from_str, "<from?>");
- if (!inet_ntop(AF_INET, &to.sin_addr, to_str , sizeof(to_str)))
- sprintf(to_str, "<to?>");
-
- recv_ifp = if_lookup_by_index(ifindex);
- if (recv_ifp) {
- zassert(ifindex == (int) recv_ifp->ifindex);
- }
+ /* ifindex sanity check */
+ if (ifindex != (int) ifp->ifindex) {
+ char from_str[INET_ADDRSTRLEN];
+ char to_str[INET_ADDRSTRLEN];
+ struct interface *recv_ifp;
+
+ if (!inet_ntop(AF_INET, &from.sin_addr, from_str , sizeof(from_str)))
+ sprintf(from_str, "<from?>");
+ if (!inet_ntop(AF_INET, &to.sin_addr, to_str , sizeof(to_str)))
+ sprintf(to_str, "<to?>");
+
+ recv_ifp = if_lookup_by_index(ifindex);
+ if (recv_ifp) {
+ zassert(ifindex == (int) recv_ifp->ifindex);
+ }
#ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH
- zlog_warn("Interface mismatch: recv PIM pkt from %s to %s on fd=%d: recv_ifindex=%d (%s) sock_ifindex=%d (%s)",
- from_str, to_str, fd,
- ifindex, recv_ifp ? recv_ifp->name : "<if-notfound>",
- ifp->ifindex, ifp->name);
+ zlog_warn("Interface mismatch: recv PIM pkt from %s to %s on fd=%d: recv_ifindex=%d (%s) sock_ifindex=%d (%s)",
+ from_str, to_str, fd,
+ ifindex, recv_ifp ? recv_ifp->name : "<if-notfound>",
+ ifp->ifindex, ifp->name);
#endif
- goto done;
- }
+ goto done;
+ }
#endif
- int fail = pim_pim_packet(ifp, buf, len);
- if (fail) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("%s: pim_pim_packet() return=%d",
- __PRETTY_FUNCTION__, fail);
- goto done;
- }
+ int fail = pim_pim_packet(ifp, buf, len);
+ if (fail) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s: pim_pim_packet() return=%d",
+ __PRETTY_FUNCTION__, fail);
+ goto done;
+ }
+
+ count++;
+ if (count % qpim_packet_process == 0)
+ cont = 0;
+ }
result = 0; /* good */
@@ -378,21 +383,22 @@ static void pim_sock_read_on(struct interface *ifp)
zlog_debug("Scheduling READ event on PIM socket fd=%d",
pim_ifp->pim_sock_fd);
}
- pim_ifp->t_pim_sock_read = 0;
+ pim_ifp->t_pim_sock_read = NULL;
zassert(!pim_ifp->t_pim_sock_read);
THREAD_READ_ON(master, pim_ifp->t_pim_sock_read, pim_sock_read, ifp,
pim_ifp->pim_sock_fd);
}
-static int pim_sock_open(struct in_addr ifaddr, ifindex_t ifindex)
+static int pim_sock_open(struct interface *ifp)
{
int fd;
+ struct pim_interface *pim_ifp = ifp->info;
- fd = pim_socket_mcast(IPPROTO_PIM, ifaddr, ifindex, 0 /* loop=false */);
+ fd = pim_socket_mcast(IPPROTO_PIM, pim_ifp->primary_address, ifp, 0 /* loop=false */);
if (fd < 0)
return -1;
- if (pim_socket_join(fd, qpim_all_pim_routers_addr, ifaddr, ifindex)) {
+ if (pim_socket_join(fd, qpim_all_pim_routers_addr, pim_ifp->primary_address, ifp->ifindex)) {
close(fd);
return -2;
}
@@ -431,9 +437,9 @@ void pim_sock_reset(struct interface *ifp)
pim_ifp->pim_sock_fd = -1;
pim_ifp->pim_sock_creation = 0;
- pim_ifp->t_pim_sock_read = 0;
+ pim_ifp->t_pim_sock_read = NULL;
- pim_ifp->t_pim_hello_timer = 0;
+ pim_ifp->t_pim_hello_timer = NULL;
pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
pim_ifp->pim_default_holdtime = -1; /* unset: means 3.5 * pim_hello_period */
pim_ifp->pim_triggered_hello_delay = PIM_DEFAULT_TRIGGERED_HELLO_DELAY;
@@ -462,18 +468,91 @@ void pim_sock_reset(struct interface *ifp)
pim_ifstat_reset(ifp);
}
-int pim_msg_send(int fd,
- struct in_addr dst,
- uint8_t *pim_msg,
- int pim_msg_size,
- const char *ifname)
+static uint16_t ip_id = 0;
+
+
+static int
+pim_msg_send_frame (int fd, char *buf, size_t len,
+ struct sockaddr *dst, size_t salen)
+{
+ struct ip *ip = (struct ip *)buf;
+
+ while (sendto (fd, buf, len, MSG_DONTWAIT, dst, salen) < 0)
+ {
+ char dst_str[INET_ADDRSTRLEN];
+
+ switch (errno)
+ {
+ case EMSGSIZE:
+ {
+ size_t hdrsize = sizeof (struct ip);
+ size_t newlen1 = ((len - hdrsize) / 2 ) & 0xFFF8;
+ size_t sendlen = newlen1 + hdrsize;
+ size_t offset = ntohs (ip->ip_off);
+
+ ip->ip_len = htons (sendlen);
+ ip->ip_off = htons (offset | IP_MF);
+ if (pim_msg_send_frame (fd, buf, sendlen, dst, salen) == 0)
+ {
+ struct ip *ip2 = (struct ip *)(buf + newlen1);
+ size_t newlen2 = len - sendlen;
+ sendlen = newlen2 + hdrsize;
+
+ memcpy (ip2, ip, hdrsize);
+ ip2->ip_len = htons (sendlen);
+ ip2->ip_off = htons (offset + (newlen1 >> 3));
+ return pim_msg_send_frame (fd, (char *)ip2, sendlen, dst, salen);
+ }
+ }
+
+ return -1;
+ break;
+ default:
+ if (PIM_DEBUG_PIM_PACKETS)
+ {
+ pim_inet4_dump ("<dst?>", ip->ip_dst, dst_str, sizeof (dst_str));
+ zlog_warn ("%s: sendto() failure to %s: fd=%d msg_size=%zd: errno=%d: %s",
+ __PRETTY_FUNCTION__,
+ dst_str, fd, len,
+ errno, safe_strerror(errno));
+ }
+ return -1;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int
+pim_msg_send(int fd, struct in_addr src,
+ struct in_addr dst, uint8_t *pim_msg,
+ int pim_msg_size, const char *ifname)
{
- ssize_t sent;
struct sockaddr_in to;
socklen_t tolen;
+ unsigned char buffer[10000];
+ unsigned char *msg_start;
+ struct ip *ip;
+
+ memset (buffer, 0, 10000);
+ int sendlen = sizeof (struct ip) + pim_msg_size;
+
+ msg_start = buffer + sizeof (struct ip);
+ memcpy (msg_start, pim_msg, pim_msg_size);
+
+ ip = (struct ip *)buffer;
+ ip->ip_id = htons (++ip_id);
+ ip->ip_hl = 5;
+ ip->ip_v = 4;
+ ip->ip_p = PIM_IP_PROTO_PIM;
+ ip->ip_src = src;
+ ip->ip_dst = dst;
+ ip->ip_ttl = MAXTTL;
+ ip->ip_len = htons (sendlen);
if (PIM_DEBUG_PIM_PACKETS) {
- char dst_str[100];
+ char dst_str[INET_ADDRSTRLEN];
pim_inet4_dump("<dst?>", dst, dst_str, sizeof(dst_str));
zlog_debug("%s: to %s on %s: msg_size=%d checksum=%x",
__PRETTY_FUNCTION__,
@@ -490,27 +569,8 @@ int pim_msg_send(int fd,
pim_pkt_dump(__PRETTY_FUNCTION__, pim_msg, pim_msg_size);
}
- sent = sendto(fd, pim_msg, pim_msg_size, MSG_DONTWAIT,
- (struct sockaddr *)&to, tolen);
- if (sent != (ssize_t) pim_msg_size) {
- int e = errno;
- char dst_str[100];
- pim_inet4_dump("<dst?>", dst, dst_str, sizeof(dst_str));
- if (sent < 0) {
- zlog_warn("%s: sendto() failure to %s on %s: fd=%d msg_size=%d: errno=%d: %s",
- __PRETTY_FUNCTION__,
- dst_str, ifname, fd, pim_msg_size,
- e, safe_strerror(e));
- }
- else {
- zlog_warn("%s: sendto() partial to %s on %s: fd=%d msg_size=%d: sent=%zd",
- __PRETTY_FUNCTION__,
- dst_str, ifname, fd,
- pim_msg_size, sent);
- }
- return -1;
- }
-
+ pim_msg_send_frame (fd, (char *)buffer, sendlen,
+ (struct sockaddr *)&to, tolen);
return 0;
}
@@ -525,7 +585,7 @@ static int hello_send(struct interface *ifp,
pim_ifp = ifp->info;
if (PIM_DEBUG_PIM_HELLO) {
- char dst_str[100];
+ char dst_str[INET_ADDRSTRLEN];
pim_inet4_dump("<dst?>", qpim_all_pim_routers_addr, dst_str, sizeof(dst_str));
zlog_debug("%s: to %s on %s: holdt=%u prop_d=%u overr_i=%u dis_join_supp=%d dr_prio=%u gen_id=%08x addrs=%d",
__PRETTY_FUNCTION__,
@@ -560,6 +620,7 @@ static int hello_send(struct interface *ifp,
PIM_MSG_TYPE_HELLO);
if (pim_msg_send(pim_ifp->pim_sock_fd,
+ pim_ifp->primary_address,
qpim_all_pim_routers_addr,
pim_msg,
pim_msg_size,
@@ -627,16 +688,14 @@ static int on_pim_hello_send(struct thread *t)
struct pim_interface *pim_ifp;
struct interface *ifp;
- zassert(t);
ifp = THREAD_ARG(t);
- zassert(ifp);
pim_ifp = ifp->info;
/*
* Schedule next hello
*/
- pim_ifp->t_pim_hello_timer = 0;
+ pim_ifp->t_pim_hello_timer = NULL;
hello_resched(ifp);
/*
@@ -692,7 +751,20 @@ void pim_hello_restart_triggered(struct interface *ifp)
pim_ifp = ifp->info;
zassert(pim_ifp);
- triggered_hello_delay_msec = 1000 * pim_ifp->pim_triggered_hello_delay;
+ /*
+ * There exists situations where we have the a RPF out this
+ * interface, but we haven't formed a neighbor yet. This
+ * happens especially during interface flaps. While
+ * we would like to handle this more gracefully in other
+ * parts of the code. In order to get us up and running
+ * let's just send the hello immediate'ish
+ * This should be revisited when we get nexthop tracking
+ * in and when we have a better handle on safely
+ * handling the rpf information for upstreams that
+ * we cannot legally reach yet.
+ */
+ triggered_hello_delay_msec = 1;
+ //triggered_hello_delay_msec = 1000 * pim_ifp->pim_triggered_hello_delay;
if (pim_ifp->t_pim_hello_timer) {
long remain_msec = pim_time_timer_remain_msec(pim_ifp->t_pim_hello_timer);
@@ -703,11 +775,11 @@ void pim_hello_restart_triggered(struct interface *ifp)
}
THREAD_OFF(pim_ifp->t_pim_hello_timer);
- pim_ifp->t_pim_hello_timer = 0;
+ pim_ifp->t_pim_hello_timer = NULL;
}
- zassert(!pim_ifp->t_pim_hello_timer);
- random_msec = random() % (triggered_hello_delay_msec + 1);
+ random_msec = triggered_hello_delay_msec;
+ //random_msec = random() % (triggered_hello_delay_msec + 1);
if (PIM_DEBUG_PIM_HELLO) {
zlog_debug("Scheduling %d msec triggered hello on interface %s",
@@ -722,28 +794,29 @@ void pim_hello_restart_triggered(struct interface *ifp)
int pim_sock_add(struct interface *ifp)
{
struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
uint32_t old_genid;
pim_ifp = ifp->info;
zassert(pim_ifp);
if (pim_ifp->pim_sock_fd >= 0) {
- zlog_warn("Can't recreate existing PIM socket fd=%d for interface %s",
- pim_ifp->pim_sock_fd, ifp->name);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("Can't recreate existing PIM socket fd=%d for interface %s",
+ pim_ifp->pim_sock_fd, ifp->name);
return -1;
}
- ifaddr = pim_ifp->primary_address;
-
- pim_ifp->pim_sock_fd = pim_sock_open(ifaddr, ifp->ifindex);
+ pim_ifp->pim_sock_fd = pim_sock_open(ifp);
if (pim_ifp->pim_sock_fd < 0) {
- zlog_warn("Could not open PIM socket on interface %s",
- ifp->name);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("Could not open PIM socket on interface %s",
+ ifp->name);
return -2;
}
- pim_ifp->t_pim_sock_read = 0;
+ pim_socket_ip_hdr (pim_ifp->pim_sock_fd);
+
+ pim_ifp->t_pim_sock_read = NULL;
pim_ifp->pim_sock_creation = pim_time_monotonic_sec();
/*
diff --git a/pimd/pim_pim.h b/pimd/pim_pim.h
index 5692a37938..00c5f9012e 100644
--- a/pimd/pim_pim.h
+++ b/pimd/pim_pim.h
@@ -28,8 +28,6 @@
#define PIM_PIM_BUFSIZE_READ (20000)
#define PIM_PIM_BUFSIZE_WRITE (20000)
-#define PIM_NEXTHOP_IFINDEX_TAB_SIZE (20)
-
#define PIM_DEFAULT_HELLO_PERIOD (30) /* seconds, RFC 4601: 4.11 */
#define PIM_DEFAULT_TRIGGERED_HELLO_DELAY (5) /* seconds, RFC 4601: 4.11 */
#define PIM_DEFAULT_DR_PRIORITY (1) /* RFC 4601: 4.3.1 */
@@ -38,15 +36,17 @@
#define PIM_DEFAULT_CAN_DISABLE_JOIN_SUPPRESSION (0) /* boolean */
#define PIM_DEFAULT_T_PERIODIC (60) /* RFC 4601: 4.11. Timer Values */
-#define PIM_MSG_TYPE_HELLO (0)
-#define PIM_MSG_TYPE_REGISTER (1)
-#define PIM_MSG_TYPE_REG_STOP (2)
-#define PIM_MSG_TYPE_JOIN_PRUNE (3)
-#define PIM_MSG_TYPE_BOOTSTRAP (4)
-#define PIM_MSG_TYPE_ASSERT (5)
-#define PIM_MSG_TYPE_GRAFT (6)
-#define PIM_MSG_TYPE_GRAFT_ACK (7)
-#define PIM_MSG_TYPE_CANDIDATE (8)
+enum pim_msg_type {
+ PIM_MSG_TYPE_HELLO = 0,
+ PIM_MSG_TYPE_REGISTER,
+ PIM_MSG_TYPE_REG_STOP,
+ PIM_MSG_TYPE_JOIN_PRUNE,
+ PIM_MSG_TYPE_BOOTSTRAP,
+ PIM_MSG_TYPE_ASSERT,
+ PIM_MSG_TYPE_GRAFT,
+ PIM_MSG_TYPE_GRAFT_ACK,
+ PIM_MSG_TYPE_CANDIDATE
+};
#define PIM_MSG_HDR_OFFSET_VERSION(pim_msg) (pim_msg)
#define PIM_MSG_HDR_OFFSET_TYPE(pim_msg) (pim_msg)
@@ -67,6 +67,7 @@ void pim_hello_restart_triggered(struct interface *ifp);
int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len);
int pim_msg_send(int fd,
+ struct in_addr src,
struct in_addr dst,
uint8_t *pim_msg,
int pim_msg_size,
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index ce3ac1a433..29b4e8a63b 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -24,6 +24,9 @@
#include "log.h"
#include "if.h"
#include "thread.h"
+#include "prefix.h"
+#include "vty.h"
+#include "plist.h"
#include "pimd.h"
#include "pim_mroute.h"
@@ -39,65 +42,150 @@
#include "pim_oil.h"
#include "pim_zebra.h"
#include "pim_join.h"
+#include "pim_util.h"
struct thread *send_test_packet_timer = NULL;
-/*
- * This seems stupidly expensive. A list lookup. Why is this
- * not a hash?
- */
-static int
-pim_check_is_my_ip_address (struct in_addr dest_addr)
+void
+pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg,
+ struct in_addr src, struct in_addr originator)
{
- /*
- * See if we can short-cut some?
- * This might not make sense if we ever leave a static RP
- * type of configuration.
- * Note - Premature optimization might bite our patooeys' here.
- */
- if (I_am_RP(dest_addr) && (dest_addr.s_addr == qpim_rp.rpf_addr.s_addr))
- return 1;
+ struct pim_interface *pinfo;
+ unsigned char buffer[10000];
+ unsigned int b1length = 0;
+ unsigned int length;
+ uint8_t *b1;
+ struct prefix p;
+
+ if (PIM_DEBUG_PIM_REG)
+ {
+ zlog_debug ("Sending Register stop for %s to %s on %s",
+ pim_str_sg_dump (sg), inet_ntoa(originator), ifp->name);
+ }
- if (if_lookup_exact_address (&dest_addr, AF_INET))
- return 1;
+ memset (buffer, 0, 10000);
+ b1 = (uint8_t *)buffer + PIM_MSG_REGISTER_STOP_LEN;
- return 0;
+ length = pim_encode_addr_group (b1, AFI_IP, 0, 0, sg->grp);
+ b1length += length;
+ b1 += length;
+
+ p.family = AF_INET;
+ p.u.prefix4 = sg->src;
+ p.prefixlen = 32;
+ length = pim_encode_addr_ucast (b1, &p);
+ b1length += length;
+
+ pim_msg_build_header (buffer, b1length + PIM_MSG_REGISTER_STOP_LEN, PIM_MSG_TYPE_REG_STOP);
+
+ pinfo = (struct pim_interface *)ifp->info;
+ if (!pinfo)
+ {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug ("%s: No pinfo!\n", __PRETTY_FUNCTION__);
+ return;
+ }
+ if (pim_msg_send (pinfo->pim_sock_fd, src, originator,
+ buffer, b1length + PIM_MSG_REGISTER_STOP_LEN,
+ ifp->name))
+ {
+ if (PIM_DEBUG_PIM_TRACE)
+ {
+ zlog_debug ("%s: could not send PIM register stop message on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ }
}
-static void
-pim_register_stop_send (struct in_addr src)
+int
+pim_register_stop_recv (uint8_t *buf, int buf_size)
{
- return;
+ struct pim_upstream *upstream = NULL;
+ struct prefix source;
+ struct prefix_sg sg;
+ int l;
+
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ l = pim_parse_addr_group (&sg, buf, buf_size);
+ buf += l;
+ buf_size -= l;
+ pim_parse_addr_ucast (&source, buf, buf_size);
+ sg.src = source.u.prefix4;
+
+ upstream = pim_upstream_find (&sg);
+ if (!upstream)
+ {
+ return 0;
+ }
+
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug ("Received Register stop for %s",
+ upstream->sg_str);
+
+ switch (upstream->join_state)
+ {
+ case PIM_UPSTREAM_NOTJOINED:
+ case PIM_UPSTREAM_PRUNE:
+ return 0;
+ break;
+ case PIM_UPSTREAM_JOINED:
+ upstream->join_state = PIM_UPSTREAM_PRUNE;
+ pim_channel_del_oif (upstream->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+ pim_upstream_start_register_stop_timer (upstream, 0);
+ break;
+ case PIM_UPSTREAM_JOIN_PENDING:
+ upstream->join_state = PIM_UPSTREAM_PRUNE;
+ pim_upstream_start_register_stop_timer (upstream, 0);
+ return 0;
+ break;
+ }
+
+ return 0;
}
void
-pim_register_send (const struct ip *ip_hdr, struct pim_rpf *rpg)
+pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct pim_rpf *rpg, int null_register, struct pim_upstream *up)
{
- unsigned char buffer[3000];
+ unsigned char buffer[10000];
unsigned char *b1;
struct pim_interface *pinfo;
struct interface *ifp;
- uint32_t plen;
+
+ if (PIM_DEBUG_PIM_REG)
+ {
+ zlog_debug ("Sending %s %sRegister Packet to %s",
+ up->sg_str, null_register ? "NULL " : "",
+ inet_ntoa (rpg->rpf_addr.u.prefix4));
+ }
ifp = rpg->source_nexthop.interface;
+ if (!ifp)
+ {
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug ("%s: No interface to transmit register on", __PRETTY_FUNCTION__);
+ return;
+ }
pinfo = (struct pim_interface *)ifp->info;
if (!pinfo) {
- zlog_debug("%s: No pinfo!\n", __PRETTY_FUNCTION__);
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug("%s: Interface: %s not configured for pim to trasmit on!\n", __PRETTY_FUNCTION__, ifp->name);
return;
}
- memset(buffer, 0, 3000);
+ memset(buffer, 0, 10000);
+ b1 = buffer + PIM_MSG_HEADER_LEN;
+ *b1 |= null_register << 6;
b1 = buffer + PIM_MSG_REGISTER_LEN;
- plen = ntohs(ip_hdr->ip_len);
- memcpy(b1, (const unsigned char *)ip_hdr, plen);
+ memcpy(b1, (const unsigned char *)buf, buf_size);
- pim_msg_build_header(buffer, plen + PIM_MSG_REGISTER_LEN, PIM_MSG_TYPE_REGISTER);
+ pim_msg_build_header(buffer, buf_size + PIM_MSG_REGISTER_LEN, PIM_MSG_TYPE_REGISTER);
if (pim_msg_send(pinfo->pim_sock_fd,
- rpg->rpf_addr,
+ src,
+ rpg->rpf_addr.u.prefix4,
buffer,
- plen + PIM_MSG_REGISTER_LEN,
+ buf_size + PIM_MSG_REGISTER_LEN,
ifp->name)) {
if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: could not send PIM register message on interface %s",
@@ -159,15 +247,16 @@ pim_register_recv (struct interface *ifp,
{
int sentRegisterStop = 0;
struct ip *ip_hdr;
- //size_t hlen;
- struct in_addr group = { .s_addr = 0 };
- struct in_addr source = { .s_addr = 0 };
- //uint8_t *msg;
+ struct prefix_sg sg;
uint32_t *bits;
+ int i_am_rp = 0;
- if (!pim_check_is_my_ip_address (dest_addr)) {
- if (PIM_DEBUG_PIM_PACKETS) {
- char dest[100];
+#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
+ ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
+
+ if (!pim_rp_check_is_my_ip_address (ip_hdr->ip_dst, dest_addr)) {
+ if (PIM_DEBUG_PIM_REG) {
+ char dest[INET_ADDRSTRLEN];
pim_inet4_dump ("<dst?>", dest_addr, dest, sizeof(dest));
zlog_debug ("%s: Received Register message for %s that I do not own", __func__,
@@ -176,7 +265,6 @@ pim_register_recv (struct interface *ifp,
return 0;
}
-#define inherited_olist(S,G) NULL
/*
* Please note this is not drawn to get the correct bit/data size
*
@@ -203,25 +291,33 @@ pim_register_recv (struct interface *ifp,
* Line above. So we need to add 4 bytes to get to the
* start of the actual Encapsulated data.
*/
-#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
- ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
- //hlen = (ip_hdr->ip_hl << 2) | PIM_MSG_REGISTER_LEN;
- //msg = (uint8_t *)tlv_buf + hlen;
- source = ip_hdr->ip_src;
- group = ip_hdr->ip_dst;
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = ip_hdr->ip_src;
+ sg.grp = ip_hdr->ip_dst;
- if (I_am_RP (group) && (dest_addr.s_addr == ((RP (group))->rpf_addr.s_addr))) {
+ i_am_rp = I_am_RP (sg.grp);
+
+ if (PIM_DEBUG_PIM_REG)
+ {
+ char src_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump ("<src?>", src_addr, src_str, sizeof (src_str));
+ zlog_debug ("Received Register message(%s) from %s on %s, rp: %d",
+ pim_str_sg_dump (&sg), src_str, ifp->name, i_am_rp);
+ }
+
+ if (i_am_rp && (dest_addr.s_addr == ((RP (sg.grp))->rpf_addr.u.prefix4.s_addr))) {
sentRegisterStop = 0;
if (*bits & PIM_REGISTER_BORDER_BIT) {
- struct in_addr pimbr = pim_br_get_pmbr (source, group);
+ struct in_addr pimbr = pim_br_get_pmbr (&sg);
if (PIM_DEBUG_PIM_PACKETS)
zlog_debug("%s: Received Register message with Border bit set", __func__);
if (pimbr.s_addr == pim_br_unknown.s_addr)
- pim_br_set_pmbr(source, group, src_addr);
+ pim_br_set_pmbr(&sg, src_addr);
else if (src_addr.s_addr != pimbr.s_addr) {
- pim_register_stop_send(src_addr);
+ pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
if (PIM_DEBUG_PIM_PACKETS)
zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet",
__func__, "Sender");
@@ -230,83 +326,81 @@ pim_register_recv (struct interface *ifp,
}
}
- struct pim_upstream *upstream = pim_upstream_find (source, group);
+ struct pim_upstream *upstream = pim_upstream_find (&sg);
/*
* If we don't have a place to send ignore the packet
*/
if (!upstream)
- return 1;
+ {
+ upstream = pim_upstream_add (&sg, ifp,
+ PIM_UPSTREAM_FLAG_MASK_SRC_STREAM,
+ __PRETTY_FUNCTION__);
+ if (!upstream)
+ {
+ zlog_warn ("Failure to create upstream state");
+ return 1;
+ }
+ PIM_UPSTREAM_FLAG_SET_SRC_STREAM(upstream->flags);
+
+ upstream->upstream_register = src_addr;
+ pim_rp_set_upstream_addr (&upstream->upstream_addr, sg.src, sg.grp);
+ if (pim_nexthop_lookup (&upstream->rpf.source_nexthop,
+ upstream->upstream_addr, 1) != 0)
+ {
+ if (PIM_DEBUG_PIM_REG)
+ {
+ zlog_debug ("Received Register(%s), for which I have no path back", upstream->sg_str);
+ }
+ PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(upstream->flags);
+ pim_upstream_del (upstream, __PRETTY_FUNCTION__);
+ return 1;
+ }
+ upstream->sg.src = sg.src;
+ upstream->rpf.rpf_addr = upstream->rpf.source_nexthop.mrib_nexthop_addr;
+
+ upstream->join_state = PIM_UPSTREAM_PRUNE;
+
+ }
if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) ||
- ((SwitchToSptDesired(source, group)) &&
- (inherited_olist(source, group) == NULL))) {
- pim_register_stop_send(src_addr);
+ ((SwitchToSptDesired(&sg)) &&
+ pim_upstream_inherited_olist (upstream) == 0)) {
+ //pim_scan_individual_oil (upstream->channel_oil);
+ pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
sentRegisterStop = 1;
+ } else {
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug ("(%s) sptbit: %d", upstream->sg_str, upstream->sptbit);
}
-
if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) ||
- (SwitchToSptDesired(source, group))) {
+ (SwitchToSptDesired(&sg))) {
if (sentRegisterStop) {
- pim_upstream_keep_alive_timer_start (upstream, PIM_RP_KEEPALIVE_PERIOD);
+ pim_upstream_keep_alive_timer_start (upstream, qpim_rp_keep_alive_time);
} else {
- pim_upstream_keep_alive_timer_start (upstream, PIM_KEEPALIVE_PERIOD);
+ pim_upstream_keep_alive_timer_start (upstream, qpim_keep_alive_time);
}
}
if (!(upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) &&
!(*bits & PIM_REGISTER_NR_BIT))
{
- pim_rp_set_upstream_addr (&upstream->upstream_addr, source);
- pim_nexthop_lookup (&upstream->rpf.source_nexthop,
- upstream->upstream_addr, NULL);
- upstream->rpf.source_nexthop.interface = ifp;
- upstream->source_addr.s_addr = source.s_addr;
- upstream->rpf.rpf_addr.s_addr = source.s_addr;
- upstream->channel_oil->oil.mfcc_origin = source;
- pim_scan_individual_oil (upstream->channel_oil);
- pim_joinprune_send(upstream->rpf.source_nexthop.interface,
- upstream->rpf.source_nexthop.mrib_nexthop_addr,
- upstream->source_addr,
- upstream->group_addr,
- 1);
-
//decapsulate and forward the iner packet to
//inherited_olist(S,G,rpt)
+ // This is taken care of by the kernel for us
}
+ pim_upstream_msdp_reg_timer_start(upstream);
} else {
- pim_register_stop_send(src_addr);
+ if (PIM_DEBUG_PIM_REG)
+ {
+ if (!i_am_rp)
+ zlog_debug ("Received Register packet for %s, Rejecting packet because I am not the RP configured for group",
+ pim_str_sg_dump (&sg));
+ else
+ zlog_debug ("Received Register packet for %s, Rejecting packet because the dst ip address is not the actual RP",
+ pim_str_sg_dump (&sg));
+ }
+ pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
}
return 1;
}
-
-
-static int
-pim_register_send_test_packet (struct thread *t)
-{
- uint8_t *packet;
-
- packet = THREAD_ARG(t);
-
- *packet = 4;
-
- return 1;
-}
-
-/*
- * pim_register_send_test_packet
- *
- * Send a test packet to the RP from source, in group and pps packets per second
- */
-void
-pim_register_send_test_packet_start (struct in_addr source,
- struct in_addr group,
- uint32_t pps)
-{
- uint8_t *packet = NULL;
-
- THREAD_TIMER_MSEC_ON(master, send_test_packet_timer,
- pim_register_send_test_packet, packet, 1000/pps);
-
- return;
-}
diff --git a/pimd/pim_register.h b/pimd/pim_register.h
index 039c0006e0..42a908b225 100644
--- a/pimd/pim_register.h
+++ b/pimd/pim_register.h
@@ -31,15 +31,14 @@
#define PIM_MSG_REGISTER_LEN (8)
#define PIM_MSG_REGISTER_STOP_LEN (4)
-void pim_register_send_test_packet_start (struct in_addr source,
- struct in_addr group,
- uint32_t pps);
+int pim_register_stop_recv (uint8_t *buf, int buf_size);
int pim_register_recv (struct interface *ifp,
struct in_addr dest_addr,
struct in_addr src_addr,
uint8_t *tlv_buf, int tlv_buf_size);
-void pim_register_send (const struct ip *msg, struct pim_rpf *rpg);
+void pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct pim_rpf *rpg, int null_register, struct pim_upstream *up);
+void pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg, struct in_addr src, struct in_addr originator);
#endif
diff --git a/pimd/pim_routemap.c b/pimd/pim_routemap.c
index f65f35ba5e..a8525b690e 100644
--- a/pimd/pim_routemap.c
+++ b/pimd/pim_routemap.c
@@ -22,6 +22,7 @@
#include <zebra.h>
#include "if.h"
+#include "vty.h"
#include "routemap.h"
#include "pimd.h"
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 26d108bcaa..dc19002a42 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -20,48 +20,598 @@
*/
#include <zebra.h>
+#include "lib/json.h"
#include "log.h"
#include "network.h"
#include "if.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "memory.h"
+#include "vty.h"
+#include "vrf.h"
+#include "plist.h"
#include "pimd.h"
+#include "pim_vty.h"
#include "pim_str.h"
+#include "pim_iface.h"
#include "pim_rp.h"
#include "pim_str.h"
#include "pim_rpf.h"
+#include "pim_sock.h"
+#include "pim_memory.h"
+#include "pim_iface.h"
+#include "pim_msdp.h"
-static int i_am_rp = 0;
+struct rp_info
+{
+ struct prefix group;
+ struct pim_rpf rp;
+ int i_am_rp;
+ char *plist;
+};
+
+static struct list *qpim_rp_list = NULL;
+static struct rp_info *tail = NULL;
+
+static void
+pim_rp_info_free (struct rp_info *rp_info)
+{
+ XFREE (MTYPE_PIM_RP, rp_info);
+}
+
+static int
+pim_rp_list_cmp (void *v1, void *v2)
+{
+ struct rp_info *rp1 = (struct rp_info *)v1;
+ struct rp_info *rp2 = (struct rp_info *)v2;
+
+ if (rp1 == rp2)
+ return 0;
+
+ if (!rp1 && rp2)
+ return -1;
+
+ if (rp1 && !rp2)
+ return 1;
+
+ /*
+ * Sort by RP IP address
+ */
+ if (rp1->rp.rpf_addr.u.prefix4.s_addr < rp2->rp.rpf_addr.u.prefix4.s_addr)
+ return -1;
+
+ if (rp1->rp.rpf_addr.u.prefix4.s_addr > rp2->rp.rpf_addr.u.prefix4.s_addr)
+ return 1;
+
+ /*
+ * Sort by group IP address
+ */
+ if (rp1->group.u.prefix4.s_addr < rp2->group.u.prefix4.s_addr)
+ return -1;
+
+ if (rp1->group.u.prefix4.s_addr > rp2->group.u.prefix4.s_addr)
+ return 1;
+
+ if (rp1 == tail)
+ return 1;
+
+ return -1;
+}
+
+void
+pim_rp_init (void)
+{
+ struct rp_info *rp_info;
+
+ qpim_rp_list = list_new ();
+ qpim_rp_list->del = (void (*)(void *))pim_rp_info_free;
+ qpim_rp_list->cmp = pim_rp_list_cmp;
+
+ rp_info = XCALLOC (MTYPE_PIM_RP, sizeof (*rp_info));
+
+ if (!rp_info)
+ return;
+
+ str2prefix ("224.0.0.0/4", &rp_info->group);
+ rp_info->group.family = AF_INET;
+ rp_info->rp.rpf_addr.family = AF_INET;
+ rp_info->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
+ tail = rp_info;
+
+ listnode_add (qpim_rp_list, rp_info);
+}
+
+void
+pim_rp_free (void)
+{
+ if (qpim_rp_list)
+ list_delete (qpim_rp_list);
+ qpim_rp_list = NULL;
+}
+
+/*
+ * Given an RP's prefix-list, return the RP's rp_info for that prefix-list
+ */
+static struct rp_info *
+pim_rp_find_prefix_list (struct in_addr rp, const char *plist)
+{
+ struct listnode *node;
+ struct rp_info *rp_info;
+
+ for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
+ {
+ if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr &&
+ rp_info->plist && strcmp(rp_info->plist, plist) == 0)
+ {
+ return rp_info;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Return true if plist is used by any rp_info
+ */
+static int
+pim_rp_prefix_list_used (const char *plist)
+{
+ struct listnode *node;
+ struct rp_info *rp_info;
+
+ for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
+ {
+ if (rp_info->plist && strcmp(rp_info->plist, plist) == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
/*
- * Checks to see if we should elect ourself the actual RP
+ * Given an RP's address, return the RP's rp_info that is an exact match for 'group'
*/
+static struct rp_info *
+pim_rp_find_exact (struct in_addr rp, struct prefix *group)
+{
+ struct listnode *node;
+ struct rp_info *rp_info;
+
+ for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
+ {
+ if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr &&
+ prefix_same (&rp_info->group, group))
+ return rp_info;
+ }
+
+ return NULL;
+}
+
+/*
+ * Given a group, return the rp_info for that group
+ */
+static struct rp_info *
+pim_rp_find_match_group (struct prefix *group)
+{
+ struct listnode *node;
+ struct rp_info *rp_info;
+ struct prefix_list *plist;
+
+ for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
+ {
+ if (rp_info->plist)
+ {
+ plist = prefix_list_lookup (AFI_IP, rp_info->plist);
+
+ if (plist && prefix_list_apply (plist, group) == PREFIX_PERMIT)
+ return rp_info;
+ }
+ else
+ {
+ if (prefix_match (&rp_info->group, group))
+ return rp_info;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * When the user makes "ip pim rp" configuration changes or if they change the
+ * prefix-list(s) used by these statements we must tickle the upstream state
+ * for each group to make them re-lookup who their RP should be.
+ *
+ * This is a placeholder function for now.
+ */
+static void
+pim_rp_refresh_group_to_rp_mapping()
+{
+ pim_msdp_i_am_rp_changed();
+}
+
void
-pim_rp_check_rp (struct in_addr old, struct in_addr new)
-{
- if (PIM_DEBUG_ZEBRA) {
- char sold[100];
- char snew[100];
- char rp[100];
- pim_inet4_dump("<rp?>", qpim_rp.rpf_addr, rp, sizeof(rp));
- pim_inet4_dump("<old?>", old, sold, sizeof(sold));
- pim_inet4_dump("<new?>", new, snew, sizeof(snew));
- zlog_debug("%s: %s for old %s new %s", __func__, rp, sold, snew );
+pim_rp_prefix_list_update (struct prefix_list *plist)
+{
+ struct listnode *node;
+ struct rp_info *rp_info;
+ int refresh_needed = 0;
+
+ for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
+ {
+ if (rp_info->plist && strcmp(rp_info->plist, prefix_list_name (plist)) == 0)
+ {
+ refresh_needed = 1;
+ break;
+ }
+ }
+
+ if (refresh_needed)
+ pim_rp_refresh_group_to_rp_mapping();
+}
+
+static int
+pim_rp_check_interface_addrs(struct rp_info *rp_info,
+ struct pim_interface *pim_ifp)
+{
+ struct listnode *node;
+ struct pim_secondary_addr *sec_addr;
+
+ if (pim_ifp->primary_address.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr)
+ return 1;
+
+ if (!pim_ifp->sec_addr_list) {
+ return 0;
}
- if (qpim_rp.rpf_addr.s_addr == INADDR_NONE)
- return;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
+ if (sec_addr->addr.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void
+pim_rp_check_interfaces (struct rp_info *rp_info)
+{
+ struct listnode *node;
+ struct interface *ifp;
+
+ rp_info->i_am_rp = 0;
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
+ {
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) {
+ rp_info->i_am_rp = 1;
+ }
+ }
+}
+
+int
+pim_rp_new (const char *rp, const char *group_range, const char *plist)
+{
+ int result;
+ struct rp_info *rp_info;
+ struct rp_info *rp_all;
+ struct prefix group_all;
+ struct listnode *node, *nnode;
+ struct rp_info *tmp_rp_info;
+ char buffer[BUFSIZ];
+
+ rp_info = XCALLOC (MTYPE_PIM_RP, sizeof (*rp_info));
+ if (!rp_info)
+ return PIM_MALLOC_FAIL;
+
+ if (group_range == NULL)
+ result = str2prefix ("224.0.0.0/4", &rp_info->group);
+ else
+ result = str2prefix (group_range, &rp_info->group);
+
+ if (!result)
+ {
+ XFREE (MTYPE_PIM_RP, rp_info);
+ return PIM_GROUP_BAD_ADDRESS;
+ }
+
+ rp_info->rp.rpf_addr.family = AF_INET;
+ result = inet_pton (rp_info->rp.rpf_addr.family, rp, &rp_info->rp.rpf_addr.u.prefix4);
+
+ if (result <= 0)
+ {
+ XFREE (MTYPE_PIM_RP, rp_info);
+ return PIM_RP_BAD_ADDRESS;
+ }
+
+ if (plist)
+ {
+ /*
+ * Return if the prefix-list is already configured for this RP
+ */
+ if (pim_rp_find_prefix_list (rp_info->rp.rpf_addr.u.prefix4, plist))
+ {
+ XFREE (MTYPE_PIM_RP, rp_info);
+ return PIM_SUCCESS;
+ }
+
+ /*
+ * Barf if the prefix-list is already configured for an RP
+ */
+ if (pim_rp_prefix_list_used (plist))
+ {
+ XFREE (MTYPE_PIM_RP, rp_info);
+ return PIM_RP_PFXLIST_IN_USE;
+ }
+
+ /*
+ * Free any existing rp_info entries for this RP
+ */
+ for (ALL_LIST_ELEMENTS (qpim_rp_list, node, nnode, tmp_rp_info))
+ {
+ if (rp_info->rp.rpf_addr.u.prefix4.s_addr == tmp_rp_info->rp.rpf_addr.u.prefix4.s_addr)
+ {
+ if (tmp_rp_info->plist)
+ pim_rp_del (rp, NULL, tmp_rp_info->plist);
+ else
+ pim_rp_del (rp, prefix2str(&tmp_rp_info->group, buffer, BUFSIZ), NULL);
+ }
+ }
+
+ rp_info->plist = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist);
+ }
+ else
+ {
+ str2prefix ("224.0.0.0/4", &group_all);
+ rp_all = pim_rp_find_match_group(&group_all);
+
+ /*
+ * Barf if group is a non-multicast subnet
+ */
+ if (! prefix_match (&rp_all->group, &rp_info->group))
+ {
+ XFREE (MTYPE_PIM_RP, rp_info);
+ return PIM_GROUP_BAD_ADDRESS;
+ }
- if (new.s_addr == qpim_rp.rpf_addr.s_addr)
+ /*
+ * Remove any prefix-list rp_info entries for this RP
+ */
+ for (ALL_LIST_ELEMENTS (qpim_rp_list, node, nnode, tmp_rp_info))
+ {
+ if (tmp_rp_info->plist &&
+ rp_info->rp.rpf_addr.u.prefix4.s_addr == tmp_rp_info->rp.rpf_addr.u.prefix4.s_addr)
+ {
+ pim_rp_del (rp, NULL, tmp_rp_info->plist);
+ }
+ }
+
+ /*
+ * Take over the 224.0.0.0/4 group if the rp is INADDR_NONE
+ */
+ if (prefix_same (&rp_all->group, &rp_info->group) &&
+ pim_rpf_addr_is_inaddr_none (&rp_all->rp))
+ {
+ rp_all->rp.rpf_addr = rp_info->rp.rpf_addr;
+ XFREE (MTYPE_PIM_RP, rp_info);
+
+ if (pim_nexthop_lookup (&rp_all->rp.source_nexthop, rp_all->rp.rpf_addr.u.prefix4, 1) != 0)
+ return PIM_RP_NO_PATH;
+
+ pim_rp_check_interfaces (rp_all);
+ pim_rp_refresh_group_to_rp_mapping();
+ return PIM_SUCCESS;
+ }
+
+ /*
+ * Return if the group is already configured for this RP
+ */
+ if (pim_rp_find_exact (rp_info->rp.rpf_addr.u.prefix4, &rp_info->group))
+ {
+ XFREE (MTYPE_PIM_RP, rp_info);
+ return PIM_SUCCESS;
+ }
+
+ /*
+ * Barf if this group is already covered by some other RP
+ */
+ tmp_rp_info = pim_rp_find_match_group (&rp_info->group);
+
+ if (tmp_rp_info)
+ {
+ if (tmp_rp_info->plist)
+ {
+ XFREE (MTYPE_PIM_RP, rp_info);
+ return PIM_GROUP_PFXLIST_OVERLAP;
+ }
+ else
+ {
+ /*
+ * If the only RP that covers this group is an RP configured for
+ * 224.0.0.0/4 that is fine, ignore that one. For all others
+ * though we must return PIM_GROUP_OVERLAP
+ */
+ if (! prefix_same (&group_all, &tmp_rp_info->group))
+ {
+ XFREE (MTYPE_PIM_RP, rp_info);
+ return PIM_GROUP_OVERLAP;
+ }
+ }
+ }
+ }
+
+ listnode_add_sort (qpim_rp_list, rp_info);
+
+ if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1) != 0)
+ return PIM_RP_NO_PATH;
+
+ pim_rp_check_interfaces (rp_info);
+ pim_rp_refresh_group_to_rp_mapping();
+ return PIM_SUCCESS;
+}
+
+int
+pim_rp_del (const char *rp, const char *group_range, const char *plist)
+{
+ struct prefix group;
+ struct in_addr rp_addr;
+ struct prefix g_all;
+ struct rp_info *rp_info;
+ struct rp_info *rp_all;
+ int result;
+
+ if (group_range == NULL)
+ result = str2prefix ("224.0.0.0/4", &group);
+ else
+ result = str2prefix (group_range, &group);
+
+ if (!result)
+ return PIM_GROUP_BAD_ADDRESS;
+
+ result = inet_pton (AF_INET, rp, &rp_addr);
+ if (result <= 0)
+ return PIM_RP_BAD_ADDRESS;
+
+ if (plist)
+ rp_info = pim_rp_find_prefix_list (rp_addr, plist);
+ else
+ rp_info = pim_rp_find_exact (rp_addr, &group);
+
+ if (!rp_info)
+ return PIM_RP_NOT_FOUND;
+
+ if (rp_info->plist)
{
- i_am_rp = 1;
- return;
+ XFREE(MTYPE_PIM_FILTER_NAME, rp_info->plist);
+ rp_info->plist = NULL;
}
- if (old.s_addr == qpim_rp.rpf_addr.s_addr)
+ str2prefix ("224.0.0.0/4", &g_all);
+ rp_all = pim_rp_find_match_group (&g_all);
+
+ if (rp_all == rp_info)
{
- i_am_rp = 0;
- return;
+ rp_all->rp.rpf_addr.family = AF_INET;
+ rp_all->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
+ rp_all->i_am_rp = 0;
+ return PIM_SUCCESS;
+ }
+
+ listnode_delete (qpim_rp_list, rp_info);
+ pim_rp_refresh_group_to_rp_mapping();
+ return PIM_SUCCESS;
+}
+
+int
+pim_rp_setup (void)
+{
+ struct listnode *node;
+ struct rp_info *rp_info;
+ int ret = 0;
+
+ for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
+ {
+ if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE)
+ continue;
+
+ if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1) != 0)
+ {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug ("Unable to lookup nexthop for rp specified");
+ ret++;
+ }
}
+
+ if (ret)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Checks to see if we should elect ourself the actual RP when new if
+ * addresses are added against an interface.
+ */
+void
+pim_rp_check_on_if_add(struct pim_interface *pim_ifp)
+{
+ struct listnode *node;
+ struct rp_info *rp_info;
+ bool i_am_rp_changed = false;
+
+ if (qpim_rp_list == NULL)
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info)) {
+ if (pim_rpf_addr_is_inaddr_none (&rp_info->rp))
+ continue;
+
+ /* if i_am_rp is already set nothing to be done (adding new addresses
+ * is not going to make a difference). */
+ if (rp_info->i_am_rp) {
+ continue;
+ }
+
+ if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) {
+ i_am_rp_changed = true;
+ rp_info->i_am_rp = 1;
+ if (PIM_DEBUG_ZEBRA) {
+ char rp[PREFIX_STRLEN];
+ pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr, rp, sizeof(rp));
+ zlog_debug("%s: %s: i am rp", __func__, rp);
+ }
+ }
+ }
+
+ if (i_am_rp_changed) {
+ pim_msdp_i_am_rp_changed();
+ }
+}
+
+/* up-optimized re-evaluation of "i_am_rp". this is used when ifaddresses
+ * are removed. Removing numbers is an uncommon event in an active network
+ * so I have made no attempt to optimize it. */
+void
+pim_i_am_rp_re_evaluate(void)
+{
+ struct listnode *node;
+ struct rp_info *rp_info;
+ bool i_am_rp_changed = false;
+ int old_i_am_rp;
+
+ if (qpim_rp_list == NULL)
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (pim_rpf_addr_is_inaddr_none(&rp_info->rp))
+ continue;
+
+ old_i_am_rp = rp_info->i_am_rp;
+ pim_rp_check_interfaces(rp_info);
+
+ if (old_i_am_rp != rp_info->i_am_rp) {
+ i_am_rp_changed = true;
+ if (PIM_DEBUG_ZEBRA) {
+ char rp[PREFIX_STRLEN];
+ pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr, rp, sizeof(rp));
+ if (rp_info->i_am_rp) {
+ zlog_debug("%s: %s: i am rp", __func__, rp);
+ } else {
+ zlog_debug("%s: %s: i am no longer rp", __func__, rp);
+ }
+ }
+ }
+ }
+
+ if (i_am_rp_changed) {
+ pim_msdp_i_am_rp_changed();
+ }
}
/*
@@ -73,7 +623,20 @@ pim_rp_check_rp (struct in_addr old, struct in_addr new)
int
pim_rp_i_am_rp (struct in_addr group)
{
- return i_am_rp;
+ struct prefix g;
+ struct rp_info *rp_info;
+
+ memset (&g, 0, sizeof (g));
+ g.family = AF_INET;
+ g.prefixlen = 32;
+ g.u.prefix4 = group;
+
+ rp_info = pim_rp_find_match_group (&g);
+
+ if (rp_info)
+ return rp_info->i_am_rp;
+
+ return 0;
}
/*
@@ -84,11 +647,24 @@ pim_rp_i_am_rp (struct in_addr group)
struct pim_rpf *
pim_rp_g (struct in_addr group)
{
- /*
- * For staticly configured RP, it is always the qpim_rp
- */
- pim_nexthop_lookup(&qpim_rp.source_nexthop, qpim_rp.rpf_addr, NULL);
- return(&qpim_rp);
+ struct prefix g;
+ struct rp_info *rp_info;
+
+ memset (&g, 0, sizeof (g));
+ g.family = AF_INET;
+ g.prefixlen = 32;
+ g.u.prefix4 = group;
+
+ rp_info = pim_rp_find_match_group (&g);
+
+ if (rp_info)
+ {
+ pim_nexthop_lookup(&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1);
+ return (&rp_info->rp);
+ }
+
+ // About to Go Down
+ return NULL;
}
/*
@@ -100,16 +676,168 @@ pim_rp_g (struct in_addr group)
*
*/
int
-pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source)
+pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source, struct in_addr group)
{
- if ((qpim_rp.rpf_addr.s_addr == INADDR_NONE) && (source.s_addr == INADDR_ANY))
+ struct rp_info *rp_info;
+ struct prefix g;
+
+ memset (&g, 0, sizeof (g));
+ g.family = AF_INET;
+ g.prefixlen = 32;
+ g.u.prefix4 = group;
+
+ rp_info = pim_rp_find_match_group (&g);
+
+ if ((pim_rpf_addr_is_inaddr_none (&rp_info->rp)) && (source.s_addr == INADDR_ANY))
{
if (PIM_DEBUG_PIM_TRACE)
zlog_debug("%s: Received a (*,G) with no RP configured", __PRETTY_FUNCTION__);
return 0;
}
- *up = (source.s_addr == INADDR_ANY) ? qpim_rp.rpf_addr : source;
+ *up = (source.s_addr == INADDR_ANY) ? rp_info->rp.rpf_addr.u.prefix4 : source;
return 1;
}
+
+int
+pim_rp_config_write (struct vty *vty)
+{
+ struct listnode *node;
+ struct rp_info *rp_info;
+ char rp_buffer[32];
+ char group_buffer[32];
+ int count = 0;
+
+ for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
+ {
+ if (pim_rpf_addr_is_inaddr_none (&rp_info->rp))
+ continue;
+
+ if (rp_info->plist)
+ vty_out(vty, "ip pim rp %s prefix-list %s%s",
+ inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp_buffer, 32),
+ rp_info->plist, VTY_NEWLINE);
+ else
+ vty_out(vty, "ip pim rp %s %s%s",
+ inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp_buffer, 32),
+ prefix2str(&rp_info->group, group_buffer, 32), VTY_NEWLINE);
+ count++;
+ }
+
+ return count;
+}
+
+int
+pim_rp_check_is_my_ip_address (struct in_addr group, struct in_addr dest_addr)
+{
+ struct rp_info *rp_info;
+ struct prefix g;
+
+ memset (&g, 0, sizeof (g));
+ g.family = AF_INET;
+ g.prefixlen = 32;
+ g.u.prefix4 = group;
+
+ rp_info = pim_rp_find_match_group (&g);
+ /*
+ * See if we can short-cut some?
+ * This might not make sense if we ever leave a static RP
+ * type of configuration.
+ * Note - Premature optimization might bite our patooeys' here.
+ */
+ if (I_am_RP(group))
+ {
+ if (dest_addr.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr)
+ return 1;
+ }
+
+ if (if_lookup_exact_address (&dest_addr, AF_INET))
+ return 1;
+
+ return 0;
+}
+
+void
+pim_rp_show_information (struct vty *vty, u_char uj)
+{
+ struct rp_info *rp_info;
+ struct rp_info *prev_rp_info = NULL;
+ struct listnode *node;
+
+ json_object *json = NULL;
+ json_object *json_rp_rows = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out (vty, "RP address group/prefix-list OIF I am RP%s", VTY_NEWLINE);
+
+ for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
+ {
+ if (!pim_rpf_addr_is_inaddr_none (&rp_info->rp))
+ {
+ char buf[48];
+
+ if (uj)
+ {
+ /*
+ * If we have moved on to a new RP then add the entry for the previous RP
+ */
+ if (prev_rp_info &&
+ prev_rp_info->rp.rpf_addr.u.prefix4.s_addr != rp_info->rp.rpf_addr.u.prefix4.s_addr)
+ {
+ json_object_object_add(json, inet_ntoa (prev_rp_info->rp.rpf_addr.u.prefix4), json_rp_rows);
+ json_rp_rows = NULL;
+ }
+
+ if (!json_rp_rows)
+ json_rp_rows = json_object_new_array();
+
+ json_row = json_object_new_object();
+ if (rp_info->rp.source_nexthop.interface)
+ json_object_string_add(json_row, "outboundInterface", rp_info->rp.source_nexthop.interface->name);
+
+ if (rp_info->i_am_rp)
+ json_object_boolean_true_add(json_row, "iAmRP");
+
+ if (rp_info->plist)
+ json_object_string_add(json_row, "prefixList", rp_info->plist);
+ else
+ json_object_string_add(json_row, "group", prefix2str(&rp_info->group, buf, 48));
+
+ json_object_array_add(json_rp_rows, json_row);
+ }
+ else
+ {
+ vty_out (vty, "%-15s ", inet_ntoa (rp_info->rp.rpf_addr.u.prefix4));
+
+ if (rp_info->plist)
+ vty_out (vty, "%-18s ", rp_info->plist);
+ else
+ vty_out (vty, "%-18s ", prefix2str(&rp_info->group, buf, 48));
+
+ if (rp_info->rp.source_nexthop.interface)
+ vty_out (vty, "%-10s ", rp_info->rp.source_nexthop.interface->name);
+ else
+ vty_out (vty, "%-10s ", "(Unknown)");
+
+ if (rp_info->i_am_rp)
+ vty_out (vty, "yes%s", VTY_NEWLINE);
+ else
+ vty_out (vty, "no%s", VTY_NEWLINE);
+ }
+
+ prev_rp_info = rp_info;
+ }
+ }
+
+ if (uj) {
+ if (prev_rp_info && json_rp_rows)
+ json_object_object_add(json, inet_ntoa (prev_rp_info->rp.rpf_addr.u.prefix4), json_rp_rows);
+
+ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+ json_object_free(json);
+ }
+}
diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h
index bb785e7efc..b32228ed49 100644
--- a/pimd/pim_rp.h
+++ b/pimd/pim_rp.h
@@ -21,11 +21,29 @@
#ifndef PIM_RP_H
#define PIM_RP_H
-void pim_rp_check_rp (struct in_addr old, struct in_addr new);
+void pim_rp_init (void);
+void pim_rp_free (void);
+
+int pim_rp_new (const char *rp, const char *group, const char *plist);
+int pim_rp_del (const char *rp, const char *group, const char *plist);
+void pim_rp_prefix_list_update (struct prefix_list *plist);
+
+int pim_rp_config_write (struct vty *vty);
+
+int pim_rp_setup (void);
+
int pim_rp_i_am_rp (struct in_addr group);
-int pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source);
+void pim_rp_check_on_if_add(struct pim_interface *pim_ifp);
+void pim_i_am_rp_re_evaluate(void);
+
+int pim_rp_check_is_my_ip_address (struct in_addr group, struct in_addr dest_addr);
+
+int pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source, struct in_addr group);
+
struct pim_rpf *pim_rp_g (struct in_addr group);
#define I_am_RP(G) pim_rp_i_am_rp ((G))
#define RP(G) pim_rp_g ((G))
+
+void pim_rp_show_information (struct vty *vty, u_char uj);
#endif
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index 8d6e7b70c1..ae00e347b5 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -33,108 +33,160 @@
#include "pim_iface.h"
#include "pim_zlookup.h"
#include "pim_ifchannel.h"
+#include "pim_time.h"
+
+static long long last_route_change_time = -1;
+long long nexthop_lookups_avoided = 0;
static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up);
-int pim_nexthop_lookup(struct pim_nexthop *nexthop,
- struct in_addr addr, struct interface *incoming)
+void
+pim_rpf_set_refresh_time (void)
{
- struct pim_zlookup_nexthop nexthop_tab[PIM_NEXTHOP_IFINDEX_TAB_SIZE];
- int num_ifindex;
- struct interface *ifp;
- int first_ifindex;
+ last_route_change_time = pim_time_monotonic_usec();
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: New last route change time: %lld",
+ __PRETTY_FUNCTION__, last_route_change_time);
+}
- memset (nexthop_tab, 0, sizeof (struct pim_zlookup_nexthop) * PIM_NEXTHOP_IFINDEX_TAB_SIZE);
+int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed)
+{
+ struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
+ int num_ifindex;
+ struct interface *ifp = NULL;
+ ifindex_t first_ifindex = 0;
+ int found = 0;
+ int i = 0;
- if (!incoming)
+ if ((nexthop->last_lookup.s_addr == addr.s_addr) &&
+ (nexthop->last_lookup_time > last_route_change_time))
{
- num_ifindex = zclient_lookup_nexthop(qpim_zclient_lookup, nexthop_tab,
- PIM_NEXTHOP_IFINDEX_TAB_SIZE,
- addr, PIM_NEXTHOP_LOOKUP_MAX);
- if (num_ifindex < 1) {
- char addr_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: could not find nexthop ifindex for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- addr_str);
- return -1;
- }
-
- first_ifindex = nexthop_tab[0].ifindex;
-
- if (num_ifindex > 1) {
- char addr_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_info("%s %s: FIXME ignoring multiple nexthop ifindex'es num_ifindex=%d for address %s (using only ifindex=%d)",
- __FILE__, __PRETTY_FUNCTION__,
- num_ifindex, addr_str, first_ifindex);
- /* debug warning only, do not return */
- }
-
- ifp = if_lookup_by_index(first_ifindex);
- if (!ifp) {
- char addr_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: could not find interface for ifindex %d (address %s)",
- __FILE__, __PRETTY_FUNCTION__,
- first_ifindex, addr_str);
- return -2;
- }
+ if (PIM_DEBUG_TRACE)
+ {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug ("%s: Using last lookup for %s at %lld, %lld",
+ __PRETTY_FUNCTION__,
+ addr_str,
+ nexthop->last_lookup_time,
+ last_route_change_time);
+ }
+ nexthop_lookups_avoided++;
+ return 0;
}
else
{
- ifp = incoming;
- first_ifindex = ifp->ifindex;
+ if (PIM_DEBUG_TRACE)
+ {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug ("%s: Looking up: %s, last lookup time: %lld, %lld",
+ __PRETTY_FUNCTION__,
+ addr_str,
+ nexthop->last_lookup_time,
+ last_route_change_time);
+ }
}
- if (!ifp->info) {
- char addr_str[100];
+ memset (nexthop_tab, 0, sizeof (struct pim_zlookup_nexthop) * MULTIPATH_NUM);
+ num_ifindex = zclient_lookup_nexthop(nexthop_tab,
+ MULTIPATH_NUM,
+ addr, PIM_NEXTHOP_LOOKUP_MAX);
+ if (num_ifindex < 1) {
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
- __PRETTY_FUNCTION__,
- ifp->name, first_ifindex, addr_str);
- /* debug warning only, do not return */
+ zlog_warn("%s %s: could not find nexthop ifindex for address %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ addr_str);
+ return -1;
}
- if (PIM_DEBUG_PIM_TRACE) {
- char nexthop_str[100];
- char addr_str[100];
- pim_inet4_dump("<nexthop?>", nexthop_tab[0].nexthop_addr, nexthop_str, sizeof(nexthop_str));
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: found nexthop %s for address %s: interface %s ifindex=%d metric=%d pref=%d",
- __FILE__, __PRETTY_FUNCTION__,
- nexthop_str, addr_str,
- ifp->name, first_ifindex,
- nexthop_tab[0].route_metric,
- nexthop_tab[0].protocol_distance);
- }
+ while (!found && (i < num_ifindex))
+ {
+ first_ifindex = nexthop_tab[i].ifindex;
- /* update nextop data */
- nexthop->interface = ifp;
- nexthop->mrib_nexthop_addr = nexthop_tab[0].nexthop_addr;
- nexthop->mrib_metric_preference = nexthop_tab[0].protocol_distance;
- nexthop->mrib_route_metric = nexthop_tab[0].route_metric;
+ ifp = if_lookup_by_index(first_ifindex);
+ if (!ifp)
+ {
+ if (PIM_DEBUG_ZEBRA)
+ {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug("%s %s: could not find interface for ifindex %d (address %s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ first_ifindex, addr_str);
+ }
+ i++;
+ continue;
+ }
+
+ if (!ifp->info)
+ {
+ if (PIM_DEBUG_ZEBRA)
+ {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug("%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
+ __PRETTY_FUNCTION__,
+ ifp->name, first_ifindex, addr_str);
+ }
+ i++;
+ }
+ else if (neighbor_needed && !pim_if_connected_to_source (ifp, addr))
+ {
+ struct pim_neighbor *nbr;
+
+ nbr = pim_neighbor_find (ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug ("ifp name: %s, pim nbr: %p", ifp->name, nbr);
+ if (!nbr && !if_is_loopback (ifp))
+ i++;
+ else
+ found = 1;
+ }
+ else
+ found = 1;
+ }
- return 0;
+ if (found)
+ {
+ if (PIM_DEBUG_ZEBRA) {
+ char nexthop_str[PREFIX_STRLEN];
+ char addr_str[INET_ADDRSTRLEN];
+ pim_addr_dump("<nexthop?>", &nexthop_tab[i].nexthop_addr, nexthop_str, sizeof(nexthop_str));
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug("%s %s: found nexthop %s for address %s: interface %s ifindex=%d metric=%d pref=%d",
+ __FILE__, __PRETTY_FUNCTION__,
+ nexthop_str, addr_str,
+ ifp->name, first_ifindex,
+ nexthop_tab[i].route_metric,
+ nexthop_tab[i].protocol_distance);
+ }
+ /* update nextop data */
+ nexthop->interface = ifp;
+ nexthop->mrib_nexthop_addr = nexthop_tab[i].nexthop_addr;
+ nexthop->mrib_metric_preference = nexthop_tab[i].protocol_distance;
+ nexthop->mrib_route_metric = nexthop_tab[i].route_metric;
+ nexthop->last_lookup = addr;
+ nexthop->last_lookup_time = pim_time_monotonic_usec();
+ return 0;
+ }
+ else
+ return -1;
}
static int nexthop_mismatch(const struct pim_nexthop *nh1,
const struct pim_nexthop *nh2)
{
- return (nh1->interface != nh2->interface)
- ||
- (nh1->mrib_nexthop_addr.s_addr != nh2->mrib_nexthop_addr.s_addr)
- ||
- (nh1->mrib_metric_preference != nh2->mrib_metric_preference)
- ||
+ return (nh1->interface != nh2->interface) ||
+ (nh1->mrib_nexthop_addr.u.prefix4.s_addr != nh2->mrib_nexthop_addr.u.prefix4.s_addr) ||
+ (nh1->mrib_metric_preference != nh2->mrib_metric_preference) ||
(nh1->mrib_route_metric != nh2->mrib_route_metric);
}
-enum pim_rpf_result pim_rpf_update(struct pim_upstream *up,
- struct in_addr *old_rpf_addr,
- struct interface *incoming)
+enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct in_addr *old_rpf_addr)
{
- struct in_addr save_rpf_addr;
+ struct prefix save_rpf_addr;
struct pim_nexthop save_nexthop;
struct pim_rpf *rpf = &up->rpf;
@@ -142,36 +194,31 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up,
save_rpf_addr = rpf->rpf_addr; /* detect change in RPF'(S,G) */
if (pim_nexthop_lookup(&rpf->source_nexthop,
- up->upstream_addr, incoming)) {
+ up->upstream_addr,
+ !PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) &&
+ !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags))) {
return PIM_RPF_FAILURE;
}
- rpf->rpf_addr = pim_rpf_find_rpf_addr(up);
- if (PIM_INADDR_IS_ANY(rpf->rpf_addr) && PIM_DEBUG_PIM_EVENTS) {
+ rpf->rpf_addr.family = AF_INET;
+ rpf->rpf_addr.u.prefix4 = pim_rpf_find_rpf_addr(up);
+ if (pim_rpf_addr_is_inaddr_any(rpf) && PIM_DEBUG_ZEBRA) {
/* RPF'(S,G) not found */
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s %s: RPF'(%s,%s) not found: won't send join upstream",
+ zlog_debug("%s %s: RPF'%s not found: won't send join upstream",
__FILE__, __PRETTY_FUNCTION__,
- src_str, grp_str);
+ up->sg_str);
/* warning only */
}
/* detect change in pim_nexthop */
if (nexthop_mismatch(&rpf->source_nexthop, &save_nexthop)) {
- if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- char nhaddr_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- pim_inet4_dump("<addr?>", rpf->source_nexthop.mrib_nexthop_addr, nhaddr_str, sizeof(nhaddr_str));
- zlog_debug("%s %s: (S,G)=(%s,%s) source nexthop now is: interface=%s address=%s pref=%d metric=%d",
+ if (PIM_DEBUG_ZEBRA) {
+ char nhaddr_str[PREFIX_STRLEN];
+ pim_addr_dump("<addr?>", &rpf->source_nexthop.mrib_nexthop_addr, nhaddr_str, sizeof(nhaddr_str));
+ zlog_debug("%s %s: (S,G)=%s source nexthop now is: interface=%s address=%s pref=%d metric=%d",
__FILE__, __PRETTY_FUNCTION__,
- src_str, grp_str,
+ up->sg_str,
rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>",
nhaddr_str,
rpf->source_nexthop.mrib_metric_preference,
@@ -186,14 +233,10 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up,
/* detect change in RPF_interface(S) */
if (save_nexthop.interface != rpf->source_nexthop.interface) {
- if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s %s: (S,G)=(%s,%s) RPF_interface(S) changed from %s to %s",
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug("%s %s: (S,G)=%s RPF_interface(S) changed from %s to %s",
__FILE__, __PRETTY_FUNCTION__,
- src_str, grp_str,
+ up->sg_str,
save_nexthop.interface ? save_nexthop.interface->name : "<oldif?>",
rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<newif?>");
/* warning only */
@@ -203,11 +246,11 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up,
}
/* detect change in RPF'(S,G) */
- if (save_rpf_addr.s_addr != rpf->rpf_addr.s_addr) {
+ if (save_rpf_addr.u.prefix4.s_addr != rpf->rpf_addr.u.prefix4.s_addr) {
/* return old rpf to caller ? */
if (old_rpf_addr)
- *old_rpf_addr = save_rpf_addr;
+ *old_rpf_addr = save_rpf_addr.u.prefix4;
return PIM_RPF_CHANGED;
}
@@ -237,20 +280,16 @@ static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up)
struct in_addr rpf_addr;
if (!up->rpf.source_nexthop.interface) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- zlog_warn("%s: missing RPF interface for upstream (S,G)=(%s,%s)",
+ zlog_warn("%s: missing RPF interface for upstream (S,G)=%s",
__PRETTY_FUNCTION__,
- src_str, grp_str);
+ up->sg_str);
rpf_addr.s_addr = PIM_NET_INADDR_ANY;
return rpf_addr;
}
rpf_ch = pim_ifchannel_find(up->rpf.source_nexthop.interface,
- up->source_addr, up->group_addr);
+ &up->sg);
if (rpf_ch) {
if (rpf_ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
return rpf_ch->ifassert_winner;
@@ -260,7 +299,7 @@ static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up)
/* return NBR( RPF_interface(S), MRIB.next_hop( S ) ) */
neigh = pim_if_find_neighbor(up->rpf.source_nexthop.interface,
- up->rpf.source_nexthop.mrib_nexthop_addr);
+ up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4);
if (neigh)
rpf_addr = neigh->source_addr;
else
@@ -268,3 +307,52 @@ static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up)
return rpf_addr;
}
+
+int
+pim_rpf_addr_is_inaddr_none (struct pim_rpf *rpf)
+{
+ switch (rpf->rpf_addr.family)
+ {
+ case AF_INET:
+ return rpf->rpf_addr.u.prefix4.s_addr == INADDR_NONE;
+ break;
+ case AF_INET6:
+ zlog_warn ("%s: v6 Unimplmeneted", __PRETTY_FUNCTION__);
+ return 1;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 0;
+}
+
+int
+pim_rpf_addr_is_inaddr_any (struct pim_rpf *rpf)
+{
+ switch (rpf->rpf_addr.family)
+ {
+ case AF_INET:
+ return rpf->rpf_addr.u.prefix4.s_addr == INADDR_ANY;
+ break;
+ case AF_INET6:
+ zlog_warn ("%s: v6 Unimplmented", __PRETTY_FUNCTION__);
+ return 1;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 0;
+}
+
+int
+pim_rpf_is_same (struct pim_rpf *rpf1, struct pim_rpf *rpf2)
+{
+ if (rpf1->source_nexthop.interface == rpf2->source_nexthop.interface)
+ return 1;
+
+ return 0;
+}
diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h
index 4d55bd6881..bb77775324 100644
--- a/pimd/pim_rpf.h
+++ b/pimd/pim_rpf.h
@@ -26,10 +26,48 @@
#include "pim_upstream.h"
#include "pim_neighbor.h"
-int pim_nexthop_lookup(struct pim_nexthop *nexthop,
- struct in_addr addr, struct interface *incoming);
-enum pim_rpf_result pim_rpf_update(struct pim_upstream *up,
- struct in_addr *old_rpf_addr,
- struct interface *incoming);
+/*
+ RFC 4601:
+
+ Metric Preference
+ Preference value assigned to the unicast routing protocol that
+ provided the route to the multicast source or Rendezvous-Point.
+
+ Metric
+ The unicast routing table metric associated with the route used to
+ reach the multicast source or Rendezvous-Point. The metric is in
+ units applicable to the unicast routing protocol used.
+*/
+struct pim_nexthop {
+ struct in_addr last_lookup;
+ long long last_lookup_time;
+ struct interface *interface; /* RPF_interface(S) */
+ struct prefix mrib_nexthop_addr; /* MRIB.next_hop(S) */
+ uint32_t mrib_metric_preference; /* MRIB.pref(S) */
+ uint32_t mrib_route_metric; /* MRIB.metric(S) */
+};
+
+struct pim_rpf {
+ struct pim_nexthop source_nexthop;
+ struct prefix rpf_addr; /* RPF'(S,G) */
+};
+
+enum pim_rpf_result {
+ PIM_RPF_OK = 0,
+ PIM_RPF_CHANGED,
+ PIM_RPF_FAILURE
+};
+
+struct pim_upstream;
+
+extern long long nexthop_lookups_avoided;
+
+int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed);
+enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct in_addr *old_rpf_addr);
+
+int pim_rpf_addr_is_inaddr_none (struct pim_rpf *rpf);
+int pim_rpf_addr_is_inaddr_any (struct pim_rpf *rpf);
+int pim_rpf_is_same (struct pim_rpf *rpf1, struct pim_rpf *rpf2);
+void pim_rpf_set_refresh_time (void);
#endif /* PIM_RPF_H */
diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c
index 54816d126b..7f62a1e9dc 100644
--- a/pimd/pim_sock.c
+++ b/pimd/pim_sock.c
@@ -42,9 +42,9 @@
#include "pim_igmp_join.h"
/* GLOBAL VARS */
-extern struct zebra_privs_t pimd_privs;
-int pim_socket_raw(int protocol)
+int
+pim_socket_raw (int protocol)
{
int fd;
@@ -67,8 +67,58 @@ int pim_socket_raw(int protocol)
return fd;
}
-int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char loop)
+int
+pim_socket_ip_hdr (int fd)
{
+ const int on = 1;
+ int ret;
+
+ if (pimd_privs.change (ZPRIVS_RAISE))
+ zlog_err ("%s: could not raise privs, %s",
+ __PRETTY_FUNCTION__, safe_strerror (errno));
+
+ ret = setsockopt (fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on));
+
+ if (pimd_privs.change (ZPRIVS_LOWER))
+ zlog_err ("%s: could not lower privs, %s",
+ __PRETTY_FUNCTION__, safe_strerror (errno));
+
+ return ret;
+}
+
+/*
+ * Given a socket and a interface,
+ * Bind that socket to that interface
+ */
+int
+pim_socket_bind (int fd, struct interface *ifp)
+{
+ int ret = 0;
+#ifdef SO_BINDTODEVICE
+
+ if (pimd_privs.change (ZPRIVS_RAISE))
+ zlog_err ("%s: could not raise privs, %s",
+ __PRETTY_FUNCTION__, safe_strerror (errno));
+
+ ret = setsockopt (fd, SOL_SOCKET,
+ SO_BINDTODEVICE, ifp->name, strlen (ifp->name));
+
+ if (pimd_privs.change (ZPRIVS_LOWER))
+ zlog_err ("%s: could not lower privs, %s",
+ __PRETTY_FUNCTION__, safe_strerror (errno));
+
+#endif
+ return ret;
+}
+
+int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp, u_char loop)
+{
+ int rcvbuf = 1024 * 1024 * 8;
+#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
+ struct ip_mreqn mreq;
+#else
+ struct ip_mreq mreq;
+#endif
int fd;
fd = pim_socket_raw(protocol);
@@ -82,23 +132,11 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char lo
if (protocol == IPPROTO_PIM)
{
int ret;
- struct interface *ifp = NULL;
-
- ifp = if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
-
- if (pimd_privs.change (ZPRIVS_RAISE))
- zlog_err ("%s: could not raise privs, %s",
- __PRETTY_FUNCTION__, safe_strerror (errno));
-
- ret = setsockopt (fd, SOL_SOCKET,
- SO_BINDTODEVICE, ifp->name, strlen (ifp->name));
-
- if (pimd_privs.change (ZPRIVS_LOWER))
- zlog_err ("%s: could not lower privs, %s",
- __PRETTY_FUNCTION__, safe_strerror (errno));
+ ret = pim_socket_bind (fd, ifp);
if (ret)
{
+ close (fd);
zlog_warn("Could not set fd: %d for interface: %s to device",
fd, ifp->name);
return PIM_SOCK_ERR_BIND;
@@ -180,14 +218,28 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char lo
return PIM_SOCK_ERR_LOOP;
}
+ memset (&mreq, 0, sizeof (mreq));
+#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
+ mreq.imr_ifindex = ifp->ifindex;
+#else
+ /*
+ * I am not sure what to do here yet for *BSD
+ */
+ //mreq.imr_interface = ifindex;
+#endif
+
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (void *) &ifaddr, sizeof(ifaddr))) {
+ (void *) &mreq, sizeof(mreq))) {
zlog_warn("Could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s",
fd, errno, safe_strerror(errno));
close(fd);
return PIM_SOCK_ERR_IFACE;
}
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)))
+ zlog_warn("%s: Failure to set buffer size to %d",
+ __PRETTY_FUNCTION__, rcvbuf);
+
{
long flags;
@@ -232,8 +284,8 @@ int pim_socket_join(int fd, struct in_addr group,
ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &opt, sizeof(opt));
if (ret) {
- char group_str[100];
- char ifaddr_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char ifaddr_str[INET_ADDRSTRLEN];
if (!inet_ntop(AF_INET, &group, group_str , sizeof(group_str)))
sprintf(group_str, "<group?>");
if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str , sizeof(ifaddr_str)))
@@ -245,8 +297,8 @@ int pim_socket_join(int fd, struct in_addr group,
}
if (PIM_DEBUG_TRACE) {
- char group_str[100];
- char ifaddr_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char ifaddr_str[INET_ADDRSTRLEN];
if (!inet_ntop(AF_INET, &group, group_str , sizeof(group_str)))
sprintf(group_str, "<group?>");
if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str , sizeof(ifaddr_str)))
@@ -265,15 +317,14 @@ int pim_socket_join_source(int fd, ifindex_t ifindex,
const char *ifname)
{
if (pim_igmp_join_source(fd, ifindex, group_addr, source_addr)) {
- int e = errno;
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: setsockopt(fd=%d) failure for IGMP group %s source %s ifindex %d on interface %s: errno=%d: %s",
__PRETTY_FUNCTION__,
fd, group_str, source_str, ifindex, ifname,
- e, safe_strerror(e));
+ errno, safe_strerror(errno));
return -1;
}
@@ -298,17 +349,14 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
if (to) {
struct sockaddr_in si;
socklen_t si_len = sizeof(si);
-
- ((struct sockaddr_in *) to)->sin_family = AF_INET;
- if (pim_socket_getsockname(fd, (struct sockaddr *) &si, &si_len)) {
- ((struct sockaddr_in *) to)->sin_port = ntohs(0);
- ((struct sockaddr_in *) to)->sin_addr.s_addr = ntohl(0);
- }
- else {
- ((struct sockaddr_in *) to)->sin_port = si.sin_port;
- ((struct sockaddr_in *) to)->sin_addr = si.sin_addr;
- }
+ memset (&si, 0, sizeof (si));
+ to->sin_family = AF_INET;
+
+ pim_socket_getsockname(fd, (struct sockaddr *) &si, &si_len);
+
+ to->sin_port = si.sin_port;
+ to->sin_addr = si.sin_addr;
if (tolen)
*tolen = sizeof(si);
@@ -346,14 +394,6 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
if (ifindex)
*ifindex = i->ipi_ifindex;
- if (to && PIM_DEBUG_PACKETS) {
- char to_str[100];
- pim_inet4_dump("<to?>", to->sin_addr, to_str, sizeof(to_str));
- zlog_debug("%s: HAVE_IP_PKTINFO to=%s,%d",
- __PRETTY_FUNCTION__,
- to_str, ntohs(to->sin_port));
- }
-
break;
}
#endif
@@ -366,14 +406,6 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
if (tolen)
*tolen = sizeof(struct sockaddr_in);
- if (to && PIM_DEBUG_PACKETS) {
- char to_str[100];
- pim_inet4_dump("<to?>", to->sin_addr, to_str, sizeof(to_str));
- zlog_debug("%s: HAVE_IP_RECVDSTADDR to=%s,%d",
- __PRETTY_FUNCTION__,
- to_str, ntohs(to->sin_port));
- }
-
break;
}
#endif
diff --git a/pimd/pim_sock.h b/pimd/pim_sock.h
index f905c661dd..b4ce901d10 100644
--- a/pimd/pim_sock.h
+++ b/pimd/pim_sock.h
@@ -36,8 +36,10 @@
#define PIM_SOCK_ERR_NAME (-10) /* Socket name (getsockname) */
#define PIM_SOCK_ERR_BIND (-11) /* Can't bind to interface */
+int pim_socket_bind (int fd, struct interface *ifp);
+int pim_socket_ip_hdr (int fd);
int pim_socket_raw(int protocol);
-int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char loop);
+int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp, u_char loop);
int pim_socket_join(int fd, struct in_addr group,
struct in_addr ifaddr, ifindex_t ifindex);
int pim_socket_join_source(int fd, ifindex_t ifindex,
diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c
index ece644a861..0354083332 100644
--- a/pimd/pim_ssmpingd.c
+++ b/pimd/pim_ssmpingd.c
@@ -25,11 +25,10 @@
#include "memory.h"
#include "sockopt.h"
+#include "pimd.h"
#include "pim_ssmpingd.h"
#include "pim_time.h"
#include "pim_sock.h"
-#include "pim_str.h"
-#include "pimd.h"
static const char * const PIM_SSMPINGD_REPLY_GROUP = "232.43.211.234";
@@ -96,7 +95,7 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl)
sockaddr.sin_port = htons(port);
if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
- char addr_str[100];
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
zlog_warn("%s: bind(fd=%d,addr=%s,port=%d,len=%zu) failure: errno=%d: %s",
__PRETTY_FUNCTION__,
@@ -195,12 +194,11 @@ static void ssmpingd_delete(struct ssmpingd_sock *ss)
THREAD_OFF(ss->t_sock_read);
if (close(ss->sock_fd)) {
- int e = errno;
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
zlog_warn("%s: failure closing ssmpingd sock_fd=%d for source %s: errno=%d: %s",
__PRETTY_FUNCTION__,
- ss->sock_fd, source_str, e, safe_strerror(e));
+ ss->sock_fd, source_str, errno, safe_strerror(errno));
/* warning only */
}
@@ -219,14 +217,13 @@ static void ssmpingd_sendto(struct ssmpingd_sock *ss,
sent = sendto(ss->sock_fd, buf, len, MSG_DONTWAIT,
(struct sockaddr *)&to, tolen);
if (sent != len) {
- int e = errno;
- char to_str[100];
+ char to_str[INET_ADDRSTRLEN];
pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
if (sent < 0) {
zlog_warn("%s: sendto() failure to %s,%d: fd=%d len=%d: errno=%d: %s",
__PRETTY_FUNCTION__,
to_str, ntohs(to.sin_port), ss->sock_fd, len,
- e, safe_strerror(e));
+ errno, safe_strerror(errno));
}
else {
zlog_warn("%s: sendto() partial to %s,%d: fd=%d len=%d: sent=%d",
@@ -255,7 +252,7 @@ static int ssmpingd_read_msg(struct ssmpingd_sock *ss)
&to, &tolen,
&ifindex);
if (len < 0) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
zlog_warn("%s: failure receiving ssmping for source %s on fd=%d: errno=%d: %s",
__PRETTY_FUNCTION__, source_str, ss->sock_fd, errno, safe_strerror(errno));
@@ -265,9 +262,9 @@ static int ssmpingd_read_msg(struct ssmpingd_sock *ss)
ifp = if_lookup_by_index(ifindex);
if (buf[0] != PIM_SSMPINGD_REQUEST) {
- char source_str[100];
- char from_str[100];
- char to_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char from_str[INET_ADDRSTRLEN];
+ char to_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
pim_inet4_dump("<from?>", from.sin_addr, from_str, sizeof(from_str));
pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
@@ -283,9 +280,9 @@ static int ssmpingd_read_msg(struct ssmpingd_sock *ss)
}
if (PIM_DEBUG_SSMPINGD) {
- char source_str[100];
- char from_str[100];
- char to_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char from_str[INET_ADDRSTRLEN];
+ char to_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
pim_inet4_dump("<from?>", from.sin_addr, from_str, sizeof(from_str));
pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
@@ -316,10 +313,7 @@ static int ssmpingd_sock_read(struct thread *t)
int sock_fd;
int result;
- zassert(t);
-
ss = THREAD_ARG(t);
- zassert(ss);
sock_fd = THREAD_FD(t);
zassert(sock_fd == ss->sock_fd);
@@ -357,18 +351,18 @@ static struct ssmpingd_sock *ssmpingd_new(struct in_addr source_addr)
sock_fd = ssmpingd_socket(source_addr, /* port: */ 4321, /* mTTL: */ 64);
if (sock_fd < 0) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: ssmpingd_socket() failure for source %s",
__PRETTY_FUNCTION__, source_str);
return 0;
}
- ss = XMALLOC(MTYPE_PIM_SSMPINGD, sizeof(*ss));
+ ss = XCALLOC(MTYPE_PIM_SSMPINGD, sizeof(*ss));
if (!ss) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_err("%s: XMALLOC(%zu) failure for ssmpingd source %s",
+ zlog_err("%s: XCALLOC(%zu) failure for ssmpingd source %s",
__PRETTY_FUNCTION__,
sizeof(*ss), source_str);
close(sock_fd);
@@ -399,7 +393,7 @@ int pim_ssmpingd_start(struct in_addr source_addr)
}
{
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_info("%s: starting ssmpingd for source %s",
__PRETTY_FUNCTION__, source_str);
@@ -407,7 +401,7 @@ int pim_ssmpingd_start(struct in_addr source_addr)
ss = ssmpingd_new(source_addr);
if (!ss) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: ssmpingd_new() failure for source %s",
__PRETTY_FUNCTION__, source_str);
@@ -423,7 +417,7 @@ int pim_ssmpingd_stop(struct in_addr source_addr)
ss = ssmpingd_find(source_addr);
if (!ss) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: could not find ssmpingd for source %s",
__PRETTY_FUNCTION__, source_str);
@@ -431,7 +425,7 @@ int pim_ssmpingd_stop(struct in_addr source_addr)
}
{
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_info("%s: stopping ssmpingd for source %s",
__PRETTY_FUNCTION__, source_str);
diff --git a/pimd/pim_static.c b/pimd/pim_static.c
index 565d6fe728..e1ccec387a 100644
--- a/pimd/pim_static.c
+++ b/pimd/pim_static.c
@@ -78,11 +78,11 @@ static struct static_route *static_route_new(unsigned int iif,
int pim_static_add(struct interface *iif, struct interface *oif, struct in_addr group, struct in_addr source)
{
- struct listnode *node = 0;
- struct static_route *s_route = 0;
- struct static_route *original_s_route = 0;
- struct pim_interface *pim_iif = iif ? iif->info : 0;
- struct pim_interface *pim_oif = oif ? oif->info : 0;
+ struct listnode *node = NULL;
+ struct static_route *s_route = NULL;
+ struct static_route *original_s_route = NULL;
+ struct pim_interface *pim_iif = iif ? iif->info : NULL;
+ struct pim_interface *pim_oif = oif ? oif->info : NULL;
ifindex_t iif_index = pim_iif ? pim_iif->mroute_vif_index : 0;
ifindex_t oif_index = pim_oif ? pim_oif->mroute_vif_index : 0;
@@ -110,8 +110,8 @@ int pim_static_add(struct interface *iif, struct interface *oif, struct in_addr
s_route->source.s_addr == source.s_addr) {
if (s_route->iif == iif_index &&
s_route->oif_ttls[oif_index]) {
- char gifaddr_str[100];
- char sifaddr_str[100];
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
zlog_warn("%s %s: Unable to add static route: Route already exists (iif=%d,oif=%d,group=%s,source=%s)",
@@ -174,10 +174,10 @@ int pim_static_add(struct interface *iif, struct interface *oif, struct in_addr
listnode_add(qpim_static_route_list, s_route);
}
- if (pim_mroute_add(&s_route->c_oil))
+ if (pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__))
{
- char gifaddr_str[100];
- char sifaddr_str[100];
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
zlog_warn("%s %s: Unable to add static route(iif=%d,oif=%d,group=%s,source=%s)",
@@ -209,8 +209,8 @@ int pim_static_add(struct interface *iif, struct interface *oif, struct in_addr
}
if (PIM_DEBUG_STATIC) {
- char gifaddr_str[100];
- char sifaddr_str[100];
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
zlog_debug("%s: Static route added(iif=%d,oif=%d,group=%s,source=%s)",
@@ -226,9 +226,9 @@ int pim_static_add(struct interface *iif, struct interface *oif, struct in_addr
int pim_static_del(struct interface *iif, struct interface *oif, struct in_addr group, struct in_addr source)
{
- struct listnode *node = 0;
- struct listnode *nextnode = 0;
- struct static_route *s_route = 0;
+ struct listnode *node = NULL;
+ struct listnode *nextnode = NULL;
+ struct static_route *s_route = NULL;
struct pim_interface *pim_iif = iif ? iif->info : 0;
struct pim_interface *pim_oif = oif ? oif->info : 0;
ifindex_t iif_index = pim_iif ? pim_iif->mroute_vif_index : 0;
@@ -253,23 +253,23 @@ int pim_static_del(struct interface *iif, struct interface *oif, struct in_addr
/* If there are no more outputs then delete the whole route, otherwise set the route with the new outputs */
if (s_route->c_oil.oil_ref_count <= 0 ?
- pim_mroute_del(&s_route->c_oil) : pim_mroute_add(&s_route->c_oil)) {
- char gifaddr_str[100];
- char sifaddr_str[100];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
- zlog_warn("%s %s: Unable to remove static route(iif=%d,oif=%d,group=%s,source=%s)",
+ pim_mroute_del(&s_route->c_oil, __PRETTY_FUNCTION__) : pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__)) {
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
+ pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
+ zlog_warn("%s %s: Unable to remove static route(iif=%d,oif=%d,group=%s,source=%s)",
__FILE__, __PRETTY_FUNCTION__,
iif_index,
oif_index,
gifaddr_str,
sifaddr_str);
- s_route->oif_ttls[oif_index] = 1;
- s_route->c_oil.oil.mfcc_ttls[oif_index] = 1;
- ++s_route->c_oil.oil_ref_count;
+ s_route->oif_ttls[oif_index] = 1;
+ s_route->c_oil.oil.mfcc_ttls[oif_index] = 1;
+ ++s_route->c_oil.oil_ref_count;
- return -1;
+ return -1;
}
s_route->c_oil.oif_creation[oif_index] = 0;
@@ -280,8 +280,8 @@ int pim_static_del(struct interface *iif, struct interface *oif, struct in_addr
}
if (PIM_DEBUG_STATIC) {
- char gifaddr_str[100];
- char sifaddr_str[100];
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
zlog_debug("%s: Static route removed(iif=%d,oif=%d,group=%s,source=%s)",
@@ -297,8 +297,8 @@ int pim_static_del(struct interface *iif, struct interface *oif, struct in_addr
}
if (!node) {
- char gifaddr_str[100];
- char sifaddr_str[100];
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
zlog_warn("%s %s: Unable to remove static route: Route does not exist(iif=%d,oif=%d,group=%s,source=%s)",
@@ -319,8 +319,8 @@ pim_static_write_mroute (struct vty *vty, struct interface *ifp)
struct listnode *node;
struct static_route *sroute;
int count = 0;
- char sbuf[100];
- char gbuf[100];
+ char sbuf[INET_ADDRSTRLEN];
+ char gbuf[INET_ADDRSTRLEN];
for (ALL_LIST_ELEMENTS_RO (qpim_static_route_list, node, sroute))
{
diff --git a/pimd/pim_str.c b/pimd/pim_str.c
index c817045697..83f2a635b3 100644
--- a/pimd/pim_str.c
+++ b/pimd/pim_str.c
@@ -28,17 +28,62 @@
#include "pim_str.h"
-void pim_inet4_dump(const char *onfail, struct in_addr addr, char *buf, int buf_size)
+void pim_addr_dump (const char *onfail, struct prefix *p, char *buf, int buf_size)
{
int save_errno = errno;
- if (!inet_ntop(AF_INET, &addr, buf, buf_size)) {
- int e = errno;
- zlog_warn("pim_inet4_dump: inet_ntop(AF_INET,buf_size=%d): errno=%d: %s",
- buf_size, e, safe_strerror(e));
+ if (!inet_ntop(p->family, &p->u.prefix, buf, buf_size)) {
+ zlog_warn("pim_addr_dump: inet_ntop(buf_size=%d): errno=%d: %s",
+ buf_size, errno, safe_strerror(errno));
if (onfail)
snprintf(buf, buf_size, "%s", onfail);
}
errno = save_errno;
}
+
+void pim_inet4_dump(const char *onfail, struct in_addr addr, char *buf, int buf_size)
+{
+ int save_errno = errno;
+
+ if (addr.s_addr == INADDR_ANY)
+ strcpy(buf, "*");
+ else
+ {
+ if (!inet_ntop(AF_INET, &addr, buf, buf_size)) {
+ zlog_warn("pim_inet4_dump: inet_ntop(AF_INET,buf_size=%d): errno=%d: %s",
+ buf_size, errno, safe_strerror(errno));
+ if (onfail)
+ snprintf(buf, buf_size, "%s", onfail);
+ }
+ }
+
+ errno = save_errno;
+}
+
+char *
+pim_str_sg_dump (const struct prefix_sg *sg)
+{
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ static char sg_str[PIM_SG_LEN];
+
+ pim_inet4_dump ("<src?>", sg->src, src_str, sizeof(src_str));
+ pim_inet4_dump ("<grp?>", sg->grp, grp_str, sizeof(grp_str));
+ snprintf (sg_str, PIM_SG_LEN, "(%s,%s)", src_str, grp_str);
+
+ return sg_str;
+}
+
+char *
+pim_str_sg_set (const struct prefix_sg *sg, char *sg_str)
+{
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump ("<src?>", sg->src, src_str, sizeof(src_str));
+ pim_inet4_dump ("<grp?>", sg->grp, grp_str, sizeof(grp_str));
+ snprintf (sg_str, PIM_SG_LEN, "(%s,%s)", src_str, grp_str);
+
+ return sg_str;
+}
diff --git a/pimd/pim_str.h b/pimd/pim_str.h
index d2af0110a4..97263e6a37 100644
--- a/pimd/pim_str.h
+++ b/pimd/pim_str.h
@@ -25,6 +25,20 @@
#include <sys/socket.h>
#include <arpa/inet.h>
+#include <prefix.h>
+
+/*
+ * Longest possible length of a (S,G) string is 36 bytes
+ * 123.123.123.123 = 16 * 2
+ * (,) = 3
+ * NULL Character at end = 1
+ * (123.123.123.123,123,123,123,123)
+ */
+#define PIM_SG_LEN 36
+
+void pim_addr_dump (const char *onfail, struct prefix *p, char *buf, int buf_size);
void pim_inet4_dump(const char *onfail, struct in_addr addr, char *buf, int buf_size);
+char *pim_str_sg_dump (const struct prefix_sg *sg);
+char *pim_str_sg_set (const struct prefix_sg *sg, char *sg_str);
#endif
diff --git a/pimd/pim_time.c b/pimd/pim_time.c
index 75f767fef1..348793cd0b 100644
--- a/pimd/pim_time.c
+++ b/pimd/pim_time.c
@@ -82,6 +82,25 @@ int64_t pim_time_monotonic_dsec()
return now_dsec;
}
+int64_t
+pim_time_monotonic_usec (void)
+{
+ struct timeval now_tv;
+ int64_t now_dsec;
+
+ if (gettime_monotonic(&now_tv)) {
+ zlog_err("%s: gettime_monotonic() failure: errno=%d: %s",
+ __PRETTY_FUNCTION__,
+ errno, safe_strerror(errno));
+ return -1;
+ }
+
+ now_dsec = ((int64_t) now_tv.tv_sec) * 1000000 + ((int64_t) now_tv.tv_usec);
+
+ return now_dsec;
+
+}
+
int pim_time_mmss(char *buf, int buf_size, long sec)
{
long mm;
diff --git a/pimd/pim_time.h b/pimd/pim_time.h
index 8ccc6a9207..de304a9f71 100644
--- a/pimd/pim_time.h
+++ b/pimd/pim_time.h
@@ -28,6 +28,7 @@
int64_t pim_time_monotonic_sec(void);
int64_t pim_time_monotonic_dsec(void);
+int64_t pim_time_monotonic_usec(void);
int pim_time_mmss(char *buf, int buf_size, long sec);
void pim_time_timer_to_mmss(char *buf, int buf_size, struct thread *t);
void pim_time_timer_to_hhmmss(char *buf, int buf_size, struct thread *t);
diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c
index 546ceb86e1..5223f60e1b 100644
--- a/pimd/pim_tlv.c
+++ b/pimd/pim_tlv.c
@@ -95,8 +95,35 @@ uint8_t *pim_tlv_append_uint32(uint8_t *buf,
#define ucast_ipv4_encoding_len (2 + sizeof(struct in_addr))
-static int
-pim_encode_unicast_address (uint8_t *buf, struct prefix *p)
+/*
+ * An Encoded-Unicast address takes the following format:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Addr Family | Encoding Type | Unicast Address
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...
+ *
+ * Addr Family
+ * The PIM address family of the 'Unicast Address' field of this
+ * address.
+ *
+ * Values 0-127 are as assigned by the IANA for Internet Address * Families in [7]. Values 128-250 are reserved to be assigned by
+ * the IANA for PIM-specific Address Families. Values 251 though
+ * 255 are designated for private use. As there is no assignment
+ * authority for this space, collisions should be expected.
+ *
+ * Encoding Type
+ * The type of encoding used within a specific Address Family. The
+ * value '0' is reserved for this field and represents the native
+ * encoding of the Address Family.
+ *
+ * Unicast Address
+ * The unicast address as represented by the given Address Family
+ * and Encoding Type.
+ */
+int
+pim_encode_addr_ucast (uint8_t *buf, struct prefix *p)
{
switch (p->family)
{
@@ -114,6 +141,79 @@ pim_encode_unicast_address (uint8_t *buf, struct prefix *p)
}
}
+#define group_ipv4_encoding_len (4 + sizeof (struct in_addr))
+
+/*
+ * Encoded-Group addresses take the following format:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Addr Family | Encoding Type |B| Reserved |Z| Mask Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Group multicast Address
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...
+ *
+ * Addr Family
+ * Described above.
+ *
+ * Encoding Type
+ * Described above.
+ *
+ * [B]idirectional PIM
+ * Indicates the group range should use Bidirectional PIM [13].
+ * For PIM-SM defined in this specification, this bit MUST be zero.
+ *
+ * Reserved
+ * Transmitted as zero. Ignored upon receipt.
+ *
+ * Admin Scope [Z]one
+ * indicates the group range is an admin scope zone. This is used
+ * in the Bootstrap Router Mechanism [11] only. For all other
+ * purposes, this bit is set to zero and ignored on receipt.
+ *
+ * Mask Len
+ * The Mask length field is 8 bits. The value is the number of
+ * contiguous one bits that are left justified and used as a mask;
+ * when combined with the group address, it describes a range of
+ * groups. It is less than or equal to the address length in bits
+ * for the given Address Family and Encoding Type. If the message
+ * is sent for a single group, then the Mask length must equal the
+ * address length in bits for the given Address Family and Encoding
+ * Type (e.g., 32 for IPv4 native encoding, 128 for IPv6 native
+ * encoding).
+ *
+ * Group multicast Address
+ * Contains the group address.
+ */
+int
+pim_encode_addr_group (uint8_t *buf, afi_t afi, int bidir, int scope, struct in_addr group)
+{
+ uint8_t flags = 0;
+
+ flags |= bidir << 8;
+ flags |= scope;
+
+ switch (afi)
+ {
+ case AFI_IP:
+ *(uint8_t *)buf = PIM_MSG_ADDRESS_FAMILY_IPV4;
+ ++buf;
+ *(uint8_t *)buf = 0;
+ ++buf;
+ *(uint8_t *)buf = flags;
+ ++buf;
+ *(uint8_t *)buf = 32;
+ ++buf;
+ memcpy (buf, &group, sizeof (struct in_addr));
+ return group_ipv4_encoding_len;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
const uint8_t *buf_pastend,
struct list *ifconnected)
@@ -143,7 +243,7 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
if ((curr + ucast_ipv4_encoding_len) > buf_pastend)
return 0;
- l_encode = pim_encode_unicast_address (curr, p);
+ l_encode = pim_encode_addr_ucast (curr, p);
curr += l_encode;
option_len += l_encode;
}
@@ -173,7 +273,7 @@ static int check_tlv_length(const char *label, const char *tlv_name,
int correct_len, int option_len)
{
if (option_len != correct_len) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: PIM hello %s TLV with incorrect value size=%d correct=%d from %s on interface %s",
label, tlv_name,
@@ -192,7 +292,7 @@ static void check_tlv_redefinition_uint16(const char *label, const char *tlv_nam
uint16_t new, uint16_t old)
{
if (PIM_OPTION_IS_SET(options, opt_mask)) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
label, tlv_name,
@@ -208,7 +308,7 @@ static void check_tlv_redefinition_uint32(const char *label, const char *tlv_nam
uint32_t new, uint32_t old)
{
if (PIM_OPTION_IS_SET(options, opt_mask)) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
label, tlv_name,
@@ -224,7 +324,7 @@ static void check_tlv_redefinition_uint32_hex(const char *label, const char *tlv
uint32_t new, uint32_t old)
{
if (PIM_OPTION_IS_SET(options, opt_mask)) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: PIM hello TLV redefined %s=%08x old=%08x from %s on interface %s",
label, tlv_name,
@@ -408,7 +508,7 @@ pim_parse_addr_ucast (struct prefix *p,
}
int
-pim_parse_addr_group (struct prefix *p,
+pim_parse_addr_group (struct prefix_sg *sg,
const uint8_t *buf,
int buf_size)
{
@@ -450,17 +550,15 @@ pim_parse_addr_group (struct prefix *p,
return -3;
}
- p->family = AF_INET; /* notice: AF_INET != PIM_MSG_ADDRESS_FAMILY_IPV4 */
- memcpy(&p->u.prefix4, addr, sizeof(struct in_addr));
- p->prefixlen = mask_len;
+ memcpy(&sg->grp.s_addr, addr, sizeof(struct in_addr));
addr += sizeof(struct in_addr);
break;
default:
{
- zlog_warn("%s: unknown group address encoding family=%d from",
- __PRETTY_FUNCTION__, family);
+ zlog_warn("%s: unknown group address encoding family=%d mask_len=%d from",
+ __PRETTY_FUNCTION__, family, mask_len);
return -4;
}
}
@@ -469,7 +567,7 @@ pim_parse_addr_group (struct prefix *p,
}
int
-pim_parse_addr_source(struct prefix *p,
+pim_parse_addr_source(struct prefix_sg *sg,
uint8_t *flags,
const uint8_t *buf,
int buf_size)
@@ -513,9 +611,7 @@ pim_parse_addr_source(struct prefix *p,
return -3;
}
- p->family = AF_INET; /* notice: AF_INET != PIM_MSG_ADDRESS_FAMILY_IPV4 */
- memcpy(&p->u.prefix4, addr, sizeof(struct in_addr));
- p->prefixlen = mask_len;
+ memcpy(&sg->src, addr, sizeof(struct in_addr));
/*
RFC 4601: 4.9.1 Encoded Source and Group Address Formats
@@ -527,9 +623,9 @@ pim_parse_addr_source(struct prefix *p,
and 128 for IPv6 native). A router SHOULD ignore any messages
received with any other mask length.
*/
- if (p->prefixlen != 32) {
+ if (mask_len != 32) {
zlog_warn("%s: IPv4 bad source address mask: %d",
- __PRETTY_FUNCTION__, p->prefixlen);
+ __PRETTY_FUNCTION__, mask_len);
return -4;
}
@@ -582,7 +678,7 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
*/
addr_offset = pim_parse_addr_ucast(&tmp, addr, pastend - addr);
if (addr_offset < 1) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
__PRETTY_FUNCTION__,
@@ -599,8 +695,8 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
switch (tmp.family) {
case AF_INET:
{
- char addr_str[100];
- char src_str[100];
+ char addr_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", tmp.u.prefix4, addr_str, sizeof(addr_str));
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello TLV option: list_old_size=%d IPv4 address %s from %s on %s",
@@ -612,7 +708,7 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
break;
default:
{
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello TLV option: list_old_size=%d UNKNOWN address family from %s on %s",
__PRETTY_FUNCTION__,
@@ -629,7 +725,7 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
*/
if (tmp.family == AF_INET) {
if (tmp.u.prefix4.s_addr == src_addr.s_addr) {
- char src_str[100];
+ char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn("%s: ignoring primary address in secondary list from %s on %s",
__PRETTY_FUNCTION__,
diff --git a/pimd/pim_tlv.h b/pimd/pim_tlv.h
index 16c5aa4b97..9c4ebc9f0f 100644
--- a/pimd/pim_tlv.h
+++ b/pimd/pim_tlv.h
@@ -109,13 +109,16 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
uint16_t option_len,
const uint8_t *tlv_curr);
+int pim_encode_addr_ucast (uint8_t *buf, struct prefix *p);
+int pim_encode_addr_group (uint8_t *buf, afi_t afi, int bidir, int scope, struct in_addr group);
+
int pim_parse_addr_ucast (struct prefix *p,
const uint8_t *buf,
int buf_size);
-int pim_parse_addr_group (struct prefix *p,
+int pim_parse_addr_group (struct prefix_sg *sg,
const uint8_t *buf,
int buf_size);
-int pim_parse_addr_source(struct prefix *p,
+int pim_parse_addr_source(struct prefix_sg *sg,
uint8_t *flags,
const uint8_t *buf,
int buf_size);
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 059de3b62e..4ae49c0fd4 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -27,6 +27,11 @@
#include "memory.h"
#include "thread.h"
#include "linklist.h"
+#include "vty.h"
+#include "plist.h"
+#include "hash.h"
+#include "jhash.h"
+#include "wheel.h"
#include "pimd.h"
#include "pim_pim.h"
@@ -44,10 +49,95 @@
#include "pim_macro.h"
#include "pim_rp.h"
#include "pim_br.h"
+#include "pim_register.h"
+#include "pim_msdp.h"
+
+struct hash *pim_upstream_hash = NULL;
+struct list *pim_upstream_list = NULL;
+struct timer_wheel *pim_upstream_sg_wheel = NULL;
static void join_timer_start(struct pim_upstream *up);
static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up);
+/*
+ * A (*,G) or a (*,*) is going away
+ * remove the parent pointer from
+ * those pointing at us
+ */
+static void
+pim_upstream_remove_children (struct pim_upstream *up)
+{
+ struct pim_upstream *child;
+
+ if (!up->sources)
+ return;
+
+ while (!list_isempty (up->sources))
+ {
+ child = listnode_head (up->sources);
+ child->parent = NULL;
+ listnode_delete (up->sources, child);
+ }
+}
+
+/*
+ * A (*,G) or a (*,*) is being created
+ * Find the children that would point
+ * at us.
+ */
+static void
+pim_upstream_find_new_children (struct pim_upstream *up)
+{
+ struct pim_upstream *child;
+ struct listnode *ch_node;
+
+ if ((up->sg.src.s_addr != INADDR_ANY) &&
+ (up->sg.grp.s_addr != INADDR_ANY))
+ return;
+
+ if ((up->sg.src.s_addr == INADDR_ANY) &&
+ (up->sg.grp.s_addr == INADDR_ANY))
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, ch_node, child))
+ {
+ if ((up->sg.grp.s_addr != INADDR_ANY) &&
+ (child->sg.grp.s_addr == up->sg.grp.s_addr) &&
+ (child != up))
+ {
+ child->parent = up;
+ listnode_add_sort (up->sources, child);
+ }
+ }
+}
+
+/*
+ * If we have a (*,*) || (S,*) there is no parent
+ * If we have a (S,G), find the (*,G)
+ * If we have a (*,G), find the (*,*)
+ */
+static struct pim_upstream *
+pim_upstream_find_parent (struct pim_upstream *child)
+{
+ struct prefix_sg any = child->sg;
+ struct pim_upstream *up = NULL;
+
+ // (S,G)
+ if ((child->sg.src.s_addr != INADDR_ANY) &&
+ (child->sg.grp.s_addr != INADDR_ANY))
+ {
+ any.src.s_addr = INADDR_ANY;
+ up = pim_upstream_find (&any);
+
+ if (up)
+ listnode_add (up->sources, child);
+
+ return up;
+ }
+
+ return NULL;
+}
+
void pim_upstream_free(struct pim_upstream *up)
{
XFREE(MTYPE_PIM_UPSTREAM, up);
@@ -61,48 +151,89 @@ static void upstream_channel_oil_detach(struct pim_upstream *up)
}
}
-void pim_upstream_delete(struct pim_upstream *up)
+void
+pim_upstream_del(struct pim_upstream *up, const char *name)
{
+ bool notify_msdp = false;
+
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s(%s): Delete %s ref count: %d",
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
+
+ --up->ref_count;
+
+ if (up->ref_count >= 1)
+ return;
+
THREAD_OFF(up->t_join_timer);
THREAD_OFF(up->t_ka_timer);
+ THREAD_OFF(up->t_rs_timer);
+ THREAD_OFF(up->t_msdp_reg_timer);
+
+ if (up->join_state == PIM_UPSTREAM_JOINED) {
+ pim_joinprune_send (up->rpf.source_nexthop.interface,
+ up->rpf.rpf_addr.u.prefix4,
+ up, 0);
+ if (up->sg.src.s_addr == INADDR_ANY) {
+ /* if a (*, G) entry in the joined state is being deleted we
+ * need to notify MSDP */
+ notify_msdp = true;
+ }
+ }
+
+ if (up->sg.src.s_addr != INADDR_ANY) {
+ wheel_remove_item (pim_upstream_sg_wheel, up);
+ notify_msdp = true;
+ }
+ pim_upstream_remove_children (up);
+ pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__);
upstream_channel_oil_detach(up);
+ if (up->sources)
+ list_delete (up->sources);
+ up->sources = NULL;
+
/*
notice that listnode_delete() can't be moved
into pim_upstream_free() because the later is
called by list_delete_all_node()
*/
- listnode_delete(qpim_upstream_list, up);
+ if (up->parent)
+ {
+ listnode_delete (up->parent->sources, up);
+ up->parent = NULL;
+ }
+ listnode_delete (pim_upstream_list, up);
+ hash_release (pim_upstream_hash, up);
+ if (notify_msdp) {
+ pim_msdp_up_del(&up->sg);
+ }
pim_upstream_free(up);
}
-static void send_join(struct pim_upstream *up)
+void
+pim_upstream_send_join (struct pim_upstream *up)
{
- zassert(up->join_state == PIM_UPSTREAM_JOINED);
-
-
- if (PIM_DEBUG_PIM_TRACE) {
- if (PIM_INADDR_IS_ANY(up->rpf.rpf_addr)) {
- char src_str[100];
- char grp_str[100];
- char rpf_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- pim_inet4_dump("<rpf?>", up->rpf.rpf_addr, rpf_str, sizeof(rpf_str));
- zlog_warn("%s: can't send join upstream: RPF'(%s,%s)=%s",
- __PRETTY_FUNCTION__,
- src_str, grp_str, rpf_str);
+ if (PIM_DEBUG_TRACE) {
+ char rpf_str[PREFIX_STRLEN];
+ pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_str, sizeof(rpf_str));
+ zlog_debug ("%s: RPF'%s=%s(%s) for Interface %s", __PRETTY_FUNCTION__,
+ up->sg_str, rpf_str, pim_upstream_state2str (up->join_state),
+ up->rpf.source_nexthop.interface->name);
+ if (pim_rpf_addr_is_inaddr_any(&up->rpf)) {
+ zlog_debug("%s: can't send join upstream: RPF'%s=%s",
+ __PRETTY_FUNCTION__,
+ up->sg_str, rpf_str);
/* warning only */
}
}
-
+
/* send Join(S,G) to the current upstream neighbor */
pim_joinprune_send(up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr,
- up->source_addr,
- up->group_addr,
+ up->rpf.rpf_addr.u.prefix4,
+ up,
1 /* join */);
}
@@ -110,13 +241,23 @@ static int on_join_timer(struct thread *t)
{
struct pim_upstream *up;
- zassert(t);
up = THREAD_ARG(t);
- zassert(up);
-
- send_join(up);
up->t_join_timer = NULL;
+
+ /*
+ * In the case of a HFR we will not ahve anyone to send this to.
+ */
+ if (PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
+ return 0;
+
+ /*
+ * Don't send the join if the outgoing interface is a loopback
+ * But since this might change leave the join timer running
+ */
+ if (!if_is_loopback (up->rpf.source_nexthop.interface))
+ pim_upstream_send_join (up);
+
join_timer_start(up);
return 0;
@@ -125,18 +266,13 @@ static int on_join_timer(struct thread *t)
static void join_timer_start(struct pim_upstream *up)
{
if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s: starting %d sec timer for upstream (S,G)=(%s,%s)",
+ zlog_debug("%s: starting %d sec timer for upstream (S,G)=%s",
__PRETTY_FUNCTION__,
qpim_t_periodic,
- src_str, grp_str);
+ up->sg_str);
}
- zassert(!up->t_join_timer);
-
+ THREAD_OFF (up->t_join_timer);
THREAD_TIMER_ON(master, up->t_join_timer,
on_join_timer,
up, qpim_t_periodic);
@@ -152,14 +288,10 @@ static void pim_upstream_join_timer_restart_msec(struct pim_upstream *up,
int interval_msec)
{
if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s: restarting %d msec timer for upstream (S,G)=(%s,%s)",
+ zlog_debug("%s: restarting %d msec timer for upstream (S,G)=%s",
__PRETTY_FUNCTION__,
interval_msec,
- src_str, grp_str);
+ up->sg_str);
}
THREAD_OFF(up->t_join_timer);
@@ -180,29 +312,21 @@ void pim_upstream_join_suppress(struct pim_upstream *up,
join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer);
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
- char grp_str[100];
- char rpf_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
+ if (PIM_DEBUG_TRACE) {
+ char rpf_str[INET_ADDRSTRLEN];
pim_inet4_dump("<rpf?>", rpf_addr, rpf_str, sizeof(rpf_str));
- zlog_debug("%s %s: detected Join(%s,%s) to RPF'(S,G)=%s: join_timer=%ld msec t_joinsuppress=%ld msec",
+ zlog_debug("%s %s: detected Join%s to RPF'(S,G)=%s: join_timer=%ld msec t_joinsuppress=%ld msec",
__FILE__, __PRETTY_FUNCTION__,
- src_str, grp_str,
+ up->sg_str,
rpf_str,
join_timer_remain_msec, t_joinsuppress_msec);
}
if (join_timer_remain_msec < t_joinsuppress_msec) {
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s %s: suppressing Join(S,G)=(%s,%s) for %ld msec",
+ if (PIM_DEBUG_TRACE) {
+ zlog_debug("%s %s: suppressing Join(S,G)=%s for %ld msec",
__FILE__, __PRETTY_FUNCTION__,
- src_str, grp_str, t_joinsuppress_msec);
+ up->sg_str, t_joinsuppress_msec);
}
pim_upstream_join_timer_restart_msec(up, t_joinsuppress_msec);
@@ -219,28 +343,20 @@ void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label,
join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer);
t_override_msec = pim_if_t_override_msec(up->rpf.source_nexthop.interface);
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
- char grp_str[100];
- char rpf_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
+ if (PIM_DEBUG_TRACE) {
+ char rpf_str[INET_ADDRSTRLEN];
pim_inet4_dump("<rpf?>", rpf_addr, rpf_str, sizeof(rpf_str));
- zlog_debug("%s: to RPF'(%s,%s)=%s: join_timer=%ld msec t_override=%d msec",
+ zlog_debug("%s: to RPF'%s=%s: join_timer=%ld msec t_override=%d msec",
debug_label,
- src_str, grp_str, rpf_str,
+ up->sg_str, rpf_str,
join_timer_remain_msec, t_override_msec);
}
if (join_timer_remain_msec > t_override_msec) {
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s: decreasing (S,G)=(%s,%s) join timer to t_override=%d msec",
+ if (PIM_DEBUG_TRACE) {
+ zlog_debug("%s: decreasing (S,G)=%s join timer to t_override=%d msec",
debug_label,
- src_str, grp_str,
+ up->sg_str,
t_override_msec);
}
@@ -250,196 +366,327 @@ void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label,
static void forward_on(struct pim_upstream *up)
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
struct listnode *chnode;
struct listnode *chnextnode;
- struct interface *ifp;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
- /* scan all interfaces */
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- pim_ifp = ifp->info;
+ /* scan (S,G) state */
+ for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
-
- if (ch->upstream != up)
- continue;
+ if (ch->upstream != up)
+ continue;
- if (pim_macro_chisin_oiflist(ch))
- pim_forward_start(ch);
+ if (pim_macro_chisin_oiflist(ch))
+ pim_forward_start(ch);
- } /* scan iface channel list */
- } /* scan iflist */
+ } /* scan iface channel list */
}
static void forward_off(struct pim_upstream *up)
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
struct listnode *chnode;
struct listnode *chnextnode;
- struct interface *ifp;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
- /* scan all interfaces */
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- pim_ifp = ifp->info;
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
+ if (ch->upstream != up)
+ continue;
- if (ch->upstream != up)
- continue;
+ pim_forward_stop(ch);
- pim_forward_stop(ch);
+ } /* scan iface channel list */
+}
- } /* scan iface channel list */
- } /* scan iflist */
+static int
+pim_upstream_could_register (struct pim_upstream *up)
+{
+ struct pim_interface *pim_ifp = up->rpf.source_nexthop.interface->info;
+
+ if (pim_ifp && PIM_I_am_DR (pim_ifp) &&
+ pim_if_connected_to_source (up->rpf.source_nexthop.interface, up->sg.src))
+ return 1;
+
+ return 0;
}
-static void pim_upstream_switch(struct pim_upstream *up,
- enum pim_upstream_state new_state)
+void
+pim_upstream_switch(struct pim_upstream *up,
+ enum pim_upstream_state new_state)
{
enum pim_upstream_state old_state = up->join_state;
- zassert(old_state != new_state);
-
- up->join_state = new_state;
- up->state_transition = pim_time_monotonic_sec();
-
if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[100];
- char grp_str[100];
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- zlog_debug("%s: PIM_UPSTREAM_%s: (S,G)=(%s,%s)",
+ zlog_debug("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
__PRETTY_FUNCTION__,
- ((new_state == PIM_UPSTREAM_JOINED) ? "JOINED" : "NOTJOINED"),
- src_str, grp_str);
+ up->sg_str,
+ pim_upstream_state2str (up->join_state),
+ pim_upstream_state2str (new_state));
}
+ /*
+ * This code still needs work.
+ */
+ switch (up->join_state)
+ {
+ case PIM_UPSTREAM_PRUNE:
+ if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
+ {
+ up->join_state = new_state;
+ up->state_transition = pim_time_monotonic_sec ();
+ }
+ break;
+ case PIM_UPSTREAM_JOIN_PENDING:
+ break;
+ case PIM_UPSTREAM_NOTJOINED:
+ case PIM_UPSTREAM_JOINED:
+ up->join_state = new_state;
+ if (old_state != new_state)
+ up->state_transition = pim_time_monotonic_sec();
+
+ break;
+ }
+
pim_upstream_update_assert_tracking_desired(up);
if (new_state == PIM_UPSTREAM_JOINED) {
- forward_on(up);
- send_join(up);
- join_timer_start(up);
+ if (old_state != PIM_UPSTREAM_JOINED)
+ {
+ int old_fhr = PIM_UPSTREAM_FLAG_TEST_FHR(up->flags);
+ forward_on(up);
+ pim_msdp_up_join_state_changed(up);
+ if (pim_upstream_could_register (up))
+ {
+ PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
+ if (!old_fhr && PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
+ {
+ pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
+ pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+ }
+ }
+ else
+ {
+ pim_upstream_send_join (up);
+ join_timer_start (up);
+ }
+ }
+ else
+ {
+ forward_on (up);
+ }
}
else {
forward_off(up);
+ if (old_state == PIM_UPSTREAM_JOINED)
+ pim_msdp_up_join_state_changed(up);
pim_joinprune_send(up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr,
- up->source_addr,
- up->group_addr,
+ up->rpf.rpf_addr.u.prefix4,
+ up,
0 /* prune */);
- zassert(up->t_join_timer);
- THREAD_OFF(up->t_join_timer);
+ if (up->t_join_timer)
+ THREAD_OFF(up->t_join_timer);
}
-
}
+static int
+pim_upstream_compare (void *arg1, void *arg2)
+{
+ const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
+ const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
-static struct pim_upstream *pim_upstream_new(struct in_addr source_addr,
- struct in_addr group_addr,
- struct interface *incoming)
+ if (ntohl(up1->sg.grp.s_addr) < ntohl(up2->sg.grp.s_addr))
+ return -1;
+
+ if (ntohl(up1->sg.grp.s_addr) > ntohl(up2->sg.grp.s_addr))
+ return 1;
+
+ if (ntohl(up1->sg.src.s_addr) < ntohl(up2->sg.src.s_addr))
+ return -1;
+
+ if (ntohl(up1->sg.src.s_addr) > ntohl(up2->sg.src.s_addr))
+ return 1;
+
+ return 0;
+}
+
+static struct pim_upstream *
+pim_upstream_new (struct prefix_sg *sg,
+ struct interface *incoming,
+ int flags)
{
- struct pim_upstream *up;
enum pim_rpf_result rpf_result;
+ struct pim_interface *pim_ifp;
+ struct pim_upstream *up;
- up = XMALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up));
+ up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up));
if (!up) {
- zlog_err("%s: PIM XMALLOC(%zu) failure",
+ zlog_err("%s: PIM XCALLOC(%zu) failure",
__PRETTY_FUNCTION__, sizeof(*up));
return NULL;
}
- up->source_addr = source_addr;
- if (!pim_rp_set_upstream_addr (&up->upstream_addr, source_addr))
+ up->sg = *sg;
+ pim_str_sg_set (sg, up->sg_str);
+ up = hash_get (pim_upstream_hash, up, hash_alloc_intern);
+ if (!pim_rp_set_upstream_addr (&up->upstream_addr, sg->src, sg->grp))
{
- if (PIM_DEBUG_PIM_TRACE)
+ if (PIM_DEBUG_TRACE)
zlog_debug("%s: Received a (*,G) with no RP configured", __PRETTY_FUNCTION__);
+ hash_release (pim_upstream_hash, up);
XFREE (MTYPE_PIM_UPSTREAM, up);
return NULL;
}
- up->group_addr = group_addr;
- up->flags = 0;
+ up->parent = pim_upstream_find_parent (up);
+ if (up->sg.src.s_addr == INADDR_ANY)
+ {
+ up->sources = list_new ();
+ up->sources->cmp = pim_upstream_compare;
+ }
+ else
+ up->sources = NULL;
+
+ pim_upstream_find_new_children (up);
+ up->flags = flags;
up->ref_count = 1;
up->t_join_timer = NULL;
up->t_ka_timer = NULL;
+ up->t_rs_timer = NULL;
+ up->t_msdp_reg_timer = NULL;
up->join_state = 0;
up->state_transition = pim_time_monotonic_sec();
up->channel_oil = NULL;
up->sptbit = PIM_UPSTREAM_SPTBIT_FALSE;
- up->rpf.source_nexthop.interface = 0;
- up->rpf.source_nexthop.mrib_nexthop_addr.s_addr = PIM_NET_INADDR_ANY;
+ up->rpf.source_nexthop.interface = NULL;
+ up->rpf.source_nexthop.mrib_nexthop_addr.family = AF_INET;
+ up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY;
up->rpf.source_nexthop.mrib_metric_preference = qpim_infinite_assert_metric.metric_preference;
up->rpf.source_nexthop.mrib_route_metric = qpim_infinite_assert_metric.route_metric;
- up->rpf.rpf_addr.s_addr = PIM_NET_INADDR_ANY;
+ up->rpf.rpf_addr.family = AF_INET;
+ up->rpf.rpf_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY;
- rpf_result = pim_rpf_update(up, 0, incoming);
+ if (up->sg.src.s_addr != INADDR_ANY)
+ wheel_add_item (pim_upstream_sg_wheel, up);
+
+ rpf_result = pim_rpf_update(up, NULL);
if (rpf_result == PIM_RPF_FAILURE) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: Attempting to create upstream(%s), Unable to RPF for source", __PRETTY_FUNCTION__,
+ up->sg_str);
+
+ if (up->parent)
+ {
+ listnode_delete (up->parent->sources, up);
+ up->parent = NULL;
+ }
+
+ if (up->sg.src.s_addr != INADDR_ANY)
+ wheel_remove_item (pim_upstream_sg_wheel, up);
+
+ pim_upstream_remove_children (up);
+ if (up->sources)
+ list_delete (up->sources);
+
+ hash_release (pim_upstream_hash, up);
XFREE(MTYPE_PIM_UPSTREAM, up);
return NULL;
}
- listnode_add(qpim_upstream_list, up);
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ if (pim_ifp)
+ up->channel_oil = pim_channel_oil_add(&up->sg, pim_ifp->mroute_vif_index);
+
+ listnode_add_sort(pim_upstream_list, up);
+
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: Created Upstream %s", __PRETTY_FUNCTION__, up->sg_str);
return up;
}
-struct pim_upstream *pim_upstream_find(struct in_addr source_addr,
- struct in_addr group_addr)
+struct pim_upstream *pim_upstream_find(struct prefix_sg *sg)
{
- struct listnode *up_node;
- struct pim_upstream *up;
+ struct pim_upstream lookup;
+ struct pim_upstream *up = NULL;
- for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
- if (group_addr.s_addr == up->group_addr.s_addr) {
- if ((up->source_addr.s_addr == INADDR_ANY) ||
- (source_addr.s_addr == up->source_addr.s_addr)) {
- return up;
- }
- }
- }
-
- return 0;
+ lookup.sg = *sg;
+ up = hash_lookup (pim_upstream_hash, &lookup);
+ return up;
}
-struct pim_upstream *pim_upstream_add(struct in_addr source_addr,
- struct in_addr group_addr,
- struct interface *incoming)
+static void pim_upstream_ref(struct pim_upstream *up, int flags)
{
- struct pim_upstream *up;
+ up->flags |= flags;
+ ++up->ref_count;
+}
- up = pim_upstream_find(source_addr, group_addr);
+struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
+ struct interface *incoming,
+ int flags, const char *name)
+{
+ struct pim_upstream *up = NULL;
+ int found = 0;
+ up = pim_upstream_find(sg);
if (up) {
- ++up->ref_count;
+ pim_upstream_ref(up, flags);
+ found = 1;
}
else {
- up = pim_upstream_new(source_addr, group_addr, incoming);
+ up = pim_upstream_new(sg, incoming, flags);
}
+ if (PIM_DEBUG_TRACE)
+ {
+ if (up)
+ zlog_debug("%s(%s): %s, found: %d: ref_count: %d",
+ __PRETTY_FUNCTION__, name,
+ up->sg_str, found,
+ up->ref_count);
+ else
+ zlog_debug("%s(%s): (%s) failure to create",
+ __PRETTY_FUNCTION__, name,
+ pim_str_sg_dump (sg));
+ }
+
return up;
}
-void pim_upstream_del(struct pim_upstream *up)
+static int
+pim_upstream_evaluate_join_desired_interface (struct pim_upstream *up,
+ struct pim_ifchannel *ch)
{
- --up->ref_count;
+ struct pim_upstream *parent = up->parent;
- if (up->ref_count < 1) {
- pim_upstream_delete(up);
- }
+ if (ch->upstream == up)
+ {
+ if (!pim_macro_ch_lost_assert(ch) && pim_macro_chisin_joins_or_include(ch))
+ return 1;
+
+ if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
+ return 0;
+ }
+
+ /*
+ * joins (*,G)
+ */
+ if (parent && ch->upstream == parent)
+ {
+ if (!pim_macro_ch_lost_assert (ch) && pim_macro_chisin_joins_or_include (ch))
+ return 1;
+ }
+
+ return 0;
}
/*
@@ -467,34 +714,23 @@ void pim_upstream_del(struct pim_upstream *up)
*/
int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
struct listnode *chnode;
struct listnode *chnextnode;
- struct interface *ifp;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
+ int ret = 0;
- /* scan all interfaces */
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- pim_ifp = ifp->info;
- if (!pim_ifp)
- continue;
-
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
- if (ch->upstream != up)
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch))
+ {
+ pim_ifp = ch->interface->info;
+ if (!pim_ifp)
continue;
- if (pim_macro_ch_lost_assert(ch))
- continue; /* keep searching */
-
- if (pim_macro_chisin_joins_or_include(ch))
- return 1; /* true */
+ ret += pim_upstream_evaluate_join_desired_interface (up, ch);
} /* scan iface channel list */
- } /* scan iflist */
- return 0; /* false */
+ return ret; /* false */
}
/*
@@ -515,14 +751,12 @@ void pim_upstream_update_join_desired(struct pim_upstream *up)
/* switched from false to true */
if (is_join_desired && !was_join_desired) {
- zassert(up->join_state == PIM_UPSTREAM_NOTJOINED);
pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
return;
}
/* switched from true to false */
if (!is_join_desired && was_join_desired) {
- zassert(up->join_state == PIM_UPSTREAM_JOINED);
pim_upstream_switch(up, PIM_UPSTREAM_NOTJOINED);
return;
}
@@ -544,22 +778,18 @@ void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr)
struct pim_upstream *up;
/*
- Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
- */
- for (ALL_LIST_ELEMENTS(qpim_upstream_list, up_node, up_nextnode, up)) {
+ * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
+ */
+ for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) {
- if (PIM_DEBUG_PIM_TRACE) {
- char neigh_str[100];
- char src_str[100];
- char grp_str[100];
- char rpf_addr_str[100];
+ if (PIM_DEBUG_TRACE) {
+ char neigh_str[INET_ADDRSTRLEN];
+ char rpf_addr_str[PREFIX_STRLEN];
pim_inet4_dump("<neigh?>", neigh_addr, neigh_str, sizeof(neigh_str));
- pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
- pim_inet4_dump("<rpf?>", up->rpf.rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
- zlog_debug("%s: matching neigh=%s against upstream (S,G)=(%s,%s) joined=%d rpf_addr=%s",
+ pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
+ zlog_debug("%s: matching neigh=%s against upstream (S,G)=%s joined=%d rpf_addr=%s",
__PRETTY_FUNCTION__,
- neigh_str, src_str, grp_str,
+ neigh_str, up->sg_str,
up->join_state == PIM_UPSTREAM_JOINED,
rpf_addr_str);
}
@@ -569,7 +799,7 @@ void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr)
continue;
/* match RPF'(S,G)=neigh_addr */
- if (up->rpf.rpf_addr.s_addr != neigh_addr.s_addr)
+ if (up->rpf.rpf_addr.u.prefix4.s_addr != neigh_addr.s_addr)
continue;
pim_upstream_join_timer_decrease_to_t_override("RPF'(S,G) GenID change",
@@ -581,130 +811,141 @@ void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr)
void pim_upstream_rpf_interface_changed(struct pim_upstream *up,
struct interface *old_rpf_ifp)
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
- struct interface *ifp;
+ struct listnode *chnode;
+ struct listnode *chnextnode;
+ struct pim_ifchannel *ch;
+ struct pim_interface *pim_ifp;
- /* scan all interfaces */
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- struct listnode *chnode;
- struct listnode *chnextnode;
- struct pim_ifchannel *ch;
- struct pim_interface *pim_ifp;
+ /* search all ifchannels */
+ for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
- pim_ifp = ifp->info;
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
- /* search all ifchannels */
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
- if (ch->upstream != up)
- continue;
+ if (ch->upstream != up)
+ continue;
- if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
- if (
- /* RPF_interface(S) was NOT I */
- (old_rpf_ifp == ch->interface)
- &&
- /* RPF_interface(S) stopped being I */
- (ch->upstream->rpf.source_nexthop.interface != ch->interface)
- ) {
- assert_action_a5(ch);
- }
- } /* PIM_IFASSERT_I_AM_LOSER */
+ if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
+ if (
+ /* RPF_interface(S) was NOT I */
+ (old_rpf_ifp == ch->interface)
+ &&
+ /* RPF_interface(S) stopped being I */
+ (ch->upstream->rpf.source_nexthop.interface != ch->interface)
+ ) {
+ assert_action_a5(ch);
+ }
+ } /* PIM_IFASSERT_I_AM_LOSER */
- pim_ifchannel_update_assert_tracking_desired(ch);
- }
+ pim_ifchannel_update_assert_tracking_desired(ch);
}
}
void pim_upstream_update_could_assert(struct pim_upstream *up)
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
struct listnode *chnode;
struct listnode *chnextnode;
- struct interface *ifp;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
- /* scan all interfaces */
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- pim_ifp = ifp->info;
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
-
- if (ch->upstream != up)
- continue;
-
- pim_ifchannel_update_could_assert(ch);
+ if (ch->upstream != up)
+ continue;
- } /* scan iface channel list */
- } /* scan iflist */
+ pim_ifchannel_update_could_assert(ch);
+ } /* scan iface channel list */
}
void pim_upstream_update_my_assert_metric(struct pim_upstream *up)
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
struct listnode *chnode;
struct listnode *chnextnode;
- struct interface *ifp;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
- /* scan all interfaces */
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- pim_ifp = ifp->info;
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
-
- if (ch->upstream != up)
- continue;
+ if (ch->upstream != up)
+ continue;
- pim_ifchannel_update_my_assert_metric(ch);
+ pim_ifchannel_update_my_assert_metric(ch);
- } /* scan iface channel list */
- } /* scan iflist */
+ } /* scan iface channel list */
}
static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up)
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
struct listnode *chnode;
struct listnode *chnextnode;
- struct interface *ifp;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
- /* scan all interfaces */
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- pim_ifp = ifp->info;
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS(pim_ifchannel_list, chnode, chnextnode, ch)) {
+ pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
+ if (ch->upstream != up)
+ continue;
- if (ch->upstream != up)
- continue;
+ pim_ifchannel_update_assert_tracking_desired(ch);
+
+ } /* scan iface channel list */
+}
+
+/* When kat is stopped CouldRegister goes to false so we need to
+ * transition the (S, G) on FHR to NI state and remove reg tunnel
+ * from the OIL */
+static void pim_upstream_fhr_kat_expiry(struct pim_upstream *up)
+{
+ if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
+ return;
- pim_ifchannel_update_assert_tracking_desired(ch);
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("kat expired on %s; clear fhr reg state", up->sg_str);
- } /* scan iface channel list */
- } /* scan iflist */
+ /* stop reg-stop timer */
+ THREAD_OFF(up->t_rs_timer);
+ /* remove regiface from the OIL if it is there*/
+ pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+ /* move to "not-joined" */
+ up->join_state = PIM_UPSTREAM_NOTJOINED;
+ PIM_UPSTREAM_FLAG_UNSET_FHR(up->flags);
+}
+
+/* When kat is started CouldRegister can go to true. And if it does we
+ * need to transition the (S, G) on FHR to JOINED state and add reg tunnel
+ * to the OIL */
+static void pim_upstream_fhr_kat_start(struct pim_upstream *up)
+{
+ if (pim_upstream_could_register(up)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("kat started on %s; set fhr reg state to joined", up->sg_str);
+
+ PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
+ if (up->join_state == PIM_UPSTREAM_NOTJOINED) {
+ pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+ up->join_state = PIM_UPSTREAM_JOINED;
+ }
+ }
}
/*
* On an RP, the PMBR value must be cleared when the
* Keepalive Timer expires
+ * KAT expiry indicates that flow is inactive. If the flow was created or
+ * maintained by activity now is the time to deref it.
*/
static int
pim_upstream_keep_alive_timer (struct thread *t)
@@ -712,41 +953,73 @@ pim_upstream_keep_alive_timer (struct thread *t)
struct pim_upstream *up;
up = THREAD_ARG(t);
+ up->t_ka_timer = NULL;
+
+ if (I_am_RP (up->sg.grp))
+ {
+ pim_br_clear_pmbr (&up->sg);
+ /*
+ * We need to do more here :)
+ * But this is the start.
+ */
+ }
- if (I_am_RP (up->group_addr))
- {
- pim_br_clear_pmbr (up->source_addr, up->group_addr);
- /*
- * We need to do more here :)
- * But this is the start.
- */
- }
- else
- {
- pim_mroute_update_counters (up->channel_oil);
+ /* source is no longer active - pull the SA from MSDP's cache */
+ pim_msdp_sa_local_del(&up->sg);
+
+ /* if entry was created because of activity we need to deref it */
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
+ {
+ pim_upstream_fhr_kat_expiry(up);
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("kat expired on %s; remove stream reference", up->sg_str);
+ PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags);
+ pim_upstream_del(up, __PRETTY_FUNCTION__);
+ }
- if (up->channel_oil->cc.oldpktcnt >= up->channel_oil->cc.pktcnt)
- {
- pim_mroute_del (up->channel_oil);
- pim_upstream_delete (up);
- }
- else
- {
- up->t_ka_timer = NULL;
- pim_upstream_keep_alive_timer_start (up, PIM_KEEPALIVE_PERIOD);
- }
- }
- return 1;
+ return 0;
}
void
pim_upstream_keep_alive_timer_start (struct pim_upstream *up,
uint32_t time)
{
+ if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("kat start on %s with no stream reference", up->sg_str);
+ }
+ THREAD_OFF (up->t_ka_timer);
THREAD_TIMER_ON (master,
up->t_ka_timer,
pim_upstream_keep_alive_timer,
up, time);
+
+ /* any time keepalive is started against a SG we will have to
+ * re-evaluate our active source database */
+ pim_msdp_sa_local_update(up);
+}
+
+/* MSDP on RP needs to know if a source is registerable to this RP */
+static int
+pim_upstream_msdp_reg_timer(struct thread *t)
+{
+ struct pim_upstream *up;
+
+ up = THREAD_ARG(t);
+ up->t_msdp_reg_timer = NULL;
+
+ /* source is no longer active - pull the SA from MSDP's cache */
+ pim_msdp_sa_local_del(&up->sg);
+ return 1;
+}
+void
+pim_upstream_msdp_reg_timer_start(struct pim_upstream *up)
+{
+ THREAD_OFF(up->t_msdp_reg_timer);
+ THREAD_TIMER_ON(master, up->t_msdp_reg_timer,
+ pim_upstream_msdp_reg_timer, up, PIM_MSDP_REG_RXED_PERIOD);
+
+ pim_msdp_sa_local_update(up);
}
/*
@@ -778,7 +1051,476 @@ pim_upstream_keep_alive_timer_start (struct pim_upstream *up,
* received for the source and group.
*/
int
-pim_upstream_switch_to_spt_desired (struct in_addr source, struct in_addr group)
+pim_upstream_switch_to_spt_desired (struct prefix_sg *sg)
+{
+ if (I_am_RP (sg->grp))
+ return 1;
+
+ return 0;
+}
+
+int
+pim_upstream_is_sg_rpt (struct pim_upstream *up)
+{
+ struct listnode *chnode;
+ struct pim_ifchannel *ch;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, chnode, ch))
+ {
+ if ((ch->upstream == up) &&
+ (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)))
+ return 1;
+ }
+
+ return 0;
+}
+/*
+ * After receiving a packet set SPTbit:
+ * void
+ * Update_SPTbit(S,G,iif) {
+ * if ( iif == RPF_interface(S)
+ * AND JoinDesired(S,G) == TRUE
+ * AND ( DirectlyConnected(S) == TRUE
+ * OR RPF_interface(S) != RPF_interface(RP(G))
+ * OR inherited_olist(S,G,rpt) == NULL
+ * OR ( ( RPF'(S,G) == RPF'(*,G) ) AND
+ * ( RPF'(S,G) != NULL ) )
+ * OR ( I_Am_Assert_Loser(S,G,iif) ) {
+ * Set SPTbit(S,G) to TRUE
+ * }
+ * }
+ */
+void
+pim_upstream_set_sptbit (struct pim_upstream *up, struct interface *incoming)
+{
+ struct pim_rpf *grpf = NULL;
+
+ // iif == RPF_interfvace(S)
+ if (up->rpf.source_nexthop.interface != incoming)
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: Incoming Interface: %s is different than RPF_interface(S) %s",
+ __PRETTY_FUNCTION__, incoming->name, up->rpf.source_nexthop.interface->name);
+ return;
+ }
+
+ // AND JoinDesired(S,G) == TRUE
+ // FIXME
+
+ // DirectlyConnected(S) == TRUE
+ if (pim_if_connected_to_source (up->rpf.source_nexthop.interface, up->sg.src))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: %s is directly connected to the source", __PRETTY_FUNCTION__,
+ up->sg_str);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ // OR RPF_interface(S) != RPF_interface(RP(G))
+ grpf = RP(up->sg.grp);
+ if (!grpf || up->rpf.source_nexthop.interface != grpf->source_nexthop.interface)
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: %s RPF_interface(S) != RPF_interface(RP(G))",
+ __PRETTY_FUNCTION__, up->sg_str);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ // OR inherited_olist(S,G,rpt) == NULL
+ if (pim_upstream_is_sg_rpt(up) && pim_upstream_empty_inherited_olist(up))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: %s OR inherited_olist(S,G,rpt) == NULL", __PRETTY_FUNCTION__,
+ up->sg_str);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ // OR ( ( RPF'(S,G) == RPF'(*,G) ) AND
+ // ( RPF'(S,G) != NULL ) )
+ if (up->parent && pim_rpf_is_same (&up->rpf, &up->parent->rpf))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: %s RPF'(S,G) is the same as RPF'(*,G)", __PRETTY_FUNCTION__,
+ up->sg_str);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ return;
+}
+
+const char *
+pim_upstream_state2str (enum pim_upstream_state join_state)
+{
+ switch (join_state)
+ {
+ case PIM_UPSTREAM_NOTJOINED:
+ return "NotJoined";
+ break;
+ case PIM_UPSTREAM_JOINED:
+ return "Joined";
+ break;
+ case PIM_UPSTREAM_JOIN_PENDING:
+ return "JoinPending";
+ break;
+ case PIM_UPSTREAM_PRUNE:
+ return "Prune";
+ break;
+ }
+ return "Unknown";
+}
+
+static int
+pim_upstream_register_stop_timer (struct thread *t)
+{
+ struct pim_interface *pim_ifp;
+ struct pim_upstream *up;
+ struct pim_rpf *rpg;
+ struct ip ip_hdr;
+ up = THREAD_ARG (t);
+
+ up->t_rs_timer = NULL;
+
+ if (PIM_DEBUG_TRACE)
+ {
+ zlog_debug ("%s: (S,G)=%s upstream register stop timer %s",
+ __PRETTY_FUNCTION__, up->sg_str,
+ pim_upstream_state2str(up->join_state));
+ }
+
+ switch (up->join_state)
+ {
+ case PIM_UPSTREAM_JOIN_PENDING:
+ up->join_state = PIM_UPSTREAM_JOINED;
+ pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+ break;
+ case PIM_UPSTREAM_JOINED:
+ break;
+ case PIM_UPSTREAM_PRUNE:
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ if (!pim_ifp)
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: Interface: %s is not configured for pim",
+ __PRETTY_FUNCTION__, up->rpf.source_nexthop.interface->name);
+ return 0;
+ }
+ up->join_state = PIM_UPSTREAM_JOIN_PENDING;
+ pim_upstream_start_register_stop_timer (up, 1);
+
+ if (((up->channel_oil->cc.lastused/100) > PIM_KEEPALIVE_PERIOD) &&
+ (I_am_RP (up->sg.grp)))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while", __PRETTY_FUNCTION__);
+ return 0;
+ }
+ rpg = RP (up->sg.grp);
+ memset (&ip_hdr, 0, sizeof (struct ip));
+ ip_hdr.ip_p = PIM_IP_PROTO_PIM;
+ ip_hdr.ip_hl = 5;
+ ip_hdr.ip_v = 4;
+ ip_hdr.ip_src = up->sg.src;
+ ip_hdr.ip_dst = up->sg.grp;
+ ip_hdr.ip_len = htons (20);
+ // checksum is broken
+ pim_register_send ((uint8_t *)&ip_hdr, sizeof (struct ip),
+ pim_ifp->primary_address, rpg, 1, up);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void
+pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_register)
+{
+ uint32_t time;
+
+ if (up->t_rs_timer)
+ {
+ THREAD_TIMER_OFF (up->t_rs_timer);
+ up->t_rs_timer = NULL;
+ }
+
+ if (!null_register)
+ {
+ uint32_t lower = (0.5 * PIM_REGISTER_SUPPRESSION_PERIOD);
+ uint32_t upper = (1.5 * PIM_REGISTER_SUPPRESSION_PERIOD);
+ time = lower + (random () % (upper - lower + 1)) - PIM_REGISTER_PROBE_PERIOD;
+ }
+ else
+ time = PIM_REGISTER_PROBE_PERIOD;
+
+ if (PIM_DEBUG_TRACE)
+ {
+ zlog_debug ("%s: (S,G)=%s Starting upstream register stop timer %d",
+ __PRETTY_FUNCTION__, up->sg_str, time);
+ }
+ THREAD_TIMER_ON (master, up->t_rs_timer,
+ pim_upstream_register_stop_timer,
+ up, time);
+}
+
+int
+pim_upstream_inherited_olist_decide (struct pim_upstream *up)
+{
+ struct pim_interface *pim_ifp;
+ struct listnode *chnextnode;
+ struct pim_ifchannel *ch;
+ struct listnode *chnode;
+ int output_intf = 0;
+
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ if (pim_ifp && !up->channel_oil)
+ up->channel_oil = pim_channel_oil_add (&up->sg, pim_ifp->mroute_vif_index);
+
+ for (ALL_LIST_ELEMENTS (pim_ifchannel_list, chnode, chnextnode, ch))
+ {
+ pim_ifp = ch->interface->info;
+ if (!pim_ifp)
+ continue;
+
+ if (pim_upstream_evaluate_join_desired_interface (up, ch))
+ {
+ int flag = PIM_OIF_FLAG_PROTO_PIM;
+
+ if (ch->sg.src.s_addr == INADDR_ANY && ch->upstream != up)
+ flag = PIM_OIF_FLAG_PROTO_STAR;
+ pim_channel_add_oif (up->channel_oil, ch->interface, flag);
+ output_intf++;
+ }
+ }
+
+ return output_intf;
+}
+
+/*
+ * For a given upstream, determine the inherited_olist
+ * and apply it.
+ *
+ * inherited_olist(S,G,rpt) =
+ * ( joins(*,*,RP(G)) (+) joins(*,G) (-) prunes(S,G,rpt) )
+ * (+) ( pim_include(*,G) (-) pim_exclude(S,G))
+ * (-) ( lost_assert(*,G) (+) lost_assert(S,G,rpt) )
+ *
+ * inherited_olist(S,G) =
+ * inherited_olist(S,G,rpt) (+)
+ * joins(S,G) (+) pim_include(S,G) (-) lost_assert(S,G)
+ *
+ * return 1 if there are any output interfaces
+ * return 0 if there are not any output interfaces
+ */
+int
+pim_upstream_inherited_olist (struct pim_upstream *up)
+{
+ int output_intf = pim_upstream_inherited_olist_decide (up);
+
+ /*
+ * If we have output_intf switch state to Join and work like normal
+ * If we don't have an output_intf that means we are probably a
+ * switch on a stick so turn on forwarding to just accept the
+ * incoming packets so we don't bother the other stuff!
+ */
+ if (output_intf)
+ pim_upstream_switch (up, PIM_UPSTREAM_JOINED);
+ else
+ forward_on (up);
+
+ return output_intf;
+}
+
+int
+pim_upstream_empty_inherited_olist (struct pim_upstream *up)
+{
+ return pim_channel_oil_empty (up->channel_oil);
+}
+
+/*
+ * When we have a new neighbor,
+ * find upstreams that don't have their rpf_addr
+ * set and see if the new neighbor allows
+ * the join to be sent
+ */
+void
+pim_upstream_find_new_rpf (void)
+{
+ struct listnode *up_node;
+ struct listnode *up_nextnode;
+ struct pim_upstream *up;
+
+ /*
+ * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
+ */
+ for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up))
+ {
+ if (pim_rpf_addr_is_inaddr_any(&up->rpf))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("Upstream %s without a path to send join, checking",
+ up->sg_str);
+ pim_rpf_update (up, NULL);
+ }
+ }
+}
+
+static unsigned int
+pim_upstream_hash_key (void *arg)
+{
+ struct pim_upstream *up = (struct pim_upstream *)arg;
+
+ return jhash_2words (up->sg.src.s_addr, up->sg.grp.s_addr, 0);
+}
+
+void pim_upstream_terminate (void)
{
+ if (pim_upstream_list)
+ list_delete (pim_upstream_list);
+ pim_upstream_list = NULL;
+
+ if (pim_upstream_hash)
+ hash_free (pim_upstream_hash);
+ pim_upstream_hash = NULL;
+}
+
+static int
+pim_upstream_equal (const void *arg1, const void *arg2)
+{
+ const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
+ const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
+
+ if ((up1->sg.grp.s_addr == up2->sg.grp.s_addr) &&
+ (up1->sg.src.s_addr == up2->sg.src.s_addr))
+ return 1;
+
return 0;
}
+
+/* rfc4601:section-4.2:"Data Packet Forwarding Rules" defines
+ * the cases where kat has to be restarted on rxing traffic -
+ *
+ * if( DirectlyConnected(S) == TRUE AND iif == RPF_interface(S) ) {
+ * set KeepaliveTimer(S,G) to Keepalive_Period
+ * # Note: a register state transition or UpstreamJPState(S,G)
+ * # transition may happen as a result of restarting
+ * # KeepaliveTimer, and must be dealt with here.
+ * }
+ * if( iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined AND
+ * inherited_olist(S,G) != NULL ) {
+ * set KeepaliveTimer(S,G) to Keepalive_Period
+ * }
+ */
+static bool pim_upstream_kat_start_ok(struct pim_upstream *up)
+{
+ /* "iif == RPF_interface(S)" check has to be done by the kernel or hw
+ * so we will skip that here */
+ if (pim_if_connected_to_source(up->rpf.source_nexthop.interface,
+ up->sg.src)) {
+ return true;
+ }
+
+ if ((up->join_state == PIM_UPSTREAM_JOINED) &&
+ !pim_upstream_empty_inherited_olist(up)) {
+ /* XXX: I have added this RP check just for 3.2 and it's a digression from
+ * what rfc-4601 says. Till now we were only running KAT on FHR and RP and
+ * there is some angst around making the change to run it all routers that
+ * maintain the (S, G) state. This is tracked via CM-13601 and MUST be
+ * removed to handle spt turn-arounds correctly in a 3-tier clos */
+ if (I_am_RP (up->sg.grp))
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Code to check and see if we've received packets on a S,G mroute
+ * and if so to set the SPT bit appropriately
+ */
+static void
+pim_upstream_sg_running (void *arg)
+{
+ struct pim_upstream *up = (struct pim_upstream *)arg;
+
+ // No packet can have arrived here if this is the case
+ if (!up->channel_oil || !up->channel_oil->installed)
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: %s is not installed in mroute",
+ __PRETTY_FUNCTION__, up->sg_str);
+ return;
+ }
+
+ /*
+ * This is a bit of a hack
+ * We've noted that we should rescan but
+ * we've missed the window for doing so in
+ * pim_zebra.c for some reason. I am
+ * only doing this at this point in time
+ * to get us up and working for the moment
+ */
+ if (up->channel_oil->oil_inherited_rescan)
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s: Handling unscanned inherited_olist for %s", __PRETTY_FUNCTION__, up->sg_str);
+ pim_upstream_inherited_olist_decide (up);
+ up->channel_oil->oil_inherited_rescan = 0;
+ }
+ pim_mroute_update_counters (up->channel_oil);
+
+ // Have we seen packets?
+ if ((up->channel_oil->cc.oldpktcnt >= up->channel_oil->cc.pktcnt) &&
+ (up->channel_oil->cc.lastused/100 > 30))
+ {
+ if (PIM_DEBUG_TRACE)
+ {
+ zlog_debug ("%s: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)",
+ __PRETTY_FUNCTION__, up->sg_str,
+ up->channel_oil->cc.oldpktcnt,
+ up->channel_oil->cc.pktcnt,
+ up->channel_oil->cc.lastused/100);
+ }
+ return;
+ }
+
+ if (pim_upstream_kat_start_ok(up)) {
+ /* Add a source reference to the stream if
+ * one doesn't already exist */
+ if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
+ {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("source reference created on kat restart %s", up->sg_str);
+
+ pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM);
+ PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
+ pim_upstream_fhr_kat_start(up);
+ }
+ pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
+ }
+
+ if (up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE)
+ {
+ pim_upstream_set_sptbit(up, up->rpf.source_nexthop.interface);
+ }
+ return;
+}
+
+void
+pim_upstream_init (void)
+{
+ pim_upstream_sg_wheel = wheel_init (master, 31000, 100,
+ pim_upstream_hash_key,
+ pim_upstream_sg_running);
+ pim_upstream_hash = hash_create_size (8192, pim_upstream_hash_key,
+ pim_upstream_equal);
+
+ pim_upstream_list = list_new ();
+ pim_upstream_list->del = (void (*)(void *)) pim_upstream_free;
+ pim_upstream_list->cmp = pim_upstream_compare;
+
+}
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index f10c8feb3b..1a50c0c6e3 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -22,52 +22,47 @@
#define PIM_UPSTREAM_H
#include <zebra.h>
+#include <prefix.h>
+
+#include <pimd/pim_rpf.h>
#define PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED (1 << 0)
-#define PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED (2 << 0)
+#define PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED (1 << 1)
+#define PIM_UPSTREAM_FLAG_MASK_FHR (1 << 2)
+#define PIM_UPSTREAM_FLAG_MASK_SRC_IGMP (1 << 3)
+#define PIM_UPSTREAM_FLAG_MASK_SRC_PIM (1 << 4)
+#define PIM_UPSTREAM_FLAG_MASK_SRC_STREAM (1 << 5)
+#define PIM_UPSTREAM_FLAG_MASK_SRC_MSDP (1 << 6)
#define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
#define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
+#define PIM_UPSTREAM_FLAG_TEST_FHR(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_FHR)
+#define PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+#define PIM_UPSTREAM_FLAG_TEST_SRC_PIM(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
+#define PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
+#define PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
#define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
#define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
+#define PIM_UPSTREAM_FLAG_SET_FHR(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_FHR)
+#define PIM_UPSTREAM_FLAG_SET_SRC_IGMP(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+#define PIM_UPSTREAM_FLAG_SET_SRC_PIM(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
+#define PIM_UPSTREAM_FLAG_SET_SRC_STREAM(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
+#define PIM_UPSTREAM_FLAG_SET_SRC_MSDP(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
#define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
#define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
-
-/*
- RFC 4601:
-
- Metric Preference
- Preference value assigned to the unicast routing protocol that
- provided the route to the multicast source or Rendezvous-Point.
-
- Metric
- The unicast routing table metric associated with the route used to
- reach the multicast source or Rendezvous-Point. The metric is in
- units applicable to the unicast routing protocol used.
-*/
-struct pim_nexthop {
- struct interface *interface; /* RPF_interface(S) */
- struct in_addr mrib_nexthop_addr; /* MRIB.next_hop(S) */
- uint32_t mrib_metric_preference; /* MRIB.pref(S) */
- uint32_t mrib_route_metric; /* MRIB.metric(S) */
-};
-
-struct pim_rpf {
- struct pim_nexthop source_nexthop;
- struct in_addr rpf_addr; /* RPF'(S,G) */
-};
-
-enum pim_rpf_result {
- PIM_RPF_OK = 0,
- PIM_RPF_CHANGED,
- PIM_RPF_FAILURE
-};
+#define PIM_UPSTREAM_FLAG_UNSET_FHR(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_FHR)
+#define PIM_UPSTREAM_FLAG_UNSET_SRC_IGMP(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+#define PIM_UPSTREAM_FLAG_UNSET_SRC_PIM(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
+#define PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
+#define PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
enum pim_upstream_state {
PIM_UPSTREAM_NOTJOINED,
- PIM_UPSTREAM_JOINED
+ PIM_UPSTREAM_JOINED,
+ PIM_UPSTREAM_JOIN_PENDING,
+ PIM_UPSTREAM_PRUNE,
};
enum pim_upstream_sptbit {
@@ -83,11 +78,14 @@ enum pim_upstream_sptbit {
See RFC 4601: 4.5.7. Sending (S,G) Join/Prune Message
*/
struct pim_upstream {
+ struct pim_upstream *parent;
struct in_addr upstream_addr;/* Who we are talking to */
- struct in_addr source_addr; /* (S,G) source key */
- struct in_addr group_addr; /* (S,G) group key */
+ struct in_addr upstream_register; /*Who we received a register from*/
+ struct prefix_sg sg; /* (S,G) group key */
+ char sg_str[PIM_SG_LEN];
uint32_t flags;
struct channel_oil *channel_oil;
+ struct list *sources;
enum pim_upstream_state join_state;
enum pim_upstream_sptbit sptbit;
@@ -99,23 +97,36 @@ struct pim_upstream {
struct thread *t_join_timer;
/*
+ * RST(S,G)
+ */
+ struct thread *t_rs_timer;
+#define PIM_REGISTER_SUPPRESSION_PERIOD (60)
+#define PIM_REGISTER_PROBE_PERIOD (15)
+
+ /*
* KAT(S,G)
*/
struct thread *t_ka_timer;
#define PIM_KEEPALIVE_PERIOD (210)
#define PIM_RP_KEEPALIVE_PERIOD ( 3 * qpim_register_suppress_time + qpim_register_probe_time )
+ /* on the RP we restart a timer to indicate if registers are being rxed for
+ * SG. This is needed by MSDP to determine its local SA cache */
+ struct thread *t_msdp_reg_timer;
+#define PIM_MSDP_REG_RXED_PERIOD (3 * (1.5 * qpim_register_suppress_time))
+
int64_t state_transition; /* Record current state uptime */
};
+struct list *pim_upstream_list;
+struct hash *pim_upstream_hash;
+
void pim_upstream_free(struct pim_upstream *up);
-void pim_upstream_delete(struct pim_upstream *up);
-struct pim_upstream *pim_upstream_find(struct in_addr source_addr,
- struct in_addr group_addr);
-struct pim_upstream *pim_upstream_add(struct in_addr source_addr,
- struct in_addr group_addr,
- struct interface *ifp);
-void pim_upstream_del(struct pim_upstream *up);
+struct pim_upstream *pim_upstream_find (struct prefix_sg *sg);
+struct pim_upstream *pim_upstream_add (struct prefix_sg *sg,
+ struct interface *ifp, int flags,
+ const char *name);
+void pim_upstream_del(struct pim_upstream *up, const char *name);
int pim_upstream_evaluate_join_desired(struct pim_upstream *up);
void pim_upstream_update_join_desired(struct pim_upstream *up);
@@ -136,7 +147,27 @@ void pim_upstream_update_my_assert_metric(struct pim_upstream *up);
void pim_upstream_keep_alive_timer_start (struct pim_upstream *up, uint32_t time);
-int pim_upstream_switch_to_spt_desired (struct in_addr source, struct in_addr group);
-#define SwitchToSptDesired(S,G) pim_upstream_switch_to_spt_desired ((S), (G))
+int pim_upstream_switch_to_spt_desired (struct prefix_sg *sg);
+#define SwitchToSptDesired(sg) pim_upstream_switch_to_spt_desired (sg)
+int pim_upstream_is_sg_rpt (struct pim_upstream *up);
+
+void pim_upstream_set_sptbit (struct pim_upstream *up, struct interface *incoming);
+
+void pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_register);
+
+void pim_upstream_send_join (struct pim_upstream *up);
+
+void pim_upstream_switch (struct pim_upstream *up, enum pim_upstream_state new_state);
+
+const char *pim_upstream_state2str (enum pim_upstream_state join_state);
+
+int pim_upstream_inherited_olist_decide (struct pim_upstream *up);
+int pim_upstream_inherited_olist (struct pim_upstream *up);
+int pim_upstream_empty_inherited_olist (struct pim_upstream *up);
+
+void pim_upstream_find_new_rpf (void);
+void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up);
+void pim_upstream_init (void);
+void pim_upstream_terminate (void);
#endif /* PIM_UPSTREAM_H */
diff --git a/pimd/pim_util.c b/pimd/pim_util.c
index f5b6a8210a..1125db00a9 100644
--- a/pimd/pim_util.c
+++ b/pimd/pim_util.c
@@ -21,6 +21,7 @@
#include <zebra.h>
#include "log.h"
+#include "prefix.h"
#include "pim_util.h"
@@ -103,3 +104,43 @@ void pim_pkt_dump(const char *label, const uint8_t *buf, int size)
size);
zlog_hexdump(buf, size);
}
+
+int
+pim_is_group_224_0_0_0_24 (struct in_addr group_addr)
+{
+ static int first = 1;
+ static struct prefix group_224;
+ struct prefix group;
+
+ if (first)
+ {
+ str2prefix ("224.0.0.0/24", &group_224);
+ first = 0;
+ }
+
+ group.family = AF_INET;
+ group.u.prefix4 = group_addr;
+ group.prefixlen = 32;
+
+ return prefix_match (&group_224, &group);
+}
+
+int
+pim_is_group_224_4 (struct in_addr group_addr)
+{
+ static int first = 1;
+ static struct prefix group_all;
+ struct prefix group;
+
+ if (first)
+ {
+ str2prefix ("224.0.0.0/4", &group_all);
+ first = 0;
+ }
+
+ group.family = AF_INET;
+ group.u.prefix4 = group_addr;
+ group.prefixlen = 32;
+
+ return prefix_match (&group_all, &group);
+}
diff --git a/pimd/pim_util.h b/pimd/pim_util.h
index d780bfbc27..94635466d9 100644
--- a/pimd/pim_util.h
+++ b/pimd/pim_util.h
@@ -32,4 +32,6 @@ uint16_t igmp_msg_decode8to16(uint8_t code);
void pim_pkt_dump(const char *label, const uint8_t *buf, int size);
+int pim_is_group_224_0_0_0_24 (struct in_addr group_addr);
+int pim_is_group_224_4 (struct in_addr group_addr);
#endif /* PIM_UTIL_H */
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index 07c65e4e53..03ee7e92ec 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -22,7 +22,10 @@
#include "if.h"
#include "linklist.h"
+#include "prefix.h"
+#include "vty.h"
#include "vrf.h"
+#include "plist.h"
#include "pimd.h"
#include "pim_vty.h"
@@ -33,11 +36,26 @@
#include "pim_pim.h"
#include "pim_oil.h"
#include "pim_static.h"
+#include "pim_rp.h"
+#include "pim_msdp.h"
-int pim_debug_config_write(struct vty *vty)
+int
+pim_debug_config_write (struct vty *vty)
{
int writes = 0;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ vty_out(vty, "debug msdp events%s", VTY_NEWLINE);
+ ++writes;
+ }
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ vty_out(vty, "debug msdp packets%s", VTY_NEWLINE);
+ ++writes;
+ }
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ vty_out(vty, "debug msdp internal%s", VTY_NEWLINE);
+ ++writes;
+ }
if (PIM_DEBUG_IGMP_EVENTS) {
vty_out(vty, "debug igmp events%s", VTY_NEWLINE);
++writes;
@@ -50,12 +68,21 @@ int pim_debug_config_write(struct vty *vty)
vty_out(vty, "debug igmp trace%s", VTY_NEWLINE);
++writes;
}
+ if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
+ vty_out(vty, "debug igmp trace detail%s", VTY_NEWLINE);
+ ++writes;
+ }
if (PIM_DEBUG_MROUTE) {
vty_out(vty, "debug mroute%s", VTY_NEWLINE);
++writes;
}
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ vty_out (vty, "debug mroute detail%s", VTY_NEWLINE);
+ ++writes;
+ }
+
if (PIM_DEBUG_PIM_EVENTS) {
vty_out(vty, "debug pim events%s", VTY_NEWLINE);
++writes;
@@ -72,10 +99,15 @@ int pim_debug_config_write(struct vty *vty)
vty_out(vty, "debug pim packet-dump receive%s", VTY_NEWLINE);
++writes;
}
+
if (PIM_DEBUG_PIM_TRACE) {
vty_out(vty, "debug pim trace%s", VTY_NEWLINE);
++writes;
}
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ vty_out(vty, "debug pim trace detail%s", VTY_NEWLINE);
+ ++writes;
+ }
if (PIM_DEBUG_ZEBRA) {
vty_out(vty, "debug pim zebra%s", VTY_NEWLINE);
@@ -87,30 +119,74 @@ int pim_debug_config_write(struct vty *vty)
++writes;
}
+ if (PIM_DEBUG_PIM_HELLO) {
+ vty_out (vty, "debug pim packets hello%s", VTY_NEWLINE);
+ ++writes;
+ }
+
+ if (PIM_DEBUG_PIM_J_P) {
+ vty_out (vty, "debug pim packets joins%s", VTY_NEWLINE);
+ ++writes;
+ }
+
+ if (PIM_DEBUG_PIM_REG) {
+ vty_out (vty, "debug pim packets register%s", VTY_NEWLINE);
+ ++writes;
+ }
+
+ if (PIM_DEBUG_STATIC) {
+ vty_out (vty, "debug pim static%s", VTY_NEWLINE);
+ ++writes;
+ }
+
return writes;
}
int pim_global_config_write(struct vty *vty)
{
int writes = 0;
- char buffer[32];
+
+ writes += pim_msdp_config_write (vty);
if (PIM_MROUTE_IS_ENABLED) {
- vty_out(vty, "%s%s", PIM_CMD_IP_MULTICAST_ROUTING, VTY_NEWLINE);
- ++writes;
- }
- if (qpim_rp.rpf_addr.s_addr != INADDR_NONE) {
- vty_out(vty, "ip pim rp %s%s", inet_ntop(AF_INET, &qpim_rp.rpf_addr, buffer, 32), VTY_NEWLINE);
+ vty_out(vty, "ip multicast-routing%s", VTY_NEWLINE);
++writes;
}
+ writes += pim_rp_config_write (vty);
+
+ if (qpim_register_suppress_time != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT)
+ {
+ vty_out (vty, "ip pim register-suppress-time %d%s",
+ qpim_register_suppress_time, VTY_NEWLINE);
+ ++writes;
+ }
+ if (qpim_t_periodic != PIM_DEFAULT_T_PERIODIC)
+ {
+ vty_out (vty, "ip pim join-prune-interval %d%s",
+ qpim_t_periodic, VTY_NEWLINE);
+ ++writes;
+ }
+ if (qpim_keep_alive_time != PIM_KEEPALIVE_PERIOD)
+ {
+ vty_out (vty, "ip pim keep-alive-timer %d%s",
+ qpim_keep_alive_time, VTY_NEWLINE);
+ ++writes;
+ }
+ if (qpim_packet_process != PIM_DEFAULT_PACKET_PROCESS)
+ {
+ vty_out (vty, "ip pim packets %d%s",
+ qpim_packet_process, VTY_NEWLINE);
+ ++writes;
+ }
+
if (qpim_ssmpingd_list) {
struct listnode *node;
struct ssmpingd_sock *ss;
vty_out(vty, "!%s", VTY_NEWLINE);
++writes;
for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
- char source_str[100];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
vty_out(vty, "ip ssmpingd %s%s", source_str, VTY_NEWLINE);
++writes;
@@ -159,17 +235,34 @@ int pim_interface_config_write(struct vty *vty)
vty_out(vty, "%s", VTY_NEWLINE);
}
+ /* update source */
+ if (PIM_INADDR_ISNOT_ANY(pim_ifp->update_source)) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", pim_ifp->update_source, src_str,
+ sizeof(src_str));
+ vty_out(vty, " ip pim use-source %s%s", src_str, VTY_NEWLINE);
+ ++writes;
+ }
+
/* IF ip igmp */
if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
vty_out(vty, " ip igmp%s", VTY_NEWLINE);
++writes;
}
+ /* ip igmp version */
+ if (pim_ifp->igmp_version != IGMP_DEFAULT_VERSION)
+ {
+ vty_out(vty, " ip igmp version %d%s",
+ pim_ifp->igmp_version,
+ VTY_NEWLINE);
+ ++writes;
+ }
+
/* IF ip igmp query-interval */
if (pim_ifp->igmp_default_query_interval != IGMP_GENERAL_QUERY_INTERVAL)
{
- vty_out(vty, " %s %d%s",
- PIM_CMD_IP_IGMP_QUERY_INTERVAL,
+ vty_out(vty, " ip igmp query-interval %d%s",
pim_ifp->igmp_default_query_interval,
VTY_NEWLINE);
++writes;
@@ -178,8 +271,7 @@ int pim_interface_config_write(struct vty *vty)
/* IF ip igmp query-max-response-time */
if (pim_ifp->igmp_query_max_response_time_dsec != IGMP_QUERY_MAX_RESPONSE_TIME_DSEC)
{
- vty_out(vty, " %s %d%s",
- PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
+ vty_out(vty, " ip igpm query-max-response-time %d%s",
pim_ifp->igmp_query_max_response_time_dsec,
VTY_NEWLINE);
++writes;
@@ -190,10 +282,10 @@ int pim_interface_config_write(struct vty *vty)
struct listnode *node;
struct igmp_join *ij;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, node, ij)) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
+ inet_ntop(AF_INET, &ij->source_addr, source_str, sizeof(source_str));
vty_out(vty, " ip igmp join %s %s%s",
group_str, source_str,
VTY_NEWLINE);
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index f2195960c4..1bb4852c6b 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -28,6 +28,8 @@
#include "zclient.h"
#include "stream.h"
#include "network.h"
+#include "vty.h"
+#include "plist.h"
#include "pimd.h"
#include "pim_pim.h"
@@ -46,6 +48,8 @@
#undef PIM_DEBUG_IFADDR_DUMP
#define PIM_DEBUG_IFADDR_DUMP
+static struct zclient *zclient = NULL;
+
static int fib_lookup_if_vif_index(struct in_addr addr);
static int del_oif(struct channel_oil *channel_oil,
struct interface *oif,
@@ -171,6 +175,7 @@ static int pim_zebra_if_state_down(int command, struct zclient *zclient,
}
if (!if_is_operative(ifp)) {
+ pim_ifchannel_delete_all(ifp);
/*
pim_if_addr_del_all() suffices for shutting down IGMP,
but not for shutting down PIM
@@ -186,6 +191,9 @@ static int pim_zebra_if_state_down(int command, struct zclient *zclient,
}
}
+ if (ifp->info)
+ pim_if_del_vif(ifp);
+
return 0;
}
@@ -220,7 +228,7 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
{
struct connected *c;
struct prefix *p;
- struct in_addr old = { .s_addr = 0 };
+ struct pim_interface *pim_ifp;
/*
zebra api notifies address adds/dels events by using the same call
@@ -234,10 +242,9 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
if (!c)
return 0;
+ pim_ifp = c->ifp->info;
p = c->address;
- if (p->family != AF_INET)
- return 0;
-
+
if (PIM_DEBUG_ZEBRA) {
char buf[BUFSIZ];
prefix2str(p, buf, BUFSIZ);
@@ -251,7 +258,25 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
#endif
}
- pim_rp_check_rp (old, p->u.prefix4);
+ if (p->family != AF_INET)
+ {
+ struct listnode *cnode;
+ struct connected *conn;
+ int v4addrs = 0;
+
+ for (ALL_LIST_ELEMENTS_RO (c->ifp->connected, cnode, conn))
+ {
+ if (conn->address->family == AF_INET)
+ v4addrs++;
+ }
+ if (!v4addrs && pim_ifp)
+ {
+ pim_ifp->primary_address = pim_find_primary_addr (c->ifp);
+ pim_if_addr_add_all (c->ifp);
+ pim_if_add_vif (c->ifp);
+ }
+ return 0;
+ }
if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
/* trying to add primary address */
@@ -262,20 +287,32 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
/* but we had a primary address already */
char buf[BUFSIZ];
- char old[100];
prefix2str(p, buf, BUFSIZ);
- pim_inet4_dump("<old?>", primary_addr, old, sizeof(old));
- zlog_warn("%s: %s primary addr old=%s: forcing secondary flag on new=%s",
+ zlog_warn("%s: %s : forcing secondary flag on %s",
__PRETTY_FUNCTION__,
- c->ifp->name, old, buf);
+ c->ifp->name, buf);
}
SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY);
}
}
pim_if_addr_add(c);
+ if (pim_ifp)
+ pim_rp_check_on_if_add(pim_ifp);
+
+ if (if_is_loopback (c->ifp))
+ {
+ struct listnode *ifnode;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
+ {
+ if (!if_is_loopback (ifp) && if_is_operative (ifp))
+ pim_if_addr_add_all (ifp);
+ }
+ }
return 0;
}
@@ -285,7 +322,6 @@ static int pim_zebra_if_address_del(int command, struct zclient *client,
{
struct connected *c;
struct prefix *p;
- struct in_addr new = { .s_addr = 0 };
/*
zebra api notifies address adds/dels events by using the same call
@@ -316,8 +352,9 @@ static int pim_zebra_if_address_del(int command, struct zclient *client,
#endif
}
- pim_rp_check_rp (p->u.prefix4, new);
pim_if_addr_del(c, 0);
+ pim_rp_setup();
+ pim_i_am_rp_re_evaluate();
return 0;
}
@@ -328,18 +365,37 @@ static void scan_upstream_rpf_cache()
struct listnode *up_nextnode;
struct pim_upstream *up;
- for (ALL_LIST_ELEMENTS(qpim_upstream_list, up_node, up_nextnode, up)) {
+ for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) {
struct in_addr old_rpf_addr;
+ struct interface *old_interface;
enum pim_rpf_result rpf_result;
- rpf_result = pim_rpf_update(up, &old_rpf_addr, NULL);
+ old_interface = up->rpf.source_nexthop.interface;
+ rpf_result = pim_rpf_update(up, &old_rpf_addr);
if (rpf_result == PIM_RPF_FAILURE)
continue;
if (rpf_result == PIM_RPF_CHANGED) {
-
+
+ /*
+ * We have detected a case where we might need to rescan
+ * the inherited o_list so do it.
+ */
+ if (up->channel_oil->oil_inherited_rescan)
+ {
+ pim_upstream_inherited_olist_decide (up);
+ up->channel_oil->oil_inherited_rescan = 0;
+ }
+
if (up->join_state == PIM_UPSTREAM_JOINED) {
-
+ /*
+ * If we come up real fast we can be here
+ * where the mroute has not been installed
+ * so install it.
+ */
+ if (!up->channel_oil->installed)
+ pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__);
+
/*
RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages
@@ -356,17 +412,13 @@ static void scan_upstream_rpf_cache()
/* send Prune(S,G) to the old upstream neighbor */
- pim_joinprune_send(up->rpf.source_nexthop.interface,
- old_rpf_addr,
- up->source_addr,
- up->group_addr,
- 0 /* prune */);
+ pim_joinprune_send(old_interface, old_rpf_addr,
+ up, 0 /* prune */);
/* send Join(S,G) to the current upstream neighbor */
pim_joinprune_send(up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr,
- up->source_addr,
- up->group_addr,
+ up->rpf.rpf_addr.u.prefix4,
+ up,
1 /* join */);
pim_upstream_join_timer_restart(up);
@@ -389,7 +441,7 @@ pim_scan_individual_oil (struct channel_oil *c_oil)
int input_iface_vif_index;
int old_vif_index;
- if (!pim_rp_set_upstream_addr (&vif_source, c_oil->oil.mfcc_origin))
+ if (!pim_rp_set_upstream_addr (&vif_source, c_oil->oil.mfcc_origin, c_oil->oil.mfcc_mcastgrp))
return;
input_iface_vif_index = fib_lookup_if_vif_index (vif_source);
@@ -397,20 +449,23 @@ pim_scan_individual_oil (struct channel_oil *c_oil)
{
if (PIM_DEBUG_ZEBRA)
{
- char source_str[100];
- char group_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
zlog_debug("%s %s: could not find input interface(%d) for (S,G)=(%s,%s)",
__FILE__, __PRETTY_FUNCTION__, c_oil->oil.mfcc_parent,
source_str, group_str);
}
- pim_mroute_del (c_oil);
+ pim_mroute_del (c_oil, __PRETTY_FUNCTION__);
return;
}
if (input_iface_vif_index == c_oil->oil.mfcc_parent)
{
+ if (!c_oil->installed)
+ pim_mroute_add (c_oil, __PRETTY_FUNCTION__);
+
/* RPF unchanged */
return;
}
@@ -419,15 +474,15 @@ pim_scan_individual_oil (struct channel_oil *c_oil)
{
struct interface *old_iif = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
- char source_str[100];
- char group_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
zlog_debug("%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d",
__FILE__, __PRETTY_FUNCTION__,
source_str, group_str,
- old_iif ? old_iif->name : "<old_iif?>", c_oil->oil.mfcc_parent,
- new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
+ old_iif->name, c_oil->oil.mfcc_parent,
+ new_iif->name, input_iface_vif_index);
}
/* new iif loops to existing oif ? */
@@ -436,39 +491,41 @@ pim_scan_individual_oil (struct channel_oil *c_oil)
struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
if (PIM_DEBUG_ZEBRA) {
- char source_str[100];
- char group_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
zlog_debug("%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d",
__FILE__, __PRETTY_FUNCTION__,
source_str, group_str,
- new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
+ new_iif->name, input_iface_vif_index);
}
- del_oif(c_oil, new_iif, PIM_OIF_FLAG_PROTO_ANY);
+ //del_oif(c_oil, new_iif, PIM_OIF_FLAG_PROTO_ANY);
}
/* update iif vif_index */
old_vif_index = c_oil->oil.mfcc_parent;
c_oil->oil.mfcc_parent = input_iface_vif_index;
- zlog_debug ("FF");
/* update kernel multicast forwarding cache (MFC) */
- if (pim_mroute_add(c_oil))
+ if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__))
{
- /* just log warning */
- struct interface *old_iif = pim_if_find_by_vif_index(old_vif_index);
- struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- zlog_warn("%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str,
- old_iif ? old_iif->name : "<old_iif?>", c_oil->oil.mfcc_parent,
- new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
+ if (PIM_DEBUG_MROUTE)
+ {
+ /* just log warning */
+ struct interface *old_iif = pim_if_find_by_vif_index(old_vif_index);
+ struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ zlog_debug("%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d",
+ __FILE__, __PRETTY_FUNCTION__,
+ source_str, group_str,
+ old_iif ? old_iif->name : "<old_iif?>", c_oil->oil.mfcc_parent,
+ new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
+ }
}
}
@@ -481,13 +538,12 @@ void pim_scan_oil()
qpim_scan_oil_last = pim_time_monotonic_sec();
++qpim_scan_oil_events;
- for (ALL_LIST_ELEMENTS(qpim_channel_oil_list, node, nextnode, c_oil))
+ for (ALL_LIST_ELEMENTS(pim_channel_oil_list, node, nextnode, c_oil))
pim_scan_individual_oil (c_oil);
}
static int on_rpf_cache_refresh(struct thread *t)
{
- zassert(t);
zassert(qpim_rpf_cache_refresher);
qpim_rpf_cache_refresher = 0;
@@ -501,13 +557,16 @@ static int on_rpf_cache_refresh(struct thread *t)
qpim_rpf_cache_refresh_last = pim_time_monotonic_sec();
++qpim_rpf_cache_refresh_events;
+ pim_rp_setup ();
return 0;
}
-static void sched_rpf_cache_refresh()
+void sched_rpf_cache_refresh(void)
{
++qpim_rpf_cache_refresh_requests;
+ pim_rpf_set_refresh_time ();
+
if (qpim_rpf_cache_refresher) {
/* Refresh timer is already running */
return;
@@ -575,17 +634,6 @@ static int redist_read_ipv4_route(int command, struct zclient *zclient,
CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : "");
}
- if (length < min_len) {
- zlog_warn("%s %s: short buffer: length=%d min_len=%d flags=%s%s%s%s",
- __FILE__, __PRETTY_FUNCTION__,
- length, min_len,
- CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? "nh" : "",
- CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? " ifi" : "",
- CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? " dist" : "",
- CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : "");
- return -1;
- }
-
/* IPv4 prefix. */
stream_get(&p.prefix, s, PSIZE(p.prefixlen));
@@ -654,6 +702,7 @@ static int redist_read_ipv4_route(int command, struct zclient *zclient,
sched_rpf_cache_refresh();
+ pim_rp_setup ();
return 0;
}
@@ -662,6 +711,7 @@ pim_zebra_connected (struct zclient *zclient)
{
zclient_send_reg_requests (zclient, VRF_DEFAULT);
}
+
void pim_zebra_init(char *zebra_sock_path)
{
int i;
@@ -676,31 +726,31 @@ void pim_zebra_init(char *zebra_sock_path)
#endif
/* Socket for receiving updates from Zebra daemon */
- qpim_zclient_update = zclient_new (master);
-
- qpim_zclient_update->zebra_connected = pim_zebra_connected;
- qpim_zclient_update->router_id_update = pim_router_id_update_zebra;
- qpim_zclient_update->interface_add = pim_zebra_if_add;
- qpim_zclient_update->interface_delete = pim_zebra_if_del;
- qpim_zclient_update->interface_up = pim_zebra_if_state_up;
- qpim_zclient_update->interface_down = pim_zebra_if_state_down;
- qpim_zclient_update->interface_address_add = pim_zebra_if_address_add;
- qpim_zclient_update->interface_address_delete = pim_zebra_if_address_del;
- qpim_zclient_update->redistribute_route_ipv4_add = redist_read_ipv4_route;
- qpim_zclient_update->redistribute_route_ipv4_del = redist_read_ipv4_route;
-
- zclient_init(qpim_zclient_update, ZEBRA_ROUTE_PIM, 0);
+ zclient = zclient_new (master);
+
+ zclient->zebra_connected = pim_zebra_connected;
+ zclient->router_id_update = pim_router_id_update_zebra;
+ zclient->interface_add = pim_zebra_if_add;
+ zclient->interface_delete = pim_zebra_if_del;
+ zclient->interface_up = pim_zebra_if_state_up;
+ zclient->interface_down = pim_zebra_if_state_down;
+ zclient->interface_address_add = pim_zebra_if_address_add;
+ zclient->interface_address_delete = pim_zebra_if_address_del;
+ zclient->redistribute_route_ipv4_add = redist_read_ipv4_route;
+ zclient->redistribute_route_ipv4_del = redist_read_ipv4_route;
+
+ zclient_init(zclient, ZEBRA_ROUTE_PIM, 0);
if (PIM_DEBUG_PIM_TRACE) {
zlog_info("zclient_init cleared redistribution request");
}
- zassert(qpim_zclient_update->redist_default == ZEBRA_ROUTE_PIM);
+ zassert(zclient->redist_default == ZEBRA_ROUTE_PIM);
/* Request all redistribution */
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (i == qpim_zclient_update->redist_default)
+ if (i == zclient->redist_default)
continue;
- vrf_bitmap_set (qpim_zclient_update->redist[AFI_IP][i], VRF_DEFAULT);;
+ vrf_bitmap_set (zclient->redist[AFI_IP][i], VRF_DEFAULT);;
if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("%s: requesting redistribution for %s (%i)",
__PRETTY_FUNCTION__, zebra_route_string(i), i);
@@ -709,7 +759,7 @@ void pim_zebra_init(char *zebra_sock_path)
/* Request default information */
zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
- qpim_zclient_update, VRF_DEFAULT);
+ zclient, VRF_DEFAULT);
if (PIM_DEBUG_PIM_TRACE) {
zlog_info("%s: requesting default information redistribution",
@@ -719,9 +769,7 @@ void pim_zebra_init(char *zebra_sock_path)
__PRETTY_FUNCTION__);
}
- zassert(!qpim_zclient_lookup);
- qpim_zclient_lookup = zclient_lookup_new();
- zassert(qpim_zclient_lookup);
+ zclient_lookup_new();
}
void igmp_anysource_forward_start(struct igmp_group *group)
@@ -754,36 +802,42 @@ void igmp_anysource_forward_stop(struct igmp_group *group)
static int fib_lookup_if_vif_index(struct in_addr addr)
{
- struct pim_zlookup_nexthop nexthop_tab[PIM_NEXTHOP_IFINDEX_TAB_SIZE];
+ struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
int num_ifindex;
int vif_index;
ifindex_t first_ifindex;
- num_ifindex = zclient_lookup_nexthop(qpim_zclient_lookup, nexthop_tab,
- PIM_NEXTHOP_IFINDEX_TAB_SIZE, addr,
+ num_ifindex = zclient_lookup_nexthop(nexthop_tab,
+ MULTIPATH_NUM, addr,
PIM_NEXTHOP_LOOKUP_MAX);
if (num_ifindex < 1) {
- char addr_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: could not find nexthop ifindex for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- addr_str);
+ if (PIM_DEBUG_ZEBRA)
+ {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug("%s %s: could not find nexthop ifindex for address %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ addr_str);
+ }
return -1;
}
first_ifindex = nexthop_tab[0].ifindex;
if (num_ifindex > 1) {
- char addr_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_info("%s %s: FIXME ignoring multiple nexthop ifindex'es num_ifindex=%d for address %s (using only ifindex=%d)",
- __FILE__, __PRETTY_FUNCTION__,
- num_ifindex, addr_str, first_ifindex);
+ if (PIM_DEBUG_ZEBRA)
+ {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug("%s %s: FIXME ignoring multiple nexthop ifindex'es num_ifindex=%d for address %s (using only ifindex=%d)",
+ __FILE__, __PRETTY_FUNCTION__,
+ num_ifindex, addr_str, first_ifindex);
+ }
/* debug warning only, do not return */
}
if (PIM_DEBUG_ZEBRA) {
- char addr_str[100];
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<ifaddr?>", addr, addr_str, sizeof(addr_str));
zlog_debug("%s %s: found nexthop ifindex=%d (interface %s) for address %s",
__FILE__, __PRETTY_FUNCTION__,
@@ -793,31 +847,17 @@ static int fib_lookup_if_vif_index(struct in_addr addr)
vif_index = pim_if_find_vifindex_by_ifindex(first_ifindex);
if (vif_index < 0) {
- char addr_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: low vif_index=%d < 1 nexthop for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- vif_index, addr_str);
+ if (PIM_DEBUG_ZEBRA)
+ {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug("%s %s: low vif_index=%d < 1 nexthop for address %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ vif_index, addr_str);
+ }
return -2;
}
- zassert(qpim_mroute_oif_highest_vif_index < MAXVIFS);
-
- if (vif_index > qpim_mroute_oif_highest_vif_index) {
- char addr_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: high vif_index=%d > highest_vif_index=%d nexthop for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- vif_index, qpim_mroute_oif_highest_vif_index, addr_str);
-
- zlog_warn("%s %s: pim disabled on interface %s vif_index=%d ?",
- __FILE__, __PRETTY_FUNCTION__,
- ifindex2ifname(vif_index),
- vif_index);
-
- return -3;
- }
-
return vif_index;
}
@@ -828,17 +868,11 @@ static int del_oif(struct channel_oil *channel_oil,
struct pim_interface *pim_ifp;
int old_ttl;
- zassert(channel_oil);
-
pim_ifp = oif->info;
- zassert(pim_ifp->mroute_vif_index >= 1);
- zassert(qpim_mroute_oif_highest_vif_index < MAXVIFS);
- zassert(pim_ifp->mroute_vif_index <= qpim_mroute_oif_highest_vif_index);
-
if (PIM_DEBUG_MROUTE) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d",
@@ -850,15 +884,18 @@ static int del_oif(struct channel_oil *channel_oil,
/* Prevent single protocol from unsubscribing same interface from
channel (S,G) multiple times */
if (!(channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask)) {
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_warn("%s %s: nonexistent protocol mask %u removed OIF %s (vif_index=%d, min_ttl=%d) from channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- proto_mask, oif->name, pim_ifp->mroute_vif_index,
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
- source_str, group_str);
+ if (PIM_DEBUG_MROUTE)
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_debug("%s %s: nonexistent protocol mask %u removed OIF %s (vif_index=%d, min_ttl=%d) from channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ proto_mask, oif->name, pim_ifp->mroute_vif_index,
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
return -2;
}
@@ -873,15 +910,18 @@ static int del_oif(struct channel_oil *channel_oil,
/* Check the OIF keeps existing before returning, and only log
warning otherwise */
if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) {
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_warn("%s %s: protocol mask %u removing nonexistent OIF %s (vif_index=%d, min_ttl=%d) from channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- proto_mask, oif->name, pim_ifp->mroute_vif_index,
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
- source_str, group_str);
+ if (PIM_DEBUG_MROUTE)
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_debug("%s %s: protocol mask %u removing nonexistent OIF %s (vif_index=%d, min_ttl=%d) from channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ proto_mask, oif->name, pim_ifp->mroute_vif_index,
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
}
return 0;
@@ -890,22 +930,25 @@ static int del_oif(struct channel_oil *channel_oil,
old_ttl = channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index];
if (old_ttl < 1) {
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_warn("%s %s: interface %s (vif_index=%d) is not output for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- oif->name, pim_ifp->mroute_vif_index,
- source_str, group_str);
+ if (PIM_DEBUG_MROUTE)
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_debug("%s %s: interface %s (vif_index=%d) is not output for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ oif->name, pim_ifp->mroute_vif_index,
+ source_str, group_str);
+ }
return -3;
}
channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = 0;
- if (pim_mroute_add(channel_oil)) {
- char group_str[100];
- char source_str[100];
+ if (pim_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
zlog_warn("%s %s: could not remove output interface %s (vif_index=%d) from channel (S,G)=(%s,%s)",
@@ -920,21 +963,24 @@ static int del_oif(struct channel_oil *channel_oil,
--channel_oil->oil_size;
if (channel_oil->oil_size < 1) {
- if (pim_mroute_del(channel_oil)) {
- /* just log a warning in case of failure */
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_warn("%s %s: failure removing OIL for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str);
+ if (pim_mroute_del(channel_oil, __PRETTY_FUNCTION__)) {
+ if (PIM_DEBUG_MROUTE)
+ {
+ /* just log a warning in case of failure */
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_debug("%s %s: failure removing OIL for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ source_str, group_str);
+ }
}
}
if (PIM_DEBUG_MROUTE) {
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d: DONE",
@@ -949,16 +995,17 @@ static int del_oif(struct channel_oil *channel_oil,
void igmp_source_forward_start(struct igmp_source *source)
{
struct igmp_group *group;
+ struct prefix_sg sg;
int result;
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = source->source_addr;
+ sg.grp = source->source_group->group_addr;
+
if (PIM_DEBUG_IGMP_TRACE) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: (S,G)=(%s,%s) igmp_sock=%d oif=%s fwd=%d",
+ zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
__PRETTY_FUNCTION__,
- source_str, group_str,
+ pim_str_sg_dump (&sg),
source->source_group->group_igmp_sock->fd,
source->source_group->group_igmp_sock->interface->name,
IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
@@ -976,16 +1023,19 @@ void igmp_source_forward_start(struct igmp_source *source)
struct in_addr vif_source;
struct pim_interface *pim_oif;
- if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr))
+ if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr, sg.grp))
return;
int input_iface_vif_index = fib_lookup_if_vif_index(vif_source);
if (input_iface_vif_index < 1) {
- char source_str[100];
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s %s: could not find input interface for source %s",
- __FILE__, __PRETTY_FUNCTION__,
- source_str);
+ if (PIM_DEBUG_IGMP_TRACE)
+ {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
+ zlog_debug("%s %s: could not find input interface for source %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ source_str);
+ }
return;
}
@@ -996,28 +1046,21 @@ void igmp_source_forward_start(struct igmp_source *source)
*/
pim_oif = source->source_group->group_igmp_sock->interface->info;
if (!pim_oif) {
- zlog_warn("%s: multicast not enabled on oif=%s ?",
- __PRETTY_FUNCTION__,
- source->source_group->group_igmp_sock->interface->name);
- return;
- }
- if (pim_oif->mroute_vif_index < 1) {
- zlog_warn("%s %s: oif=%s vif_index=%d < 1",
- __FILE__, __PRETTY_FUNCTION__,
- source->source_group->group_igmp_sock->interface->name,
- pim_oif->mroute_vif_index);
+ if (PIM_DEBUG_IGMP_TRACE)
+ {
+ zlog_debug("%s: multicast not enabled on oif=%s ?",
+ __PRETTY_FUNCTION__,
+ source->source_group->group_igmp_sock->interface->name);
+ }
return;
}
+
if (input_iface_vif_index == pim_oif->mroute_vif_index) {
/* ignore request for looped MFC entry */
if (PIM_DEBUG_IGMP_TRACE) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: ignoring request for looped MFC entry (S,G)=(%s,%s): igmp_sock=%d oif=%s vif_index=%d",
+ zlog_debug("%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d",
__PRETTY_FUNCTION__,
- source_str, group_str,
+ pim_str_sg_dump (&sg),
source->source_group->group_igmp_sock->fd,
source->source_group->group_igmp_sock->interface->name,
input_iface_vif_index);
@@ -1025,17 +1068,15 @@ void igmp_source_forward_start(struct igmp_source *source)
return;
}
- source->source_channel_oil = pim_channel_oil_add(group->group_addr,
- source->source_addr,
+ source->source_channel_oil = pim_channel_oil_add(&sg,
input_iface_vif_index);
if (!source->source_channel_oil) {
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s %s: could not create OIL for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str);
+ if (PIM_DEBUG_IGMP_TRACE)
+ {
+ zlog_debug("%s %s: could not create OIL for channel (S,G)=%s",
+ __FILE__, __PRETTY_FUNCTION__,
+ pim_str_sg_dump (&sg));
+ }
return;
}
}
@@ -1044,8 +1085,11 @@ void igmp_source_forward_start(struct igmp_source *source)
group->group_igmp_sock->interface,
PIM_OIF_FLAG_PROTO_IGMP);
if (result) {
- zlog_warn("%s: add_oif() failed with return=%d",
- __func__, result);
+ if (PIM_DEBUG_MROUTE)
+ {
+ zlog_warn("%s: add_oif() failed with return=%d",
+ __func__, result);
+ }
return;
}
@@ -1053,8 +1097,13 @@ void igmp_source_forward_start(struct igmp_source *source)
Feed IGMPv3-gathered local membership information into PIM
per-interface (S,G) state.
*/
- pim_ifchannel_local_membership_add(group->group_igmp_sock->interface,
- source->source_addr, group->group_addr);
+ if (!pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, &sg))
+ {
+ if (PIM_DEBUG_MROUTE)
+ zlog_warn ("%s: Failure to add local membership for %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
+ return;
+ }
IGMP_SOURCE_DO_FORWARDING(source->source_flags);
}
@@ -1066,16 +1115,17 @@ void igmp_source_forward_start(struct igmp_source *source)
void igmp_source_forward_stop(struct igmp_source *source)
{
struct igmp_group *group;
+ struct prefix_sg sg;
int result;
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = source->source_addr;
+ sg.grp = source->source_group->group_addr;
+
if (PIM_DEBUG_IGMP_TRACE) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: (S,G)=(%s,%s) igmp_sock=%d oif=%s fwd=%d",
+ zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
__PRETTY_FUNCTION__,
- source_str, group_str,
+ pim_str_sg_dump (&sg),
source->source_group->group_igmp_sock->fd,
source->source_group->group_igmp_sock->interface->name,
IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
@@ -1104,8 +1154,9 @@ void igmp_source_forward_stop(struct igmp_source *source)
group->group_igmp_sock->interface,
PIM_OIF_FLAG_PROTO_IGMP);
if (result) {
- zlog_warn("%s: del_oif() failed with return=%d",
- __func__, result);
+ if (PIM_DEBUG_IGMP_TRACE)
+ zlog_debug("%s: del_oif() failed with return=%d",
+ __func__, result);
return;
}
@@ -1114,7 +1165,7 @@ void igmp_source_forward_stop(struct igmp_source *source)
per-interface (S,G) state.
*/
pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
- source->source_addr, group->group_addr);
+ &sg);
IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
}
@@ -1122,14 +1173,15 @@ void igmp_source_forward_stop(struct igmp_source *source)
void pim_forward_start(struct pim_ifchannel *ch)
{
struct pim_upstream *up = ch->upstream;
+ uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
if (PIM_DEBUG_PIM_TRACE) {
- char source_str[100];
- char group_str[100];
- char upstream_str[100];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ char upstream_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", ch->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", ch->group_addr, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", ch->sg.src, source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", ch->sg.grp, group_str, sizeof(group_str));
pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str, sizeof(upstream_str));
zlog_debug("%s: (S,G)=(%s,%s) oif=%s(%s)",
__PRETTY_FUNCTION__,
@@ -1139,31 +1191,32 @@ void pim_forward_start(struct pim_ifchannel *ch)
if (!up->channel_oil) {
int input_iface_vif_index = fib_lookup_if_vif_index(up->upstream_addr);
if (input_iface_vif_index < 1) {
- char source_str[100];
- pim_inet4_dump("<source?>", up->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s %s: could not find input interface for source %s",
- __FILE__, __PRETTY_FUNCTION__,
- source_str);
+ if (PIM_DEBUG_PIM_TRACE)
+ {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", up->sg.src, source_str, sizeof(source_str));
+ zlog_debug("%s %s: could not find input interface for source %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ source_str);
+ }
return;
}
- up->channel_oil = pim_channel_oil_add(up->group_addr, up->source_addr,
+ up->channel_oil = pim_channel_oil_add(&up->sg,
input_iface_vif_index);
if (!up->channel_oil) {
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", up->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", up->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s %s: could not create OIL for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str);
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s %s: could not create OIL for channel (S,G)=%s",
+ __FILE__, __PRETTY_FUNCTION__,
+ up->sg_str);
return;
}
}
- pim_channel_add_oif(up->channel_oil,
- ch->interface,
- PIM_OIF_FLAG_PROTO_PIM);
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+ mask = PIM_OIF_FLAG_PROTO_IGMP;
+
+ pim_channel_add_oif(up->channel_oil, ch->interface, mask);
}
void pim_forward_stop(struct pim_ifchannel *ch)
@@ -1171,23 +1224,16 @@ void pim_forward_stop(struct pim_ifchannel *ch)
struct pim_upstream *up = ch->upstream;
if (PIM_DEBUG_PIM_TRACE) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", ch->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", ch->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: (S,G)=(%s,%s) oif=%s",
+ zlog_debug("%s: (S,G)=%s oif=%s",
__PRETTY_FUNCTION__,
- source_str, group_str, ch->interface->name);
+ ch->sg_str, ch->interface->name);
}
if (!up->channel_oil) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", ch->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", ch->group_addr, group_str, sizeof(group_str));
- zlog_warn("%s: (S,G)=(%s,%s) oif=%s missing channel OIL",
- __PRETTY_FUNCTION__,
- source_str, group_str, ch->interface->name);
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: (S,G)=%s oif=%s missing channel OIL",
+ __PRETTY_FUNCTION__,
+ ch->sg_str, ch->interface->name);
return;
}
@@ -1196,3 +1242,17 @@ void pim_forward_stop(struct pim_ifchannel *ch)
ch->interface,
PIM_OIF_FLAG_PROTO_PIM);
}
+
+void
+pim_zebra_zclient_update (struct vty *vty)
+{
+ vty_out(vty, "Zclient update socket: ");
+
+ if (zclient) {
+ vty_out(vty, "%d failures=%d%s", zclient->sock,
+ zclient->fail, VTY_NEWLINE);
+ }
+ else {
+ vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
+ }
+}
diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h
index 257c9b896f..476185def1 100644
--- a/pimd/pim_zebra.h
+++ b/pimd/pim_zebra.h
@@ -25,6 +25,7 @@
#include "pim_ifchannel.h"
void pim_zebra_init(char *zebra_sock_path);
+void pim_zebra_zclient_update (struct vty *vty);
void pim_scan_individual_oil (struct channel_oil *c_oil);
void pim_scan_oil(void);
@@ -38,4 +39,5 @@ void igmp_source_forward_stop(struct igmp_source *source);
void pim_forward_start(struct pim_ifchannel *ch);
void pim_forward_stop(struct pim_ifchannel *ch);
+void sched_rpf_cache_refresh(void);
#endif /* PIM_ZEBRA_H */
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index af561a0b62..e1a8e820b7 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -27,13 +27,17 @@
#include "stream.h"
#include "network.h"
#include "thread.h"
+#include "prefix.h"
+#include "vty.h"
#include "pimd.h"
+#include "pim_iface.h"
#include "pim_pim.h"
#include "pim_str.h"
+#include "pim_oil.h"
#include "pim_zlookup.h"
-extern int zclient_debug;
+static struct zclient *zlookup = NULL;
static void zclient_lookup_sched(struct zclient *zlookup, int delay);
@@ -116,28 +120,31 @@ static void zclient_lookup_failed(struct zclient *zlookup)
zclient_lookup_reconnect(zlookup);
}
-struct zclient *zclient_lookup_new()
+void
+zclient_lookup_free (void)
{
- struct zclient *zlookup;
+ zclient_free (zlookup);
+ zlookup = NULL;
+}
+void
+zclient_lookup_new (void)
+{
zlookup = zclient_new (master);
if (!zlookup) {
zlog_err("%s: zclient_new() failure",
__PRETTY_FUNCTION__);
- return 0;
+ return;
}
zlookup->sock = -1;
- zlookup->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zlookup->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zlookup->t_connect = 0;
+ zlookup->t_connect = NULL;
zclient_lookup_sched_now(zlookup);
zlog_notice("%s: zclient lookup socket initialized",
__PRETTY_FUNCTION__);
- return zlookup;
}
static int zclient_read_nexthop(struct zclient *zlookup,
@@ -159,8 +166,8 @@ static int zclient_read_nexthop(struct zclient *zlookup,
int nexthop_num;
int i, err;
- if (PIM_DEBUG_ZEBRA) {
- char addr_str[100];
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
zlog_debug("%s: addr=%s",
__PRETTY_FUNCTION__,
@@ -192,8 +199,8 @@ static int zclient_read_nexthop(struct zclient *zlookup,
raddr.s_addr = stream_get_ipv4(s);
if (raddr.s_addr != addr.s_addr) {
- char addr_str[100];
- char raddr_str[100];
+ char addr_str[INET_ADDRSTRLEN];
+ char raddr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str));
zlog_warn("%s: address mismatch: addr=%s raddr=%s",
@@ -212,77 +219,52 @@ static int zclient_read_nexthop(struct zclient *zlookup,
return -6;
}
- length -= MIN_LEN;
-
for (i = 0; i < nexthop_num; ++i) {
enum nexthop_types_t nexthop_type;
+ struct pim_neighbor *nbr;
- if (length < 1) {
- zlog_err("%s: socket %d empty input expecting nexthop_type: len=%d",
- __func__, zlookup->sock, length);
- return -7;
- }
-
nexthop_type = stream_getc(s);
- --length;
-
+ if (num_ifindex >= tab_size) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ (num_ifindex + 1), tab_size, addr_str);
+ return num_ifindex;
+ }
switch (nexthop_type) {
case NEXTHOP_TYPE_IFINDEX:
case NEXTHOP_TYPE_IPV4_IFINDEX:
- if (num_ifindex >= tab_size) {
- char addr_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- (num_ifindex + 1), tab_size, addr_str);
- return num_ifindex;
- }
- if (nexthop_type == NEXTHOP_TYPE_IPV4_IFINDEX) {
- if (length < 4) {
- zlog_err("%s: socket %d short input expecting nexthop IPv4-addr: len=%d",
- __func__, zlookup->sock, length);
- return -8;
- }
- nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s);
- length -= 4;
+ case NEXTHOP_TYPE_IPV4:
+ nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
+ if (nexthop_type == NEXTHOP_TYPE_IPV4_IFINDEX ||
+ nexthop_type == NEXTHOP_TYPE_IPV4) {
+ nexthop_tab[num_ifindex].nexthop_addr.u.prefix4.s_addr = stream_get_ipv4(s);
}
else {
- nexthop_tab[num_ifindex].nexthop_addr.s_addr = PIM_NET_INADDR_ANY;
+ nexthop_tab[num_ifindex].nexthop_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY;
}
nexthop_tab[num_ifindex].ifindex = stream_getl(s);
nexthop_tab[num_ifindex].protocol_distance = distance;
nexthop_tab[num_ifindex].route_metric = metric;
++num_ifindex;
break;
- case NEXTHOP_TYPE_IPV4:
- if (num_ifindex >= tab_size) {
- char addr_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- (num_ifindex + 1), tab_size, addr_str);
- return num_ifindex;
- }
- nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s);
- length -= 4;
- nexthop_tab[num_ifindex].ifindex = 0;
- nexthop_tab[num_ifindex].protocol_distance = distance;
- nexthop_tab[num_ifindex].route_metric = metric;
- if (PIM_DEBUG_ZEBRA) {
- char addr_str[100];
- char nexthop_str[100];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- pim_inet4_dump("<nexthop?>", nexthop_tab[num_ifindex].nexthop_addr, nexthop_str, sizeof(nexthop_str));
- zlog_debug("%s %s: zebra returned recursive nexthop %s for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- nexthop_str, addr_str);
- }
- ++num_ifindex;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET6;
+ stream_get (&nexthop_tab[num_ifindex].nexthop_addr.u.prefix6, s, 16);
+ nexthop_tab[num_ifindex].ifindex = stream_getl (s);
+ nbr = pim_neighbor_find_if (if_lookup_by_index_vrf (nexthop_tab[num_ifindex].ifindex, VRF_DEFAULT));
+ if (nbr)
+ {
+ nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
+ nexthop_tab[num_ifindex].nexthop_addr.u.prefix4 = nbr->source_addr;
+ }
+ ++num_ifindex;
break;
default:
/* do nothing */
{
- char addr_str[100];
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
zlog_warn("%s %s: found non-ifindex nexthop type=%d for address %s",
__FILE__, __PRETTY_FUNCTION__,
@@ -295,16 +277,16 @@ static int zclient_read_nexthop(struct zclient *zlookup,
return num_ifindex;
}
-static int zclient_lookup_nexthop_once(struct zclient *zlookup,
- struct pim_zlookup_nexthop nexthop_tab[],
- const int tab_size,
- struct in_addr addr)
+static int
+zclient_lookup_nexthop_once (struct pim_zlookup_nexthop nexthop_tab[],
+ const int tab_size,
+ struct in_addr addr)
{
struct stream *s;
int ret;
- if (PIM_DEBUG_ZEBRA) {
- char addr_str[100];
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
zlog_debug("%s: addr=%s",
__PRETTY_FUNCTION__,
@@ -327,8 +309,8 @@ static int zclient_lookup_nexthop_once(struct zclient *zlookup,
ret = writen(zlookup->sock, s->data, stream_get_endp(s));
if (ret < 0) {
- zlog_err("%s %s: writen() failure writing to zclient lookup socket",
- __FILE__, __PRETTY_FUNCTION__);
+ zlog_err("%s %s: writen() failure: %d writing to zclient lookup socket",
+ __FILE__, __PRETTY_FUNCTION__, errno);
zclient_lookup_failed(zlookup);
return -2;
}
@@ -343,26 +325,28 @@ static int zclient_lookup_nexthop_once(struct zclient *zlookup,
tab_size, addr);
}
-int zclient_lookup_nexthop(struct zclient *zlookup,
- struct pim_zlookup_nexthop nexthop_tab[],
- const int tab_size,
- struct in_addr addr,
- int max_lookup)
+int
+zclient_lookup_nexthop (struct pim_zlookup_nexthop nexthop_tab[],
+ const int tab_size,
+ struct in_addr addr,
+ int max_lookup)
{
int lookup;
uint32_t route_metric = 0xFFFFFFFF;
uint8_t protocol_distance = 0xFF;
+ qpim_nexthop_lookups++;
+
for (lookup = 0; lookup < max_lookup; ++lookup) {
int num_ifindex;
int first_ifindex;
- struct in_addr nexthop_addr;
+ struct prefix nexthop_addr;
- num_ifindex = zclient_lookup_nexthop_once(qpim_zclient_lookup, nexthop_tab,
- PIM_NEXTHOP_IFINDEX_TAB_SIZE, addr);
+ num_ifindex = zclient_lookup_nexthop_once(nexthop_tab,
+ tab_size, addr);
if (num_ifindex < 1) {
if (PIM_DEBUG_ZEBRA) {
- char addr_str[100];
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
zlog_debug("%s %s: lookup=%d/%d: could not find nexthop ifindex for address %s",
__FILE__, __PRETTY_FUNCTION__,
@@ -378,9 +362,13 @@ int zclient_lookup_nexthop(struct zclient *zlookup,
}
/*
- FIXME: Non-recursive nexthop ensured only for first ifindex.
- However, recursive route lookup should really be fixed in zebra daemon.
- See also TODO T24.
+ * FIXME: Non-recursive nexthop ensured only for first ifindex.
+ * However, recursive route lookup should really be fixed in zebra daemon.
+ * See also TODO T24.
+ *
+ * So Zebra for NEXTHOP_TYPE_IPV4 returns the ifindex now since
+ * it was being stored. This Doesn't solve all cases of
+ * recursive lookup but for the most common types it does.
*/
first_ifindex = nexthop_tab[0].ifindex;
nexthop_addr = nexthop_tab[0].nexthop_addr;
@@ -390,7 +378,7 @@ int zclient_lookup_nexthop(struct zclient *zlookup,
if (lookup > 0) {
/* Report non-recursive success after first lookup */
if (PIM_DEBUG_ZEBRA) {
- char addr_str[100];
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
zlog_debug("%s %s: lookup=%d/%d: found non-recursive ifindex=%d for address %s dist=%d met=%d",
__FILE__, __PRETTY_FUNCTION__,
@@ -400,7 +388,7 @@ int zclient_lookup_nexthop(struct zclient *zlookup,
}
/* use last address as nexthop address */
- nexthop_tab[0].nexthop_addr = addr;
+ nexthop_tab[0].nexthop_addr.u.prefix4 = addr;
/* report original route metric/distance */
nexthop_tab[0].route_metric = route_metric;
@@ -411,10 +399,10 @@ int zclient_lookup_nexthop(struct zclient *zlookup,
}
if (PIM_DEBUG_ZEBRA) {
- char addr_str[100];
- char nexthop_str[100];
+ char addr_str[INET_ADDRSTRLEN];
+ char nexthop_str[PREFIX_STRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- pim_inet4_dump("<nexthop?>", nexthop_addr, nexthop_str, sizeof(nexthop_str));
+ pim_addr_dump("<nexthop?>", &nexthop_addr, nexthop_str, sizeof(nexthop_str));
zlog_debug("%s %s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s dist=%d met=%d",
__FILE__, __PRETTY_FUNCTION__,
lookup, max_lookup, nexthop_str, addr_str,
@@ -422,12 +410,12 @@ int zclient_lookup_nexthop(struct zclient *zlookup,
nexthop_tab[0].route_metric);
}
- addr = nexthop_addr; /* use nexthop addr for recursive lookup */
+ addr = nexthop_addr.u.prefix4; /* use nexthop addr for recursive lookup */
} /* for (max_lookup) */
if (PIM_DEBUG_ZEBRA) {
- char addr_str[100];
+ char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
zlog_warn("%s %s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s",
__FILE__, __PRETTY_FUNCTION__,
@@ -436,3 +424,100 @@ int zclient_lookup_nexthop(struct zclient *zlookup,
return -2;
}
+
+void
+pim_zlookup_show_ip_multicast (struct vty *vty)
+{
+ vty_out(vty, "Zclient lookup socket: ");
+ if (zlookup) {
+ vty_out(vty, "%d failures=%d%s", zlookup->sock,
+ zlookup->fail, VTY_NEWLINE);
+ }
+ else {
+ vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
+ }
+}
+
+int
+pim_zlookup_sg_statistics (struct channel_oil *c_oil)
+{
+ struct stream *s = zlookup->obuf;
+ uint16_t command = 0;
+ unsigned long long lastused;
+ struct prefix_sg sg;
+ int count = 0;
+ int ret;
+ struct interface *ifp = pim_if_find_by_vif_index (c_oil->oil.mfcc_parent);
+
+ if (PIM_DEBUG_ZEBRA)
+ {
+ struct prefix_sg more;
+
+ more.src = c_oil->oil.mfcc_origin;
+ more.grp = c_oil->oil.mfcc_mcastgrp;
+ zlog_debug ("Sending Request for New Channel Oil Information(%s)", pim_str_sg_dump (&more));
+ }
+
+ if (!ifp)
+ return -1;
+
+ stream_reset (s);
+ zclient_create_header (s, ZEBRA_IPMR_ROUTE_STATS, VRF_DEFAULT);
+ stream_put_in_addr (s, &c_oil->oil.mfcc_origin);
+ stream_put_in_addr (s, &c_oil->oil.mfcc_mcastgrp);
+ stream_putl (s, ifp->ifindex);
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ count = stream_get_endp (s);
+ ret = writen (zlookup->sock, s->data, count);
+ if (ret <= 0)
+ {
+ zlog_err("%s %s: writen() failure: %d writing to zclient lookup socket",
+ __FILE__, __PRETTY_FUNCTION__, errno);
+ return -1;
+ }
+
+ s = zlookup->ibuf;
+
+ while (command != ZEBRA_IPMR_ROUTE_STATS)
+ {
+ int err;
+ uint16_t length = 0;
+ vrf_id_t vrf_id;
+ u_char marker;
+ u_char version;
+
+ stream_reset (s);
+ err = zclient_read_header (s, zlookup->sock, &length, &marker, &version,
+ &vrf_id, &command);
+ if (err < 0)
+ {
+ zlog_err ("%s %s: zclient_read_header() failed",
+ __FILE__, __PRETTY_FUNCTION__);
+ zclient_lookup_failed(zlookup);
+ return -1;
+ }
+ }
+
+ sg.src.s_addr = stream_get_ipv4 (s);
+ sg.grp.s_addr = stream_get_ipv4 (s);
+ if (sg.src.s_addr != c_oil->oil.mfcc_origin.s_addr ||
+ sg.grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr)
+ {
+ zlog_err ("%s: Received wrong %s information",
+ __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
+ zclient_lookup_failed (zlookup);
+ return -3;
+ }
+
+ stream_get (&lastused, s, sizeof (lastused));
+ ret = stream_getl (s);
+
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug ("Received %lld for %s success: %d", lastused, pim_str_sg_dump (&sg), ret);
+
+ c_oil->cc.lastused = lastused;
+
+ return 0;
+
+}
diff --git a/pimd/pim_zlookup.h b/pimd/pim_zlookup.h
index dbce92647b..34b1434c66 100644
--- a/pimd/pim_zlookup.h
+++ b/pimd/pim_zlookup.h
@@ -28,18 +28,21 @@
#define PIM_NEXTHOP_LOOKUP_MAX (3) /* max. recursive route lookup */
struct pim_zlookup_nexthop {
- struct in_addr nexthop_addr;
+ struct prefix nexthop_addr;
ifindex_t ifindex;
uint32_t route_metric;
uint8_t protocol_distance;
};
-struct zclient *zclient_lookup_new(void);
+void zclient_lookup_new (void);
+void zclient_lookup_free (void);
-int zclient_lookup_nexthop(struct zclient *zlookup,
- struct pim_zlookup_nexthop nexthop_tab[],
+int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
const int tab_size,
struct in_addr addr,
int max_lookup);
+void pim_zlookup_show_ip_multicast (struct vty *vty);
+
+int pim_zlookup_sg_statistics (struct channel_oil *c_oil);
#endif /* PIM_ZLOOKUP_H */
diff --git a/pimd/pimd.c b/pimd/pimd.c
index 15e52afc1d..2316cd08f5 100644
--- a/pimd/pimd.c
+++ b/pimd/pimd.c
@@ -23,6 +23,9 @@
#include "log.h"
#include "memory.h"
#include "if.h"
+#include "prefix.h"
+#include "vty.h"
+#include "plist.h"
#include "pimd.h"
#include "pim_cmd.h"
@@ -35,6 +38,8 @@
#include "pim_rpf.h"
#include "pim_ssmpingd.h"
#include "pim_static.h"
+#include "pim_rp.h"
+#include "pim_zlookup.h"
const char *const PIM_ALL_SYSTEMS = MCAST_ALL_SYSTEMS;
const char *const PIM_ALL_ROUTERS = MCAST_ALL_ROUTERS;
@@ -45,21 +50,15 @@ struct thread_master *master = NULL;
uint32_t qpim_debugs = 0;
int qpim_mroute_socket_fd = -1;
int64_t qpim_mroute_socket_creation = 0; /* timestamp of creation */
-struct thread *qpim_mroute_socket_reader = 0;
-int qpim_mroute_oif_highest_vif_index = -1;
-struct list *qpim_channel_oil_list = 0;
int qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */
-struct list *qpim_upstream_list = 0;
-struct zclient *qpim_zclient_update = 0;
-struct zclient *qpim_zclient_lookup = 0;
struct pim_assert_metric qpim_infinite_assert_metric;
-long qpim_rpf_cache_refresh_delay_msec = 10000;
-struct thread *qpim_rpf_cache_refresher = 0;
+long qpim_rpf_cache_refresh_delay_msec = 50;
+struct thread *qpim_rpf_cache_refresher = NULL;
int64_t qpim_rpf_cache_refresh_requests = 0;
int64_t qpim_rpf_cache_refresh_events = 0;
int64_t qpim_rpf_cache_refresh_last = 0;
struct in_addr qpim_inaddr_any;
-struct list *qpim_ssmpingd_list = 0;
+struct list *qpim_ssmpingd_list = NULL;
struct in_addr qpim_ssmpingd_group_addr;
int64_t qpim_scan_oil_events = 0;
int64_t qpim_scan_oil_last = 0;
@@ -67,8 +66,11 @@ int64_t qpim_mroute_add_events = 0;
int64_t qpim_mroute_add_last = 0;
int64_t qpim_mroute_del_events = 0;
int64_t qpim_mroute_del_last = 0;
-struct list *qpim_static_route_list = 0;
-struct pim_rpf qpim_rp = { .rpf_addr.s_addr = INADDR_NONE };
+struct list *qpim_static_route_list = NULL;
+unsigned int qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
+signed int qpim_rp_keep_alive_time = 0;
+int64_t qpim_nexthop_lookups = 0;
+int qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
int32_t qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
int32_t qpim_register_probe_time = PIM_REGISTER_PROBE_TIME_DEFAULT;
@@ -77,22 +79,31 @@ static void pim_free()
{
pim_ssmpingd_destroy();
- if (qpim_channel_oil_list)
- list_free(qpim_channel_oil_list);
+ pim_oil_terminate ();
- if (qpim_upstream_list)
- list_free(qpim_upstream_list);
+ pim_upstream_terminate ();
if (qpim_static_route_list)
list_free(qpim_static_route_list);
+ pim_if_terminate ();
+ pim_rp_free ();
+
pim_route_map_terminate();
+
+ zclient_lookup_free ();
+
+ zprivs_terminate(&pimd_privs);
}
void pim_init()
{
srandom(time(NULL));
+ qpim_rp_keep_alive_time = PIM_RP_KEEPALIVE_PERIOD;
+
+ pim_rp_init ();
+
if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) {
zlog_err("%s %s: could not solve %s to group address: errno=%d: %s",
__FILE__, __PRETTY_FUNCTION__,
@@ -101,22 +112,9 @@ void pim_init()
return;
}
- qpim_channel_oil_list = list_new();
- if (!qpim_channel_oil_list) {
- zlog_err("%s %s: failure: channel_oil_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return;
- }
- qpim_channel_oil_list->del = (void (*)(void *)) pim_channel_oil_free;
+ pim_oil_init ();
- qpim_upstream_list = list_new();
- if (!qpim_upstream_list) {
- zlog_err("%s %s: failure: upstream_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- pim_free();
- return;
- }
- qpim_upstream_list->del = (void (*)(void *)) pim_upstream_free;
+ pim_upstream_init ();
qpim_static_route_list = list_new();
if (!qpim_static_route_list) {
@@ -127,10 +125,6 @@ void pim_init()
qpim_static_route_list->del = (void (*)(void *)) pim_static_route_free;
qpim_mroute_socket_fd = -1; /* mark mroute as disabled */
- qpim_mroute_oif_highest_vif_index = -1;
-
- zassert(!qpim_debugs);
- zassert(!PIM_MROUTE_IS_ENABLED);
qpim_inaddr_any.s_addr = PIM_NET_INADDR_ANY;
diff --git a/pimd/pimd.h b/pimd/pimd.h
index 2230a6ce91..1f8dcdfb29 100644
--- a/pimd/pimd.h
+++ b/pimd/pimd.h
@@ -23,13 +23,13 @@
#include <stdint.h>
+#include "pim_str.h"
#include "pim_memory.h"
#include "pim_assert.h"
#define PIMD_PROGNAME "pimd"
#define PIMD_DEFAULT_CONFIG "pimd.conf"
#define PIMD_VTY_PORT 2611
-#define PIMD_BUG_ADDRESS "https://github.com/udhos/qpimd"
#define PIM_IP_HEADER_MIN_LEN (20)
#define PIM_IP_HEADER_MAX_LEN (60)
@@ -51,6 +51,8 @@
#define PIM_INADDR_IS_ANY(addr) (addr).s_addr == PIM_NET_INADDR_ANY
#define PIM_INADDR_ISNOT_ANY(addr) ((addr).s_addr != PIM_NET_INADDR_ANY) /* struct in_addr addr */
+#define max(x,y) ((x) > (y) ? (x) : (y))
+
#define PIM_MASK_PIM_EVENTS (1 << 0)
#define PIM_MASK_PIM_EVENTS_DETAIL (1 << 1)
#define PIM_MASK_PIM_PACKETS (1 << 2)
@@ -65,9 +67,28 @@
#define PIM_MASK_ZEBRA (1 << 11)
#define PIM_MASK_SSMPINGD (1 << 12)
#define PIM_MASK_MROUTE (1 << 13)
-#define PIM_MASK_PIM_HELLO (1 << 14)
-#define PIM_MASK_PIM_J_P (1 << 15)
-#define PIM_MASK_STATIC (1 << 16)
+#define PIM_MASK_MROUTE_DETAIL (1 << 14)
+#define PIM_MASK_PIM_HELLO (1 << 15)
+#define PIM_MASK_PIM_J_P (1 << 16)
+#define PIM_MASK_STATIC (1 << 17)
+#define PIM_MASK_PIM_REG (1 << 18)
+#define PIM_MASK_MSDP_EVENTS (1 << 19)
+#define PIM_MASK_MSDP_PACKETS (1 << 20)
+#define PIM_MASK_MSDP_INTERNAL (1 << 21)
+
+
+/* PIM error codes */
+#define PIM_SUCCESS 0
+#define PIM_MALLOC_FAIL -1
+#define PIM_GROUP_BAD_ADDRESS -2
+#define PIM_GROUP_OVERLAP -3
+#define PIM_GROUP_PFXLIST_OVERLAP -4
+#define PIM_RP_BAD_ADDRESS -5
+#define PIM_RP_NO_PATH -6
+#define PIM_RP_NOT_FOUND -7
+#define PIM_RP_PFXLIST_IN_USE -8
+#define PIM_IFACE_NOT_FOUND -9
+#define PIM_UPDATE_SOURCE_DUP -10
const char *const PIM_ALL_SYSTEMS;
const char *const PIM_ALL_ROUTERS;
@@ -75,17 +96,12 @@ const char *const PIM_ALL_PIM_ROUTERS;
const char *const PIM_ALL_IGMP_ROUTERS;
extern struct thread_master *master;
+extern struct zebra_privs_t pimd_privs;
uint32_t qpim_debugs;
int qpim_mroute_socket_fd;
int64_t qpim_mroute_socket_creation; /* timestamp of creation */
-struct thread *qpim_mroute_socket_reader;
-int qpim_mroute_oif_highest_vif_index;
-struct list *qpim_channel_oil_list; /* list of struct channel_oil */
struct in_addr qpim_all_pim_routers_addr;
int qpim_t_periodic; /* Period between Join/Prune Messages */
-struct list *qpim_upstream_list; /* list of struct pim_upstream */
-struct zclient *qpim_zclient_update;
-struct zclient *qpim_zclient_lookup;
struct pim_assert_metric qpim_infinite_assert_metric;
long qpim_rpf_cache_refresh_delay_msec;
struct thread *qpim_rpf_cache_refresher;
@@ -101,8 +117,12 @@ int64_t qpim_mroute_add_events;
int64_t qpim_mroute_add_last;
int64_t qpim_mroute_del_events;
int64_t qpim_mroute_del_last;
+int64_t qpim_nexthop_lookups;
struct list *qpim_static_route_list; /* list of routes added statically */
-struct pim_rpf qpim_rp;
+extern unsigned int qpim_keep_alive_time;
+extern signed int qpim_rp_keep_alive_time;
+extern int qpim_packet_process;
+#define PIM_DEFAULT_PACKET_PROCESS 3
#define PIM_JP_HOLDTIME (qpim_t_periodic * 7 / 2)
@@ -132,12 +152,17 @@ extern int32_t qpim_register_probe_time;
#define PIM_DEBUG_ZEBRA (qpim_debugs & PIM_MASK_ZEBRA)
#define PIM_DEBUG_SSMPINGD (qpim_debugs & PIM_MASK_SSMPINGD)
#define PIM_DEBUG_MROUTE (qpim_debugs & PIM_MASK_MROUTE)
+#define PIM_DEBUG_MROUTE_DETAIL (qpim_debugs & PIM_MASK_MROUTE_DETAIL)
#define PIM_DEBUG_PIM_HELLO (qpim_debugs & PIM_MASK_PIM_HELLO)
#define PIM_DEBUG_PIM_J_P (qpim_debugs & PIM_MASK_PIM_J_P)
+#define PIM_DEBUG_PIM_REG (qpim_debugs & PIM_MASK_PIM_REG)
#define PIM_DEBUG_STATIC (qpim_debugs & PIM_MASK_STATIC)
+#define PIM_DEBUG_MSDP_EVENTS (qpim_debugs & PIM_MASK_MSDP_EVENTS)
+#define PIM_DEBUG_MSDP_PACKETS (qpim_debugs & PIM_MASK_MSDP_PACKETS)
+#define PIM_DEBUG_MSDP_INTERNAL (qpim_debugs & PIM_MASK_MSDP_INTERNAL)
-#define PIM_DEBUG_EVENTS (qpim_debugs & (PIM_MASK_PIM_EVENTS | PIM_MASK_IGMP_EVENTS))
-#define PIM_DEBUG_PACKETS (qpim_debugs & (PIM_MASK_PIM_PACKETS | PIM_MASK_IGMP_PACKETS))
+#define PIM_DEBUG_EVENTS (qpim_debugs & (PIM_MASK_PIM_EVENTS | PIM_MASK_IGMP_EVENTS | PIM_MASK_MSDP_EVENTS))
+#define PIM_DEBUG_PACKETS (qpim_debugs & (PIM_MASK_PIM_PACKETS | PIM_MASK_IGMP_PACKETS | PIM_MASK_MSDP_PACKETS))
#define PIM_DEBUG_TRACE (qpim_debugs & (PIM_MASK_PIM_TRACE | PIM_MASK_IGMP_TRACE))
#define PIM_DO_DEBUG_PIM_EVENTS (qpim_debugs |= PIM_MASK_PIM_EVENTS)
@@ -152,9 +177,14 @@ extern int32_t qpim_register_probe_time;
#define PIM_DO_DEBUG_ZEBRA (qpim_debugs |= PIM_MASK_ZEBRA)
#define PIM_DO_DEBUG_SSMPINGD (qpim_debugs |= PIM_MASK_SSMPINGD)
#define PIM_DO_DEBUG_MROUTE (qpim_debugs |= PIM_MASK_MROUTE)
+#define PIM_DO_DEBUG_MROUTE_DETAIL (qpim_debugs |= PIM_MASK_MROUTE_DETAIL)
#define PIM_DO_DEBUG_PIM_HELLO (qpim_debugs |= PIM_MASK_PIM_HELLO)
#define PIM_DO_DEBUG_PIM_J_P (qpim_debugs |= PIM_MASK_PIM_J_P)
+#define PIM_DO_DEBUG_PIM_REG (qpim_debugs |= PIM_MASK_PIM_REG)
#define PIM_DO_DEBUG_STATIC (qpim_debugs |= PIM_MASK_STATIC)
+#define PIM_DO_DEBUG_MSDP_EVENTS (qpim_debugs |= PIM_MASK_MSDP_EVENTS)
+#define PIM_DO_DEBUG_MSDP_PACKETS (qpim_debugs |= PIM_MASK_MSDP_PACKETS)
+#define PIM_DO_DEBUG_MSDP_INTERNAL (qpim_debugs |= PIM_MASK_MSDP_INTERNAL)
#define PIM_DONT_DEBUG_PIM_EVENTS (qpim_debugs &= ~PIM_MASK_PIM_EVENTS)
#define PIM_DONT_DEBUG_PIM_PACKETS (qpim_debugs &= ~PIM_MASK_PIM_PACKETS)
@@ -168,9 +198,14 @@ extern int32_t qpim_register_probe_time;
#define PIM_DONT_DEBUG_ZEBRA (qpim_debugs &= ~PIM_MASK_ZEBRA)
#define PIM_DONT_DEBUG_SSMPINGD (qpim_debugs &= ~PIM_MASK_SSMPINGD)
#define PIM_DONT_DEBUG_MROUTE (qpim_debugs &= ~PIM_MASK_MROUTE)
+#define PIM_DONT_DEBUG_MROUTE_DETAIL (qpim_debugs &= ~PIM_MASK_MROUTE_DETAIL)
#define PIM_DONT_DEBUG_PIM_HELLO (qpim_debugs &= ~PIM_MASK_PIM_HELLO)
#define PIM_DONT_DEBUG_PIM_J_P (qpim_debugs &= ~PIM_MASK_PIM_J_P)
+#define PIM_DONT_DEBUG_PIM_REG (qpim_debugs &= ~PIM_MASK_PIM_REG)
#define PIM_DONT_DEBUG_STATIC (qpim_debugs &= ~PIM_MASK_STATIC)
+#define PIM_DONT_DEBUG_MSDP_EVENTS (qpim_debugs &= ~PIM_MASK_MSDP_EVENTS)
+#define PIM_DONT_DEBUG_MSDP_PACKETS (qpim_debugs &= ~PIM_MASK_MSDP_PACKETS)
+#define PIM_DONT_DEBUG_MSDP_INTERNAL (qpim_debugs &= ~PIM_MASK_MSDP_INTERNAL)
void pim_init(void);
void pim_terminate(void);
diff --git a/redhat/.gitignore b/redhat/.gitignore
index e399bd8114..a38f1c06e3 100644
--- a/redhat/.gitignore
+++ b/redhat/.gitignore
@@ -1,5 +1,5 @@
zebra.spec
-quagga.spec
+frr.spec
Makefile
Makefile.in
.nfs*
diff --git a/ripd/rip_debug.c b/ripd/rip_debug.c
index a267874ade..fbf2262b8c 100644
--- a/ripd/rip_debug.c
+++ b/ripd/rip_debug.c
@@ -90,37 +90,18 @@ DEFUN (debug_rip_packet,
DEFUN (debug_rip_packet_direct,
debug_rip_packet_direct_cmd,
- "debug rip packet (recv|send)",
+ "debug rip packet <recv|send>",
DEBUG_STR
RIP_STR
"RIP packet\n"
"RIP receive packet\n"
"RIP send packet\n")
{
+ int idx_recv_send = 3;
rip_debug_packet |= RIP_DEBUG_PACKET;
- if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
+ if (strncmp ("send", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0)
rip_debug_packet |= RIP_DEBUG_SEND;
- if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
- rip_debug_packet |= RIP_DEBUG_RECV;
- return CMD_SUCCESS;
-}
-
-/* N.B. the "detail" modifier is a no-op. we leave this command
- for legacy compatibility. */
-DEFUN_DEPRECATED (debug_rip_packet_detail,
- debug_rip_packet_detail_cmd,
- "debug rip packet (recv|send) detail",
- DEBUG_STR
- RIP_STR
- "RIP packet\n"
- "RIP receive packet\n"
- "RIP send packet\n"
- "Detailed information display\n")
-{
- rip_debug_packet |= RIP_DEBUG_PACKET;
- if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
- rip_debug_packet |= RIP_DEBUG_SEND;
- if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
+ if (strncmp ("recv", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0)
rip_debug_packet |= RIP_DEBUG_RECV;
return CMD_SUCCESS;
}
@@ -162,7 +143,7 @@ DEFUN (no_debug_rip_packet,
DEFUN (no_debug_rip_packet_direct,
no_debug_rip_packet_direct_cmd,
- "no debug rip packet (recv|send)",
+ "no debug rip packet <recv|send>",
NO_STR
DEBUG_STR
RIP_STR
@@ -170,14 +151,15 @@ DEFUN (no_debug_rip_packet_direct,
"RIP option set for receive packet\n"
"RIP option set for send packet\n")
{
- if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
+ int idx_recv_send = 4;
+ if (strncmp ("send", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0)
{
if (IS_RIP_DEBUG_RECV)
rip_debug_packet &= ~RIP_DEBUG_SEND;
else
rip_debug_packet = 0;
}
- else if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
+ else if (strncmp ("recv", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0)
{
if (IS_RIP_DEBUG_SEND)
rip_debug_packet &= ~RIP_DEBUG_RECV;
@@ -265,7 +247,6 @@ rip_debug_init (void)
install_element (ENABLE_NODE, &debug_rip_events_cmd);
install_element (ENABLE_NODE, &debug_rip_packet_cmd);
install_element (ENABLE_NODE, &debug_rip_packet_direct_cmd);
- install_element (ENABLE_NODE, &debug_rip_packet_detail_cmd);
install_element (ENABLE_NODE, &debug_rip_zebra_cmd);
install_element (ENABLE_NODE, &no_debug_rip_events_cmd);
install_element (ENABLE_NODE, &no_debug_rip_packet_cmd);
@@ -275,7 +256,6 @@ rip_debug_init (void)
install_element (CONFIG_NODE, &debug_rip_events_cmd);
install_element (CONFIG_NODE, &debug_rip_packet_cmd);
install_element (CONFIG_NODE, &debug_rip_packet_direct_cmd);
- install_element (CONFIG_NODE, &debug_rip_packet_detail_cmd);
install_element (CONFIG_NODE, &debug_rip_zebra_cmd);
install_element (CONFIG_NODE, &no_debug_rip_events_cmd);
install_element (CONFIG_NODE, &no_debug_rip_packet_cmd);
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 6d6cb0c686..772ba49f93 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -122,9 +122,9 @@ rip_interface_new (void)
struct rip_interface *ri;
ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
-
+
rip_interface_reset (ri);
-
+
return ri;
}
@@ -556,7 +556,7 @@ rip_interface_reset (struct rip_interface *ri)
ri->prefix[RIP_FILTER_IN] = NULL;
ri->prefix[RIP_FILTER_OUT] = NULL;
-
+
ri->recv_badpackets = 0;
ri->recv_badroutes = 0;
ri->sent_updates = 0;
@@ -585,24 +585,26 @@ rip_if_down(struct interface *ifp)
struct list *list = NULL;
struct listnode *listnode = NULL, *nextnode = NULL;
if (rip)
- for (rp = route_top (rip->table); rp; rp = route_next (rp))
- if ((list = rp->info) != NULL)
- for (ALL_LIST_ELEMENTS (list, listnode, nextnode, rinfo))
- if (rinfo->ifindex == ifp->ifindex)
- rip_ecmp_delete (rinfo);
+ {
+ for (rp = route_top (rip->table); rp; rp = route_next (rp))
+ if ((list = rp->info) != NULL)
+ for (ALL_LIST_ELEMENTS (list, listnode, nextnode, rinfo))
+ if (rinfo->ifindex == ifp->ifindex)
+ rip_ecmp_delete (rinfo);
- ri = ifp->info;
+ ri = ifp->info;
- if (ri->running)
- {
- if (IS_RIP_DEBUG_EVENT)
- zlog_debug ("turn off %s", ifp->name);
+ if (ri->running)
+ {
+ if (IS_RIP_DEBUG_EVENT)
+ zlog_debug ("turn off %s", ifp->name);
- /* Leave from multicast group. */
- rip_multicast_leave (ifp, rip->sock);
+ /* Leave from multicast group. */
+ rip_multicast_leave (ifp, rip->sock);
- ri->running = 0;
- }
+ ri->running = 0;
+ }
+ }
return 0;
}
@@ -1216,24 +1218,25 @@ rip_passive_nondefault_clean (void)
/* RIP enable network or interface configuration. */
DEFUN (rip_network,
rip_network_cmd,
- "network (A.B.C.D/M|WORD)",
+ "network <A.B.C.D/M|WORD>",
"Enable routing on an IP network\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Interface name\n")
{
+ int idx_ipv4_word = 1;
int ret;
struct prefix_ipv4 p;
- ret = str2prefix_ipv4 (argv[0], &p);
+ ret = str2prefix_ipv4 (argv[idx_ipv4_word]->arg, &p);
if (ret)
ret = rip_enable_network_add ((struct prefix *) &p);
else
- ret = rip_enable_if_add (argv[0]);
+ ret = rip_enable_if_add (argv[idx_ipv4_word]->arg);
if (ret < 0)
{
- vty_out (vty, "There is a same network configuration %s%s", argv[0],
+ vty_out (vty, "There is a same network configuration %s%s", argv[idx_ipv4_word]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1244,25 +1247,26 @@ DEFUN (rip_network,
/* RIP enable network or interface configuration. */
DEFUN (no_rip_network,
no_rip_network_cmd,
- "no network (A.B.C.D/M|WORD)",
+ "no network <A.B.C.D/M|WORD>",
NO_STR
"Enable routing on an IP network\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Interface name\n")
{
+ int idx_ipv4_word = 2;
int ret;
struct prefix_ipv4 p;
- ret = str2prefix_ipv4 (argv[0], &p);
+ ret = str2prefix_ipv4 (argv[idx_ipv4_word]->arg, &p);
if (ret)
ret = rip_enable_network_delete ((struct prefix *) &p);
else
- ret = rip_enable_if_delete (argv[0]);
+ ret = rip_enable_if_delete (argv[idx_ipv4_word]->arg);
if (ret < 0)
{
- vty_out (vty, "Can't find network configuration %s%s", argv[0],
+ vty_out (vty, "Can't find network configuration %s%s", argv[idx_ipv4_word]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1277,10 +1281,11 @@ DEFUN (rip_neighbor,
"Specify a neighbor router\n"
"Neighbor address\n")
{
+ int idx_ipv4 = 1;
int ret;
struct prefix_ipv4 p;
- ret = str2prefix_ipv4 (argv[0], &p);
+ ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
if (ret <= 0)
{
@@ -1301,10 +1306,11 @@ DEFUN (no_rip_neighbor,
"Specify a neighbor router\n"
"Neighbor address\n")
{
+ int idx_ipv4 = 2;
int ret;
struct prefix_ipv4 p;
- ret = str2prefix_ipv4 (argv[0], &p);
+ ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
if (ret <= 0)
{
@@ -1319,7 +1325,7 @@ DEFUN (no_rip_neighbor,
DEFUN (ip_rip_receive_version,
ip_rip_receive_version_cmd,
- "ip rip receive version (1|2|none)",
+ "ip rip receive version <(1-2)|none>",
IP_STR
"Routing Information Protocol\n"
"Advertisement reception\n"
@@ -1328,13 +1334,13 @@ DEFUN (ip_rip_receive_version,
"RIP version 2\n"
"None\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_type = 4;
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
- switch (*argv[0])
+ switch (argv[idx_type]->arg[0])
{
case '1':
ri->ri_receive = RI_RIP_VERSION_1;
@@ -1354,7 +1360,7 @@ DEFUN (ip_rip_receive_version,
DEFUN (ip_rip_receive_version_1,
ip_rip_receive_version_1_cmd,
- "ip rip receive version 1 2",
+ "ip rip receive version (1-1) (2-2)",
IP_STR
"Routing Information Protocol\n"
"Advertisement reception\n"
@@ -1362,10 +1368,9 @@ DEFUN (ip_rip_receive_version_1,
"RIP version 1\n"
"RIP version 2\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
/* Version 1 and 2. */
@@ -1375,7 +1380,7 @@ DEFUN (ip_rip_receive_version_1,
DEFUN (ip_rip_receive_version_2,
ip_rip_receive_version_2_cmd,
- "ip rip receive version 2 1",
+ "ip rip receive version (2-2) (1-1)",
IP_STR
"Routing Information Protocol\n"
"Advertisement reception\n"
@@ -1383,10 +1388,9 @@ DEFUN (ip_rip_receive_version_2,
"RIP version 2\n"
"RIP version 1\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
/* Version 1 and 2. */
@@ -1396,37 +1400,28 @@ DEFUN (ip_rip_receive_version_2,
DEFUN (no_ip_rip_receive_version,
no_ip_rip_receive_version_cmd,
- "no ip rip receive version",
+ "no ip rip receive version [(1-2)]",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Advertisement reception\n"
- "Version control\n")
+ "Version control\n"
+ "Version 1\n"
+ "Version 2\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
ri->ri_receive = RI_RIP_UNSPEC;
return CMD_SUCCESS;
}
-ALIAS (no_ip_rip_receive_version,
- no_ip_rip_receive_version_num_cmd,
- "no ip rip receive version (1|2)",
- NO_STR
- IP_STR
- "Routing Information Protocol\n"
- "Advertisement reception\n"
- "Version control\n"
- "Version 1\n"
- "Version 2\n")
DEFUN (ip_rip_send_version,
ip_rip_send_version_cmd,
- "ip rip send version (1|2)",
+ "ip rip send version (1-2)",
IP_STR
"Routing Information Protocol\n"
"Advertisement transmission\n"
@@ -1434,19 +1429,19 @@ DEFUN (ip_rip_send_version,
"RIP version 1\n"
"RIP version 2\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_type = 4;
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
/* Version 1. */
- if (atoi (argv[0]) == 1)
+ if (atoi (argv[idx_type]->arg) == 1)
{
ri->ri_send = RI_RIP_VERSION_1;
return CMD_SUCCESS;
}
- if (atoi (argv[0]) == 2)
+ if (atoi (argv[idx_type]->arg) == 2)
{
ri->ri_send = RI_RIP_VERSION_2;
return CMD_SUCCESS;
@@ -1456,7 +1451,7 @@ DEFUN (ip_rip_send_version,
DEFUN (ip_rip_send_version_1,
ip_rip_send_version_1_cmd,
- "ip rip send version 1 2",
+ "ip rip send version (1-1) (2-2)",
IP_STR
"Routing Information Protocol\n"
"Advertisement transmission\n"
@@ -1464,10 +1459,9 @@ DEFUN (ip_rip_send_version_1,
"RIP version 1\n"
"RIP version 2\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
/* Version 1 and 2. */
@@ -1477,7 +1471,7 @@ DEFUN (ip_rip_send_version_1,
DEFUN (ip_rip_send_version_2,
ip_rip_send_version_2_cmd,
- "ip rip send version 2 1",
+ "ip rip send version (2-2) (1-1)",
IP_STR
"Routing Information Protocol\n"
"Advertisement transmission\n"
@@ -1485,10 +1479,9 @@ DEFUN (ip_rip_send_version_2,
"RIP version 2\n"
"RIP version 1\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
/* Version 1 and 2. */
@@ -1498,33 +1491,24 @@ DEFUN (ip_rip_send_version_2,
DEFUN (no_ip_rip_send_version,
no_ip_rip_send_version_cmd,
- "no ip rip send version",
+ "no ip rip send version [(1-2)]",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Advertisement transmission\n"
- "Version control\n")
+ "Version control\n"
+ "Version 1\n"
+ "Version 2\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
ri->ri_send = RI_RIP_UNSPEC;
return CMD_SUCCESS;
}
-ALIAS (no_ip_rip_send_version,
- no_ip_rip_send_version_num_cmd,
- "no ip rip send version (1|2)",
- NO_STR
- IP_STR
- "Routing Information Protocol\n"
- "Advertisement transmission\n"
- "Version control\n"
- "Version 1\n"
- "Version 2\n")
DEFUN (ip_rip_v2_broadcast,
ip_rip_v2_broadcast_cmd,
@@ -1533,10 +1517,9 @@ DEFUN (ip_rip_v2_broadcast,
"Routing Information Protocol\n"
"Send ip broadcast v2 update\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
ri->v2_broadcast = 1;
@@ -1551,10 +1534,9 @@ DEFUN (no_ip_rip_v2_broadcast,
"Routing Information Protocol\n"
"Send ip broadcast v2 update\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
ri->v2_broadcast = 0;
@@ -1563,64 +1545,57 @@ DEFUN (no_ip_rip_v2_broadcast,
DEFUN (ip_rip_authentication_mode,
ip_rip_authentication_mode_cmd,
- "ip rip authentication mode (md5|text)",
+ "ip rip authentication mode <md5|text> [auth-length <rfc|old-ripd>]",
IP_STR
"Routing Information Protocol\n"
"Authentication control\n"
"Authentication mode\n"
"Keyed message digest\n"
- "Clear text authentication\n")
+ "Clear text authentication\n"
+ "MD5 authentication data length\n"
+ "RFC compatible\n"
+ "Old ripd compatible\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ char *cryptmode = argv[4]->text;
+ char *authlen = (argc > 5) ? argv[6]->text : NULL;
struct rip_interface *ri;
int auth_type;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
- if ( (argc < 1) || (argc > 2) )
- {
- vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
+ if (strmatch ("md5", cryptmode))
auth_type = RIP_AUTH_MD5;
- else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
+ else {
+ assert (strmatch ("text", cryptmode));
auth_type = RIP_AUTH_SIMPLE_PASSWORD;
- else
- {
- vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ }
- if (argc == 1)
- {
- ri->auth_type = auth_type;
- return CMD_SUCCESS;
- }
+ ri->auth_type = auth_type;
- if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
+ if (argc > 5)
+ {
+ if (auth_type != RIP_AUTH_MD5)
{
vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
return CMD_WARNING;
}
+ if (strmatch ("rfc", authlen))
+ ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
+ else
+ {
+ assert (strmatch ("old-ripd", authlen));
+ ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
+ }
+ }
- if (strncmp ("r", argv[1], 1) == 0)
- ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
- else if (strncmp ("o", argv[1], 1) == 0)
- ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
- else
- return CMD_WARNING;
-
- ri->auth_type = auth_type;
-
return CMD_SUCCESS;
}
-ALIAS (ip_rip_authentication_mode,
- ip_rip_authentication_mode_authlen_cmd,
- "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
+DEFUN (no_ip_rip_authentication_mode,
+ no_ip_rip_authentication_mode_cmd,
+ "no ip rip authentication mode [<md5|text> [auth-length <rfc|old-ripd>]]",
+ NO_STR
IP_STR
"Routing Information Protocol\n"
"Authentication control\n"
@@ -1630,20 +1605,10 @@ ALIAS (ip_rip_authentication_mode,
"MD5 authentication data length\n"
"RFC compatible\n"
"Old ripd compatible\n")
-
-DEFUN (no_ip_rip_authentication_mode,
- no_ip_rip_authentication_mode_cmd,
- "no ip rip authentication mode",
- NO_STR
- IP_STR
- "Routing Information Protocol\n"
- "Authentication control\n"
- "Authentication mode\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
ri->auth_type = RIP_NO_AUTH;
@@ -1652,31 +1617,6 @@ DEFUN (no_ip_rip_authentication_mode,
return CMD_SUCCESS;
}
-ALIAS (no_ip_rip_authentication_mode,
- no_ip_rip_authentication_mode_type_cmd,
- "no ip rip authentication mode (md5|text)",
- NO_STR
- IP_STR
- "Routing Information Protocol\n"
- "Authentication control\n"
- "Authentication mode\n"
- "Keyed message digest\n"
- "Clear text authentication\n")
-
-ALIAS (no_ip_rip_authentication_mode,
- no_ip_rip_authentication_mode_type_authlen_cmd,
- "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
- NO_STR
- IP_STR
- "Routing Information Protocol\n"
- "Authentication control\n"
- "Authentication mode\n"
- "Keyed message digest\n"
- "Clear text authentication\n"
- "MD5 authentication data length\n"
- "RFC compatible\n"
- "Old ripd compatible\n")
-
DEFUN (ip_rip_authentication_string,
ip_rip_authentication_string_cmd,
"ip rip authentication string LINE",
@@ -1686,13 +1626,13 @@ DEFUN (ip_rip_authentication_string,
"Authentication string\n"
"Authentication string\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_line = 4;
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
- if (strlen (argv[0]) > 16)
+ if (strlen (argv[idx_line]->arg) > 16)
{
vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
VTY_NEWLINE);
@@ -1708,24 +1648,24 @@ DEFUN (ip_rip_authentication_string,
if (ri->auth_str)
free (ri->auth_str);
- ri->auth_str = strdup (argv[0]);
+ ri->auth_str = strdup (argv[idx_line]->arg);
return CMD_SUCCESS;
}
DEFUN (no_ip_rip_authentication_string,
no_ip_rip_authentication_string_cmd,
- "no ip rip authentication string",
+ "no ip rip authentication string [LINE]",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Authentication control\n"
+ "Authentication string\n"
"Authentication string\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *)vty->index;
ri = ifp->info;
if (ri->auth_str)
@@ -1736,15 +1676,6 @@ DEFUN (no_ip_rip_authentication_string,
return CMD_SUCCESS;
}
-ALIAS (no_ip_rip_authentication_string,
- no_ip_rip_authentication_string2_cmd,
- "no ip rip authentication string LINE",
- NO_STR
- IP_STR
- "Routing Information Protocol\n"
- "Authentication control\n"
- "Authentication string\n"
- "Authentication string\n")
DEFUN (ip_rip_authentication_key_chain,
ip_rip_authentication_key_chain_cmd,
@@ -1755,10 +1686,10 @@ DEFUN (ip_rip_authentication_key_chain,
"Authentication key-chain\n"
"name of key-chain\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_line = 4;
struct rip_interface *ri;
- ifp = (struct interface *) vty->index;
ri = ifp->info;
if (ri->auth_str)
@@ -1771,24 +1702,24 @@ DEFUN (ip_rip_authentication_key_chain,
if (ri->key_chain)
free (ri->key_chain);
- ri->key_chain = strdup (argv[0]);
+ ri->key_chain = strdup (argv[idx_line]->arg);
return CMD_SUCCESS;
}
DEFUN (no_ip_rip_authentication_key_chain,
no_ip_rip_authentication_key_chain_cmd,
- "no ip rip authentication key-chain",
+ "no ip rip authentication key-chain [LINE]",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Authentication control\n"
- "Authentication key-chain\n")
+ "Authentication key-chain\n"
+ "name of key-chain\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = (struct interface *) vty->index;
ri = ifp->info;
if (ri->key_chain)
@@ -1799,15 +1730,6 @@ DEFUN (no_ip_rip_authentication_key_chain,
return CMD_SUCCESS;
}
-ALIAS (no_ip_rip_authentication_key_chain,
- no_ip_rip_authentication_key_chain2_cmd,
- "no ip rip authentication key-chain LINE",
- NO_STR
- IP_STR
- "Routing Information Protocol\n"
- "Authentication control\n"
- "Authentication key-chain\n"
- "name of key-chain\n")
/* CHANGED: ip rip split-horizon
Cisco and Zebra's command is
@@ -1820,10 +1742,9 @@ DEFUN (ip_rip_split_horizon,
"Routing Information Protocol\n"
"Perform split horizon\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = vty->index;
ri = ifp->info;
ri->split_horizon = RIP_SPLIT_HORIZON;
@@ -1838,10 +1759,9 @@ DEFUN (ip_rip_split_horizon_poisoned_reverse,
"Perform split horizon\n"
"With poisoned-reverse\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = vty->index;
ri = ifp->info;
ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
@@ -1860,10 +1780,9 @@ DEFUN (no_ip_rip_split_horizon,
"Routing Information Protocol\n"
"Perform split horizon\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = vty->index;
ri = ifp->info;
ri->split_horizon = RIP_NO_SPLIT_HORIZON;
@@ -1879,18 +1798,17 @@ DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
"Perform split horizon\n"
"With poisoned-reverse\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct rip_interface *ri;
- ifp = vty->index;
ri = ifp->info;
switch( ri->split_horizon )
{
- case RIP_SPLIT_HORIZON_POISONED_REVERSE:
- ri->split_horizon = RIP_SPLIT_HORIZON;
- default:
- break;
+ case RIP_SPLIT_HORIZON_POISONED_REVERSE:
+ ri->split_horizon = RIP_SPLIT_HORIZON;
+ default:
+ break;
}
return CMD_SUCCESS;
@@ -1898,43 +1816,39 @@ DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
DEFUN (rip_passive_interface,
rip_passive_interface_cmd,
- "passive-interface (IFNAME|default)",
+ "passive-interface <IFNAME|default>",
"Suppress routing updates on an interface\n"
"Interface name\n"
"default for all interfaces\n")
{
- const char *ifname = argv[0];
-
- if (!strcmp(ifname,"default")) {
+ if (argv[1]->type == WORD_TKN) { // user passed 'default'
passive_default = 1;
rip_passive_nondefault_clean();
return CMD_SUCCESS;
}
if (passive_default)
- return rip_passive_nondefault_unset (vty, ifname);
+ return rip_passive_nondefault_unset (vty, argv[1]->arg);
else
- return rip_passive_nondefault_set (vty, ifname);
+ return rip_passive_nondefault_set (vty, argv[1]->arg);
}
DEFUN (no_rip_passive_interface,
no_rip_passive_interface_cmd,
- "no passive-interface (IFNAME|default)",
+ "no passive-interface <IFNAME|default>",
NO_STR
"Suppress routing updates on an interface\n"
"Interface name\n"
"default for all interfaces\n")
{
- const char *ifname = argv[0];
-
- if (!strcmp(ifname,"default")) {
+ if (argv[2]->type == WORD_TKN) {
passive_default = 0;
rip_passive_nondefault_clean();
return CMD_SUCCESS;
}
if (passive_default)
- return rip_passive_nondefault_set (vty, ifname);
+ return rip_passive_nondefault_set (vty, argv[2]->arg);
else
- return rip_passive_nondefault_unset (vty, ifname);
+ return rip_passive_nondefault_unset (vty, argv[2]->arg);
}
/* Write rip configuration of each interface. */
@@ -2119,13 +2033,9 @@ rip_if_init (void)
/* Install interface node. */
install_node (&interface_node, rip_interface_config_write);
+ if_cmd_init ();
/* Install commands. */
- install_element (CONFIG_NODE, &interface_cmd);
- install_element (CONFIG_NODE, &no_interface_cmd);
- install_default (INTERFACE_NODE);
- install_element (INTERFACE_NODE, &interface_desc_cmd);
- install_element (INTERFACE_NODE, &no_interface_desc_cmd);
install_element (RIP_NODE, &rip_network_cmd);
install_element (RIP_NODE, &no_rip_network_cmd);
install_element (RIP_NODE, &rip_neighbor_cmd);
@@ -2138,30 +2048,23 @@ rip_if_init (void)
install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
- install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
- install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
install_element (INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_v2_broadcast_cmd);
install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
- install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
- install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
- install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
- install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
- install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
diff --git a/ripd/rip_offset.c b/ripd/rip_offset.c
index 0155f90ef0..5e0e71579a 100644
--- a/ripd/rip_offset.c
+++ b/ripd/rip_offset.c
@@ -282,19 +282,22 @@ rip_offset_list_apply_out (struct prefix_ipv4 *p, struct interface *ifp,
DEFUN (rip_offset_list,
rip_offset_list_cmd,
- "offset-list WORD (in|out) <0-16>",
+ "offset-list WORD <in|out> (0-16)",
"Modify RIP metric\n"
"Access-list name\n"
"For incoming updates\n"
"For outgoing updates\n"
"Metric value\n")
{
- return rip_offset_list_set (vty, argv[0], argv[1], argv[2], NULL);
+ int idx_word = 1;
+ int idx_in_out = 2;
+ int idx_number = 3;
+ return rip_offset_list_set (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, NULL);
}
DEFUN (rip_offset_list_ifname,
rip_offset_list_ifname_cmd,
- "offset-list WORD (in|out) <0-16> IFNAME",
+ "offset-list WORD <in|out> (0-16) IFNAME",
"Modify RIP metric\n"
"Access-list name\n"
"For incoming updates\n"
@@ -302,12 +305,16 @@ DEFUN (rip_offset_list_ifname,
"Metric value\n"
"Interface to match\n")
{
- return rip_offset_list_set (vty, argv[0], argv[1], argv[2], argv[3]);
+ int idx_word = 1;
+ int idx_in_out = 2;
+ int idx_number = 3;
+ int idx_ifname = 4;
+ return rip_offset_list_set (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, argv[idx_ifname]->arg);
}
DEFUN (no_rip_offset_list,
no_rip_offset_list_cmd,
- "no offset-list WORD (in|out) <0-16>",
+ "no offset-list WORD <in|out> (0-16)",
NO_STR
"Modify RIP metric\n"
"Access-list name\n"
@@ -315,12 +322,15 @@ DEFUN (no_rip_offset_list,
"For outgoing updates\n"
"Metric value\n")
{
- return rip_offset_list_unset (vty, argv[0], argv[1], argv[2], NULL);
+ int idx_word = 2;
+ int idx_in_out = 3;
+ int idx_number = 4;
+ return rip_offset_list_unset (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, NULL);
}
DEFUN (no_rip_offset_list_ifname,
no_rip_offset_list_ifname_cmd,
- "no offset-list WORD (in|out) <0-16> IFNAME",
+ "no offset-list WORD <in|out> (0-16) IFNAME",
NO_STR
"Modify RIP metric\n"
"Access-list name\n"
@@ -329,7 +339,11 @@ DEFUN (no_rip_offset_list_ifname,
"Metric value\n"
"Interface to match\n")
{
- return rip_offset_list_unset (vty, argv[0], argv[1], argv[2], argv[3]);
+ int idx_word = 2;
+ int idx_in_out = 3;
+ int idx_number = 4;
+ int idx_ifname = 5;
+ return rip_offset_list_unset (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, argv[idx_ifname]->arg);
}
static int
diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c
index 8b48adfd55..6fd647596c 100644
--- a/ripd/rip_routemap.c
+++ b/ripd/rip_routemap.c
@@ -24,6 +24,7 @@
#include "memory.h"
#include "prefix.h"
+#include "vty.h"
#include "routemap.h"
#include "command.h"
#include "filter.h"
@@ -45,104 +46,6 @@ struct rip_metric_modifier
u_char metric;
};
-/* Add rip route map rule. */
-static int
-rip_route_match_add (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_add_match (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% RIP Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% RIP Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
-/* Delete rip route map rule. */
-static int
-rip_route_match_delete (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_delete_match (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% RIP Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% RIP Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
-/* Add rip route map rule. */
-static int
-rip_route_set_add (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_add_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% RIP Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- /* rip, ripng and other protocols share the set metric command
- but only values from 0 to 16 are valid for rip and ripng
- if metric is out of range for rip and ripng, it is not for
- other protocols. Do not return an error */
- if (strcmp(command, "metric")) {
- vty_out (vty, "%% RIP Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- }
- return CMD_SUCCESS;
-}
-
-/* Delete rip route map rule. */
-static int
-rip_route_set_delete (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_delete_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% RIP Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% RIP Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
/* Hook function for updating route_map assignment. */
/* ARGSUSED */
static void
@@ -685,394 +588,50 @@ static struct route_map_rule_cmd route_set_tag_cmd =
#define MATCH_STR "Match values from routing table\n"
#define SET_STR "Set values in destination routing protocol\n"
-DEFUN (match_metric,
- match_metric_cmd,
- "match metric <0-4294967295>",
- MATCH_STR
- "Match metric of route\n"
- "Metric value\n")
-{
- return rip_route_match_add (vty, vty->index, "metric", argv[0]);
-}
-
-DEFUN (no_match_metric,
- no_match_metric_cmd,
- "no match metric",
- NO_STR
- MATCH_STR
- "Match metric of route\n")
-{
- if (argc == 0)
- return rip_route_match_delete (vty, vty->index, "metric", NULL);
-
- return rip_route_match_delete (vty, vty->index, "metric", argv[0]);
-}
-
-ALIAS (no_match_metric,
- no_match_metric_val_cmd,
- "no match metric <0-4294967295>",
- NO_STR
- MATCH_STR
- "Match metric of route\n"
- "Metric value\n")
-
-DEFUN (match_interface,
- match_interface_cmd,
- "match interface WORD",
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-{
- return rip_route_match_add (vty, vty->index, "interface", argv[0]);
-}
-
-DEFUN (no_match_interface,
- no_match_interface_cmd,
- "no match interface",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n")
-{
- if (argc == 0)
- return rip_route_match_delete (vty, vty->index, "interface", NULL);
-
- return rip_route_match_delete (vty, vty->index, "interface", argv[0]);
-}
-
-ALIAS (no_match_interface,
- no_match_interface_val_cmd,
- "no match interface WORD",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-
-DEFUN (match_ip_next_hop,
- match_ip_next_hop_cmd,
- "match ip next-hop (<1-199>|<1300-2699>|WORD)",
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-{
- return rip_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
-}
-
-DEFUN (no_match_ip_next_hop,
- no_match_ip_next_hop_cmd,
- "no match ip next-hop",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n")
-{
- if (argc == 0)
- return rip_route_match_delete (vty, vty->index, "ip next-hop", NULL);
-
- return rip_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
-}
-
-ALIAS (no_match_ip_next_hop,
- no_match_ip_next_hop_val_cmd,
- "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-
-DEFUN (match_ip_next_hop_prefix_list,
- match_ip_next_hop_prefix_list_cmd,
- "match ip next-hop prefix-list WORD",
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return rip_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
-}
-
-DEFUN (no_match_ip_next_hop_prefix_list,
- no_match_ip_next_hop_prefix_list_cmd,
- "no match ip next-hop prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n")
-{
- if (argc == 0)
- return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
-
- return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
-}
-
-ALIAS (no_match_ip_next_hop_prefix_list,
- no_match_ip_next_hop_prefix_list_val_cmd,
- "no match ip next-hop prefix-list WORD",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-
-DEFUN (match_ip_address,
- match_ip_address_cmd,
- "match ip address (<1-199>|<1300-2699>|WORD)",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-
-{
- return rip_route_match_add (vty, vty->index, "ip address", argv[0]);
-}
-
-DEFUN (no_match_ip_address,
- no_match_ip_address_cmd,
- "no match ip address",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n")
-{
- if (argc == 0)
- return rip_route_match_delete (vty, vty->index, "ip address", NULL);
-
- return rip_route_match_delete (vty, vty->index, "ip address", argv[0]);
-}
-
-ALIAS (no_match_ip_address,
- no_match_ip_address_val_cmd,
- "no match ip address (<1-199>|<1300-2699>|WORD)",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-
-DEFUN (match_ip_address_prefix_list,
- match_ip_address_prefix_list_cmd,
- "match ip address prefix-list WORD",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return rip_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
-}
-
-DEFUN (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_cmd,
- "no match ip address prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n")
-{
- if (argc == 0)
- return rip_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
-
- return rip_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
-}
-
-ALIAS (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_val_cmd,
- "no match ip address prefix-list WORD",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-
-DEFUN (match_tag,
- match_tag_cmd,
- "match tag <1-4294967295>",
- MATCH_STR
- "Match tag of route\n"
- "Metric value\n")
-{
- return rip_route_match_add (vty, vty->index, "tag", argv[0]);
-}
-
-DEFUN (no_match_tag,
- no_match_tag_cmd,
- "no match tag",
- NO_STR
- MATCH_STR
- "Match tag of route\n")
-{
- if (argc == 0)
- return rip_route_match_delete (vty, vty->index, "tag", NULL);
-
- return rip_route_match_delete (vty, vty->index, "tag", argv[0]);
-}
-
-ALIAS (no_match_tag,
- no_match_tag_val_cmd,
- "no match tag <1-4294967295>",
- NO_STR
- MATCH_STR
- "Match tag of route\n"
- "Metric value\n")
-
-/* set functions */
-
-DEFUN (set_metric,
- set_metric_cmd,
- "set metric <0-4294967295>",
- SET_STR
- "Metric value for destination routing protocol\n"
- "Metric value\n")
+void
+rip_route_map_reset ()
{
- return rip_route_set_add (vty, vty->index, "metric", argv[0]);
+ ;
}
-ALIAS (set_metric,
- set_metric_addsub_cmd,
- "set metric <+/-metric>",
- SET_STR
- "Metric value for destination routing protocol\n"
- "Add or subtract metric\n")
-
-DEFUN (no_set_metric,
- no_set_metric_cmd,
- "no set metric",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n")
+/* Route-map init */
+void
+rip_route_map_init ()
{
- if (argc == 0)
- return rip_route_set_delete (vty, vty->index, "metric", NULL);
+ route_map_init ();
- return rip_route_set_delete (vty, vty->index, "metric", argv[0]);
-}
+ route_map_add_hook (rip_route_map_update);
+ route_map_delete_hook (rip_route_map_update);
-ALIAS (no_set_metric,
- no_set_metric_val_cmd,
- "no set metric <0-4294967295>",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n"
- "Metric value\n")
-
-ALIAS (no_set_metric,
- no_set_metric_addsub_cmd,
- "no set metric <+/-metric>",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n"
- "Add or subtract metric\n")
-
-DEFUN (set_ip_nexthop,
- set_ip_nexthop_cmd,
- "set ip next-hop A.B.C.D",
- SET_STR
- IP_STR
- "Next hop address\n"
- "IP address of next hop\n")
-{
- union sockunion su;
- int ret;
+ route_map_match_interface_hook (generic_match_add);
+ route_map_no_match_interface_hook (generic_match_delete);
- ret = str2sockunion (argv[0], &su);
- if (ret < 0)
- {
- vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (su.sin.sin_addr.s_addr == 0 ||
- IPV4_CLASS_DE(su.sin.sin_addr.s_addr))
- {
- vty_out (vty, "%% nexthop address cannot be 0.0.0.0, multicast "
- "or reserved%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ route_map_match_ip_address_hook (generic_match_add);
+ route_map_no_match_ip_address_hook (generic_match_delete);
- return rip_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
-}
+ route_map_match_ip_address_prefix_list_hook (generic_match_add);
+ route_map_no_match_ip_address_prefix_list_hook (generic_match_delete);
-DEFUN (no_set_ip_nexthop,
- no_set_ip_nexthop_cmd,
- "no set ip next-hop",
- NO_STR
- SET_STR
- IP_STR
- "Next hop address\n")
-{
- if (argc == 0)
- return rip_route_set_delete (vty, vty->index, "ip next-hop", NULL);
-
- return rip_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
-}
+ route_map_match_ip_next_hop_hook (generic_match_add);
+ route_map_no_match_ip_next_hop_hook (generic_match_delete);
-ALIAS (no_set_ip_nexthop,
- no_set_ip_nexthop_val_cmd,
- "no set ip next-hop A.B.C.D",
- NO_STR
- SET_STR
- IP_STR
- "Next hop address\n"
- "IP address of next hop\n")
-
-DEFUN (set_tag,
- set_tag_cmd,
- "set tag <1-4294967295>",
- SET_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
-{
- return rip_route_set_add (vty, vty->index, "tag", argv[0]);
-}
+ route_map_match_ip_next_hop_prefix_list_hook (generic_match_add);
+ route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete);
-DEFUN (no_set_tag,
- no_set_tag_cmd,
- "no set tag",
- NO_STR
- SET_STR
- "Tag value for routing protocol\n")
-{
- if (argc == 0)
- return rip_route_set_delete (vty, vty->index, "tag", NULL);
-
- return rip_route_set_delete (vty, vty->index, "tag", argv[0]);
-}
+ route_map_match_metric_hook (generic_match_add);
+ route_map_no_match_metric_hook (generic_match_delete);
-ALIAS (no_set_tag,
- no_set_tag_val_cmd,
- "no set tag <1-4294967295>",
- NO_STR
- SET_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
+ route_map_match_tag_hook (generic_match_add);
+ route_map_no_match_tag_hook (generic_match_delete);
-void
-rip_route_map_reset ()
-{
- ;
-}
+ route_map_set_ip_nexthop_hook (generic_set_add);
+ route_map_no_set_ip_nexthop_hook (generic_set_delete);
-/* Route-map init */
-void
-rip_route_map_init ()
-{
- route_map_init ();
+ route_map_set_metric_hook (generic_set_add);
+ route_map_no_set_metric_hook (generic_set_delete);
- route_map_add_hook (rip_route_map_update);
- route_map_delete_hook (rip_route_map_update);
+ route_map_set_tag_hook (generic_set_add);
+ route_map_no_set_tag_hook (generic_set_delete);
route_map_install_match (&route_match_metric_cmd);
route_map_install_match (&route_match_interface_cmd);
@@ -1085,38 +644,4 @@ rip_route_map_init ()
route_map_install_set (&route_set_metric_cmd);
route_map_install_set (&route_set_ip_nexthop_cmd);
route_map_install_set (&route_set_tag_cmd);
-
- install_element (RMAP_NODE, &match_metric_cmd);
- install_element (RMAP_NODE, &no_match_metric_cmd);
- install_element (RMAP_NODE, &no_match_metric_val_cmd);
- install_element (RMAP_NODE, &match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_val_cmd);
- install_element (RMAP_NODE, &match_ip_next_hop_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
- install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
- install_element (RMAP_NODE, &match_ip_address_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
- install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
- install_element (RMAP_NODE, &match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_val_cmd);
-
- install_element (RMAP_NODE, &set_metric_cmd);
- install_element (RMAP_NODE, &set_metric_addsub_cmd);
- install_element (RMAP_NODE, &no_set_metric_cmd);
- install_element (RMAP_NODE, &no_set_metric_val_cmd);
- install_element (RMAP_NODE, &no_set_metric_addsub_cmd);
- install_element (RMAP_NODE, &set_ip_nexthop_cmd);
- install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
- install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
- install_element (RMAP_NODE, &set_tag_cmd);
- install_element (RMAP_NODE, &no_set_tag_cmd);
- install_element (RMAP_NODE, &no_set_tag_val_cmd);
}
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index 44fc1cd8f9..7fa3baea7e 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -263,46 +263,6 @@ static struct {
{0, 0, NULL}
};
-DEFUN (router_zebra,
- router_zebra_cmd,
- "router zebra",
- "Enable a routing process\n"
- "Make connection to zebra daemon\n")
-{
- vty->node = ZEBRA_NODE;
- zclient->enable = 1;
- zclient_start (zclient);
- return CMD_SUCCESS;
-}
-
-DEFUN (no_router_zebra,
- no_router_zebra_cmd,
- "no router zebra",
- NO_STR
- "Enable a routing process\n"
- "Make connection to zebra daemon\n")
-{
- zclient->enable = 0;
- zclient_stop (zclient);
- return CMD_SUCCESS;
-}
-
-#if 0
-static int
-rip_redistribute_set (int type)
-{
- if (vrf_bitmap_check (zclient->redist[AFI_IP][type], VRF_DEFAULT))
- return CMD_SUCCESS;
-
- vrf_bitmap_set (zclient->redist[AFI_IP][type], VRF_DEFAULT);
-
- if (zclient->sock > 0)
- zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, API_IP, type);
-
- return CMD_SUCCESS;
-}
-#endif
-
static int
rip_redistribute_unset (int type)
{
@@ -379,7 +339,7 @@ DEFUN (rip_redistribute_type,
for(i = 0; redist_type[i].str; i++)
{
- if (strncmp (redist_type[i].str, argv[0],
+ if (strncmp (redist_type[i].str, argv[2]->arg,
redist_type[i].str_min_len) == 0)
{
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
@@ -388,7 +348,7 @@ DEFUN (rip_redistribute_type,
}
}
- vty_out(vty, "Invalid type %s%s", argv[0],
+ vty_out(vty, "Invalid type %s%s", argv[2]->arg,
VTY_NEWLINE);
return CMD_WARNING;
@@ -405,7 +365,7 @@ DEFUN (no_rip_redistribute_type,
for (i = 0; redist_type[i].str; i++)
{
- if (strncmp(redist_type[i].str, argv[0],
+ if (strncmp(redist_type[i].str, argv[3]->arg,
redist_type[i].str_min_len) == 0)
{
rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP);
@@ -415,7 +375,7 @@ DEFUN (no_rip_redistribute_type,
}
}
- vty_out(vty, "Invalid type %s%s", argv[0],
+ vty_out(vty, "Invalid type %s%s", argv[3]->arg,
VTY_NEWLINE);
return CMD_WARNING;
@@ -429,21 +389,21 @@ DEFUN (rip_redistribute_type_routemap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ int idx_protocol = 1;
+ int idx_word = 3;
int i;
for (i = 0; redist_type[i].str; i++) {
- if (strncmp(redist_type[i].str, argv[0],
- redist_type[i].str_min_len) == 0)
+ if (strmatch (redist_type[i].str, argv[idx_protocol]->text))
{
- rip_routemap_set (redist_type[i].type, argv[1]);
+ rip_routemap_set (redist_type[i].type, argv[idx_word]->arg);
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
redist_type[i].type, 0, VRF_DEFAULT);
return CMD_SUCCESS;
}
}
- vty_out(vty, "Invalid type %s%s", argv[0],
- VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -457,42 +417,42 @@ DEFUN (no_rip_redistribute_type_routemap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ int idx_protocol = 2;
+ int idx_word = 4;
int i;
- for (i = 0; redist_type[i].str; i++)
- {
- if (strncmp(redist_type[i].str, argv[0],
- redist_type[i].str_min_len) == 0)
- {
- if (rip_routemap_unset (redist_type[i].type,argv[1]))
- return CMD_WARNING;
- rip_redistribute_unset (redist_type[i].type);
- return CMD_SUCCESS;
- }
- }
+ for (i = 0; redist_type[i].str; i++) {
+ if (strmatch (redist_type[i].str, argv[idx_protocol]->text))
+ {
+ if (rip_routemap_unset (redist_type[i].type,argv[idx_word]->arg))
+ return CMD_WARNING;
+ rip_redistribute_unset (redist_type[i].type);
+ return CMD_SUCCESS;
+ }
+ }
- vty_out(vty, "Invalid type %s%s", argv[0],
- VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text, VTY_NEWLINE);
return CMD_WARNING;
}
DEFUN (rip_redistribute_type_metric,
rip_redistribute_type_metric_cmd,
- "redistribute " FRR_REDIST_STR_RIPD " metric <0-16>",
+ "redistribute " FRR_REDIST_STR_RIPD " metric (0-16)",
REDIST_STR
FRR_REDIST_HELP_STR_RIPD
"Metric\n"
"Metric value\n")
{
+ int idx_protocol = 1;
+ int idx_number = 3;
int i;
int metric;
- metric = atoi (argv[1]);
+ metric = atoi (argv[idx_number]->arg);
for (i = 0; redist_type[i].str; i++) {
- if (strncmp(redist_type[i].str, argv[0],
- redist_type[i].str_min_len) == 0)
+ if (strmatch (redist_type[i].str, argv[idx_protocol]->text))
{
rip_redistribute_metric_set (redist_type[i].type, metric);
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
@@ -501,44 +461,42 @@ DEFUN (rip_redistribute_type_metric,
}
}
- vty_out(vty, "Invalid type %s%s", argv[0],
- VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text, VTY_NEWLINE);
return CMD_WARNING;
}
DEFUN (no_rip_redistribute_type_metric,
no_rip_redistribute_type_metric_cmd,
- "no redistribute " FRR_REDIST_STR_RIPD " metric <0-16>",
+ "no redistribute " FRR_REDIST_STR_RIPD " metric (0-16)",
NO_STR
REDIST_STR
FRR_REDIST_HELP_STR_RIPD
"Metric\n"
"Metric value\n")
{
+ int idx_protocol = 2;
+ int idx_number = 4;
int i;
- for (i = 0; redist_type[i].str; i++)
- {
- if (strncmp(redist_type[i].str, argv[0],
- redist_type[i].str_min_len) == 0)
- {
- if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
- return CMD_WARNING;
- rip_redistribute_unset (redist_type[i].type);
- return CMD_SUCCESS;
- }
- }
+ for (i = 0; redist_type[i].str; i++) {
+ if (strmatch (redist_type[i].str, argv[idx_protocol]->text))
+ {
+ if (rip_metric_unset (redist_type[i].type, atoi(argv[idx_number]->arg)))
+ return CMD_WARNING;
+ rip_redistribute_unset (redist_type[i].type);
+ return CMD_SUCCESS;
+ }
+ }
- vty_out(vty, "Invalid type %s%s", argv[0],
- VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text, VTY_NEWLINE);
return CMD_WARNING;
}
DEFUN (rip_redistribute_type_metric_routemap,
rip_redistribute_type_metric_routemap_cmd,
- "redistribute " FRR_REDIST_STR_RIPD " metric <0-16> route-map WORD",
+ "redistribute " FRR_REDIST_STR_RIPD " metric (0-16) route-map WORD",
REDIST_STR
FRR_REDIST_HELP_STR_RIPD
"Metric\n"
@@ -546,25 +504,26 @@ DEFUN (rip_redistribute_type_metric_routemap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ int idx_protocol = 1;
+ int idx_number = 3;
+ int idx_word = 5;
int i;
int metric;
- metric = atoi (argv[1]);
+ metric = atoi (argv[idx_number]->arg);
for (i = 0; redist_type[i].str; i++) {
- if (strncmp(redist_type[i].str, argv[0],
- redist_type[i].str_min_len) == 0)
+ if (strmatch (redist_type[i].str, argv[idx_protocol]->text))
{
rip_redistribute_metric_set (redist_type[i].type, metric);
- rip_routemap_set (redist_type[i].type, argv[2]);
+ rip_routemap_set (redist_type[i].type, argv[idx_word]->arg);
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
redist_type[i].type, 0, VRF_DEFAULT);
return CMD_SUCCESS;
}
}
- vty_out(vty, "Invalid type %s%s", argv[0],
- VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -572,8 +531,7 @@ DEFUN (rip_redistribute_type_metric_routemap,
DEFUN (no_rip_redistribute_type_metric_routemap,
no_rip_redistribute_type_metric_routemap_cmd,
- "no redistribute " FRR_REDIST_STR_RIPD
- " metric <0-16> route-map WORD",
+ "no redistribute " FRR_REDIST_STR_RIPD " metric (0-16) route-map WORD",
NO_STR
REDIST_STR
FRR_REDIST_HELP_STR_RIPD
@@ -582,27 +540,27 @@ DEFUN (no_rip_redistribute_type_metric_routemap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ int idx_protocol = 2;
+ int idx_number = 4;
+ int idx_word = 6;
int i;
- for (i = 0; redist_type[i].str; i++)
- {
- if (strncmp(redist_type[i].str, argv[0],
- redist_type[i].str_min_len) == 0)
- {
- if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
- return CMD_WARNING;
- if (rip_routemap_unset (redist_type[i].type, argv[2]))
- {
- rip_redistribute_metric_set(redist_type[i].type, atoi(argv[1]));
- return CMD_WARNING;
- }
- rip_redistribute_unset (redist_type[i].type);
- return CMD_SUCCESS;
- }
+ for (i = 0; redist_type[i].str; i++) {
+ if (strmatch (redist_type[i].str, argv[idx_protocol]->text))
+ {
+ if (rip_metric_unset (redist_type[i].type, atoi(argv[idx_number]->arg)))
+ return CMD_WARNING;
+ if (rip_routemap_unset (redist_type[i].type, argv[idx_word]->arg))
+ {
+ rip_redistribute_metric_set(redist_type[i].type, atoi(argv[idx_number]->arg));
+ return CMD_WARNING;
+ }
+ rip_redistribute_unset (redist_type[i].type);
+ return CMD_SUCCESS;
+ }
}
- vty_out(vty, "Invalid type %s%s", argv[0],
- VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -744,8 +702,6 @@ rip_zclient_init (struct thread_master *master)
install_node (&zebra_node, config_write_zebra);
/* Install command elements to zebra node. */
- install_element (CONFIG_NODE, &router_zebra_cmd);
- install_element (CONFIG_NODE, &no_router_zebra_cmd);
install_default (ZEBRA_NODE);
install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd);
install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
diff --git a/ripd/ripd.c b/ripd/ripd.c
index a99de3876b..bcf4cd3347 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -45,6 +45,8 @@
#include "ripd/ripd.h"
#include "ripd/rip_debug.h"
+DEFINE_QOBJ_TYPE(rip)
+
/* UDP receive buffer size */
#define RIP_UDP_RCV_BUF 41600
@@ -334,11 +336,11 @@ rip_filter (int rip_distribute, struct prefix_ipv4 *p, struct rip_interface *ri)
if (IS_RIP_DEBUG_PACKET)
zlog_debug ("%s/%d filtered by distribute %s",
inet_ntoa (p->prefix), p->prefixlen, inout);
- return -1;
- }
- }
+ return -1;
+ }
+ }
if (ri->prefix[rip_distribute])
- {
+{
if (prefix_list_apply (ri->prefix[rip_distribute],
(struct prefix *) p) == PREFIX_DENY)
{
@@ -356,7 +358,7 @@ rip_filter (int rip_distribute, struct prefix_ipv4 *p, struct rip_interface *ri)
if (dist->list[distribute])
{
alist = access_list_lookup (AFI_IP, dist->list[distribute]);
-
+
if (alist)
{
if (access_list_apply (alist, (struct prefix *) p) == FILTER_DENY)
@@ -371,7 +373,7 @@ rip_filter (int rip_distribute, struct prefix_ipv4 *p, struct rip_interface *ri)
if (dist->prefix[distribute])
{
plist = prefix_list_lookup (AFI_IP, dist->prefix[distribute]);
-
+
if (plist)
{
if (prefix_list_apply (plist,
@@ -2698,6 +2700,8 @@ rip_create (void)
rip_event (RIP_READ, rip->sock);
rip_event (RIP_UPDATE_EVENT, 1);
+ QOBJ_REG (rip, rip);
+
return 0;
}
@@ -2816,8 +2820,7 @@ DEFUN (router_rip,
return CMD_WARNING;
}
}
- vty->node = RIP_NODE;
- vty->index = rip;
+ VTY_PUSH_CONTEXT(RIP_NODE, rip);
return CMD_SUCCESS;
}
@@ -2836,13 +2839,14 @@ DEFUN (no_router_rip,
DEFUN (rip_version,
rip_version_cmd,
- "version <1-2>",
+ "version (1-2)",
"Set routing protocol version\n"
"version\n")
{
+ int idx_number = 1;
int version;
- version = atoi (argv[0]);
+ version = atoi (argv[idx_number]->arg);
if (version != RIPv1 && version != RIPv2)
{
vty_out (vty, "invalid rip version %d%s", version,
@@ -2853,27 +2857,22 @@ DEFUN (rip_version,
rip->version_recv = version;
return CMD_SUCCESS;
-}
+}
DEFUN (no_rip_version,
no_rip_version_cmd,
- "no version",
+ "no version [(1-2)]",
NO_STR
- "Set routing protocol version\n")
+ "Set routing protocol version\n"
+ "Version\n")
{
/* Set RIP version to the default. */
rip->version_send = RI_RIP_VERSION_2;
rip->version_recv = RI_RIP_VERSION_1_AND_2;
return CMD_SUCCESS;
-}
+}
-ALIAS (no_rip_version,
- no_rip_version_val_cmd,
- "no version <1-2>",
- NO_STR
- "Set routing protocol version\n"
- "version\n")
DEFUN (rip_route,
rip_route_cmd,
@@ -2881,11 +2880,12 @@ DEFUN (rip_route,
"RIP static route configuration\n"
"IP prefix <network>/<length>\n")
{
+ int idx_ipv4_prefixlen = 1;
int ret;
struct prefix_ipv4 p;
struct route_node *node;
- ret = str2prefix_ipv4 (argv[0], &p);
+ ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
if (ret < 0)
{
vty_out (vty, "Malformed address%s", VTY_NEWLINE);
@@ -2917,11 +2917,12 @@ DEFUN (no_rip_route,
"RIP static route configuration\n"
"IP prefix <network>/<length>\n")
{
+ int idx_ipv4_prefixlen = 2;
int ret;
struct prefix_ipv4 p;
struct route_node *node;
- ret = str2prefix_ipv4 (argv[0], &p);
+ ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
if (ret < 0)
{
vty_out (vty, "Malformed address%s", VTY_NEWLINE);
@@ -2933,7 +2934,7 @@ DEFUN (no_rip_route,
node = route_node_lookup (rip->route, (struct prefix *) &p);
if (! node)
{
- vty_out (vty, "Can't find route %s.%s", argv[0],
+ vty_out (vty, "Can't find route %s.%s", argv[idx_ipv4_prefixlen]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -2966,13 +2967,14 @@ rip_update_default_metric (void)
DEFUN (rip_default_metric,
rip_default_metric_cmd,
- "default-metric <1-16>",
+ "default-metric (1-16)",
"Set a metric of redistribute routes\n"
"Default metric\n")
{
+ int idx_number = 1;
if (rip)
{
- rip->default_metric = atoi (argv[0]);
+ rip->default_metric = atoi (argv[idx_number]->arg);
/* rip_update_default_metric (); */
}
return CMD_SUCCESS;
@@ -2980,7 +2982,7 @@ DEFUN (rip_default_metric,
DEFUN (no_rip_default_metric,
no_rip_default_metric_cmd,
- "no default-metric",
+ "no default-metric [(1-16)]",
NO_STR
"Set a metric of redistribute routes\n"
"Default metric\n")
@@ -2993,22 +2995,19 @@ DEFUN (no_rip_default_metric,
return CMD_SUCCESS;
}
-ALIAS (no_rip_default_metric,
- no_rip_default_metric_val_cmd,
- "no default-metric <1-16>",
- NO_STR
- "Set a metric of redistribute routes\n"
- "Default metric\n")
DEFUN (rip_timers,
rip_timers_cmd,
- "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
+ "timers basic (5-2147483647) (5-2147483647) (5-2147483647)",
"Adjust routing timers\n"
"Basic routing protocol update timers\n"
"Routing table update timer value in second. Default is 30.\n"
"Routing information timeout timer. Default is 180.\n"
"Garbage collection timer. Default is 120.\n")
{
+ int idx_number = 2;
+ int idx_number_2 = 3;
+ int idx_number_3 = 4;
unsigned long update;
unsigned long timeout;
unsigned long garbage;
@@ -3016,21 +3015,21 @@ DEFUN (rip_timers,
unsigned long RIP_TIMER_MAX = 2147483647;
unsigned long RIP_TIMER_MIN = 5;
- update = strtoul (argv[0], &endptr, 10);
+ update = strtoul (argv[idx_number]->arg, &endptr, 10);
if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN || *endptr != '\0')
{
vty_out (vty, "update timer value error%s", VTY_NEWLINE);
return CMD_WARNING;
}
- timeout = strtoul (argv[1], &endptr, 10);
+ timeout = strtoul (argv[idx_number_2]->arg, &endptr, 10);
if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN || *endptr != '\0')
{
vty_out (vty, "timeout timer value error%s", VTY_NEWLINE);
return CMD_WARNING;
}
- garbage = strtoul (argv[2], &endptr, 10);
+ garbage = strtoul (argv[idx_number_3]->arg, &endptr, 10);
if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN || *endptr != '\0')
{
vty_out (vty, "garbage timer value error%s", VTY_NEWLINE);
@@ -3050,10 +3049,13 @@ DEFUN (rip_timers,
DEFUN (no_rip_timers,
no_rip_timers_cmd,
- "no timers basic",
+ "no timers basic [(0-65535) (0-65535) (0-65535)]",
NO_STR
"Adjust routing timers\n"
- "Basic routing protocol update timers\n")
+ "Basic routing protocol update timers\n"
+ "Routing table update timer value in second. Default is 30.\n"
+ "Routing information timeout timer. Default is 180.\n"
+ "Garbage collection timer. Default is 120.\n")
{
/* Set each timer value to the default. */
rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
@@ -3066,15 +3068,6 @@ DEFUN (no_rip_timers,
return CMD_SUCCESS;
}
-ALIAS (no_rip_timers,
- no_rip_timers_val_cmd,
- "no timers basic <0-65535> <0-65535> <0-65535>",
- NO_STR
- "Adjust routing timers\n"
- "Basic routing protocol update timers\n"
- "Routing table update timer value in second. Default is 30.\n"
- "Routing information timeout timer. Default is 180.\n"
- "Garbage collection timer. Default is 120.\n")
struct route_table *rip_distance_table;
@@ -3275,17 +3268,18 @@ rip_distance_show (struct vty *vty)
DEFUN (rip_distance,
rip_distance_cmd,
- "distance <1-255>",
+ "distance (1-255)",
"Administrative distance\n"
"Distance value\n")
{
- rip->distance = atoi (argv[0]);
+ int idx_number = 1;
+ rip->distance = atoi (argv[idx_number]->arg);
return CMD_SUCCESS;
}
DEFUN (no_rip_distance,
no_rip_distance_cmd,
- "no distance <1-255>",
+ "no distance (1-255)",
NO_STR
"Administrative distance\n"
"Distance value\n")
@@ -3296,49 +3290,59 @@ DEFUN (no_rip_distance,
DEFUN (rip_distance_source,
rip_distance_source_cmd,
- "distance <1-255> A.B.C.D/M",
+ "distance (1-255) A.B.C.D/M",
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n")
{
- rip_distance_set (vty, argv[0], argv[1], NULL);
+ int idx_number = 1;
+ int idx_ipv4_prefixlen = 2;
+ rip_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
return CMD_SUCCESS;
}
DEFUN (no_rip_distance_source,
no_rip_distance_source_cmd,
- "no distance <1-255> A.B.C.D/M",
+ "no distance (1-255) A.B.C.D/M",
NO_STR
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n")
{
- rip_distance_unset (vty, argv[0], argv[1], NULL);
+ int idx_number = 2;
+ int idx_ipv4_prefixlen = 3;
+ rip_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
return CMD_SUCCESS;
}
DEFUN (rip_distance_source_access_list,
rip_distance_source_access_list_cmd,
- "distance <1-255> A.B.C.D/M WORD",
+ "distance (1-255) A.B.C.D/M WORD",
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n"
"Access list name\n")
{
- rip_distance_set (vty, argv[0], argv[1], argv[2]);
+ int idx_number = 1;
+ int idx_ipv4_prefixlen = 2;
+ int idx_word = 3;
+ rip_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
return CMD_SUCCESS;
}
DEFUN (no_rip_distance_source_access_list,
no_rip_distance_source_access_list_cmd,
- "no distance <1-255> A.B.C.D/M WORD",
+ "no distance (1-255) A.B.C.D/M WORD",
NO_STR
"Administrative distance\n"
"Distance value\n"
"IP source prefix\n"
"Access list name\n")
{
- rip_distance_unset (vty, argv[0], argv[1], argv[2]);
+ int idx_number = 2;
+ int idx_ipv4_prefixlen = 3;
+ int idx_word = 4;
+ rip_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
return CMD_SUCCESS;
}
@@ -3850,6 +3854,8 @@ rip_clean (void)
if (rip)
{
+ QOBJ_UNREG (rip);
+
/* Clear RIP routes */
for (rp = route_top (rip->table); rp; rp = route_next (rp))
if ((list = rp->info) != NULL)
@@ -4043,13 +4049,10 @@ rip_init (void)
install_default (RIP_NODE);
install_element (RIP_NODE, &rip_version_cmd);
install_element (RIP_NODE, &no_rip_version_cmd);
- install_element (RIP_NODE, &no_rip_version_val_cmd);
install_element (RIP_NODE, &rip_default_metric_cmd);
install_element (RIP_NODE, &no_rip_default_metric_cmd);
- install_element (RIP_NODE, &no_rip_default_metric_val_cmd);
install_element (RIP_NODE, &rip_timers_cmd);
install_element (RIP_NODE, &no_rip_timers_cmd);
- install_element (RIP_NODE, &no_rip_timers_val_cmd);
install_element (RIP_NODE, &rip_route_cmd);
install_element (RIP_NODE, &no_rip_route_cmd);
install_element (RIP_NODE, &rip_distance_cmd);
diff --git a/ripd/ripd.h b/ripd/ripd.h
index cb4764a7f1..68b3d1fc6e 100644
--- a/ripd/ripd.h
+++ b/ripd/ripd.h
@@ -22,6 +22,7 @@
#ifndef _ZEBRA_RIP_H
#define _ZEBRA_RIP_H
+#include "qobj.h"
#include "rip_memory.h"
/* RIP version number. */
@@ -156,7 +157,10 @@ struct rip
int metric_config;
u_int32_t metric;
} route_map[ZEBRA_ROUTE_MAX];
+
+ QOBJ_FIELDS
};
+DECLARE_QOBJ_TYPE(rip)
/* RIP routing table entry which belong to rip_packet. */
struct rte
@@ -389,7 +393,6 @@ extern void rip_route_map_init (void);
extern void rip_route_map_reset (void);
extern void rip_snmp_init (void);
extern void rip_zclient_init(struct thread_master *);
-extern void rip_zclient_start (void);
extern void rip_zclient_reset (void);
extern void rip_offset_init (void);
extern int if_check_address (struct in_addr addr);
diff --git a/ripngd/ripng_debug.c b/ripngd/ripng_debug.c
index eb8ff5dc6d..16c8b3400d 100644
--- a/ripngd/ripng_debug.c
+++ b/ripngd/ripng_debug.c
@@ -91,38 +91,18 @@ DEFUN (debug_ripng_packet,
DEFUN (debug_ripng_packet_direct,
debug_ripng_packet_direct_cmd,
- "debug ripng packet (recv|send)",
+ "debug ripng packet <recv|send>",
DEBUG_STR
"RIPng configuration\n"
"Debug option set for ripng packet\n"
"Debug option set for receive packet\n"
"Debug option set for send packet\n")
{
+ int idx_recv_send = 3;
ripng_debug_packet |= RIPNG_DEBUG_PACKET;
- if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
+ if (strncmp ("send", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0)
ripng_debug_packet |= RIPNG_DEBUG_SEND;
- if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
- ripng_debug_packet |= RIPNG_DEBUG_RECV;
-
- return CMD_SUCCESS;
-}
-
-/* N.B. the "detail" modifier is a no-op. we leave this command
- for legacy compatibility. */
-DEFUN_DEPRECATED (debug_ripng_packet_detail,
- debug_ripng_packet_detail_cmd,
- "debug ripng packet (recv|send) detail",
- DEBUG_STR
- "RIPng configuration\n"
- "Debug option set for ripng packet\n"
- "Debug option set for receive packet\n"
- "Debug option set for send packet\n"
- "Debug option set detaied information\n")
-{
- ripng_debug_packet |= RIPNG_DEBUG_PACKET;
- if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
- ripng_debug_packet |= RIPNG_DEBUG_SEND;
- if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
+ if (strncmp ("recv", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0)
ripng_debug_packet |= RIPNG_DEBUG_RECV;
return CMD_SUCCESS;
@@ -165,7 +145,7 @@ DEFUN (no_debug_ripng_packet,
DEFUN (no_debug_ripng_packet_direct,
no_debug_ripng_packet_direct_cmd,
- "no debug ripng packet (recv|send)",
+ "no debug ripng packet <recv|send>",
NO_STR
DEBUG_STR
"RIPng configuration\n"
@@ -173,14 +153,15 @@ DEFUN (no_debug_ripng_packet_direct,
"Debug option set for receive packet\n"
"Debug option set for send packet\n")
{
- if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
+ int idx_recv_send = 4;
+ if (strncmp ("send", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0)
{
if (IS_RIPNG_DEBUG_RECV)
ripng_debug_packet &= ~RIPNG_DEBUG_SEND;
else
ripng_debug_packet = 0;
}
- else if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
+ else if (strncmp ("recv", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0)
{
if (IS_RIPNG_DEBUG_SEND)
ripng_debug_packet &= ~RIPNG_DEBUG_RECV;
@@ -269,7 +250,6 @@ ripng_debug_init ()
install_element (ENABLE_NODE, &debug_ripng_events_cmd);
install_element (ENABLE_NODE, &debug_ripng_packet_cmd);
install_element (ENABLE_NODE, &debug_ripng_packet_direct_cmd);
- install_element (ENABLE_NODE, &debug_ripng_packet_detail_cmd);
install_element (ENABLE_NODE, &debug_ripng_zebra_cmd);
install_element (ENABLE_NODE, &no_debug_ripng_events_cmd);
install_element (ENABLE_NODE, &no_debug_ripng_packet_cmd);
@@ -279,7 +259,6 @@ ripng_debug_init ()
install_element (CONFIG_NODE, &debug_ripng_events_cmd);
install_element (CONFIG_NODE, &debug_ripng_packet_cmd);
install_element (CONFIG_NODE, &debug_ripng_packet_direct_cmd);
- install_element (CONFIG_NODE, &debug_ripng_packet_detail_cmd);
install_element (CONFIG_NODE, &debug_ripng_zebra_cmd);
install_element (CONFIG_NODE, &no_debug_ripng_events_cmd);
install_element (CONFIG_NODE, &no_debug_ripng_packet_cmd);
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index a8742ec9a4..1ac9e40f67 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -953,20 +953,21 @@ DEFUN (ripng_network,
"RIPng enable on specified interface or network.\n"
"Interface or address")
{
+ int idx_if_or_addr = 1;
int ret;
struct prefix p;
- ret = str2prefix (argv[0], &p);
+ ret = str2prefix (argv[idx_if_or_addr]->arg, &p);
/* Given string is IPv6 network or interface name. */
if (ret)
ret = ripng_enable_network_add (&p);
else
- ret = ripng_enable_if_add (argv[0]);
+ ret = ripng_enable_if_add (argv[idx_if_or_addr]->arg);
if (ret < 0)
{
- vty_out (vty, "There is same network configuration %s%s", argv[0],
+ vty_out (vty, "There is same network configuration %s%s", argv[idx_if_or_addr]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -982,20 +983,21 @@ DEFUN (no_ripng_network,
"RIPng enable on specified interface or network.\n"
"Interface or address")
{
+ int idx_if_or_addr = 2;
int ret;
struct prefix p;
- ret = str2prefix (argv[0], &p);
+ ret = str2prefix (argv[idx_if_or_addr]->arg, &p);
/* Given string is interface name. */
if (ret)
ret = ripng_enable_network_delete (&p);
else
- ret = ripng_enable_if_delete (argv[0]);
+ ret = ripng_enable_if_delete (argv[idx_if_or_addr]->arg);
if (ret < 0)
{
- vty_out (vty, "can't find network %s%s", argv[0],
+ vty_out (vty, "can't find network %s%s", argv[idx_if_or_addr]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1010,10 +1012,9 @@ DEFUN (ipv6_ripng_split_horizon,
"Routing Information Protocol\n"
"Perform split horizon\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ripng_interface *ri;
- ifp = vty->index;
ri = ifp->info;
ri->split_horizon = RIPNG_SPLIT_HORIZON;
@@ -1028,10 +1029,9 @@ DEFUN (ipv6_ripng_split_horizon_poisoned_reverse,
"Perform split horizon\n"
"With poisoned-reverse\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ripng_interface *ri;
- ifp = vty->index;
ri = ifp->info;
ri->split_horizon = RIPNG_SPLIT_HORIZON_POISONED_REVERSE;
@@ -1040,38 +1040,30 @@ DEFUN (ipv6_ripng_split_horizon_poisoned_reverse,
DEFUN (no_ipv6_ripng_split_horizon,
no_ipv6_ripng_split_horizon_cmd,
- "no ipv6 ripng split-horizon",
+ "no ipv6 ripng split-horizon [poisoned-reverse]",
NO_STR
IPV6_STR
"Routing Information Protocol\n"
- "Perform split horizon\n")
+ "Perform split horizon\n"
+ "With poisoned-reverse\n")
{
- struct interface *ifp;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
struct ripng_interface *ri;
- ifp = vty->index;
ri = ifp->info;
ri->split_horizon = RIPNG_NO_SPLIT_HORIZON;
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_ripng_split_horizon,
- no_ipv6_ripng_split_horizon_poisoned_reverse_cmd,
- "no ipv6 ripng split-horizon poisoned-reverse",
- NO_STR
- IPV6_STR
- "Routing Information Protocol\n"
- "Perform split horizon\n"
- "With poisoned-reverse\n")
-
DEFUN (ripng_passive_interface,
ripng_passive_interface_cmd,
"passive-interface IFNAME",
"Suppress routing updates on an interface\n"
"Interface name\n")
{
- return ripng_passive_interface_set (vty, argv[0]);
+ int idx_ifname = 1;
+ return ripng_passive_interface_set (vty, argv[idx_ifname]->arg);
}
DEFUN (no_ripng_passive_interface,
@@ -1081,7 +1073,8 @@ DEFUN (no_ripng_passive_interface,
"Suppress routing updates on an interface\n"
"Interface name\n")
{
- return ripng_passive_interface_unset (vty, argv[0]);
+ int idx_ifname = 2;
+ return ripng_passive_interface_unset (vty, argv[idx_ifname]->arg);
}
static struct ripng_interface *
@@ -1194,13 +1187,7 @@ ripng_if_init ()
/* Install interface node. */
install_node (&interface_node, interface_config_write);
-
- /* Install commands. */
- install_element (CONFIG_NODE, &interface_cmd);
- install_element (CONFIG_NODE, &no_interface_cmd);
- install_default (INTERFACE_NODE);
- install_element (INTERFACE_NODE, &interface_desc_cmd);
- install_element (INTERFACE_NODE, &no_interface_desc_cmd);
+ if_cmd_init ();
install_element (RIPNG_NODE, &ripng_network_cmd);
install_element (RIPNG_NODE, &no_ripng_network_cmd);
@@ -1210,5 +1197,4 @@ ripng_if_init ()
install_element (INTERFACE_NODE, &ipv6_ripng_split_horizon_cmd);
install_element (INTERFACE_NODE, &ipv6_ripng_split_horizon_poisoned_reverse_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ripng_split_horizon_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_ripng_split_horizon_poisoned_reverse_cmd);
}
diff --git a/ripngd/ripng_offset.c b/ripngd/ripng_offset.c
index 4ed6e9b0c4..dcddf96ebf 100644
--- a/ripngd/ripng_offset.c
+++ b/ripngd/ripng_offset.c
@@ -290,19 +290,22 @@ ripng_offset_list_apply_out (struct prefix_ipv6 *p, struct interface *ifp,
DEFUN (ripng_offset_list,
ripng_offset_list_cmd,
- "offset-list WORD (in|out) <0-16>",
+ "offset-list WORD <in|out> (0-16)",
"Modify RIPng metric\n"
"Access-list name\n"
"For incoming updates\n"
"For outgoing updates\n"
"Metric value\n")
{
- return ripng_offset_list_set (vty, argv[0], argv[1], argv[2], NULL);
+ int idx_word = 1;
+ int idx_in_out = 2;
+ int idx_number = 3;
+ return ripng_offset_list_set (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, NULL);
}
DEFUN (ripng_offset_list_ifname,
ripng_offset_list_ifname_cmd,
- "offset-list WORD (in|out) <0-16> IFNAME",
+ "offset-list WORD <in|out> (0-16) IFNAME",
"Modify RIPng metric\n"
"Access-list name\n"
"For incoming updates\n"
@@ -310,12 +313,16 @@ DEFUN (ripng_offset_list_ifname,
"Metric value\n"
"Interface to match\n")
{
- return ripng_offset_list_set (vty, argv[0], argv[1], argv[2], argv[3]);
+ int idx_word = 1;
+ int idx_in_out = 2;
+ int idx_number = 3;
+ int idx_ifname = 4;
+ return ripng_offset_list_set (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, argv[idx_ifname]->arg);
}
DEFUN (no_ripng_offset_list,
no_ripng_offset_list_cmd,
- "no offset-list WORD (in|out) <0-16>",
+ "no offset-list WORD <in|out> (0-16)",
NO_STR
"Modify RIPng metric\n"
"Access-list name\n"
@@ -323,12 +330,15 @@ DEFUN (no_ripng_offset_list,
"For outgoing updates\n"
"Metric value\n")
{
- return ripng_offset_list_unset (vty, argv[0], argv[1], argv[2], NULL);
+ int idx_word = 2;
+ int idx_in_out = 3;
+ int idx_number = 4;
+ return ripng_offset_list_unset (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, NULL);
}
DEFUN (no_ripng_offset_list_ifname,
no_ripng_offset_list_ifname_cmd,
- "no offset-list WORD (in|out) <0-16> IFNAME",
+ "no offset-list WORD <in|out> (0-16) IFNAME",
NO_STR
"Modify RIPng metric\n"
"Access-list name\n"
@@ -337,7 +347,11 @@ DEFUN (no_ripng_offset_list_ifname,
"Metric value\n"
"Interface to match\n")
{
- return ripng_offset_list_unset (vty, argv[0], argv[1], argv[2], argv[3]);
+ int idx_word = 2;
+ int idx_in_out = 3;
+ int idx_number = 4;
+ int idx_ifname = 5;
+ return ripng_offset_list_unset (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, argv[idx_ifname]->arg);
}
static int
diff --git a/ripngd/ripng_routemap.c b/ripngd/ripng_routemap.c
index 19fa70227d..7cab5861bf 100644
--- a/ripngd/ripng_routemap.c
+++ b/ripngd/ripng_routemap.c
@@ -24,6 +24,7 @@
#include "if.h"
#include "memory.h"
#include "prefix.h"
+#include "vty.h"
#include "routemap.h"
#include "command.h"
#include "sockunion.h"
@@ -42,95 +43,6 @@ struct rip_metric_modifier
u_char metric;
};
-
-static int
-ripng_route_match_add (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_add_match (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
-static int
-ripng_route_match_delete (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_delete_match (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
-static int
-ripng_route_set_add (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_add_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
-static int
-ripng_route_set_delete (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
-{
- int ret;
-
- ret = route_map_delete_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
/* `match metric METRIC' */
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
@@ -442,7 +354,7 @@ route_set_tag (void *rule, struct prefix *prefix,
/* Fetch routemap's rule information. */
tag = rule;
rinfo = object;
-
+
/* Set next hop value. */
rinfo->tag_out = *tag;
}
@@ -462,216 +374,6 @@ static struct route_map_rule_cmd route_set_tag_cmd =
#define MATCH_STR "Match values from routing table\n"
#define SET_STR "Set values in destination routing protocol\n"
-DEFUN (match_metric,
- match_metric_cmd,
- "match metric <0-4294967295>",
- MATCH_STR
- "Match metric of route\n"
- "Metric value\n")
-{
- return ripng_route_match_add (vty, vty->index, "metric", argv[0]);
-}
-
-DEFUN (no_match_metric,
- no_match_metric_cmd,
- "no match metric",
- NO_STR
- MATCH_STR
- "Match metric of route\n")
-{
- if (argc == 0)
- return ripng_route_match_delete (vty, vty->index, "metric", NULL);
-
- return ripng_route_match_delete (vty, vty->index, "metric", argv[0]);
-}
-
-ALIAS (no_match_metric,
- no_match_metric_val_cmd,
- "no match metric <0-4294967295>",
- NO_STR
- MATCH_STR
- "Match metric of route\n"
- "Metric value\n")
-
-DEFUN (match_interface,
- match_interface_cmd,
- "match interface WORD",
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-{
- return ripng_route_match_add (vty, vty->index, "interface", argv[0]);
-}
-
-DEFUN (no_match_interface,
- no_match_interface_cmd,
- "no match interface",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n")
-{
- if (argc == 0)
- return ripng_route_match_delete (vty, vty->index, "interface", NULL);
-
- return ripng_route_match_delete (vty, vty->index, "interface", argv[0]);
-}
-
-ALIAS (no_match_interface,
- no_match_interface_val_cmd,
- "no match interface WORD",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-
-DEFUN (match_tag,
- match_tag_cmd,
- "match tag <1-4294967295>",
- MATCH_STR
- "Match tag of route\n"
- "Metric value\n")
-{
- return ripng_route_match_add (vty, vty->index, "tag", argv[0]);
-}
-
-DEFUN (no_match_tag,
- no_match_tag_cmd,
- "no match tag",
- NO_STR
- MATCH_STR
- "Match tag of route\n")
-{
- if (argc == 0)
- return ripng_route_match_delete (vty, vty->index, "tag", NULL);
-
- return ripng_route_match_delete (vty, vty->index, "tag", argv[0]);
-}
-
-ALIAS (no_match_tag,
- no_match_tag_val_cmd,
- "no match tag <1-4294967295>",
- NO_STR
- MATCH_STR
- "Match tag of route\n"
- "Metric value\n")
-
-/* set functions */
-
-DEFUN (set_metric,
- set_metric_cmd,
- "set metric <0-4294967295>",
- "Set value\n"
- "Metric value for destination routing protocol\n"
- "Metric value\n")
-{
- return ripng_route_set_add (vty, vty->index, "metric", argv[0]);
-}
-
-DEFUN (no_set_metric,
- no_set_metric_cmd,
- "no set metric",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n")
-{
- if (argc == 0)
- return ripng_route_set_delete (vty, vty->index, "metric", NULL);
-
- return ripng_route_set_delete (vty, vty->index, "metric", argv[0]);
-}
-
-ALIAS (no_set_metric,
- no_set_metric_val_cmd,
- "no set metric <0-4294967295>",
- NO_STR
- SET_STR
- "Metric value for destination routing protocol\n"
- "Metric value\n")
-
-DEFUN (set_ipv6_nexthop_local,
- set_ipv6_nexthop_local_cmd,
- "set ipv6 next-hop local X:X::X:X",
- SET_STR
- IPV6_STR
- "IPv6 next-hop address\n"
- "IPv6 local address\n"
- "IPv6 address of next hop\n")
-{
- union sockunion su;
- int ret;
-
- ret = str2sockunion (argv[0], &su);
- if (ret < 0)
- {
- vty_out (vty, "%% Malformed next-hop local address%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (!IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr))
- {
- vty_out (vty, "%% Invalid link-local nexthop address%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return ripng_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
-}
-
-DEFUN (no_set_ipv6_nexthop_local,
- no_set_ipv6_nexthop_local_cmd,
- "no set ipv6 next-hop local",
- NO_STR
- SET_STR
- IPV6_STR
- "IPv6 next-hop address\n"
- "IPv6 local address\n")
-{
- if (argc == 0)
- return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
-
- return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
-}
-
-ALIAS (no_set_ipv6_nexthop_local,
- no_set_ipv6_nexthop_local_val_cmd,
- "no set ipv6 next-hop local X:X::X:X",
- NO_STR
- SET_STR
- IPV6_STR
- "IPv6 next-hop address\n"
- "IPv6 local address\n"
- "IPv6 address of next hop\n")
-
-DEFUN (set_tag,
- set_tag_cmd,
- "set tag <1-4294967295>",
- SET_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
-{
- return ripng_route_set_add (vty, vty->index, "tag", argv[0]);
-}
-
-DEFUN (no_set_tag,
- no_set_tag_cmd,
- "no set tag",
- NO_STR
- SET_STR
- "Tag value for routing protocol\n")
-{
- if (argc == 0)
- return ripng_route_set_delete (vty, vty->index, "tag", NULL);
-
- return ripng_route_set_delete (vty, vty->index, "tag", argv[0]);
-}
-
-ALIAS (no_set_tag,
- no_set_tag_val_cmd,
- "no set tag <1-4294967295>",
- NO_STR
- SET_STR
- "Tag value for routing protocol\n"
- "Tag value\n")
-
void
ripng_route_map_reset ()
{
@@ -684,31 +386,28 @@ ripng_route_map_init ()
{
route_map_init ();
+ route_map_match_interface_hook (generic_match_add);
+ route_map_no_match_interface_hook (generic_match_delete);
+
+ route_map_match_metric_hook (generic_match_add);
+ route_map_no_match_metric_hook (generic_match_delete);
+
+ route_map_match_tag_hook (generic_match_add);
+ route_map_no_match_tag_hook (generic_match_delete);
+
+ route_map_set_ipv6_nexthop_local_hook (generic_set_add);
+ route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete);
+
+ route_map_set_metric_hook (generic_set_add);
+ route_map_no_set_metric_hook (generic_set_delete);
+
+ route_map_set_tag_hook (generic_set_add);
+ route_map_no_set_tag_hook (generic_set_delete);
+
route_map_install_match (&route_match_metric_cmd);
route_map_install_match (&route_match_interface_cmd);
route_map_install_match (&route_match_tag_cmd);
-
route_map_install_set (&route_set_metric_cmd);
route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
route_map_install_set (&route_set_tag_cmd);
-
- install_element (RMAP_NODE, &match_metric_cmd);
- install_element (RMAP_NODE, &no_match_metric_cmd);
- install_element (RMAP_NODE, &no_match_metric_val_cmd);
- install_element (RMAP_NODE, &match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_val_cmd);
- install_element (RMAP_NODE, &match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_val_cmd);
-
- install_element (RMAP_NODE, &set_metric_cmd);
- install_element (RMAP_NODE, &no_set_metric_cmd);
- install_element (RMAP_NODE, &no_set_metric_val_cmd);
- install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
- install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
- install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
- install_element (RMAP_NODE, &set_tag_cmd);
- install_element (RMAP_NODE, &no_set_tag_cmd);
- install_element (RMAP_NODE, &no_set_tag_val_cmd);
}
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index 67337caf28..964af81d1f 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -99,7 +99,7 @@ ripng_zebra_ipv6_send (struct route_node *rp, u_char cmd)
}
zapi_ipv6_route (cmd, zclient,
- (struct prefix_ipv6 *)&rp->p, &api);
+ (struct prefix_ipv6 *)&rp->p, NULL, &api);
if (IS_RIPNG_DEBUG_ZEBRA)
{
@@ -140,7 +140,7 @@ ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
struct zapi_ipv6 api;
unsigned long ifindex;
struct in6_addr nexthop;
- struct prefix_ipv6 p;
+ struct prefix_ipv6 p, src_p;
s = zclient->ibuf;
ifindex = 0;
@@ -158,6 +158,18 @@ ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s));
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
+ {
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ }
+
+ if (src_p.prefixlen)
+ /* we completely ignore srcdest routes for now. */
+ return 0;
+
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
@@ -292,30 +304,6 @@ ripng_redistribute_clean ()
}
}
-DEFUN (router_zebra,
- router_zebra_cmd,
- "router zebra",
- "Enable a routing process\n"
- "Make connection to zebra daemon\n")
-{
- vty->node = ZEBRA_NODE;
- zclient->enable = 1;
- zclient_start (zclient);
- return CMD_SUCCESS;
-}
-
-DEFUN (no_router_zebra,
- no_router_zebra_cmd,
- "no router zebra",
- NO_STR
- "Disable a routing process\n"
- "Stop connection to zebra daemon\n")
-{
- zclient->enable = 0;
- zclient_stop (zclient);
- return CMD_SUCCESS;
-}
-
DEFUN (ripng_redistribute_ripng,
ripng_redistribute_ripng_cmd,
"redistribute ripng",
@@ -345,11 +333,12 @@ DEFUN (ripng_redistribute_type,
{
int type;
- type = proto_redistnum(AFI_IP6, argv[0]);
+ char *proto = argv[argc - 1]->text;
+ type = proto_redistnum(AFI_IP6, proto);
if (type < 0)
{
- vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", proto, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -359,18 +348,23 @@ DEFUN (ripng_redistribute_type,
DEFUN (no_ripng_redistribute_type,
no_ripng_redistribute_type_cmd,
- "no redistribute " FRR_REDIST_STR_RIPNGD,
+ "no redistribute " FRR_REDIST_STR_RIPNGD " [metric (0-16)] [route-map WORD]",
NO_STR
"Redistribute\n"
- FRR_REDIST_HELP_STR_RIPNGD)
+ FRR_REDIST_HELP_STR_RIPNGD
+ "Metric\n"
+ "Metric value\n"
+ "Route map reference\n"
+ "Pointer to route-map entries\n")
{
int type;
- type = proto_redistnum(AFI_IP6, argv[0]);
+ char *proto = argv[2]->text;
+ type = proto_redistnum(AFI_IP6, proto);
if (type < 0)
{
- vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", proto, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -382,21 +376,23 @@ DEFUN (no_ripng_redistribute_type,
DEFUN (ripng_redistribute_type_metric,
ripng_redistribute_type_metric_cmd,
- "redistribute " FRR_REDIST_STR_RIPNGD " metric <0-16>",
+ "redistribute " FRR_REDIST_STR_RIPNGD " metric (0-16)",
"Redistribute\n"
FRR_REDIST_HELP_STR_RIPNGD
"Metric\n"
"Metric value\n")
{
+ int idx_protocol = 1;
+ int idx_number = 3;
int type;
int metric;
- metric = atoi (argv[1]);
- type = proto_redistnum(AFI_IP6, argv[0]);
+ metric = atoi (argv[idx_number]->arg);
+ type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
if (type < 0)
{
- vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -406,15 +402,6 @@ DEFUN (ripng_redistribute_type_metric,
return CMD_SUCCESS;
}
-ALIAS (no_ripng_redistribute_type,
- no_ripng_redistribute_type_metric_cmd,
- "no redistribute " FRR_REDIST_STR_RIPNGD " metric <0-16>",
- NO_STR
- "Redistribute\n"
- FRR_REDIST_HELP_STR_RIPNGD
- "Metric\n"
- "Metric value\n")
-
DEFUN (ripng_redistribute_type_routemap,
ripng_redistribute_type_routemap_cmd,
"redistribute " FRR_REDIST_STR_RIPNGD " route-map WORD",
@@ -423,34 +410,27 @@ DEFUN (ripng_redistribute_type_routemap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ int idx_protocol = 1;
+ int idx_word = 3;
int type;
- type = proto_redistnum(AFI_IP6, argv[0]);
+ type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
if (type < 0)
{
- vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text, VTY_NEWLINE);
return CMD_WARNING;
}
- ripng_redistribute_routemap_set (type, argv[1]);
+ ripng_redistribute_routemap_set (type, argv[idx_word]->text);
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
VRF_DEFAULT);
return CMD_SUCCESS;
}
-ALIAS (no_ripng_redistribute_type,
- no_ripng_redistribute_type_routemap_cmd,
- "no redistribute " FRR_REDIST_STR_RIPNGD " route-map WORD",
- NO_STR
- "Redistribute\n"
- FRR_REDIST_HELP_STR_RIPNGD
- "Route map reference\n"
- "Pointer to route-map entries\n")
-
DEFUN (ripng_redistribute_type_metric_routemap,
ripng_redistribute_type_metric_routemap_cmd,
- "redistribute " FRR_REDIST_STR_RIPNGD " metric <0-16> route-map WORD",
+ "redistribute " FRR_REDIST_STR_RIPNGD " metric (0-16) route-map WORD",
"Redistribute\n"
FRR_REDIST_HELP_STR_RIPNGD
"Metric\n"
@@ -458,33 +438,27 @@ DEFUN (ripng_redistribute_type_metric_routemap,
"Route map reference\n"
"Pointer to route-map entries\n")
{
+ int idx_protocol = 1;
+ int idx_number = 3;
+ int idx_word = 5;
int type;
int metric;
- type = proto_redistnum(AFI_IP6, argv[0]);
- metric = atoi (argv[1]);
+ type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
+ metric = atoi (argv[idx_number]->arg);
if (type < 0)
{
- vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
+ vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text, VTY_NEWLINE);
return CMD_WARNING;
}
ripng_redistribute_metric_set (type, metric);
- ripng_redistribute_routemap_set (type, argv[2]);
+ ripng_redistribute_routemap_set (type, argv[idx_word]->text);
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
return CMD_SUCCESS;
}
-ALIAS (no_ripng_redistribute_type,
- no_ripng_redistribute_type_metric_routemap_cmd,
- "no redistribute " FRR_REDIST_STR_RIPNGD " metric <0-16> route-map WORD",
- NO_STR
- "Redistribute\n"
- FRR_REDIST_HELP_STR_RIPNGD
- "Route map reference\n"
- "Pointer to route-map entries\n")
-
void
ripng_redistribute_write (struct vty *vty, int config_mode)
{
@@ -576,8 +550,6 @@ zebra_init (struct thread_master *master)
install_node (&zebra_node, zebra_config_write);
/* Install command element for zebra node. */
- install_element (CONFIG_NODE, &router_zebra_cmd);
- install_element (CONFIG_NODE, &no_router_zebra_cmd);
install_default (ZEBRA_NODE);
install_element (ZEBRA_NODE, &ripng_redistribute_ripng_cmd);
install_element (ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd);
@@ -588,7 +560,4 @@ zebra_init (struct thread_master *master)
install_element (RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
- install_element (RIPNG_NODE, &no_ripng_redistribute_type_routemap_cmd);
- install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_cmd);
- install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_routemap_cmd);
}
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index 4d59ef2038..c8c18928c9 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -627,11 +627,11 @@ ripng_filter (int ripng_distribute, struct prefix_ipv6 *p,
if (IS_RIPNG_DEBUG_PACKET)
zlog_debug ("%s/%d filtered by distribute %s",
inet6_ntoa (p->prefix), p->prefixlen, inout);
- return -1;
- }
- }
+ return -1;
+ }
+ }
if (ri->prefix[ripng_distribute])
- {
+{
if (prefix_list_apply (ri->prefix[ripng_distribute],
(struct prefix *) p) == PREFIX_DENY)
{
@@ -649,7 +649,7 @@ ripng_filter (int ripng_distribute, struct prefix_ipv6 *p,
if (dist->list[distribute])
{
alist = access_list_lookup (AFI_IP6, dist->list[distribute]);
-
+
if (alist)
{
if (access_list_apply (alist,
@@ -665,7 +665,7 @@ ripng_filter (int ripng_distribute, struct prefix_ipv6 *p,
if (dist->prefix[distribute])
{
plist = prefix_list_lookup (AFI_IP6, dist->prefix[distribute]);
-
+
if (plist)
{
if (prefix_list_apply (plist,
@@ -2259,11 +2259,12 @@ DEFUN (ripng_route,
"Static route setup\n"
"Set static RIPng route announcement\n")
{
+ int idx_ipv6addr = 1;
int ret;
struct prefix_ipv6 p;
struct route_node *rp;
- ret = str2prefix_ipv6 (argv[0], (struct prefix_ipv6 *)&p);
+ ret = str2prefix_ipv6 (argv[idx_ipv6addr]->arg, (struct prefix_ipv6 *)&p);
if (ret <= 0)
{
vty_out (vty, "Malformed address%s", VTY_NEWLINE);
@@ -2292,11 +2293,12 @@ DEFUN (no_ripng_route,
"Static route setup\n"
"Delete static RIPng route announcement\n")
{
+ int idx_ipv6addr = 2;
int ret;
struct prefix_ipv6 p;
struct route_node *rp;
- ret = str2prefix_ipv6 (argv[0], (struct prefix_ipv6 *)&p);
+ ret = str2prefix_ipv6 (argv[idx_ipv6addr]->arg, (struct prefix_ipv6 *)&p);
if (ret <= 0)
{
vty_out (vty, "Malformed address%s", VTY_NEWLINE);
@@ -2326,11 +2328,12 @@ DEFUN (ripng_aggregate_address,
"Set aggregate RIPng route announcement\n"
"Aggregate network\n")
{
+ int idx_ipv6_prefixlen = 1;
int ret;
struct prefix p;
struct route_node *node;
- ret = str2prefix_ipv6 (argv[0], (struct prefix_ipv6 *)&p);
+ ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, (struct prefix_ipv6 *)&p);
if (ret <= 0)
{
vty_out (vty, "Malformed address%s", VTY_NEWLINE);
@@ -2359,11 +2362,12 @@ DEFUN (no_ripng_aggregate_address,
"Delete aggregate RIPng route announcement\n"
"Aggregate network")
{
+ int idx_ipv6_prefixlen = 2;
int ret;
struct prefix p;
struct route_node *rn;
- ret = str2prefix_ipv6 (argv[0], (struct prefix_ipv6 *) &p);
+ ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, (struct prefix_ipv6 *) &p);
if (ret <= 0)
{
vty_out (vty, "Malformed address%s", VTY_NEWLINE);
@@ -2387,20 +2391,21 @@ DEFUN (no_ripng_aggregate_address,
DEFUN (ripng_default_metric,
ripng_default_metric_cmd,
- "default-metric <1-16>",
+ "default-metric (1-16)",
"Set a metric of redistribute routes\n"
"Default metric\n")
{
+ int idx_number = 1;
if (ripng)
{
- ripng->default_metric = atoi (argv[0]);
+ ripng->default_metric = atoi (argv[idx_number]->arg);
}
return CMD_SUCCESS;
}
DEFUN (no_ripng_default_metric,
no_ripng_default_metric_cmd,
- "no default-metric",
+ "no default-metric [(1-16)]",
NO_STR
"Set a metric of redistribute routes\n"
"Default metric\n")
@@ -2412,12 +2417,6 @@ DEFUN (no_ripng_default_metric,
return CMD_SUCCESS;
}
-ALIAS (no_ripng_default_metric,
- no_ripng_default_metric_val_cmd,
- "no default-metric <1-16>",
- NO_STR
- "Set a metric of redistribute routes\n"
- "Default metric\n")
#if 0
/* RIPng update timer setup. */
@@ -2524,20 +2523,23 @@ DEFUN (no_ripng_garbage_timer,
DEFUN (ripng_timers,
ripng_timers_cmd,
- "timers basic <0-65535> <0-65535> <0-65535>",
+ "timers basic (0-65535) (0-65535) (0-65535)",
"RIPng timers setup\n"
"Basic timer\n"
"Routing table update timer value in second. Default is 30.\n"
"Routing information timeout timer. Default is 180.\n"
"Garbage collection timer. Default is 120.\n")
{
+ int idx_number = 2;
+ int idx_number_2 = 3;
+ int idx_number_3 = 4;
unsigned long update;
unsigned long timeout;
unsigned long garbage;
- VTY_GET_INTEGER_RANGE("update timer", update, argv[0], 0, 65535);
- VTY_GET_INTEGER_RANGE("timeout timer", timeout, argv[1], 0, 65535);
- VTY_GET_INTEGER_RANGE("garbage timer", garbage, argv[2], 0, 65535);
+ VTY_GET_INTEGER_RANGE("update timer", update, argv[idx_number]->arg, 0, 65535);
+ VTY_GET_INTEGER_RANGE("timeout timer", timeout, argv[idx_number_2]->arg, 0, 65535);
+ VTY_GET_INTEGER_RANGE("garbage timer", garbage, argv[idx_number_3]->arg, 0, 65535);
/* Set each timer value. */
ripng->update_time = update;
@@ -2552,10 +2554,13 @@ DEFUN (ripng_timers,
DEFUN (no_ripng_timers,
no_ripng_timers_cmd,
- "no timers basic",
+ "no timers basic [(0-65535) (0-65535) (0-65535)]",
NO_STR
"RIPng timers setup\n"
- "Basic timer\n")
+ "Basic timer\n"
+ "Routing table update timer value in second. Default is 30.\n"
+ "Routing information timeout timer. Default is 180.\n"
+ "Garbage collection timer. Default is 120.\n")
{
/* Set each timer value to the default. */
ripng->update_time = RIPNG_UPDATE_TIMER_DEFAULT;
@@ -2568,17 +2573,9 @@ DEFUN (no_ripng_timers,
return CMD_SUCCESS;
}
-ALIAS (no_ripng_timers,
- no_ripng_timers_val_cmd,
- "no timers basic <0-65535> <0-65535> <0-65535>",
- NO_STR
- "RIPng timers setup\n"
- "Basic timer\n"
- "Routing table update timer value in second. Default is 30.\n"
- "Routing information timeout timer. Default is 180.\n"
- "Garbage collection timer. Default is 120.\n")
-
-DEFUN (show_ipv6_protocols, show_ipv6_protocols_cmd,
+#if 0
+DEFUN (show_ipv6_protocols,
+ show_ipv6_protocols_cmd,
"show ipv6 protocols",
SHOW_STR
IPV6_STR
@@ -2603,6 +2600,7 @@ DEFUN (show_ipv6_protocols, show_ipv6_protocols_cmd,
return CMD_SUCCESS;
}
+#endif
/* Please be carefull to use this command. */
DEFUN (ripng_default_information_originate,
@@ -3106,12 +3104,11 @@ ripng_init ()
install_element (RIPNG_NODE, &ripng_default_metric_cmd);
install_element (RIPNG_NODE, &no_ripng_default_metric_cmd);
- install_element (RIPNG_NODE, &no_ripng_default_metric_val_cmd);
install_element (RIPNG_NODE, &ripng_timers_cmd);
install_element (RIPNG_NODE, &no_ripng_timers_cmd);
- install_element (RIPNG_NODE, &no_ripng_timers_val_cmd);
#if 0
+ install_element (VIEW_NODE, &show_ipv6_protocols_cmd);
install_element (RIPNG_NODE, &ripng_update_timer_cmd);
install_element (RIPNG_NODE, &no_ripng_update_timer_cmd);
install_element (RIPNG_NODE, &ripng_timeout_timer_cmd);
diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h
index e340eeecc2..70cba3c680 100644
--- a/ripngd/ripngd.h
+++ b/ripngd/ripngd.h
@@ -358,7 +358,6 @@ extern void ripng_route_map_reset (void);
extern void ripng_terminate (void);
/* zclient_init() is done by ripng_zebra.c:zebra_init() */
extern void zebra_init(struct thread_master *);
-extern void ripng_zclient_start (void);
extern void ripng_zclient_reset (void);
extern void ripng_offset_init (void);
diff --git a/tests/.gitignore b/tests/.gitignore
index 3002b27149..bab3385da2 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -3,6 +3,7 @@ Makefile.in
*.o
tags
TAGS
+.cache
.deps
.nfs*
*~
@@ -14,28 +15,31 @@ TAGS
*.log
*.sum
*.xml
+*.pyc
.arch-inventory
.arch-ids
-aspathtest
-ecommtest
-heavy
-heavythread
-heavywq
-tabletest
-test-timer-correctness
-test-timer-performance
-testbgpcap
-testbgpmpath
-testbgpmpattr
-testbuffer
-testchecksum
-testcli
-testmemory
-testprivs
-testsegv
-testsig
-teststream
-testnexthopiter
-testcommands
-test-commands-defun.c
-site.exp
+__pycache__
+.dirstamp
+/bgpd/test_aspath
+/bgpd/test_capability
+/bgpd/test_ecommunity
+/bgpd/test_mp_attr
+/bgpd/test_mpath
+/lib/cli/test_cli
+/lib/cli/test_commands
+/lib/cli/test_commands_defun.c
+/lib/test_buffer
+/lib/test_checksum
+/lib/test_heavy
+/lib/test_heavy_thread
+/lib/test_heavy_wq
+/lib/test_memory
+/lib/test_nexthop_iter
+/lib/test_privs
+/lib/test_srcdest_table
+/lib/test_segv
+/lib/test_sig
+/lib/test_stream
+/lib/test_table
+/lib/test_timer_correctness
+/lib/test_timer_performance
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 442635fb79..922ec37a24 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,96 +1,148 @@
-AUTOMAKE_OPTIONS = dejagnu
-DEJATOOL = libfrr
+PYTHON ?= python
-SUBDIRS = \
- bgpd.tests \
- libfrr.tests
-
-EXTRA_DIST = \
- config/unix.exp \
- lib/bgpd.exp \
- lib/libfrr.exp \
- global-conf.exp \
- testcommands.in \
- testcommands.refout \
- testcli.in \
- testcli.refout
-
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
+AUTOMAKE_OPTIONS = subdir-objects
+AM_CPPFLAGS = \
+ -I.. \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/lib \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/tests/helpers/c \
+ -I$(top_builddir)/tests/helpers/c \
+ -O
DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
if BGPD
-TESTS_BGPD = aspathtest testbgpcap ecommtest testbgpmpattr testbgpmpath
-DEJATOOL += bgpd
+TESTS_BGPD = \
+ bgpd/test_aspath \
+ bgpd/test_capability \
+ bgpd/test_ecommunity \
+ bgpd/test_mp_attr \
+ bgpd/test_mpath
else
TESTS_BGPD =
endif
if ENABLE_BGP_VNC
-BGP_VNC_RFP_LIB=@top_builddir@/$(LIBRFP)/librfp.a
+BGP_VNC_RFP_LIB=@top_builddir@/$(LIBRFP)/librfp.a
else
BGP_VNC_RFP_LIB =
endif
-check_PROGRAMS = testsig testsegv testbuffer testmemory heavy heavywq heavythread \
- testprivs teststream testchecksum tabletest testnexthopiter \
- testcommands test-timer-correctness test-timer-performance \
- testcli \
- $(TESTS_BGPD)
+check_PROGRAMS = \
+ lib/test_buffer \
+ lib/test_checksum \
+ lib/test_heavy_thread \
+ lib/test_heavy_wq \
+ lib/test_heavy \
+ lib/test_memory \
+ lib/test_nexthop_iter \
+ lib/test_privs \
+ lib/test_srcdest_table \
+ lib/test_segv \
+ lib/test_sig \
+ lib/test_stream \
+ lib/test_table \
+ lib/test_timer_correctness \
+ lib/test_timer_performance \
+ lib/cli/test_cli \
+ lib/cli/test_commands \
+ $(TESTS_BGPD)
../vtysh/vtysh_cmd.c:
$(MAKE) -C ../vtysh vtysh_cmd.c
-test-commands-defun.c: ../vtysh/vtysh_cmd.c
+lib/cli/test_commands_defun.c: ../vtysh/vtysh_cmd.c
sed \
-e 's/"vtysh\.h"/"tests.h"/' \
-e 's/vtysh_init_cmd/test_init_cmd/' \
-e 's/VTYSH_[A-Z][A-Z_0-9]*/0/g' \
< ../vtysh/vtysh_cmd.c \
- > test-commands-defun.c
+ > "$@"
+
+BUILT_SOURCES = lib/cli/test_commands_defun.c
-BUILT_SOURCES = test-commands-defun.c
-noinst_HEADERS = prng.h tests.h common-cli.h
+noinst_HEADERS = \
+ ./helpers/c/prng.h \
+ ./helpers/c/tests.h \
+ ./lib/cli/common_cli.h
-testcli_SOURCES = test-cli.c common-cli.c
-testsig_SOURCES = test-sig.c
-testsegv_SOURCES = test-segv.c
-testbuffer_SOURCES = test-buffer.c
-testmemory_SOURCES = test-memory.c
-testprivs_SOURCES = test-privs.c
-teststream_SOURCES = test-stream.c
-heavy_SOURCES = heavy.c main.c
-heavywq_SOURCES = heavy-wq.c main.c
-heavythread_SOURCES = heavy-thread.c main.c
-aspathtest_SOURCES = aspath_test.c
-testbgpcap_SOURCES = bgp_capability_test.c
-ecommtest_SOURCES = ecommunity_test.c
-testbgpmpattr_SOURCES = bgp_mp_attr_test.c
-testchecksum_SOURCES = test-checksum.c
-testbgpmpath_SOURCES = bgp_mpath_test.c
-tabletest_SOURCES = table_test.c
-testnexthopiter_SOURCES = test-nexthop-iter.c prng.c
-testcommands_SOURCES = test-commands-defun.c test-commands.c prng.c
-test_timer_correctness_SOURCES = test-timer-correctness.c prng.c
-test_timer_performance_SOURCES = test-timer-performance.c prng.c
+lib_test_buffer_SOURCES = lib/test_buffer.c
+lib_test_checksum_SOURCES = lib/test_checksum.c
+lib_test_heavy_thread_SOURCES = lib/test_heavy_thread.c helpers/c/main.c
+lib_test_heavy_wq_SOURCES = lib/test_heavy_wq.c helpers/c/main.c
+lib_test_heavy_SOURCES = lib/test_heavy.c helpers/c/main.c
+lib_test_memory_SOURCES = lib/test_memory.c
+lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c
+lib_test_privs_SOURCES = lib/test_privs.c
+lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \
+ helpers/c/prng.c
+lib_test_segv_SOURCES = lib/test_segv.c
+lib_test_sig_SOURCES = lib/test_sig.c
+lib_test_stream_SOURCES = lib/test_stream.c
+lib_test_table_SOURCES = lib/test_table.c
+lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \
+ helpers/c/prng.c
+lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \
+ helpers/c/prng.c
+lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c
+lib_cli_test_commands_SOURCES = lib/cli/test_commands_defun.c \
+ lib/cli/test_commands.c \
+ helpers/c/prng.c
+bgpd_test_aspath_SOURCES = bgpd/test_aspath.c
+bgpd_test_capability_SOURCES = bgpd/test_capability.c
+bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c
+bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c
+bgpd_test_mpath_SOURCES = bgpd/test_mpath.c
+
+ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@
+BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm
+
+lib_test_buffer_LDADD = $(ALL_TESTS_LDADD)
+lib_test_checksum_LDADD = $(ALL_TESTS_LDADD)
+lib_test_heavy_thread_LDADD = $(ALL_TESTS_LDADD) -lm
+lib_test_heavy_wq_LDADD = $(ALL_TESTS_LDADD) -lm
+lib_test_heavy_LDADD = $(ALL_TESTS_LDADD) -lm
+lib_test_memory_LDADD = $(ALL_TESTS_LDADD)
+lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD)
+lib_test_privs_LDADD = $(ALL_TESTS_LDADD)
+lib_test_srcdest_table_LDADD = $(ALL_TESTS_LDADD)
+lib_test_segv_LDADD = $(ALL_TESTS_LDADD)
+lib_test_sig_LDADD = $(ALL_TESTS_LDADD)
+lib_test_stream_LDADD = $(ALL_TESTS_LDADD)
+lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm
+lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD)
+lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD)
+lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD)
+lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD)
+bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_capability_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD)
+
+EXTRA_DIST = \
+ runtests.py \
+ bgpd/test_aspath.py \
+ bgpd/test_capability.py \
+ bgpd/test_ecommunity.py \
+ bgpd/test_mp_attr.py \
+ bgpd/test_mpath.py \
+ helpers/python/frrsix.py \
+ helpers/python/frrtest.py \
+ lib/cli/test_commands.in \
+ lib/cli/test_commands.py \
+ lib/cli/test_commands.refout \
+ lib/cli/test_cli.in \
+ lib/cli/test_cli.py \
+ lib/cli/test_cli.refout \
+ lib/test_nexthop_iter.py \
+ lib/test_srcdest_table.py \
+ lib/test_stream.py \
+ lib/test_stream.refout \
+ lib/test_table.py \
+ lib/test_timer_correctness.py
-testcli_LDADD = ../lib/libfrr.la @LIBCAP@
-testsig_LDADD = ../lib/libfrr.la @LIBCAP@
-testsegv_LDADD = ../lib/libfrr.la @LIBCAP@
-testbuffer_LDADD = ../lib/libfrr.la @LIBCAP@
-testmemory_LDADD = ../lib/libfrr.la @LIBCAP@
-testprivs_LDADD = ../lib/libfrr.la @LIBCAP@
-teststream_LDADD = ../lib/libfrr.la @LIBCAP@
-heavy_LDADD = ../lib/libfrr.la @LIBCAP@ -lm
-heavywq_LDADD = ../lib/libfrr.la @LIBCAP@ -lm
-heavythread_LDADD = ../lib/libfrr.la @LIBCAP@ -lm
-aspathtest_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-testbgpcap_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-ecommtest_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-testbgpmpattr_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-testchecksum_LDADD = ../lib/libfrr.la @LIBCAP@
-testbgpmpath_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-tabletest_LDADD = ../lib/libfrr.la @LIBCAP@ -lm
-testnexthopiter_LDADD = ../lib/libfrr.la @LIBCAP@
-testcommands_LDADD = ../lib/libfrr.la @LIBCAP@
-test_timer_correctness_LDADD = ../lib/libfrr.la @LIBCAP@
-test_timer_performance_LDADD = ../lib/libfrr.la @LIBCAP@
+.PHONY: tests.xml
+tests.xml: $(check_PROGRAMS)
+ $(PYTHON) runtests.py --junitxml=$@ -v
+check: tests.xml
diff --git a/tests/bgpd.tests/Makefile.am b/tests/bgpd.tests/Makefile.am
deleted file mode 100644
index 5900186cf5..0000000000
--- a/tests/bgpd.tests/Makefile.am
+++ /dev/null
@@ -1,7 +0,0 @@
-EXTRA_DIST = \
- aspathtest.exp \
- ecommtest.exp \
- testbgpcap.exp \
- testbgpmpath.exp \
- testbgpmpattr.exp
-
diff --git a/tests/bgpd.tests/aspathtest.exp b/tests/bgpd.tests/aspathtest.exp
deleted file mode 100644
index f5f262f80a..0000000000
--- a/tests/bgpd.tests/aspathtest.exp
+++ /dev/null
@@ -1,76 +0,0 @@
-set timeout 10
-set testprefix "aspathtest "
-set aborted 0
-set color 1
-
-spawn sh -c "exec ./aspathtest 2>/dev/null"
-
-# proc onetest { test_name note start } {
-# proc headerline { line } {
-
-set parserno 0
-proc parsertest { test_name } {
- global parserno
- headerline "test $parserno"
- onetest "parse $test_name" " ($parserno)" "$test_name:"
- onetest "parse $test_name +empty_prepend" " (#$parserno)" "empty prepend $test_name:"
- incr parserno 1
-}
-set attrno 0
-proc attrtest { test_name } {
- global attrno
- headerline "aspath_attr test $attrno"
- onetest "attr $test_name" " (#$attrno)" "$test_name"
- incr attrno 1
-}
-
-
-parsertest "seq1"
-parsertest "seq2"
-parsertest "seq3"
-parsertest "seqset"
-parsertest "seqset2"
-parsertest "multi"
-parsertest "confed"
-parsertest "confed2"
-parsertest "confset"
-parsertest "confmulti"
-parsertest "seq4"
-parsertest "tripleseq1"
-parsertest "someprivate"
-parsertest "allprivate"
-parsertest "long"
-parsertest "seq1extra"
-parsertest "empty"
-parsertest "redundantset"
-parsertest "reconcile_lead_asp"
-parsertest "reconcile_new_asp"
-parsertest "reconcile_confed"
-parsertest "reconcile_start_trans"
-parsertest "reconcile_start_trans4"
-parsertest "reconcile_start_trans_error"
-parsertest "redundantset2"
-parsertest "zero-size overflow"
-parsertest "zero-size overflow + valid segment"
-parsertest "invalid segment type"
-
-for {set i 0} {$i < 10} {incr i 1} { onetest "prepend $i" "" "prepend test $i"; }
-for {set i 0} {$i < 5} {incr i 1} { onetest "aggregate $i" "" "aggregate test $i"; }
-for {set i 0} {$i < 5} {incr i 1} { onetest "reconcile $i" "" "reconcile test $i"; }
-for {set i 0} {$i < 22} {incr i 1} { onetest "compare $i" "" "left cmp "; }
-
-onetest "empty_get" "" "empty_get_test"
-attrtest "basic test"
-attrtest "length too short"
-attrtest "length too long"
-attrtest "incorrect flag"
-attrtest "as4_path, with as2 format data"
-attrtest "as4, with incorrect attr length"
-attrtest "basic 4-byte as-path"
-attrtest "4b AS_PATH: too short"
-attrtest "4b AS_PATH: too long"
-attrtest "4b AS_PATH: too long2"
-attrtest "4b AS_PATH: bad flags"
-attrtest "4b AS4_PATH w/o AS_PATH"
-attrtest "4b AS4_PATH: confed"
-
diff --git a/tests/bgpd.tests/ecommtest.exp b/tests/bgpd.tests/ecommtest.exp
deleted file mode 100644
index cbeb03af52..0000000000
--- a/tests/bgpd.tests/ecommtest.exp
+++ /dev/null
@@ -1,13 +0,0 @@
-set timeout 10
-set testprefix "ecommtest "
-set aborted 0
-set color 0
-
-spawn sh -c "exec ./ecommtest 2>/dev/null"
-
-# proc simpletest { start } {
-
-simpletest "ipaddr"
-simpletest "ipaddr-so"
-simpletest "asn"
-simpletest "asn4"
diff --git a/tests/bgpd.tests/testbgpcap.exp b/tests/bgpd.tests/testbgpcap.exp
deleted file mode 100644
index aba6906bc0..0000000000
--- a/tests/bgpd.tests/testbgpcap.exp
+++ /dev/null
@@ -1,51 +0,0 @@
-set timeout 10
-set testprefix "testbgpcap "
-set aborted 0
-set color 1
-
-spawn sh -c "exec ./testbgpcap 2>/dev/null"
-
-# proc simpletest { start } {
-
-simpletest "MP4: MP IP/Uni"
-simpletest "MPv6: MP IPv6/Uni"
-simpletest "MP2: MP IP/Multicast"
-simpletest "MP3: MP IP6/MPLS-labeled VPN"
-simpletest "MP5: MP IP6/MPLS-VPN"
-simpletest "MP6: MP IP4/MPLS-laveled VPN"
-simpletest "MP8: MP unknown AFI/SAFI"
-simpletest "MP-short: MP IP4/Unicast, length too short (< minimum)"
-simpletest "MP-overflow: MP IP4/Unicast, length too long"
-simpletest "caphdr: capability header, and no more"
-simpletest "nodata: header, no data but length says there is"
-simpletest "padded: valid, with padding"
-simpletest "minsize: violates minsize requirement"
-simpletest "ORF: ORF, simple, single entry, single tuple"
-simpletest "ORF-many: ORF, multi entry/tuple"
-simpletest "ORFlo: ORF, multi entry/tuple, hdr length too short"
-simpletest "ORFlu: ORF, multi entry/tuple, length too long"
-simpletest "ORFnu: ORF, multi entry/tuple, entry number too long"
-simpletest "ORFno: ORF, multi entry/tuple, entry number too short"
-simpletest "ORFpad: ORF, multi entry/tuple, padded to align"
-simpletest "AS4: AS4 capability"
-simpletest "GR: GR capability"
-simpletest "GR-short: GR capability, but header length too short"
-simpletest "GR-long: GR capability, but header length too long"
-simpletest "GR-trunc: GR capability, but truncated"
-simpletest "GR-empty: GR capability, but empty."
-simpletest "MP-empty: MP capability, but empty."
-simpletest "ORF-empty: ORF capability, but empty."
-simpletest "AS4-empty: AS4 capability, but empty."
-simpletest "dyn-empty: Dynamic capability, but empty."
-simpletest "dyn-old: Dynamic capability (deprecated version)"
-simpletest "Cap-singlets: One capability per Optional-Param"
-simpletest "Cap-series: Series of capability, one Optional-Param"
-simpletest "AS4more: AS4 capability after other caps (singlets)"
-simpletest "AS4series: AS4 capability, in series of capabilities"
-simpletest "AS4real: AS4 capability, in series of capabilities"
-simpletest "AS4real2: AS4 capability, in series of capabilities"
-simpletest "DynCap: Dynamic Capability Message, IP/Multicast"
-simpletest "DynCapLong: Dynamic Capability Message, IP/Multicast, truncated"
-simpletest "DynCapPadded: Dynamic Capability Message, IP/Multicast, padded"
-simpletest "DynCapMPCpadded: Dynamic Capability Message, IP/Multicast, cap data padded"
-simpletest "DynCapMPCoverflow: Dynamic Capability Message, IP/Multicast, cap data != length"
diff --git a/tests/bgpd.tests/testbgpmpath.exp b/tests/bgpd.tests/testbgpmpath.exp
deleted file mode 100644
index 6820f636a4..0000000000
--- a/tests/bgpd.tests/testbgpmpath.exp
+++ /dev/null
@@ -1,12 +0,0 @@
-set timeout 10
-set testprefix "testbgpmpath "
-set aborted 0
-set color 1
-
-spawn sh -c "exec ./testbgpmpath 2>/dev/null"
-
-# proc simpletest { start } {
-
-simpletest "bgp maximum-paths config"
-simpletest "bgp_mp_list"
-simpletest "bgp_info_mpath_update"
diff --git a/tests/bgpd.tests/testbgpmpattr.exp b/tests/bgpd.tests/testbgpmpattr.exp
deleted file mode 100644
index 1abce3fc9a..0000000000
--- a/tests/bgpd.tests/testbgpmpattr.exp
+++ /dev/null
@@ -1,38 +0,0 @@
-set timeout 10
-set testprefix "testbgpmpattr "
-set aborted 0
-set color 1
-
-spawn sh -c "exec ./testbgpmpattr 2>/dev/null"
-
-# proc simpletest { start } {
-
-simpletest "IPv6: IPV6 MP Reach, global nexthop, 1 NLRI"
-simpletest "IPv6-2: IPV6 MP Reach, global nexthop, 2 NLRIs"
-simpletest "IPv6-default: IPV6 MP Reach, global nexthop, 2 NLRIs + default"
-simpletest "IPv6-lnh: IPV6 MP Reach, global+local nexthops, 2 NLRIs + default"
-simpletest "IPv6-nhlen: IPV6 MP Reach, inappropriate nexthop length"
-simpletest "IPv6-nhlen2: IPV6 MP Reach, invalid nexthop length"
-simpletest "IPv6-nhlen3: IPV6 MP Reach, nexthop length overflow"
-simpletest "IPv6-nhlen4: IPV6 MP Reach, nexthop length short"
-simpletest "IPv6-nlri: IPV6 MP Reach, NLRI bitlen overflow"
-simpletest "IPv4: IPv4 MP Reach, 2 NLRIs + default"
-simpletest "IPv4-nhlen: IPv4 MP Reach, nexthop lenth overflow"
-simpletest "IPv4-nlrilen: IPv4 MP Reach, nlri lenth overflow"
-simpletest "IPv4-VPNv4: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs"
-simpletest "IPv4-VPNv4-bogus-plen: IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len"
-simpletest "IPv4-VPNv4-plen1-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short"
-simpletest "IPv4-VPNv4-plen1-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long"
-simpletest "IPv4-VPNv4-plenn-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long"
-simpletest "IPv4-VPNv4-plenn-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short"
-simpletest "IPv4-VPNv4-bogus-rd-type: IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)"
-simpletest "IPv4-VPNv4-0-nlri: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus"
-simpletest "IPv6-bug: IPv6, global nexthop, 1 default NLRI"
-simpletest "IPv6-unreach: IPV6 MP Unreach, 1 NLRI"
-simpletest "IPv6-unreach2: IPV6 MP Unreach, 2 NLRIs"
-simpletest "IPv6-unreach-default: IPV6 MP Unreach, 2 NLRIs + default"
-simpletest "IPv6-unreach-nlri: IPV6 MP Unreach, NLRI bitlen overflow"
-simpletest "IPv4-unreach: IPv4 MP Unreach, 2 NLRIs + default"
-simpletest "IPv4-unreach-nlrilen: IPv4 MP Unreach, nlri length overflow"
-simpletest "IPv4-unreach-VPNv4: IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs"
-
diff --git a/tests/aspath_test.c b/tests/bgpd/test_aspath.c
index 9d595807fe..f3999cbcff 100644
--- a/tests/aspath_test.c
+++ b/tests/bgpd/test_aspath.c
@@ -1331,6 +1331,7 @@ int
main (void)
{
int i = 0;
+ qobj_init ();
bgp_master_init ();
master = bm->master;
bgp_option_set (BGP_OPT_NO_LISTEN);
diff --git a/tests/bgpd/test_aspath.py b/tests/bgpd/test_aspath.py
new file mode 100644
index 0000000000..15ae514c87
--- /dev/null
+++ b/tests/bgpd/test_aspath.py
@@ -0,0 +1,79 @@
+import frrtest
+import re
+
+re_okfail = re.compile(r'^(?:\x1b\[3[12]m)?(?P<ret>OK|failed)'.encode('utf8'),
+ re.MULTILINE)
+
+class TestAspath(frrtest.TestMultiOut):
+ program = './test_aspath'
+
+ def _parsertest(self, line):
+ if not hasattr(self, 'parserno'):
+ self.parserno = -1
+ self.parserno += 1
+
+ self._onesimple("test %d" % self.parserno)
+ self._okfail("%s:" % line, okfail=re_okfail)
+ self._okfail("empty prepend %s:" % line, okfail=re_okfail)
+
+ def _attrtest(self, line):
+ if not hasattr(self, 'attrno'):
+ self.attrno = -1
+ self.attrno += 1
+
+ self._onesimple("aspath_attr test %d" % self.attrno)
+ self._okfail(line, okfail=re_okfail)
+
+TestAspath.parsertest("seq1")
+TestAspath.parsertest("seq2")
+TestAspath.parsertest("seq3")
+TestAspath.parsertest("seqset")
+TestAspath.parsertest("seqset2")
+TestAspath.parsertest("multi")
+TestAspath.parsertest("confed")
+TestAspath.parsertest("confed2")
+TestAspath.parsertest("confset")
+TestAspath.parsertest("confmulti")
+TestAspath.parsertest("seq4")
+TestAspath.parsertest("tripleseq1")
+TestAspath.parsertest("someprivate")
+TestAspath.parsertest("allprivate")
+TestAspath.parsertest("long")
+TestAspath.parsertest("seq1extra")
+TestAspath.parsertest("empty")
+TestAspath.parsertest("redundantset")
+TestAspath.parsertest("reconcile_lead_asp")
+TestAspath.parsertest("reconcile_new_asp")
+TestAspath.parsertest("reconcile_confed")
+TestAspath.parsertest("reconcile_start_trans")
+TestAspath.parsertest("reconcile_start_trans4")
+TestAspath.parsertest("reconcile_start_trans_error")
+TestAspath.parsertest("redundantset2")
+TestAspath.parsertest("zero-size overflow")
+TestAspath.parsertest("zero-size overflow + valid segment")
+TestAspath.parsertest("invalid segment type")
+
+for i in range(10):
+ TestAspath.okfail("prepend test %d" % i)
+for i in range(5):
+ TestAspath.okfail("aggregate test %d" % i)
+for i in range(5):
+ TestAspath.okfail("reconcile test %d" % i)
+for _ in range(22):
+ TestAspath.okfail("left cmp ")
+
+TestAspath.okfail("empty_get_test")
+
+TestAspath.attrtest("basic test")
+TestAspath.attrtest("length too short")
+TestAspath.attrtest("length too long")
+TestAspath.attrtest("incorrect flag")
+TestAspath.attrtest("as4_path, with as2 format data")
+TestAspath.attrtest("as4, with incorrect attr length")
+TestAspath.attrtest("basic 4-byte as-path")
+TestAspath.attrtest("4b AS_PATH: too short")
+TestAspath.attrtest("4b AS_PATH: too long")
+TestAspath.attrtest("4b AS_PATH: too long2")
+TestAspath.attrtest("4b AS_PATH: bad flags")
+TestAspath.attrtest("4b AS4_PATH w/o AS_PATH")
+TestAspath.attrtest("4b AS4_PATH: confed")
diff --git a/tests/bgp_capability_test.c b/tests/bgpd/test_capability.c
index 7fa4be5611..f83dee5e1c 100644
--- a/tests/bgp_capability_test.c
+++ b/tests/bgpd/test_capability.c
@@ -124,21 +124,21 @@ static struct test_segment mp_segments[] =
"MP IP6/MPLS-labeled VPN",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
6, SHOULD_PARSE, 0,
- 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ 1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
/* 7 */
{ "MP5",
"MP IP6/MPLS-VPN",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
6, SHOULD_PARSE, 0,
- 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
+ 1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
/* 8 */
{ "MP6",
"MP IP4/MPLS-laveled VPN",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
6, SHOULD_PARSE, 0,
- 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ 1, AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
/* 10 */
{ "MP8",
@@ -585,22 +585,26 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
if (!ret && t->validate_afi)
{
- safi_t safi = t->safi;
+ afi_t afi;
+ safi_t safi;
- if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
- failed++;
-
- printf ("MP: %u/%u (%u): recv %u, nego %u\n",
- t->afi, t->safi, safi,
- peer->afc_recv[t->afi][safi],
- peer->afc_nego[t->afi][safi]);
+ /* Convert AFI, SAFI to internal values, check. */
+ if (bgp_map_afi_safi_iana2int (afi_int2iana(t->afi), t->safi, &afi, &safi))
+ {
+ if (t->afi_valid == VALID_AFI)
+ failed++;
+ }
+ printf ("MP: %u(%u)/%u(%u): recv %u, nego %u\n",
+ t->afi, afi, t->safi, safi,
+ peer->afc_recv[afi][safi],
+ peer->afc_nego[afi][safi]);
if (t->afi_valid == VALID_AFI)
{
- if (!peer->afc_recv[t->afi][safi])
+ if (!peer->afc_recv[afi][safi])
failed++;
- if (!peer->afc_nego[t->afi][safi])
+ if (!peer->afc_nego[afi][safi])
failed++;
}
}
diff --git a/tests/bgpd/test_capability.py b/tests/bgpd/test_capability.py
new file mode 100644
index 0000000000..4cb650092b
--- /dev/null
+++ b/tests/bgpd/test_capability.py
@@ -0,0 +1,47 @@
+import frrtest
+
+class TestCapability(frrtest.TestMultiOut):
+ program = './test_capability'
+
+TestCapability.okfail("MP4: MP IP/Uni")
+TestCapability.okfail("MPv6: MP IPv6/Uni")
+TestCapability.okfail("MP2: MP IP/Multicast")
+TestCapability.okfail("MP3: MP IP6/MPLS-labeled VPN")
+TestCapability.okfail("MP5: MP IP6/MPLS-VPN")
+TestCapability.okfail("MP6: MP IP4/MPLS-laveled VPN")
+TestCapability.okfail("MP8: MP unknown AFI/SAFI")
+TestCapability.okfail("MP-short: MP IP4/Unicast, length too short (< minimum)")
+TestCapability.okfail("MP-overflow: MP IP4/Unicast, length too long")
+TestCapability.okfail("caphdr: capability header, and no more")
+TestCapability.okfail("nodata: header, no data but length says there is")
+TestCapability.okfail("padded: valid, with padding")
+TestCapability.okfail("minsize: violates minsize requirement")
+TestCapability.okfail("ORF: ORF, simple, single entry, single tuple")
+TestCapability.okfail("ORF-many: ORF, multi entry/tuple")
+TestCapability.okfail("ORFlo: ORF, multi entry/tuple, hdr length too short")
+TestCapability.okfail("ORFlu: ORF, multi entry/tuple, length too long")
+TestCapability.okfail("ORFnu: ORF, multi entry/tuple, entry number too long")
+TestCapability.okfail("ORFno: ORF, multi entry/tuple, entry number too short")
+TestCapability.okfail("ORFpad: ORF, multi entry/tuple, padded to align")
+TestCapability.okfail("AS4: AS4 capability")
+TestCapability.okfail("GR: GR capability")
+TestCapability.okfail("GR-short: GR capability, but header length too short")
+TestCapability.okfail("GR-long: GR capability, but header length too long")
+TestCapability.okfail("GR-trunc: GR capability, but truncated")
+TestCapability.okfail("GR-empty: GR capability, but empty.")
+TestCapability.okfail("MP-empty: MP capability, but empty.")
+TestCapability.okfail("ORF-empty: ORF capability, but empty.")
+TestCapability.okfail("AS4-empty: AS4 capability, but empty.")
+TestCapability.okfail("dyn-empty: Dynamic capability, but empty.")
+TestCapability.okfail("dyn-old: Dynamic capability (deprecated version)")
+TestCapability.okfail("Cap-singlets: One capability per Optional-Param")
+TestCapability.okfail("Cap-series: Series of capability, one Optional-Param")
+TestCapability.okfail("AS4more: AS4 capability after other caps (singlets)")
+TestCapability.okfail("AS4series: AS4 capability, in series of capabilities")
+TestCapability.okfail("AS4real: AS4 capability, in series of capabilities")
+TestCapability.okfail("AS4real2: AS4 capability, in series of capabilities")
+TestCapability.okfail("DynCap: Dynamic Capability Message, IP/Multicast")
+TestCapability.okfail("DynCapLong: Dynamic Capability Message, IP/Multicast, truncated")
+TestCapability.okfail("DynCapPadded: Dynamic Capability Message, IP/Multicast, padded")
+TestCapability.okfail("DynCapMPCpadded: Dynamic Capability Message, IP/Multicast, cap data padded")
+TestCapability.okfail("DynCapMPCoverflow: Dynamic Capability Message, IP/Multicast, cap data != length")
diff --git a/tests/ecommunity_test.c b/tests/bgpd/test_ecommunity.c
index 9166af6142..9166af6142 100644
--- a/tests/ecommunity_test.c
+++ b/tests/bgpd/test_ecommunity.c
diff --git a/tests/bgpd/test_ecommunity.py b/tests/bgpd/test_ecommunity.py
new file mode 100644
index 0000000000..3a17ec9e31
--- /dev/null
+++ b/tests/bgpd/test_ecommunity.py
@@ -0,0 +1,9 @@
+import frrtest
+
+class TestEcommunity(frrtest.TestMultiOut):
+ program = './test_ecommunity'
+
+TestEcommunity.okfail('ipaddr')
+TestEcommunity.okfail('ipaddr-so')
+TestEcommunity.okfail('asn')
+TestEcommunity.okfail('asn4')
diff --git a/tests/bgp_mp_attr_test.c b/tests/bgpd/test_mp_attr.c
index dfb8ed9f7a..397612c315 100644
--- a/tests/bgp_mp_attr_test.c
+++ b/tests/bgpd/test_mp_attr.c
@@ -317,7 +317,7 @@ static struct test_segment {
{ "IPv4-VPNv4",
"IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs",
{
- /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
+ /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
0, 0, 0, 0,
@@ -338,12 +338,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_PARSE,
- AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
{ "IPv4-VPNv4-bogus-plen",
"IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len",
{
- /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
+ /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 1, 2,
0, 0xff, 3, 4,
@@ -355,12 +355,12 @@ static struct test_segment {
},
(3 + 1 + 3*4 + 1 + 3 + 4 + 1),
SHOULD_ERR,
- AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
{ "IPv4-VPNv4-plen1-short",
"IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short",
{
- /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
+ /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
0, 0, 0, 0,
@@ -381,12 +381,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_ERR,
- AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
{ "IPv4-VPNv4-plen1-long",
"IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long",
{
- /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
+ /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
0, 0, 0, 0,
@@ -407,12 +407,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_ERR,
- AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
{ "IPv4-VPNv4-plenn-long",
"IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long",
{
- /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
+ /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
0, 0, 0, 0,
@@ -434,12 +434,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
SHOULD_ERR,
- AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
{ "IPv4-VPNv4-plenn-short",
"IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short",
{
- /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
+ /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
0, 0, 0, 0,
@@ -460,12 +460,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_ERR,
- AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
{ "IPv4-VPNv4-bogus-rd-type",
"IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)",
{
- /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
+ /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
0, 0, 0, 0,
@@ -486,12 +486,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_PARSE,
- AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
{ "IPv4-VPNv4-0-nlri",
"IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus",
{
- /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
+ /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
0, 0, 0, 0,
@@ -513,7 +513,7 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
SHOULD_ERR,
- AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
/* From bug #385 */
@@ -625,7 +625,7 @@ static struct test_segment mp_unreach_segments [] =
{ "IPv4-unreach-VPNv4",
"IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs",
{
- /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
+ /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* NLRI tuples */ 88 + 16,
0, 1, 2, /* tag */
/* rd, 8 octets */
@@ -641,7 +641,7 @@ static struct test_segment mp_unreach_segments [] =
},
(3 + (1+3+8+2) + (1+3+8+3)),
SHOULD_PARSE,
- AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
+ AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
{ NULL, NULL, {0}, 0, 0}
};
@@ -656,19 +656,6 @@ handle_result (struct peer *peer, struct test_segment *t,
{
int oldfailed = failed;
- if (!parse_ret)
- {
- safi_t safi = t->safi;
-
- if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
- failed++;
-
- printf ("MP: %u/%u (%u): recv %u, nego %u\n",
- t->afi, t->safi, safi,
- peer->afc_recv[t->afi][safi],
- peer->afc_nego[t->afi][safi]);
- }
-
printf ("mp attr parsed?: %s\n", parse_ret ? "no" : "yes");
if (!parse_ret)
printf ("nrli parsed?: %s\n", nlri_ret ? "no" : "yes");
@@ -720,9 +707,20 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
parse_ret = bgp_mp_reach_parse (&attr_args, &nlri);
else
parse_ret = bgp_mp_unreach_parse (&attr_args, &nlri);
-
- if (parse_ret == 0 && t->afi_valid == VALID_AFI)
- assert (nlri.afi == t->afi && nlri.safi == t->safi);
+ if (!parse_ret)
+ {
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
+
+ /* Convert AFI, SAFI to internal values, check. */
+ if (bgp_map_afi_safi_int2iana (nlri.afi, nlri.safi, &pkt_afi, &pkt_safi))
+ assert (0);
+
+ printf ("MP: %u(%u)/%u(%u): recv %u, nego %u\n",
+ nlri.afi , pkt_afi, nlri.safi, pkt_safi,
+ peer->afc_recv[nlri.afi][nlri.safi],
+ peer->afc_nego[nlri.afi][nlri.safi]);
+ }
if (!parse_ret)
{
@@ -731,7 +729,7 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
else
nlri_ret = bgp_nlri_parse (peer, NULL, &nlri);
}
-
+ zlog_err("xxxxxxxxxxxxxxxx nlri ret %u", nlri_ret);
handle_result (peer, t, parse_ret, nlri_ret);
}
diff --git a/tests/bgpd/test_mp_attr.py b/tests/bgpd/test_mp_attr.py
new file mode 100644
index 0000000000..46d0c42402
--- /dev/null
+++ b/tests/bgpd/test_mp_attr.py
@@ -0,0 +1,33 @@
+import frrtest
+
+class TestMpAttr(frrtest.TestMultiOut):
+ program = './test_mp_attr'
+
+TestMpAttr.okfail("IPv6: IPV6 MP Reach, global nexthop, 1 NLRI")
+TestMpAttr.okfail("IPv6-2: IPV6 MP Reach, global nexthop, 2 NLRIs")
+TestMpAttr.okfail("IPv6-default: IPV6 MP Reach, global nexthop, 2 NLRIs + default")
+TestMpAttr.okfail("IPv6-lnh: IPV6 MP Reach, global+local nexthops, 2 NLRIs + default")
+TestMpAttr.okfail("IPv6-nhlen: IPV6 MP Reach, inappropriate nexthop length")
+TestMpAttr.okfail("IPv6-nhlen2: IPV6 MP Reach, invalid nexthop length")
+TestMpAttr.okfail("IPv6-nhlen3: IPV6 MP Reach, nexthop length overflow")
+TestMpAttr.okfail("IPv6-nhlen4: IPV6 MP Reach, nexthop length short")
+TestMpAttr.okfail("IPv6-nlri: IPV6 MP Reach, NLRI bitlen overflow")
+TestMpAttr.okfail("IPv4: IPv4 MP Reach, 2 NLRIs + default")
+TestMpAttr.okfail("IPv4-nhlen: IPv4 MP Reach, nexthop lenth overflow")
+TestMpAttr.okfail("IPv4-nlrilen: IPv4 MP Reach, nlri lenth overflow")
+TestMpAttr.okfail("IPv4-VPNv4: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs")
+TestMpAttr.okfail("IPv4-VPNv4-bogus-plen: IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len")
+TestMpAttr.okfail("IPv4-VPNv4-plen1-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short")
+TestMpAttr.okfail("IPv4-VPNv4-plen1-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long")
+TestMpAttr.okfail("IPv4-VPNv4-plenn-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long")
+TestMpAttr.okfail("IPv4-VPNv4-plenn-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short")
+TestMpAttr.okfail("IPv4-VPNv4-bogus-rd-type: IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)")
+TestMpAttr.okfail("IPv4-VPNv4-0-nlri: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus")
+TestMpAttr.okfail("IPv6-bug: IPv6, global nexthop, 1 default NLRI")
+TestMpAttr.okfail("IPv6-unreach: IPV6 MP Unreach, 1 NLRI")
+TestMpAttr.okfail("IPv6-unreach2: IPV6 MP Unreach, 2 NLRIs")
+TestMpAttr.okfail("IPv6-unreach-default: IPV6 MP Unreach, 2 NLRIs + default")
+TestMpAttr.okfail("IPv6-unreach-nlri: IPV6 MP Unreach, NLRI bitlen overflow")
+TestMpAttr.okfail("IPv4-unreach: IPv4 MP Unreach, 2 NLRIs + default")
+TestMpAttr.okfail("IPv4-unreach-nlrilen: IPv4 MP Unreach, nlri length overflow")
+TestMpAttr.okfail("IPv4-unreach-VPNv4: IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs")
diff --git a/tests/bgp_mpath_test.c b/tests/bgpd/test_mpath.c
index f9eb1534f3..f9eb1534f3 100644
--- a/tests/bgp_mpath_test.c
+++ b/tests/bgpd/test_mpath.c
diff --git a/tests/bgpd/test_mpath.py b/tests/bgpd/test_mpath.py
new file mode 100644
index 0000000000..3024669507
--- /dev/null
+++ b/tests/bgpd/test_mpath.py
@@ -0,0 +1,9 @@
+import frrtest
+
+class TestMpath(frrtest.TestMultiOut):
+ program = './test_mpath'
+
+TestMpath.okfail("bgp maximum-paths config")
+TestMpath.okfail("bgp_mp_list")
+TestMpath.okfail("bgp_info_mpath_update")
+
diff --git a/tests/config/unix.exp b/tests/config/unix.exp
deleted file mode 100644
index 2f6bceadbe..0000000000
--- a/tests/config/unix.exp
+++ /dev/null
@@ -1,102 +0,0 @@
-
-# every test should always be run and always return some status.
-# so, if we lose sync with a multi-test program, aborted will be used
-# to flag the remainder of the tests as untested.
-#set aborted 0
-
-# only match with color codes since "failed" / "OK" might otherwise
-# be part of the output...
-#set color 1
-
-set xfail 0
-
-proc onesimple { test_name match } {
- global verbose
- global aborted
- global testprefix
- if { $aborted > 0 } {
- untested "$testprefix$test_name"
- return
- }
- if { $verbose > 0 } {
- send_user "$testprefix$test_name$note\n"
- }
- expect {
- "$match" { pass "$testprefix$test_name"; }
- eof { fail "$testprefix$test_name"; set aborted 1; }
- timeout { unresolved "$testprefix$test_name"; set aborted 1; }
- }
-}
-
-proc onetest { test_name note start } {
- global aborted
- global testprefix
- global verbose
- global color
- global xfail
-
- if { $aborted > 0 } {
- untested "$testprefix$test_name"
- return
- }
-
- if { $verbose > 0 } {
- send_user "$testprefix$test_name$note\n"
- }
- expect {
- "$start" { }
-
- eof { unresolved "$testprefix$test_name"; set aborted 1; }
- timeout { unresolved "$testprefix$test_name"; set aborted 1; }
- }
-
- if { $aborted > 0 } {
- send_user "sync failed: $testprefix$test_name$note -- $testprefix aborted!\n"
- return
- }
-
- if { $color } {
- set pat "(32mOK|31mfailed)"
- } else {
- set pat "(OK|failed)"
- }
- expect {
- # need this because otherwise expect will skip over a "failed" and
- # grab the next "OK" (or the other way around)
- -re "$pat" {
- if { "$expect_out(0,string)" == "32mOK" || "$expect_out(0,string)" == "OK" } {
- pass "$testprefix$test_name"
- } else {
- if { $xfail } {
- xfail "$testprefix$test_name"
- } else {
- fail "$testprefix$test_name"
- }
- }
- return
- }
-
- eof { unresolved "$testprefix$test_name"; set aborted 1; }
- timeout { unresolved "$testprefix$test_name"; set aborted 1; }
- }
-
- if { $aborted > 0 } {
- send_user "failed: $testprefix$test_name$note -- $testprefix aborted!\n"
- return
- }
-}
-
-proc headerline { line } {
- global aborted
- if { $aborted > 0 } { return; }
- expect {
- $line { return; }
- eof { send_user "numbering mismatch!\n"; set aborted 1; }
- timeout { send_user "numbering mismatch!\n"; set aborted 1; }
- }
-}
-
-proc simpletest { start } {
- onetest "$start" "" "$start"
-}
-
diff --git a/tests/global-conf.exp b/tests/global-conf.exp
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/global-conf.exp
+++ /dev/null
diff --git a/tests/main.c b/tests/helpers/c/main.c
index b3e6e706ff..b3e6e706ff 100644
--- a/tests/main.c
+++ b/tests/helpers/c/main.c
diff --git a/tests/prng.c b/tests/helpers/c/prng.c
index bdcfb07af1..bdcfb07af1 100644
--- a/tests/prng.c
+++ b/tests/helpers/c/prng.c
diff --git a/tests/prng.h b/tests/helpers/c/prng.h
index cf0bacc5f8..cf0bacc5f8 100644
--- a/tests/prng.h
+++ b/tests/helpers/c/prng.h
diff --git a/tests/tests.h b/tests/helpers/c/tests.h
index a528e55f05..a528e55f05 100644
--- a/tests/tests.h
+++ b/tests/helpers/c/tests.h
diff --git a/tests/helpers/python/frrsix.py b/tests/helpers/python/frrsix.py
new file mode 100644
index 0000000000..91714f0c67
--- /dev/null
+++ b/tests/helpers/python/frrsix.py
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2010-2017 Benjamin Peterson
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+#
+# This code is taken from the six python2 to python3 compatibility module
+#
+
+import sys
+
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+
+def add_metaclass(metaclass):
+ """Class decorator for creating a class with a metaclass."""
+ def wrapper(cls):
+ orig_vars = cls.__dict__.copy()
+ slots = orig_vars.get('__slots__')
+ if slots is not None:
+ if isinstance(slots, str):
+ slots = [slots]
+ for slots_var in slots:
+ orig_vars.pop(slots_var)
+ orig_vars.pop('__dict__', None)
+ orig_vars.pop('__weakref__', None)
+ return metaclass(cls.__name__, cls.__bases__, orig_vars)
+ return wrapper
+
+if PY3:
+ import builtins
+ exec_ = getattr(builtins,'exec')
+
+ def reraise(tp, value, tb=None):
+ try:
+ if value is None:
+ value = tp()
+ if value.__traceback__ is not tb:
+ raise value.with_traceback(tb)
+ raise value
+ finally:
+ value = None
+ tb = None
+
+else:
+ def exec_(_code_, _globs_=None, _locs_=None):
+ """Execute code in a namespace."""
+ if _globs_ is None:
+ frame = sys._getframe(1)
+ _globs_ = frame.f_globals
+ if _locs_ is None:
+ _locs_ = frame.f_locals
+ del frame
+ elif _locs_ is None:
+ _locs_ = _globs_
+ exec("""exec _code_ in _globs_, _locs_""")
+
+ exec_("""def reraise(tp, value, tb=None):
+ try:
+ raise tp, value, tb
+ finally:
+ tb = None
+""")
diff --git a/tests/helpers/python/frrtest.py b/tests/helpers/python/frrtest.py
new file mode 100644
index 0000000000..2814416d11
--- /dev/null
+++ b/tests/helpers/python/frrtest.py
@@ -0,0 +1,177 @@
+#
+# Test helpers for FRR
+#
+# Copyright (C) 2017 by David Lamparter & Christian Franke,
+# Open Source Routing / NetDEF Inc.
+#
+# This file is part of FreeRangeRouting (FRR)
+#
+# FRR is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+#
+# FRR is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with FRR; see the file COPYING. If not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+
+import subprocess
+import sys
+import re
+import inspect
+import os
+
+import frrsix
+
+#
+# These are the gritty internals of the TestMultiOut implementation.
+# See below for the definition of actual TestMultiOut tests.
+#
+
+class MultiTestFailure(Exception):
+ pass
+
+class MetaTestMultiOut(type):
+ def __getattr__(cls, name):
+ if name.startswith('_'):
+ raise AttributeError
+
+ internal_name = '_{}'.format(name)
+ if internal_name not in dir(cls):
+ raise AttributeError
+
+ def registrar(*args, **kwargs):
+ cls._add_test(getattr(cls,internal_name), *args, **kwargs)
+ return registrar
+
+@frrsix.add_metaclass(MetaTestMultiOut)
+class _TestMultiOut(object):
+ def _run_tests(self):
+ if 'tests_run' in dir(self.__class__) and self.tests_run:
+ return
+ self.__class__.tests_run = True
+ basedir = os.path.dirname(inspect.getsourcefile(type(self)))
+ program = os.path.join(basedir, self.program)
+ proc = subprocess.Popen([program], stdout=subprocess.PIPE)
+ self.output,_ = proc.communicate('')
+ self.exitcode = proc.wait()
+
+ self.__class__.testresults = {}
+ for test in self.tests:
+ try:
+ test(self)
+ except MultiTestFailure:
+ self.testresults[test] = sys.exc_info()
+ else:
+ self.testresults[test] = None
+
+ def _exit_cleanly(self):
+ if self.exitcode != 0:
+ raise MultiTestFailure("Program did not terminate with exit code 0")
+
+ @classmethod
+ def _add_test(cls, method, *args, **kwargs):
+ if 'tests' not in dir(cls):
+ setattr(cls,'tests',[])
+ cls._add_test(cls._exit_cleanly)
+
+ def matchfunction(self):
+ method(self, *args, **kwargs)
+ cls.tests.append(matchfunction)
+
+ def testfunction(self):
+ self._run_tests()
+ result = self.testresults[matchfunction]
+ if result is not None:
+ frrsix.reraise(*result)
+
+ testname = re.sub(r'[^A-Za-z0-9]', '_', '%r%r' % (args, kwargs))
+ testname = re.sub(r'__*', '_', testname)
+ testname = testname.strip('_')
+ if not testname:
+ testname = method.__name__.strip('_')
+ if "test_%s" % testname in dir(cls):
+ index = 2
+ while "test_%s_%d" % (testname,index) in dir(cls):
+ index += 1
+ testname = "%s_%d" % (testname, index)
+ setattr(cls,"test_%s" % testname, testfunction)
+
+#
+# This class houses the actual TestMultiOut tests types.
+# If you want to add a new test type, you probably do it here.
+#
+# Say you want to add a test type called foobarlicious. Then define
+# a function _foobarlicious here that takes self and the test arguments
+# when called. That function should check the output in self.output
+# to see whether it matches the expectation of foobarlicious with the
+# given arguments and should then adjust self.output according to how
+# much output it consumed.
+# If the output doesn't meet the expectations, MultiTestFailure can be
+# raised, however that should only be done after self.output has been
+# modified according to consumed content.
+#
+
+re_okfail = re.compile(r'(?:[3[12]m|^)?(?P<ret>OK|failed)'.encode('utf8'),
+ re.MULTILINE)
+class TestMultiOut(_TestMultiOut):
+ def _onesimple(self, line):
+ if type(line) is str:
+ line = line.encode('utf8')
+ idx = self.output.find(line)
+ if idx != -1:
+ self.output = self.output[idx+len(line):]
+ else:
+ raise MultiTestFailure("%r could not be found" % line)
+
+ def _okfail(self, line, okfail=re_okfail):
+ self._onesimple(line)
+
+ m = okfail.search(self.output)
+ if m is None:
+ raise MultiTestFailure('OK/fail not found')
+ self.output = self.output[m.end():]
+
+ if m.group('ret') != 'OK'.encode('utf8'):
+ raise MultiTestFailure('Test output indicates failure')
+
+#
+# This class implements a test comparing the output of a program against
+# an existing reference output
+#
+
+class TestRefMismatch(Exception):
+ pass
+class TestExitNonzero(Exception):
+ pass
+
+class TestRefOut(object):
+ def test_refout(self):
+ basedir = os.path.dirname(inspect.getsourcefile(type(self)))
+ program = os.path.join(basedir, self.program)
+
+ refin = program + '.in'
+ refout = program + '.refout'
+
+ intext = ''
+ if os.path.exists(refin):
+ with open(refin, 'rb') as f:
+ intext = f.read()
+ with open(refout, 'rb') as f:
+ reftext = f.read()
+
+ proc = subprocess.Popen([program],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
+ outtext,_ = proc.communicate(intext)
+ if outtext != reftext:
+ raise TestRefMismatch(self, outtext, reftext)
+ if proc.wait() != 0:
+ raise TestExitNonzero(self)
diff --git a/tests/lib/bgpd.exp b/tests/lib/bgpd.exp
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/lib/bgpd.exp
+++ /dev/null
diff --git a/tests/common-cli.c b/tests/lib/cli/common_cli.c
index aed20b2d53..83196e04aa 100644
--- a/tests/common-cli.c
+++ b/tests/lib/cli/common_cli.c
@@ -29,18 +29,18 @@
#include "memory_vty.h"
#include "log.h"
-#include "common-cli.h"
+#include "common_cli.h"
struct thread_master *master;
int dump_args(struct vty *vty, const char *descr,
- int argc, const char **argv)
+ int argc, struct cmd_token *argv[])
{
int i;
vty_out (vty, "%s with %d args.%s", descr, argc, VTY_NEWLINE);
for (i = 0; i < argc; i++)
{
- vty_out (vty, "[%02d]: %s%s", i, argv[i], VTY_NEWLINE);
+ vty_out (vty, "[%02d]: %s%s", i, argv[i]->arg, VTY_NEWLINE);
}
return CMD_SUCCESS;
@@ -49,6 +49,12 @@ int dump_args(struct vty *vty, const char *descr,
static void vty_do_exit(void)
{
printf ("\nend.\n");
+ cmd_terminate ();
+ vty_terminate ();
+ thread_master_free (master);
+ closezlog (zlog_default);
+
+ log_memstats_stderr ("testcli");
exit (0);
}
@@ -72,7 +78,7 @@ main (int argc, char **argv)
/* Library inits. */
cmd_init (1);
- host.name = strdup ("test");
+ cmd_hostname_set ("test");
vty_init (master);
memory_init ();
diff --git a/tests/common-cli.h b/tests/lib/cli/common_cli.h
index 8f6751512e..9c72b08e44 100644
--- a/tests/common-cli.h
+++ b/tests/lib/cli/common_cli.h
@@ -36,7 +36,7 @@ extern void test_init (void);
extern struct thread_master *master;
extern int dump_args(struct vty *vty, const char *descr,
- int argc, const char **argv);
+ int argc, struct cmd_token *argv[]);
#define DUMMY_HELPSTR \
"00\n01\n02\n03\n04\n05\n06\n07\n08\n09\n" \
diff --git a/tests/test-cli.c b/tests/lib/cli/test_cli.c
index 6fab6d52cb..1a316022e2 100644
--- a/tests/test-cli.c
+++ b/tests/lib/cli/test_cli.c
@@ -22,16 +22,15 @@
#include <zebra.h>
-#include "common-cli.h"
+#include "common_cli.h"
DUMMY_DEFUN(cmd0, "arg ipv4 A.B.C.D");
DUMMY_DEFUN(cmd1, "arg ipv4m A.B.C.D/M");
DUMMY_DEFUN(cmd2, "arg ipv6 X:X::X:X");
DUMMY_DEFUN(cmd3, "arg ipv6m X:X::X:X/M");
-DUMMY_DEFUN(cmd4, "arg range <5-15>");
-DUMMY_DEFUN(cmd5, "pat a ( a|b)");
-DUMMY_DEFUN(cmd6, "pat b (a|)");
-DUMMY_DEFUN(cmd7, "pat c (a | b|c) A.B.C.D");
+DUMMY_DEFUN(cmd4, "arg range (5-15)");
+DUMMY_DEFUN(cmd5, "pat a < a|b>");
+DUMMY_DEFUN(cmd7, "pat c <a | b|c> A.B.C.D");
DUMMY_DEFUN(cmd8, "pat d { foo A.B.C.D|bar X:X::X:X| baz }");
DUMMY_DEFUN(cmd9, "pat e [ WORD ]");
DUMMY_DEFUN(cmd10, "pat f [key]");
@@ -47,7 +46,6 @@ void test_init(void)
install_element (ENABLE_NODE, &cmd3_cmd);
install_element (ENABLE_NODE, &cmd4_cmd);
install_element (ENABLE_NODE, &cmd5_cmd);
- install_element (ENABLE_NODE, &cmd6_cmd);
install_element (ENABLE_NODE, &cmd7_cmd);
install_element (ENABLE_NODE, &cmd8_cmd);
install_element (ENABLE_NODE, &cmd9_cmd);
diff --git a/tests/testcli.in b/tests/lib/cli/test_cli.in
index f4212b9758..5c146ef984 100644
--- a/tests/testcli.in
+++ b/tests/lib/cli/test_cli.in
@@ -50,11 +50,6 @@ pat a ?b
pat a c?
pat a a x
-pat b
-pat b ?a
-pat b x
-pat b x y
-
pat c a
pat c a 1.2.3.4
pat c b 2.3.4
diff --git a/tests/lib/cli/test_cli.py b/tests/lib/cli/test_cli.py
new file mode 100644
index 0000000000..e3c31c2d91
--- /dev/null
+++ b/tests/lib/cli/test_cli.py
@@ -0,0 +1,4 @@
+import frrtest
+
+class TestCli(frrtest.TestRefOut):
+ program = './test_cli'
diff --git a/tests/testcli.refout b/tests/lib/cli/test_cli.refout
index 7da5494827..8b438baee2 100644
--- a/tests/testcli.refout
+++ b/tests/lib/cli/test_cli.refout
@@ -1,24 +1,26 @@
test# echo this is a test message
this is a test message
test# echo foo bla
- MESSAGE The message to echo
- <cr>
+% There is no matched command.
test# echo foo bla baz
foo bla baz
test# echo
% Command incomplete.
test#
test# arg ipv4 1.2.3.4
-cmd0 with 1 args.
-[00]: 1.2.3.4
+cmd0 with 3 args.
+[00]: arg
+[01]: ipv4
+[02]: 1.2.3.4
test# arg ipv4 1.2.
A.B.C.D 02
test# arg ipv4 1.2.3.4
-cmd0 with 1 args.
-[00]: 1.2.3.4
+cmd0 with 3 args.
+[00]: arg
+[01]: ipv4
+[02]: 1.2.3.4
test# arg ipv4 1.2.3
-cmd0 with 1 args.
-[00]: 1.2.3
+% [NONE] Unknown command: arg ipv4 1.2.3
test# arg ipv4 1.2.3.4.5
% [NONE] Unknown command: arg ipv4 1.2.3.4.5
test# arg ipv4 1.a.3.4
@@ -27,13 +29,17 @@ test# arg ipv4 blah
% [NONE] Unknown command: arg ipv4 blah
test#
test# arg ipv4m 1.2.3.0/24
-cmd1 with 1 args.
-[00]: 1.2.3.0/24
+cmd1 with 3 args.
+[00]: arg
+[01]: ipv4m
+[02]: 1.2.3.0/24
test# arg ipv4m 1.2.
A.B.C.D/M 02
test# arg ipv4m 1.2.3.0/24
-cmd1 with 1 args.
-[00]: 1.2.3.0/24
+cmd1 with 3 args.
+[00]: arg
+[01]: ipv4m
+[02]: 1.2.3.0/24
test# arg ipv4m 1.2.3/9
% [NONE] Unknown command: arg ipv4m 1.2.3/9
test# arg ipv4m 1.2.3.4.5/6
@@ -50,28 +56,36 @@ test# arg ipv4m 1.2.3.0/9a
% [NONE] Unknown command: arg ipv4m 1.2.3.0/9a
test#
test# arg ipv6 de4d:b33f::cafe
-cmd2 with 1 args.
-[00]: de4d:b33f::cafe
+cmd2 with 3 args.
+[00]: arg
+[01]: ipv6
+[02]: de4d:b33f::cafe
test# arg ipv6 de4d:b3
% There is no matched command.
test# arg ipv6 de4d:b33f::caf
X:X::X:X 02
test# arg ipv6 de4d:b33f::cafe
-cmd2 with 1 args.
-[00]: de4d:b33f::cafe
+cmd2 with 3 args.
+[00]: arg
+[01]: ipv6
+[02]: de4d:b33f::cafe
test# arg ipv6 de4d:b3
test# arg ipv6 de4d:b33f::caf
X:X::X:X 02
test# arg ipv6 de4d:b33f::cafe
-cmd2 with 1 args.
-[00]: de4d:b33f::cafe
+cmd2 with 3 args.
+[00]: arg
+[01]: ipv6
+[02]: de4d:b33f::cafe
test# arg ipv6 de4d:b33f:z::cafe
% [NONE] Unknown command: arg ipv6 de4d:b33f:z::cafe
test# arg ipv6 de4d:b33f:cafe:
% [NONE] Unknown command: arg ipv6 de4d:b33f:cafe:
test# arg ipv6 ::
-cmd2 with 1 args.
-[00]: ::
+cmd2 with 3 args.
+[00]: arg
+[01]: ipv6
+[02]: ::
test# arg ipv6 ::/
% [NONE] Unknown command: arg ipv6 ::/
test# arg ipv6 1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0
@@ -79,29 +93,39 @@ test# arg ipv6 1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0
test# arg ipv6 12::34::56
% [NONE] Unknown command: arg ipv6 12::34::56
test# arg ipv6m dead:beef:cafe::/64
-cmd3 with 1 args.
-[00]: dead:beef:cafe::/64
+cmd3 with 3 args.
+[00]: arg
+[01]: ipv6m
+[02]: dead:beef:cafe::/64
test# arg ipv6m dead:be
X:X::X:X/M 02
test# arg ipv6m dead:beef:cafe:
X:X::X:X/M 02
test# arg ipv6m dead:beef:cafe::/64
-cmd3 with 1 args.
-[00]: dead:beef:cafe::/64
+cmd3 with 3 args.
+[00]: arg
+[01]: ipv6m
+[02]: dead:beef:cafe::/64
test#
test# arg range 4
% [NONE] Unknown command: arg range 4
test# arg range 5
-cmd4 with 1 args.
-[00]: 5
+cmd4 with 3 args.
+[00]: arg
+[01]: range
+[02]: 5
test# arg range 9
- <5-15> 02
+ (5-15) 02
test# arg range 9
-cmd4 with 1 args.
-[00]: 9
+cmd4 with 3 args.
+[00]: arg
+[01]: range
+[02]: 9
test# arg range 15
-cmd4 with 1 args.
-[00]: 15
+cmd4 with 3 args.
+[00]: arg
+[01]: range
+[02]: 15
test# arg range 16
% [NONE] Unknown command: arg range 16
test# arg range -1
@@ -122,21 +146,25 @@ test# pa
test# papat
% Command incomplete.
test# pat
-a b c d e f
+a c d e f
test# pat
% Command incomplete.
test#
test# pat a
% Command incomplete.
test# pat a a
-cmd5 with 1 args.
-[00]: a
+cmd5 with 3 args.
+[00]: pat
+[01]: a
+[02]: a
test# pat a
a 02
b 03
test# pat a b
-cmd5 with 1 args.
-[00]: b
+cmd5 with 3 args.
+[00]: pat
+[01]: a
+[02]: b
test# pat a c
% There is no matched command.
test# pat a c
@@ -144,109 +172,113 @@ test# pat a c
test# pat a a x
% [NONE] Unknown command: pat a a x
test#
-test# pat b
-% Command incomplete.
-test# pat b
- a 02
-test# pat b a
-cmd6 with 1 args.
-[00]: a
-test# pat b x
-% [NONE] Unknown command: pat b x
-test# pat b x y
-% [NONE] Unknown command: pat b x y
-test#
test# pat c a
% Command incomplete.
test# pat c a 1.2.3.4
-cmd7 with 2 args.
-[00]: a
-[01]: 1.2.3.4
+cmd7 with 4 args.
+[00]: pat
+[01]: c
+[02]: a
+[03]: 1.2.3.4
test# pat c b 2.3.4
-cmd7 with 2 args.
-[00]: b
-[01]: 2.3.4
+% [NONE] Unknown command: pat c b 2.3.4
test# pat c c
A.B.C.D 05
test# pat c c x
% [NONE] Unknown command: pat c c x
test#
test# pat d
-cmd8 with 3 args.
-[00]: (null)
-[01]: (null)
-[02]: (null)
+% Command incomplete.
test# pat d
bar baz foo
test# pat d
-cmd8 with 3 args.
-[00]: (null)
-[01]: (null)
-[02]: (null)
+% Command incomplete.
test# pat d foo 1.2.3.4
-cmd8 with 3 args.
-[00]: 1.2.3.4
-[01]: (null)
-[02]: (null)
+cmd8 with 4 args.
+[00]: pat
+[01]: d
+[02]: foo
+[03]: 1.2.3.4
test# pat d foo
% Command incomplete.
test# pat d noooo
% [NONE] Unknown command: pat d noooo
test# pat d bar 1::2
-cmd8 with 3 args.
-[00]: (null)
-[01]: 1::2
-[02]: (null)
+cmd8 with 4 args.
+[00]: pat
+[01]: d
+[02]: bar
+[03]: 1::2
test# pat d bar 1::2 foo 3.4.5.6
-cmd8 with 3 args.
-[00]: 3.4.5.6
-[01]: 1::2
-[02]: (null)
+cmd8 with 6 args.
+[00]: pat
+[01]: d
+[02]: bar
+[03]: 1::2
+[04]: foo
+[05]: 3.4.5.6
test# pat d ba
bar 04
baz 06
test# pat d baz
cmd8 with 3 args.
-[00]: (null)
-[01]: (null)
+[00]: pat
+[01]: d
[02]: baz
test# pat d foo 3.4.5.6 baz
-cmd8 with 3 args.
-[00]: 3.4.5.6
-[01]: (null)
-[02]: baz
+cmd8 with 5 args.
+[00]: pat
+[01]: d
+[02]: foo
+[03]: 3.4.5.6
+[04]: baz
test#
test# pat e
-% Command incomplete.
+cmd9 with 2 args.
+[00]: pat
+[01]: e
test# pat e f
-% Command incomplete.
+cmd9 with 3 args.
+[00]: pat
+[01]: e
+[02]: f
test# pat e f g
-% Command incomplete.
+% [NONE] Unknown command: pat e f g
test# pat e 1.2.3.4
-% Command incomplete.
+cmd9 with 3 args.
+[00]: pat
+[01]: e
+[02]: 1.2.3.4
test#
test# pat f
-cmd10 with 0 args.
+cmd10 with 2 args.
+[00]: pat
+[01]: f
test# pat f foo
-cmd10 with 1 args.
-[00]: foo
+% [NONE] Unknown command: pat f foo
test# pat f key
-cmd10 with 1 args.
-[00]: key
+cmd10 with 3 args.
+[00]: pat
+[01]: f
+[02]: key
test#
test# alt a
test# alt a a
WORD 02
test# alt a ab
-cmd11 with 1 args.
-[00]: ab
+cmd11 with 3 args.
+[00]: alt
+[01]: a
+[02]: ab
test# alt a 1
test# alt a 1.2
A.B.C.D 02
WORD 02
test# alt a 1.2.3.4
-cmd12 with 1 args.
-[00]: 1.2.3.4
+cmd12 with 3 args.
+[00]: alt
+[01]: a
+[02]: 1.2.3.4
test# alt a 1
test# alt a 1:2
WORD 02
@@ -255,14 +287,16 @@ test# alt a 1:2::
WORD 02
X:X::X:X 02
test# alt a 1:2::3
-cmd13 with 1 args.
-[00]: 1:2::3
+cmd13 with 3 args.
+[00]: alt
+[01]: a
+[02]: 1:2::3
test#
test# conf t
test(config)# do pat d baz
cmd8 with 3 args.
-[00]: (null)
-[01]: (null)
+[00]: pat
+[01]: d
[02]: baz
test(config)# exit
test#
diff --git a/tests/test-commands.c b/tests/lib/cli/test_commands.c
index 802002e861..272e3d12b7 100644
--- a/tests/test-commands.c
+++ b/tests/lib/cli/test_commands.c
@@ -146,7 +146,7 @@ static struct cmd_node keychain_key_node =
};
static int
-test_callback(struct cmd_element *cmd, struct vty *vty, int argc, const char *argv[])
+test_callback(const struct cmd_element *cmd, struct vty *vty, int argc, struct cmd_token *argv[])
{
int offset;
int rv;
@@ -162,7 +162,7 @@ test_callback(struct cmd_element *cmd, struct vty *vty, int argc, const char *ar
for (i = 0; i < argc; i++)
{
rv = snprintf(test_buf + offset, sizeof(test_buf) - offset, "%s'%s'",
- (i == 0) ? ": " : ", ", argv[i]);
+ (i == 0) ? ": " : ", ", argv[i]->arg);
if (rv < 0)
abort();
offset += rv;
@@ -317,7 +317,7 @@ test_run(struct prng *prng, struct vty *vty, const char *cmd, unsigned int edit_
printf(" '%s'\n", completions[j]);
XFREE(MTYPE_TMP, completions[j]);
}
- XFREE(MTYPE_VECTOR_INDEX, completions);
+ XFREE(MTYPE_TMP, completions);
}
vty->node = cnode->node;
@@ -332,7 +332,7 @@ test_run(struct prng *prng, struct vty *vty, const char *cmd, unsigned int edit_
for (j = 0; j < vector_active(descriptions); j++)
{
struct cmd_token *cmd = vector_slot(descriptions, j);
- printf(" '%s' '%s'\n", cmd->cmd, cmd->desc);
+ printf(" '%s' '%s'\n", cmd->text, cmd->desc);
}
vector_free(descriptions);
}
diff --git a/tests/testcommands.in b/tests/lib/cli/test_commands.in
index 7fe62799f1..7fe62799f1 100644
--- a/tests/testcommands.in
+++ b/tests/lib/cli/test_commands.in
diff --git a/tests/lib/cli/test_commands.py b/tests/lib/cli/test_commands.py
new file mode 100644
index 0000000000..85e34fa15b
--- /dev/null
+++ b/tests/lib/cli/test_commands.py
@@ -0,0 +1,8 @@
+import frrtest
+import pytest
+import os
+
+@pytest.mark.skipif('QUAGGA_TEST_COMMANDS' not in os.environ,
+ reason='QUAGGA_TEST_COMMANDS not set')
+class TestCommands(frrtest.TestRefOut):
+ program = './test_commands'
diff --git a/tests/testcommands.refout b/tests/lib/cli/test_commands.refout
index 9d4a6ef03e..9d4a6ef03e 100644
--- a/tests/testcommands.refout
+++ b/tests/lib/cli/test_commands.refout
diff --git a/tests/lib/libfrr.exp b/tests/lib/libfrr.exp
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/lib/libfrr.exp
+++ /dev/null
diff --git a/tests/test-buffer.c b/tests/lib/test_buffer.c
index 67e4035806..67e4035806 100644
--- a/tests/test-buffer.c
+++ b/tests/lib/test_buffer.c
diff --git a/tests/test-checksum.c b/tests/lib/test_checksum.c
index 53ab260e26..53ab260e26 100644
--- a/tests/test-checksum.c
+++ b/tests/lib/test_checksum.c
diff --git a/tests/heavy.c b/tests/lib/test_heavy.c
index 9af46c88f7..6ba8d9aa6d 100644
--- a/tests/heavy.c
+++ b/tests/lib/test_heavy.c
@@ -82,7 +82,7 @@ clear_something (struct vty *vty, const char *str)
DEFUN (clear_foo,
clear_foo_cmd,
- "clear foo .LINE",
+ "clear foo LINE...",
"clear command\n"
"arbitrary string\n")
{
diff --git a/tests/heavy-thread.c b/tests/lib/test_heavy_thread.c
index c2e71c17d6..c43fa76c0e 100644
--- a/tests/heavy-thread.c
+++ b/tests/lib/test_heavy_thread.c
@@ -104,7 +104,7 @@ clear_something (struct thread *thread)
DEFUN (clear_foo,
clear_foo_cmd,
- "clear foo .LINE",
+ "clear foo LINE...",
"clear command\n"
"arbitrary string\n")
{
diff --git a/tests/heavy-wq.c b/tests/lib/test_heavy_wq.c
index 2d15dc37bd..97371face1 100644
--- a/tests/heavy-wq.c
+++ b/tests/lib/test_heavy_wq.c
@@ -140,7 +140,7 @@ clear_something (struct vty *vty, const char *str)
DEFUN (clear_foo,
clear_foo_cmd,
- "clear foo .LINE",
+ "clear foo LINE...",
"clear command\n"
"arbitrary string\n")
{
diff --git a/tests/test-memory.c b/tests/lib/test_memory.c
index 6849b9dceb..6849b9dceb 100644
--- a/tests/test-memory.c
+++ b/tests/lib/test_memory.c
diff --git a/tests/test-nexthop-iter.c b/tests/lib/test_nexthop_iter.c
index 250379329b..250379329b 100644
--- a/tests/test-nexthop-iter.c
+++ b/tests/lib/test_nexthop_iter.c
diff --git a/tests/lib/test_nexthop_iter.py b/tests/lib/test_nexthop_iter.py
new file mode 100644
index 0000000000..bb330a1c75
--- /dev/null
+++ b/tests/lib/test_nexthop_iter.py
@@ -0,0 +1,7 @@
+import frrtest
+
+class TestNexthopIter(frrtest.TestMultiOut):
+ program = './test_nexthop_iter'
+
+TestNexthopIter.onesimple('Simple test passed.')
+TestNexthopIter.onesimple('PRNG test passed.')
diff --git a/tests/test-privs.c b/tests/lib/test_privs.c
index c6ccc28e7a..c6ccc28e7a 100644
--- a/tests/test-privs.c
+++ b/tests/lib/test_privs.c
diff --git a/tests/test-segv.c b/tests/lib/test_segv.c
index 1810c5f4b2..1810c5f4b2 100644
--- a/tests/test-segv.c
+++ b/tests/lib/test_segv.c
diff --git a/tests/test-sig.c b/tests/lib/test_sig.c
index 4a04240303..4a04240303 100644
--- a/tests/test-sig.c
+++ b/tests/lib/test_sig.c
diff --git a/tests/lib/test_srcdest_table.c b/tests/lib/test_srcdest_table.c
new file mode 100644
index 0000000000..cfc2deb8d6
--- /dev/null
+++ b/tests/lib/test_srcdest_table.c
@@ -0,0 +1,457 @@
+/*
+ * Test srcdest table for correctness.
+ *
+ * Copyright (C) 2017 by David Lamparter & Christian Franke,
+ * Open Source Routing / NetDEF Inc.
+ *
+ * This file is part of FreeRangeRouting (FRR)
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FRR; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "hash.h"
+#include "memory.h"
+#include "prefix.h"
+#include "prng.h"
+#include "srcdest_table.h"
+#include "table.h"
+
+/* Copied from ripngd/ripng_nexthop.h - maybe the whole s6_addr32 thing
+ * should be added by autoconf if not present?
+ */
+#ifndef s6_addr32
+#if defined(SUNOS_5)
+/* Some SunOS define s6_addr32 only to kernel */
+#define s6_addr32 _S6_un._S6_u32
+#else
+#define s6_addr32 __u6_addr.__u6_addr32
+#endif /* SUNOS_5 */
+#endif /*s6_addr32*/
+
+struct thread_master *master;
+
+/* This structure is copied from lib/srcdest_table.c to which it is
+ * private as far as other parts of Quagga are concerned.
+ */
+struct srcdest_rnode
+{
+ /* must be first in structure for casting to/from route_node */
+ ROUTE_NODE_FIELDS;
+
+ struct route_table *src_table;
+};
+
+struct test_state
+{
+ struct route_table *table;
+ struct hash *log;
+};
+
+static char *
+format_srcdest(const struct prefix_ipv6 *dst_p,
+ const struct prefix_ipv6 *src_p)
+{
+ char dst_str[BUFSIZ];
+ char src_str[BUFSIZ];
+ char *rv;
+ int ec;
+
+ prefix2str((const struct prefix*)dst_p, dst_str, sizeof(dst_str));
+ if (src_p && src_p->prefixlen)
+ prefix2str((const struct prefix*)src_p, src_str, sizeof(src_str));
+ else
+ src_str[0] = '\0';
+
+ ec = asprintf(&rv, "%s%s%s", dst_str,
+ (src_str[0] != '\0') ? " from " : "",
+ src_str);
+
+ assert(ec > 0);
+ return rv;
+}
+
+static unsigned int log_key(void *data)
+{
+ struct prefix *hash_entry = data;
+ struct prefix_ipv6 *dst_p = (struct prefix_ipv6*) &hash_entry[0];
+ struct prefix_ipv6 *src_p = (struct prefix_ipv6*) &hash_entry[1];
+ unsigned int hash = 0;
+ unsigned int i;
+
+ hash = (hash * 33) ^ (unsigned int)dst_p->prefixlen;
+ for (i = 0; i < 4; i++)
+ hash = (hash * 33) ^ (unsigned int)dst_p->prefix.s6_addr32[i];
+
+ hash = (hash * 33) ^ (unsigned int)src_p->prefixlen;
+ if (src_p->prefixlen)
+ for (i = 0; i < 4; i++)
+ hash = (hash * 33) ^ (unsigned int)src_p->prefix.s6_addr32[i];
+
+ return hash;
+}
+
+static int
+log_cmp(const void *a, const void *b)
+{
+ if (a == NULL && b != NULL)
+ return 0;
+ if (b == NULL && a != NULL)
+ return 0;
+
+ return !memcmp(a, b, 2 * sizeof(struct prefix));
+}
+
+static void
+log_free(void *data)
+{
+ XFREE(MTYPE_TMP, data);
+}
+
+static void *
+log_alloc(void *data)
+{
+ void *rv = XMALLOC(MTYPE_TMP, 2 * sizeof(struct prefix));
+ memcpy(rv, data, 2 * sizeof(struct prefix));
+ return rv;
+}
+
+static struct test_state *
+test_state_new(void)
+{
+ struct test_state *rv;
+
+ rv = XCALLOC(MTYPE_TMP, sizeof(*rv));
+ assert(rv);
+
+ rv->table = srcdest_table_init();
+ assert(rv->table);
+
+ rv->log = hash_create(log_key, log_cmp);
+ return rv;
+}
+
+static void
+test_state_free(struct test_state *test)
+{
+ route_table_finish(test->table);
+ hash_clean(test->log, log_free);
+ hash_free(test->log);
+ XFREE(MTYPE_TMP, test);
+}
+
+static void
+test_state_add_route(struct test_state *test,
+ struct prefix_ipv6 *dst_p,
+ struct prefix_ipv6 *src_p)
+{
+ struct route_node *rn = srcdest_rnode_get(
+ test->table, (struct prefix*)dst_p, src_p
+ );
+ struct prefix hash_entry[2];
+
+ memset(hash_entry, 0, sizeof(hash_entry));
+ memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
+ memcpy(&hash_entry[1], src_p, sizeof(*src_p));
+
+ if (rn->info) {
+ route_unlock_node(rn);
+ assert(hash_lookup(test->log, hash_entry) != NULL);
+ return;
+ } else {
+ assert(hash_lookup(test->log, hash_entry) == NULL);
+ }
+
+ rn->info = (void*) 0xdeadbeef;
+ hash_get(test->log, hash_entry, log_alloc);
+};
+
+static void
+test_state_del_route(struct test_state *test,
+ struct prefix_ipv6 *dst_p,
+ struct prefix_ipv6 *src_p)
+{
+ struct route_node *rn = srcdest_rnode_lookup(
+ test->table, (struct prefix*)dst_p, src_p
+ );
+ struct prefix hash_entry[2];
+
+ memset(hash_entry, 0, sizeof(hash_entry));
+ memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
+ memcpy(&hash_entry[1], src_p, sizeof(*src_p));
+
+ if (!rn) {
+ assert(!hash_lookup(test->log, hash_entry));
+ return;
+ }
+
+ assert(rn->info == (void*)0xdeadbeef);
+ rn->info = NULL;
+ route_unlock_node(rn);
+ route_unlock_node(rn);
+
+ struct prefix *hash_entry_intern = hash_release(test->log, hash_entry);
+ assert(hash_entry_intern != NULL);
+ XFREE(MTYPE_TMP, hash_entry_intern);
+}
+
+static void
+verify_log(struct hash_backet* backet, void *arg)
+{
+ struct test_state *test = arg;
+ struct prefix *hash_entry = backet->data;
+ struct prefix *dst_p = &hash_entry[0];
+ struct prefix_ipv6 *src_p = (struct prefix_ipv6*)&hash_entry[1];
+ struct route_node *rn = srcdest_rnode_lookup(test->table, dst_p, src_p);
+
+ assert(rn);
+ assert(rn->info == (void*)0xdeadbeef);
+
+ route_unlock_node(rn);
+}
+
+static void
+dump_log(struct hash_backet* backet, void *arg)
+{
+ struct prefix *hash_entry = backet->data;
+ struct prefix_ipv6 *dst_p = (struct prefix_ipv6*)&hash_entry[0];
+ struct prefix_ipv6 *src_p = (struct prefix_ipv6*)&hash_entry[1];
+ char *route_id = format_srcdest(dst_p, src_p);
+
+ fprintf(stderr, " %s\n", route_id);
+ free(route_id);
+}
+
+static void
+test_dump(struct test_state *test)
+{
+ fprintf(stderr, "Contents of hash table:\n");
+ hash_iterate(test->log, dump_log, test);
+ fprintf(stderr, "\n");
+}
+
+static void
+test_failed(struct test_state *test, const char *message,
+ struct prefix_ipv6 *dst_p, struct prefix_ipv6 *src_p)
+{
+ char *route_id = format_srcdest(dst_p, src_p);
+
+ fprintf(stderr, "Test failed. Error: %s\n", message);
+ fprintf(stderr, "Route in question: %s\n", route_id);
+ free(route_id);
+
+ test_dump(test);
+ assert(3 == 4);
+}
+
+static void
+test_state_verify(struct test_state *test)
+{
+ struct route_node *rn;
+ struct prefix hash_entry[2];
+
+ memset(hash_entry, 0, sizeof(hash_entry));
+
+ /* Verify that there are no elements in the table which have never
+ * been added */
+ for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn))
+ {
+ struct prefix_ipv6 *dst_p, *src_p;
+
+ /* While we are iterating, we hold a lock on the current route_node,
+ * so all the lock counts we check for take that into account; in idle
+ * state all the numbers will be exactly one less.
+ *
+ * Also this makes quite some assumptions based on the current
+ * implementation details of route_table and srcdest_table - another
+ * valid implementation might trigger assertions here.
+ */
+
+ if (rnode_is_dstnode(rn))
+ {
+ struct srcdest_rnode *srn = (struct srcdest_rnode *)rn;
+ unsigned int expected_lock = 1; /* We are in the loop */
+
+ if (rn->info != NULL) /* The route node is not internal */
+ expected_lock++;
+ if (srn->src_table != NULL) /* There's a source table associated with rn */
+ expected_lock++;
+
+ if (rn->lock != expected_lock)
+ test_failed(test, "Dest rnode lock count doesn't match expected count!",
+ (struct prefix_ipv6*)&rn->p, NULL);
+ }
+ else
+ {
+ unsigned int expected_lock = 1; /* We are in the loop */
+
+ if (rn->info != NULL) /* The route node is not internal */
+ expected_lock++;
+
+ if (rn->lock != expected_lock)
+ {
+ struct prefix_ipv6 *dst_p, *src_p;
+ srcdest_rnode_prefixes(rn, (struct prefix**)&dst_p,
+ (struct prefix**)&src_p);
+
+ test_failed(test, "Src rnode lock count doesn't match expected count!",
+ dst_p, src_p);
+ }
+ }
+
+ if (!rn->info)
+ continue;
+
+ assert(rn->info == (void*)0xdeadbeef);
+
+ srcdest_rnode_prefixes(rn, (struct prefix**)&dst_p, (struct prefix**)&src_p);
+ memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
+ if (src_p)
+ memcpy(&hash_entry[1], src_p, sizeof(*src_p));
+ else
+ memset(&hash_entry[1], 0, sizeof(hash_entry[1]));
+
+ if (hash_lookup(test->log, hash_entry) == NULL)
+ test_failed(test, "Route is missing in hash", dst_p, src_p);
+ }
+
+ /* Verify that all added elements are still in the table */
+ hash_iterate(test->log, verify_log, test);
+}
+
+static void
+get_rand_prefix(struct prng *prng, struct prefix_ipv6 *p)
+{
+ int i;
+
+ memset(p, 0, sizeof(*p));
+
+ for (i = 0; i < 4; i++)
+ p->prefix.s6_addr32[i] = prng_rand(prng);
+ p->prefixlen = prng_rand(prng) % 129;
+ p->family = AF_INET6;
+
+ apply_mask((struct prefix*)p);
+}
+
+static void
+get_rand_prefix_pair(struct prng *prng, struct prefix_ipv6 *dst_p,
+ struct prefix_ipv6 *src_p)
+{
+ get_rand_prefix(prng, dst_p);
+ if ((prng_rand(prng) % 4) == 0)
+ {
+ get_rand_prefix(prng, src_p);
+ if (src_p->prefixlen)
+ return;
+ }
+
+ memset(src_p, 0, sizeof(*src_p));
+}
+
+static void
+test_state_add_rand_route(struct test_state *test,
+ struct prng *prng)
+{
+ struct prefix_ipv6 dst_p, src_p;
+
+ get_rand_prefix_pair(prng, &dst_p, &src_p);
+ test_state_add_route(test, &dst_p, &src_p);
+}
+
+static void
+test_state_del_rand_route(struct test_state *test,
+ struct prng *prng)
+{
+ struct prefix_ipv6 dst_p, src_p;
+
+ get_rand_prefix_pair(prng, &dst_p, &src_p);
+ test_state_del_route(test, &dst_p, &src_p);
+}
+
+static void
+test_state_del_one_route(struct test_state *test,
+ struct prng *prng)
+{
+ unsigned int which_route = prng_rand(prng) % test->log->count;
+ struct route_node *rn;
+ struct prefix *dst_p, *src_p;
+ struct prefix_ipv6 dst6_p, src6_p;
+
+ for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn))
+ {
+ if (!rn->info)
+ continue;
+ if (!which_route) {
+ route_unlock_node(rn);
+ break;
+ }
+ which_route--;
+ }
+
+ assert(rn);
+ srcdest_rnode_prefixes(rn, &dst_p, &src_p);
+ memcpy(&dst6_p, dst_p, sizeof(dst6_p));
+ if (src_p)
+ memcpy(&src6_p, src_p, sizeof(src6_p));
+ else
+ memset(&src6_p, 0, sizeof(src6_p));
+
+ test_state_del_route(test, &dst6_p, &src6_p);
+}
+
+static void
+run_prng_test(void)
+{
+ struct test_state *test = test_state_new();
+ struct prng *prng = prng_new(0);
+ size_t i;
+
+ for (i = 0; i < 1000; i++)
+ {
+ switch (prng_rand(prng) % 10)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ test_state_add_rand_route(test, prng);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ test_state_del_one_route(test, prng);
+ break;
+ case 8:
+ case 9:
+ test_state_del_rand_route(test, prng);
+ break;
+ }
+ test_state_verify(test);
+ }
+
+ prng_free(prng);
+ test_state_free(test);
+}
+
+int main(int argc, char *argv[])
+{
+ run_prng_test();
+ printf("PRNG Test successful.\n");
+ return 0;
+}
diff --git a/tests/lib/test_srcdest_table.py b/tests/lib/test_srcdest_table.py
new file mode 100644
index 0000000000..ee73121025
--- /dev/null
+++ b/tests/lib/test_srcdest_table.py
@@ -0,0 +1,6 @@
+import frrtest
+
+class TestSrcdestTable(frrtest.TestMultiOut):
+ program = './test_srcdest_table'
+
+TestSrcdestTable.onesimple('PRNG Test successful.')
diff --git a/tests/test-stream.c b/tests/lib/test_stream.c
index 3ac45eb203..3ac45eb203 100644
--- a/tests/test-stream.c
+++ b/tests/lib/test_stream.c
diff --git a/tests/lib/test_stream.py b/tests/lib/test_stream.py
new file mode 100644
index 0000000000..6f42db1839
--- /dev/null
+++ b/tests/lib/test_stream.py
@@ -0,0 +1,4 @@
+import frrtest
+
+class TestStream(frrtest.TestRefOut):
+ program = './test_stream'
diff --git a/tests/lib/test_stream.refout b/tests/lib/test_stream.refout
new file mode 100644
index 0000000000..cf52e1301e
--- /dev/null
+++ b/tests/lib/test_stream.refout
@@ -0,0 +1,8 @@
+endp: 15, readable: 15, writeable: 1009
+0xef 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef
+endp: 15, readable: 15, writeable: 0
+0xef 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef
+c: 0xef
+w: 0xbeef
+l: 0xdeadbeef
+q: 0xdeadbeefdeadbeef
diff --git a/tests/table_test.c b/tests/lib/test_table.c
index 4042e1aaa2..4042e1aaa2 100644
--- a/tests/table_test.c
+++ b/tests/lib/test_table.c
diff --git a/tests/lib/test_table.py b/tests/lib/test_table.py
new file mode 100644
index 0000000000..e724421273
--- /dev/null
+++ b/tests/lib/test_table.py
@@ -0,0 +1,10 @@
+import frrtest
+
+class TestTable(frrtest.TestMultiOut):
+ program = './test_table'
+
+for i in range(6):
+ TestTable.onesimple('Verifying cmp')
+for i in range(11):
+ TestTable.onesimple('Verifying successor')
+TestTable.onesimple('Verified pausing')
diff --git a/tests/test-timer-correctness.c b/tests/lib/test_timer_correctness.c
index e523929be1..e523929be1 100644
--- a/tests/test-timer-correctness.c
+++ b/tests/lib/test_timer_correctness.c
diff --git a/tests/lib/test_timer_correctness.py b/tests/lib/test_timer_correctness.py
new file mode 100644
index 0000000000..8b4a765a81
--- /dev/null
+++ b/tests/lib/test_timer_correctness.py
@@ -0,0 +1,6 @@
+import frrtest
+
+class TestTimerCorrectness(frrtest.TestMultiOut):
+ program = './test_timer_correctness'
+
+TestTimerCorrectness.onesimple('Expected output and actual output match.')
diff --git a/tests/test-timer-performance.c b/tests/lib/test_timer_performance.c
index ee45ede6ac..a7d09beecc 100644
--- a/tests/test-timer-performance.c
+++ b/tests/lib/test_timer_performance.c
@@ -61,7 +61,7 @@ int main(int argc, char **argv)
for (i = 0; i < SCHEDULE_TIMERS; i++)
thread_cancel(timers[i]);
- quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv_start);
+ monotime(&tv_start);
for (i = 0; i < SCHEDULE_TIMERS; i++)
{
@@ -72,7 +72,7 @@ int main(int argc, char **argv)
NULL, interval_msec);
}
- quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv_lap);
+ monotime(&tv_lap);
for (i = 0; i < REMOVE_TIMERS; i++)
{
@@ -84,7 +84,7 @@ int main(int argc, char **argv)
timers[index] = NULL;
}
- quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv_stop);
+ monotime(&tv_stop);
t_schedule = 1000 * (tv_lap.tv_sec - tv_start.tv_sec);
t_schedule += (tv_lap.tv_usec - tv_start.tv_usec) / 1000;
diff --git a/tests/libfrr.tests/Makefile.am b/tests/libfrr.tests/Makefile.am
deleted file mode 100644
index 4b74e2d3fb..0000000000
--- a/tests/libfrr.tests/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-EXTRA_DIST = \
- tabletest.exp \
- test-timer-correctness.exp \
- testcommands.exp \
- testcli.exp \
- testnexthopiter.exp
diff --git a/tests/libfrr.tests/tabletest.exp b/tests/libfrr.tests/tabletest.exp
deleted file mode 100644
index 7496994b7f..0000000000
--- a/tests/libfrr.tests/tabletest.exp
+++ /dev/null
@@ -1,9 +0,0 @@
-set timeout 10
-set testprefix "tabletest "
-set aborted 0
-
-spawn sh -c "exec ./tabletest 2>/dev/null"
-
-for {set i 0} {$i < 6} {incr i 1} { onesimple "cmp $i" "Verifying cmp"; }
-for {set i 0} {$i < 11} {incr i 1} { onesimple "succ $i" "Verifying successor"; }
-onesimple "pause" "Verified pausing"
diff --git a/tests/libfrr.tests/test-timer-correctness.exp b/tests/libfrr.tests/test-timer-correctness.exp
deleted file mode 100644
index 570150cd51..0000000000
--- a/tests/libfrr.tests/test-timer-correctness.exp
+++ /dev/null
@@ -1,7 +0,0 @@
-set timeout 10
-set testprefix "test-timer-correctness"
-set aborted 0
-
-spawn sh -c "exec ./test-timer-correctness 2>/dev/null"
-
-onesimple "" "Expected output and actual output match."
diff --git a/tests/libfrr.tests/testcli.exp b/tests/libfrr.tests/testcli.exp
deleted file mode 100644
index 778bd0caa3..0000000000
--- a/tests/libfrr.tests/testcli.exp
+++ /dev/null
@@ -1,23 +0,0 @@
-set timeout 30
-set test_name "testcli"
-
-spawn sh -c "./testcli < $env(srcdir)/testcli.in | diff -au $env(srcdir)/testcli.refout -"
-
-expect {
- eof {
- }
- timeout {
- exp_close
- fail "$test_name: timeout"
- }
-}
-
-catch wait result
-set os_error [lindex $result 2]
-set exit_status [lindex $result 3]
-
-if { $os_error == 0 && $exit_status == 0 } {
- pass "$test_name"
-} else {
- fail "$test_name"
-}
diff --git a/tests/libfrr.tests/testcommands.exp b/tests/libfrr.tests/testcommands.exp
deleted file mode 100644
index c5d5a00730..0000000000
--- a/tests/libfrr.tests/testcommands.exp
+++ /dev/null
@@ -1,31 +0,0 @@
-set timeout 30
-set test_name "testcommands"
-
-if {![info exists env(QUAGGA_TEST_COMMANDS)]} {
- # sadly, the test randomly fails when configure parameters differ from
- # what was used to create testcommands.refout. this can be fixed by
- # shipping a matching vtysh_cmd.c, which we'll add after 0.99.23
- pass "$test_name"
- return 0
-}
-
-spawn sh -c "./testcommands -e 0 < $env(srcdir)/testcommands.in | diff -au - $env(srcdir)/testcommands.refout"
-
-expect {
- eof {
- }
- timeout {
- exp_close
- fail "$test_name: timeout"
- }
-}
-
-catch wait result
-set os_error [lindex $result 2]
-set exit_status [lindex $result 3]
-
-if { $os_error == 0 && $exit_status == 0 } {
- pass "$test_name"
-} else {
- fail "$test_name"
-}
diff --git a/tests/libfrr.tests/testnexthopiter.exp b/tests/libfrr.tests/testnexthopiter.exp
deleted file mode 100644
index 777b753995..0000000000
--- a/tests/libfrr.tests/testnexthopiter.exp
+++ /dev/null
@@ -1,8 +0,0 @@
-set timeout 10
-set testprefix "testnexthopiter "
-set aborted 0
-
-spawn sh -c "exec ./testnexthopiter 2>/dev/null"
-
-onesimple "simple" "Simple test passed."
-onesimple "prng" "PRNG test passed."
diff --git a/tests/libfrr.tests/teststream.exp b/tests/libfrr.tests/teststream.exp
deleted file mode 100644
index c977bb4417..0000000000
--- a/tests/libfrr.tests/teststream.exp
+++ /dev/null
@@ -1,28 +0,0 @@
-set timeout 10
-spawn sh -c "exec ./teststream 2>/dev/null"
-
-expect {
- "endp: 15, readable: 15, writeable: 1009" { }
- eof { fail "teststream"; exit; } timeout { fail "teststream"; exit; } }
-expect {
- "0xef 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef" { }
- eof { fail "teststream"; exit; } timeout { fail "teststream"; exit; } }
-expect {
- "endp: 15, readable: 15, writeable: 0" { }
- eof { fail "teststream"; exit; } timeout { fail "teststream"; exit; } }
-expect {
- "0xef 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef" { }
- eof { fail "teststream"; exit; } timeout { fail "teststream"; exit; } }
-expect {
- "c: 0xef" { }
- eof { fail "teststream"; exit; } timeout { fail "teststream"; exit; } }
-expect {
- "w: 0xbeef" { }
- eof { fail "teststream"; exit; } timeout { fail "teststream"; exit; } }
-expect {
- "l: 0xdeadbeef" { }
- eof { fail "teststream"; exit; } timeout { fail "teststream"; exit; } }
-expect {
- "q: 0xdeadbeefdeadbeef" { }
- eof { fail "teststream"; exit; } timeout { fail "teststream"; exit; } }
-pass "teststream"
diff --git a/tests/runtests.py b/tests/runtests.py
new file mode 100644
index 0000000000..533dc6b167
--- /dev/null
+++ b/tests/runtests.py
@@ -0,0 +1,6 @@
+import pytest
+import sys
+import os
+
+sys.path.append(os.path.join(os.path.dirname(__file__), 'helpers','python'))
+raise SystemExit(pytest.main(sys.argv[1:]))
diff --git a/tools/.gitignore b/tools/.gitignore
index dd5bf7c67c..066b0887ae 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -3,4 +3,6 @@
*~
*.loT
-
+.libs
+*.o
+permutations
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 2f1bfc0604..b2d56170c1 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,4 +1,14 @@
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
+DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
+AM_CFLAGS = $(WERROR)
+EXTRA_DIST =
+
+bin_PROGRAMS = permutations
+permutations_SOURCES = permutations.c
+permutations_LDADD = ../lib/libfrr.la
+
sbin_SCRIPTS = frr-reload.py frr
-EXTRA_DIST = frr.service frr-reload.py frr
+EXTRA_DIST += frr.service frr-reload.py frr
+EXTRA_DIST += xml2cli.pl
diff --git a/tools/cmd_check.py b/tools/cmd_check.py
deleted file mode 100755
index bfe90c4392..0000000000
--- a/tools/cmd_check.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/python3
-# Command Checker
-# Copyright (C) 2016 Cumulus Networks, Inc.
-#
-# This file is part of Quagga.
-#
-# Quagga is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2, or (at your option) any
-# later version.
-#
-# Quagga is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Quagga; see the file COPYING. If not, write to the Free
-# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-#
-
-# Parses a source file, ensuring that CLI definitions (DEFUNs, ALIASs, etc)
-# have install_command called on them at some point.
-import sys
-import glob
-import re
-import os
-from pprint import pprint
-
-# patterns used to extract commands
-command_patterns = [
- r'DEF.*\(.*\n\s*([0-9a-z_]*_cmd)',
- r'ALIAS.*\(.*\n\s*([0-9a-z_]*_cmd)',
-]
-
-# patterns that count as installing the command
-install_patterns = [
- r'install_element.*\(.*{0}',
- r'INSTALL.*\(.*{0}'
-]
-
-def process(filename):
- cmds = []
- uninstalled = []
- sourcetext = ''
- headertext = ''
-
- # read source file and header file
- with open(filename) as cf:
- try:
- sourcetext = cf.read()
- headerfile = filename.replace('.c', '.h')
- if os.path.isfile(headerfile):
- with open(headerfile) as hf:
- headertext = hf.read()
- except:
- print('Error reading {0}, skipping'.format(filename))
- return
-
- # build list of defined commands that aren't mentioned in header
- for pattern in command_patterns:
- matches = re.findall(pattern, sourcetext, re.M)
- cmds += filter(lambda x: re.search(x, headertext) is None, matches)
-
- # build list of not installed commands
- for cmd in cmds:
- pats = [ ip.format(cmd) for ip in install_patterns ]
- if all([ re.search(pat, sourcetext) is None for pat in pats ]):
- uninstalled.append(cmd)
-
- if len(uninstalled) > 0:
- print('\033[92m', end='')
- print('{0}'.format(filename))
- print('\033[0m', end='')
- for cmd in uninstalled:
- print(' {0}'.format(cmd))
- print('')
-
-usage = """
-Usage:
- ./cmd_check.py <path> [<path>...]
-
- where 'path' is a C source file or directory
- containing C source files
-"""
-
-if __name__ == '__main__':
- if len(sys.argv) < 2:
- print(usage)
- exit()
-
- cwd = os.getcwd()
- for arg in sys.argv[1:]:
- # collect all c files
- globstr = arg
- if os.path.isdir(arg):
- os.chdir(arg)
- globstr = '*.c'
- for filename in glob.glob(globstr):
- process(filename)
- os.chdir(cwd)
diff --git a/tools/cocci.h b/tools/cocci.h
new file mode 100644
index 0000000000..3d877a7b4b
--- /dev/null
+++ b/tools/cocci.h
@@ -0,0 +1,34 @@
+/* some of this stuff doesn't seem to parse properly in coccinelle */
+
+#define DEFUN(funcname, cmdname, str, help) \
+ static int funcname \
+ (const struct cmd_element *self, \
+ struct vty *vty, \
+ int argc, \
+ struct cmd_token *argv[])
+#define DEFUN_HIDDEN(funcname, cmdname, str, help) \
+ static int funcname \
+ (const struct cmd_element *self, \
+ struct vty *vty, \
+ int argc, \
+ struct cmd_token *argv[])
+
+#define ENABLE_BGP_VNC 1
+#define ALL_LIST_ELEMENTS_RO(list,node,data) \
+ (node) = listhead(list), ((data) = NULL);\
+ (node) != NULL && ((data) = listgetdata(node)); \
+ (node) = listnextnode(node), ((data) = NULL)
+#define ALL_LIST_ELEMENTS(list,node,nextnode,data) \
+ (node) = listhead(list), ((data) = NULL); \
+ (node) != NULL && \
+ ((data) = listgetdata(node),(nextnode) = node->next); \
+ (node) = (nextnode), ((data) = NULL)
+#define LIST_HEAD(name, type) \
+ struct name { \
+ struct type *lh_first; /* first element */ \
+ }
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
diff --git a/tools/permutations.c b/tools/permutations.c
new file mode 100644
index 0000000000..0ca980b259
--- /dev/null
+++ b/tools/permutations.c
@@ -0,0 +1,112 @@
+/*
+ * Generates all possible matching inputs for a command string.
+ * --
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "command.h"
+#include "graph.h"
+#include "vector.h"
+
+#define USAGE "usage: permutations <cmdstr>"
+
+void
+permute (struct graph_node *);
+void
+pretty_print_graph (struct graph_node *start, int level);
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stdout, USAGE"\n");
+ exit(EXIT_SUCCESS);
+ }
+ struct cmd_element *cmd = calloc (1, sizeof (struct cmd_element));
+ cmd->string = strdup(argv[1]);
+
+ struct graph *graph = graph_new();
+ struct cmd_token *token = new_cmd_token (START_TKN, cmd->attr, NULL, NULL);
+ graph_new_node (graph, token, NULL);
+ command_parse_format (graph, cmd);
+
+ permute (vector_slot (graph->nodes, 0));
+ pretty_print_graph (vector_slot (graph->nodes, 0), 0);
+}
+
+void
+permute (struct graph_node *start)
+{
+ static struct list *position = NULL;
+ if (!position) position = list_new ();
+
+ // recursive dfs
+ listnode_add (position, start);
+ for (unsigned int i = 0; i < vector_active (start->to); i++)
+ {
+ struct graph_node *gn = vector_slot (start->to, i);
+ struct cmd_token *tok = gn->data;
+ if (tok->type == END_TKN)
+ {
+ struct graph_node *gnn;
+ struct listnode *ln;
+ for (ALL_LIST_ELEMENTS_RO (position,ln,gnn))
+ {
+ struct cmd_token *tt = gnn->data;
+ if (tt->type < SPECIAL_TKN)
+ fprintf (stdout, "%s ", tt->text);
+ }
+ fprintf (stdout, "\n");
+ }
+ else
+ permute (gn);
+ }
+ list_delete_node (position, listtail(position));
+}
+
+void
+pretty_print_graph (struct graph_node *start, int level)
+{
+ // print this node
+ struct cmd_token *tok = start->data;
+ fprintf (stdout, "%s[%d] ", tok->text, tok->type);
+
+ int numto = vector_active (start->to);
+ if (numto)
+ {
+ if (numto > 1)
+ fprintf (stdout, "\n");
+ for (unsigned int i = 0; i < vector_active (start->to); i++)
+ {
+ struct graph_node *adj = vector_slot (start->to, i);
+ // if we're listing multiple children, indent!
+ if (numto > 1)
+ for (int j = 0; j < level+1; j++)
+ fprintf (stdout, " ");
+ // if this node is a vararg, just print *
+ if (adj == start)
+ fprintf (stdout, "*");
+ else
+ pretty_print_graph (adj, numto > 1 ? level+1 : level);
+ }
+ }
+ else
+ fprintf(stdout, "\n");
+}
diff --git a/tools/vty_check.cocci b/tools/vty_check.cocci
new file mode 100644
index 0000000000..7e5fcc405b
--- /dev/null
+++ b/tools/vty_check.cocci
@@ -0,0 +1,22 @@
+/*
+ * VTY_DECLVAR_CONTEXT contains a built-in "if (!var) return;"
+ */
+@@
+identifier var, typ;
+statement S;
+@@
+
+ {
+ ...
+ \(
+ VTY_DECLVAR_CONTEXT(typ, var);
+ \|
+ VTY_DECLVAR_CONTEXT_SUB(typ, var);
+ \)
+ ...
+- if (
+- \( !var \| var == NULL \)
+- )
+- S
+ ...
+ }
diff --git a/tools/vty_index.cocci b/tools/vty_index.cocci
new file mode 100644
index 0000000000..8290e80b91
--- /dev/null
+++ b/tools/vty_index.cocci
@@ -0,0 +1,244 @@
+/*
+ * prep: strip off casts, they cause things to fail matching later.
+ */
+
+@@
+identifier casttarget;
+symbol vty;
+@@
+
+- (struct casttarget *)vty->index
++ vty->index
+
+/*
+ * variant 1: local variable assigned from vty->index
+ */
+
+@@
+identifier sn, nn;
+identifier fn;
+@@
+
+ int fn(...)
+ {
++ VTY_DECLVAR_CONTEXT (sn, nn);
+ ...
+ \(
+- struct sn *nn;
+ ...
+- nn = vty->index;
+ \|
+- struct sn *nn = vty->index;
+ \|
+- struct sn *nn = vty->index;
+ ...
+- nn = vty->index;
+ \)
+ ...
+ }
+
+@@
+identifier sn, nn;
+identifier fn;
+type Tr;
+@@
+
+ Tr *fn(...)
+ {
++ struct sn *nn = VTY_GET_CONTEXT(sn);
+ ...
+ \(
+- struct sn *nn;
+ ...
+- nn = vty->index;
++ if (!nn) {
++ return NULL;
++ }
+ \|
+- struct sn *nn = vty->index;
++ if (!nn) {
++ return NULL;
++ }
+ \|
+- struct sn *nn = vty->index;
+ ...
+- nn = vty->index;
++ if (!nn) {
++ return NULL;
++ }
+ \)
+ ...
+ }
+
+/*
+ * variant 2: vty wrapper func with (vty, vty->index, ...) signature
+ */
+
+/* find calls of this pattern first; arg will be dropped in rule3 */
+@rule1@
+identifier fn !~ "generic_(set|match)_";
+expression arg;
+@@
+
+ fn(arg, arg->index, ...)
+
+@ script:python @
+fn << rule1.fn;
+arg << rule1.arg;
+@@
+print "R01 removing vty-index argument on %s(%s, ...)" % (fn, arg)
+
+#/* strip arg on the vty wrapper func, add local handling */
+@ rule2 @
+identifier rule1.fn;
+identifier arg;
+identifier T;
+@@
+
+ static int fn (struct vty *vty,
+- struct T * arg,
+ ...)
+ {
++ VTY_DECLVAR_CONTEXT (T, arg);
+ ...
+ }
+
+/* drop argument on call sites identified earlier */
+@ rule3 @
+identifier rule1.fn;
+expression arg;
+@@
+
+ fn(arg,
+- arg->index,
+ ...)
+
+
+/*
+ * variant 3: function calls with "vty->index" argument (but no vty)
+ *
+ * a bit more complicated since we need to find the type from the header.
+ */
+
+/* find call sites first
+ * remember function name for later declvar insertion
+ */
+@ rule11 exists@
+identifier fn;
+identifier fparent;
+type Tr;
+@@
+
+ Tr fparent (...)
+ {
+ ...
+ fn(vty->index, ...)
+ ...
+ }
+
+@ script:python @
+fn << rule11.fn;
+@@
+print "R11 removing vty-index argument on %s(...)" % (fn)
+
+#/* find type of the argument - note args are mostly unnamed in Quagga :( */
+@ rule12 @
+identifier rule11.fn;
+identifier T, argname;
+type Tr;
+@@
+
+(
+ Tr fn(struct T *, ...);
+|
+ Tr fn(struct T * argname, ...);
+)
+
+@ script:python @
+fn << rule11.fn;
+T << rule12.T;
+@@
+print "R12 removing vty-index type is %s for %s(...)" % (T, fn)
+
+#/* add declvar
+# * this is split from rule14 so we support multiple calls in one func */
+@ rule13a @
+identifier rule11.fparent;
+identifier rule12.T;
+@@
+
+ int fparent (...)
+ {
++ VTY_DECLVAR_CONTEXT(T, T);
+ ...
+ }
+
+@ rule13b @
+identifier rule11.fparent;
+identifier rule12.T;
+type Tr;
+@@
+
+ Tr *fparent (...)
+ {
++ struct T *T = VTY_GET_CONTEXT(T);
++ if (!T) {
++ return NULL;
++ }
+ ...
+ }
+
+/* now replace the argument in the call */
+@ rule14 exists @
+identifier rule11.fn;
+identifier rule12.T;
+@@
+
+ {
+ ...
+ \(
+ fn(
+- vty->index,
++ T,
+ ...)
+ \|
+ fn(
+- vty->index
++ T
+ )
+ \)
+ ...
+ }
+
+/* special case ... */
+@rule30@
+identifier fn =~ "generic_(set|match)_";
+expression arg;
+@@
+
+ fn(arg,
+- arg->index,
++ VTY_GET_CONTEXT(route_map_index),
+ ...)
+
+/* and finally - PUSH_CONTEXT */
+@ rule99a exists @
+identifier tnode;
+identifier vexpr =~ "NULL";
+@@
+
+- vty->node = tnode;
+ ...
+- vty->index = vexpr;
++ VTY_PUSH_CONTEXT_NULL(tnode);
+
+@ rule99b exists @
+identifier tnode;
+expression vexpr;
+@@
+
+- vty->node = tnode;
+ ...
+- vty->index = vexpr;
++ VTY_PUSH_CONTEXT(tnode, vexpr);
+
diff --git a/tools/vty_index.sh b/tools/vty_index.sh
new file mode 100755
index 0000000000..0ac8bfb341
--- /dev/null
+++ b/tools/vty_index.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+sed -e '1istatic void bgp_debug_clear_updgrp_update_dbg(struct bgp *bgp);' -i \
+ bgpd/bgp_debug.c
+sed -e 's%^#if 0%#if 1 /* 0 */%' -i \
+ ospfd/ospf_vty.c \
+ ospf6d/ospf6_top.c \
+ #
+spatch \
+ --sp-file tools/vty_index.cocci \
+ --macro-file tools/cocci.h \
+ --all-includes -I . -I lib \
+ --use-gitgrep --dir . --in-place
+
+sed -e 's%^#if 1 /\* 0 \*/%#if 0%' -i \
+ ospfd/ospf_vty.c \
+ ospf6d/ospf6_top.c \
+ #
+sed -e '1d' -i \
+ bgpd/bgp_debug.c
+
diff --git a/tools/xml2cli.pl b/tools/xml2cli.pl
index 43789131c3..40f905bcde 100755
--- a/tools/xml2cli.pl
+++ b/tools/xml2cli.pl
@@ -41,17 +41,19 @@ use XML::LibXML;
"ipv4m" => "A.B.C.D/M",
"ipv6" => "X:X::X:X",
"ipv6m" => "X:X::X:X/M",
- "mtu" => "<1500-9180>",
+ "mtu" => "(1500-9180)",
+ "acl_range" => "(1-199)",
+ "acl_expanded_range" => "(1300-2699)",
# BGP specific
"rd" => "ASN:nn_or_IP-address:nn",
- "asn" => "<1-4294967295>",
+ "asn" => "(1-4294967295)",
"community" => "AA:NN",
- "clist" => "<1-500>",
+ "clist" => "(1-500)",
# LDP specific
- "disc_time" => "<1-65535>",
- "session_time" => "<15-65535>",
- "pwid" => "<1-4294967295>",
- "hops" => "<1-254>"
+ "disc_time" => "(1-65535)",
+ "session_time" => "(15-65535)",
+ "pwid" => "(1-4294967295)",
+ "hops" => "(1-254)"
);
# parse options node and store the corresponding information
@@ -91,7 +93,7 @@ sub parse_options {
push (@cmdstr, $name);
$::options{$options_name}{'help'} .= "\n \"" . $help . "\\n\"";
}
- $::options{$options_name}{'cmdstr'} = "(" . join('|', @cmdstr) . ")";
+ $::options{$options_name}{'cmdstr'} = "<" . join('|', @cmdstr) . ">";
}
# given a subtree, replace all the corresponding include nodes by
@@ -122,7 +124,7 @@ sub generate_arguments {
my @nodes = @_;
my $arguments;
my $no_args = 1;
- my $argc = 0;
+ my $argc = -1;
$arguments .= " struct vty_arg *args[] =\n";
$arguments .= " {\n";
@@ -130,6 +132,7 @@ sub generate_arguments {
my %node = %{$nodes[$i]};
my $arg_value;
+ $argc++;
if (not $node{'arg'}) {
next;
}
@@ -139,7 +142,9 @@ sub generate_arguments {
# argv[] element. for the other types of nodes, the value of the
# argument is the name of the node
if ($node{'input'} or $node{'type'} eq "select") {
- $arg_value = "argv[" . $argc++ . "]";
+ $arg_value = "argv[" . $argc . "]->arg";
+ } elsif ($node{'optional'}) {
+ $arg_value = "(argc > " . $argc . " ? argv[" . $argc. "]->arg : NULL)";
} else {
$arg_value = '"' . $node{'name'} . '"';
}
@@ -195,12 +200,16 @@ sub generate_code {
$helpstr .= $::options{$options_name}{'help'};
} else {
$funcname .= $node{'name'} . " ";
- $cmdstr .= $node{'name'} . " ";
+ if ($node{'optional'}) {
+ $cmdstr .= "[" . $node{'name'} . "] ";
+ } else {
+ $cmdstr .= $node{'name'} . " ";
+ }
$helpstr .= "\n \"" . $node{'help'} . "\\n\"";
}
# update the command string
- if ($node{'function'} ne "inherited") {
+ if ($node{'function'} ne "inherited" and $node{'function'}) {
$function = $node{'function'};
}
}
@@ -278,6 +287,7 @@ sub parse_tree {
$node{'help'} = $xml_node->findvalue('./@help');
$node{'function'} = $xml_node->findvalue('./@function');
$node{'ifdef'} = $xml_node->findvalue('./@ifdef');
+ $node{'optional'} = $xml_node->findvalue('./@optional');
# push node to stack
push (@nodes, \%node);
diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am
index b85723aa05..376f380a32 100644
--- a/vtysh/Makefile.am
+++ b/vtysh/Makefile.am
@@ -59,10 +59,6 @@ if OSPF6D
vtysh_scan += $(top_srcdir)/ospf6d/*.c
endif
-if LDPD
-vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c
-endif
-
if RIPD
vtysh_scan += $(top_srcdir)/ripd/*.c
endif
@@ -89,5 +85,22 @@ vtysh_cmd_FILES = $(vtysh_scan) \
$(top_srcdir)/watchfrr/watchfrr_vty.c \
$(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC)
-vtysh_cmd.c: $(vtysh_cmd_FILES) extract.pl
- ./extract.pl $(vtysh_cmd_FILES) > vtysh_cmd.c
+# this is slightly iffy... ldp_vty_cmds.c can be located in either
+# $srcdir or $builddir depending on whether it's coming pre-built from a
+# dist tarball or being built. automake uses VPATH to find it, but that
+# doesn't work here...
+# so after running "make ldp_vty_cmds.c", the file can be in either of the
+# two directories. we need to do some magic to find out which.
+vtysh_cmd_DEPS = $(vtysh_cmd_FILES)
+if LDPD
+$(top_builddir)/ldpd/ldp_vty_cmds.c:
+ make -C "$(top_builddir)/ldpd" ldp_vty_cmds.c
+vtysh_cmd_DEPS += $(top_builddir)/ldpd/ldp_vty_cmds.c
+endif
+
+vtysh_cmd.c: $(vtysh_cmd_DEPS) extract.pl
+ if test -n "${LDPD}"; then \
+ ldpcmds="$(top_srcdir)/ldpd/ldp_vty_cmds.c"; \
+ test -f "$(top_builddir)/ldpd/ldp_vty_cmds.c" && ldpcmds="$(top_builddir)/ldpd/ldp_vty_cmds.c"; \
+ fi; \
+ ./extract.pl $(vtysh_cmd_FILES) $${ldpcmds} > vtysh_cmd.c
diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in
index 8842f3f5d0..c1b1d705a4 100755
--- a/vtysh/extract.pl.in
+++ b/vtysh/extract.pl.in
@@ -34,7 +34,7 @@ print <<EOF;
EOF
$ignore{'"interface IFNAME"'} = "ignore";
-$ignore{'"interface IFNAME " "vrf <0-65535>"'} = "ignore";
+$ignore{'"interface IFNAME " "vrf (0-65535)"'} = "ignore";
$ignore{'"interface IFNAME " "vrf NAME"'} = "ignore";
$ignore{'"link-params"'} = "ignore";
$ignore{'"vrf NAME"'} = "ignore";
@@ -42,26 +42,25 @@ $ignore{'"ip vrf NAME"'} = "ignore";
$ignore{'"router rip"'} = "ignore";
$ignore{'"router ripng"'} = "ignore";
$ignore{'"router ospf"'} = "ignore";
-$ignore{'"router ospf <1-65535>"'} = "ignore";
+$ignore{'"router ospf (1-65535)"'} = "ignore";
$ignore{'"router ospf6"'} = "ignore";
$ignore{'"mpls ldp"'} = "ignore";
$ignore{'"l2vpn WORD type vpls"'} = "ignore";
$ignore{'"member pseudowire IFNAME"'} = "ignore";
$ignore{'"router bgp"'} = "ignore";
-$ignore{'"router bgp " "<1-4294967295>"'} = "ignore";
-$ignore{'"router bgp " "<1-4294967295>" " (view|vrf) WORD"'} = "ignore";
+$ignore{'"router bgp " "(1-4294967295)"'} = "ignore";
+$ignore{'"router bgp " "(1-4294967295)" " <view|vrf> WORD"'} = "ignore";
+$ignore{'"router bgp [(1-4294967295) [<view|vrf> WORD]]"'} = "ignore";
$ignore{'"router isis WORD"'} = "ignore";
$ignore{'"router zebra"'} = "ignore";
$ignore{'"address-family ipv4"'} = "ignore";
-$ignore{'"address-family ipv4 (unicast|multicast|vpn|encap)"'} = "ignore";
+$ignore{'"address-family ipv4 [<unicast|multicast|vpn|encap>]"'} = "ignore";
$ignore{'"address-family ipv6"'} = "ignore";
-$ignore{'"address-family ipv6 (unicast|multicast|vpn|encap)"'} = "ignore";
-$ignore{'"address-family ipv4 vpn"'} = "ignore";
+$ignore{'"address-family ipv6 [<unicast|multicast|vpn|encap>]"'} = "ignore";
$ignore{'"address-family vpnv4"'} = "ignore";
$ignore{'"address-family vpnv4 unicast"'} = "ignore";
$ignore{'"address-family ipv4 vrf NAME"'} = "ignore";
-$ignore{'"address-family encap"'} = "ignore";
-$ignore{'"address-family encapv4"'} = "ignore";
+$ignore{'"address-family <encap|encapv4>"'} = "ignore";
$ignore{'"address-family encapv6"'} = "ignore";
$ignore{'"address-family ipv4 encap"'} = "ignore";
$ignore{'"address-family ipv6 encap"'} = "ignore";
@@ -71,24 +70,31 @@ $ignore{'"address-family vpnv6 unicast"'} = "ignore";
$ignore{'"exit-address-family"'} = "ignore";
$ignore{'"exit-link-params"'} = "ignore";
$ignore{'"vnc defaults"'} = "ignore";
+$ignore{'"vnc l2-group NAME"'} = "ignore";
$ignore{'"vnc nve-group NAME"'} = "ignore";
$ignore{'"exit-vnc"'} = "ignore";
$ignore{'"key chain WORD"'} = "ignore";
-$ignore{'"key <0-2147483647>"'} = "ignore";
-$ignore{'"route-map WORD (deny|permit) <1-65535>"'} = "ignore";
+$ignore{'"key (0-2147483647)"'} = "ignore";
+$ignore{'"route-map WORD <deny|permit> (1-65535)"'} = "ignore";
$ignore{'"show route-map"'} = "ignore";
$ignore{'"line vty"'} = "ignore";
$ignore{'"who"'} = "ignore";
$ignore{'"terminal monitor"'} = "ignore";
$ignore{'"terminal no monitor"'} = "ignore";
$ignore{'"show history"'} = "ignore";
+$ignore{'"router ospf [(1-65535)]"'} = "ignore";
+$ignore{'"address-family vpnv6 [unicast]"'} = "ignore";
+$ignore{'"address-family vpnv4 [unicast]"'} = "ignore";
+$ignore{'"logical-router (1-65535) ns NAME"'} = "ignore";
+$ignore{'"vrf-policy NAME"' } = "ignore";
+$ignore{'"exit-vrf-policy"' } = "ignore";
my $cli_stomp = 0;
foreach (@ARGV) {
$file = $_;
- open (FH, "@CPP@ -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -DHAVE_IPV6 -I@top_builddir@ -I@srcdir@/ -I@srcdir@/.. -I@top_srcdir@/lib -I@top_builddir@/lib -I@top_srcdir@/bgpd -I@top_srcdir@/@LIBRFP@ -I@top_srcdir@/bgpd/rfapi @CPPFLAGS@ $file |");
+ open (FH, "@CPP@ -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -I@top_builddir@ -I@srcdir@/ -I@srcdir@/.. -I@top_srcdir@/lib -I@top_builddir@/lib -I@top_srcdir@/bgpd -I@top_srcdir@/@LIBRFP@ -I@top_srcdir@/bgpd/rfapi @CPPFLAGS@ $file |");
local $/; undef $/;
$line = <FH>;
close (FH);
@@ -170,7 +176,7 @@ foreach (@ARGV) {
elsif ($file =~ /librfp\/.*\.c$/ || $file =~ /rfapi\/.*\.c$/) {
$protocol = "VTYSH_BGPD";
}
- else {
+ else {
($protocol) = ($file =~ /^.*\/([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/);
$protocol = "VTYSH_" . uc $protocol;
}
@@ -226,11 +232,6 @@ foreach (@ARGV) {
}
}
-my $bad_cli_stomps = 108;
-# Currently we have $bad_cli_stomps. This was determined by
-# running this script and counting up the collisions from what
-# was returned.
-#
# When we have cli commands that map to the same function name, we
# can introduce subtle bugs due to code not being called when
# we think it is.
@@ -238,15 +239,9 @@ my $bad_cli_stomps = 108;
# If extract.pl fails with a error message and you've been
# modifying the cli, then go back and fix your code to
# not have cli command function collisions.
-#
-# If you've removed a cli overwrite, you can safely subtract
-# one from $bad_cli_stomps. If you've added to the problem
# please fix your code before submittal
-if ($cli_stomp != $bad_cli_stomps) {
- warn "Expected $bad_cli_stomps command line stomps, but got $cli_stomp instead\n";
- if ($cli_stomp > $bad_cli_stomps) {
- exit $cli_stomp;
- }
+if ($cli_stomp) {
+ warn "There are $cli_stomp command line stomps\n";
}
# Check finaly alive $cmd;
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 7546b4ddb0..6427b8c165 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -271,7 +271,7 @@ vtysh_execute_func (const char *line, int pager)
int ret, cmd_stat;
u_int i;
vector vline;
- struct cmd_element *cmd;
+ const struct cmd_element *cmd;
FILE *fp = NULL;
int closepager = 0;
int tried = 0;
@@ -312,6 +312,10 @@ vtysh_execute_func (const char *line, int pager)
{
vtysh_execute("exit-address-family");
}
+ else if (saved_node == BGP_VRF_POLICY_NODE && (tried == 1))
+ {
+ vtysh_execute("exit-vrf-policy");
+ }
else if ((saved_node == BGP_VNC_DEFAULTS_NODE
|| saved_node == BGP_VNC_NVE_GROUP_NODE
|| saved_node == BGP_VNC_L2_GROUP_NODE) && (tried == 1))
@@ -482,7 +486,7 @@ vtysh_mark_file (const char *filename)
int ret;
vector vline;
int tried = 0;
- struct cmd_element *cmd;
+ const struct cmd_element *cmd;
int saved_ret, prev_node;
int lineno = 0;
char *vty_buf_copy = NULL;
@@ -650,7 +654,7 @@ int
vtysh_config_from_file (struct vty *vty, FILE *fp)
{
int ret;
- struct cmd_element *cmd;
+ const struct cmd_element *cmd;
int lineno = 0;
int retcode = CMD_SUCCESS;
@@ -767,32 +771,25 @@ vtysh_rl_describe (void)
for (i = 0; i < vector_active (describe); i++)
if ((token = vector_slot (describe, i)) != NULL)
{
- int len;
-
- if (token->cmd[0] == '\0')
- continue;
+ if (token->text[0] == '\0')
+ continue;
- len = strlen (token->cmd);
- if (token->cmd[0] == '.')
- len--;
+ int len = strlen (token->text);
- if (width < len)
- width = len;
+ if (width < len)
+ width = len;
}
for (i = 0; i < vector_active (describe); i++)
if ((token = vector_slot (describe, i)) != NULL)
{
- if (token->cmd[0] == '\0')
- continue;
-
if (! token->desc)
fprintf (stdout," %-s\n",
- token->cmd[0] == '.' ? token->cmd + 1 : token->cmd);
+ token->text);
else
fprintf (stdout," %-*s %s\n",
width,
- token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
+ token->text,
token->desc);
}
@@ -831,8 +828,6 @@ command_generator (const char *text, int state)
if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
vector_set (vline, NULL);
- if (matched)
- XFREE (MTYPE_TMP, matched);
matched = cmd_complete_command (vline, vty, &complete_status);
cmd_free_strvec (vline);
}
@@ -840,6 +835,9 @@ command_generator (const char *text, int state)
if (matched && matched[index])
return matched[index++];
+ XFREE (MTYPE_TMP, matched);
+ matched = NULL;
+
return NULL;
}
@@ -970,6 +968,11 @@ static struct cmd_node bgp_vnc_nve_group_node =
"%s(config-router-vnc-nve-group)# "
};
+static struct cmd_node bgp_vrf_policy_node = {
+ BGP_VRF_POLICY_NODE,
+ "%s(config-router-vrf-policy)# "
+};
+
static struct cmd_node bgp_vnc_l2_group_node =
{
BGP_VNC_L2_GROUP_NODE,
@@ -1086,49 +1089,23 @@ DEFUNSH (VTYSH_REALLYALL,
DEFUNSH (VTYSH_BGPD,
router_bgp,
router_bgp_cmd,
- "router bgp " CMD_AS_RANGE,
+ "router bgp [(1-4294967295) [<view|vrf> WORD]]",
ROUTER_STR
BGP_STR
- AS_STR)
+ AS_STR
+ "BGP view\nBGP VRF\n"
+ "View/VRF name\n")
{
vty->node = BGP_NODE;
return CMD_SUCCESS;
}
-ALIAS_SH (VTYSH_BGPD,
- router_bgp,
- router_bgp_asn_cmd,
- "router bgp",
- ROUTER_STR
- BGP_STR)
-
-ALIAS_SH (VTYSH_BGPD,
- router_bgp,
- router_bgp_view_cmd,
- "router bgp " CMD_AS_RANGE " (view|vrf) WORD",
- ROUTER_STR
- BGP_STR
- AS_STR
- "BGP view\nBGP VRF\n"
- "View/VRF name\n")
-
DEFUNSH (VTYSH_BGPD,
address_family_vpnv4,
address_family_vpnv4_cmd,
- "address-family vpnv4",
+ "address-family vpnv4 [unicast]",
"Enter Address Family command mode\n"
- "Address family\n")
-{
- vty->node = BGP_VPNV4_NODE;
- return CMD_SUCCESS;
-}
-
-DEFUNSH (VTYSH_BGPD,
- address_family_vpnv4_unicast,
- address_family_vpnv4_unicast_cmd,
- "address-family vpnv4 unicast",
- "Enter Address Family command mode\n"
- "Address family\n"
+ "Address Family\n"
"Address Family Modifier\n")
{
vty->node = BGP_VPNV4_NODE;
@@ -1138,20 +1115,9 @@ DEFUNSH (VTYSH_BGPD,
DEFUNSH (VTYSH_BGPD,
address_family_vpnv6,
address_family_vpnv6_cmd,
- "address-family vpnv6",
- "Enter Address Family command mode\n"
- "Address family\n")
-{
- vty->node = BGP_VPNV6_NODE;
- return CMD_SUCCESS;
-}
-
-DEFUNSH (VTYSH_BGPD,
- address_family_vpnv6_unicast,
- address_family_vpnv6_unicast_cmd,
- "address-family vpnv6 unicast",
+ "address-family vpnv6 [unicast]",
"Enter Address Family command mode\n"
- "Address family\n"
+ "Address Family\n"
"Address Family Modifier\n")
{
vty->node = BGP_VPNV6_NODE;
@@ -1159,22 +1125,12 @@ DEFUNSH (VTYSH_BGPD,
}
DEFUNSH (VTYSH_BGPD,
- address_family_encap,
- address_family_encap_cmd,
- "address-family encap",
- "Enter Address Family command mode\n"
- "Address family\n")
-{
- vty->node = BGP_ENCAP_NODE;
- return CMD_SUCCESS;
-}
-
-DEFUNSH (VTYSH_BGPD,
address_family_encapv4,
address_family_encapv4_cmd,
- "address-family encapv4",
+ "address-family <encap|encapv4>",
"Enter Address Family command mode\n"
- "Address family\n")
+ "Address Family\n"
+ "Address Family\n")
{
vty->node = BGP_ENCAP_NODE;
return CMD_SUCCESS;
@@ -1185,7 +1141,7 @@ DEFUNSH (VTYSH_BGPD,
address_family_encapv6_cmd,
"address-family encapv6",
"Enter Address Family command mode\n"
- "Address family\n")
+ "Address Family\n")
{
vty->node = BGP_ENCAPV6_NODE;
return CMD_SUCCESS;
@@ -1194,108 +1150,56 @@ DEFUNSH (VTYSH_BGPD,
DEFUNSH (VTYSH_BGPD,
address_family_ipv4_unicast,
address_family_ipv4_unicast_cmd,
- "address-family ipv4 unicast",
+ "address-family ipv4 [<unicast|multicast|vpn|encap>]",
"Enter Address Family command mode\n"
- "Address family\n"
- "Address Family Modifier\n")
+ "Address Family\n"
+ "Address Family Modifier\n"
+ "Address Family Modifier\n"
+ "Address Family Modifier\n"
+ "Address Family Modifier\n")
{
- vty->node = BGP_IPV4_NODE;
- return CMD_SUCCESS;
-}
+ int idx = 0;
-DEFUNSH (VTYSH_BGPD,
- address_family_ipv4_multicast,
- address_family_ipv4_multicast_cmd,
- "address-family ipv4 multicast",
- "Enter Address Family command mode\n"
- "Address family\n"
- "Address Family Modifier\n")
-{
- vty->node = BGP_IPV4M_NODE;
- return CMD_SUCCESS;
-}
+ if (argv_find (argv, argc, "multicast", &idx))
+ vty->node = BGP_IPV4M_NODE;
-DEFUNSH (VTYSH_BGPD,
- address_family_ipv4_encap,
- address_family_ipv4_encap_cmd,
- "address-family ipv4 encap",
- "Enter Address Family command mode\n"
- "Address family\n"
- "Address Family Modifier\n")
-{
- vty->node = BGP_ENCAP_NODE;
- return CMD_SUCCESS;
-}
+ else if (argv_find (argv, argc, "encap", &idx))
+ vty->node = BGP_ENCAP_NODE;
+
+ else if (argv_find (argv, argc, "vpn", &idx))
+ vty->node = BGP_VPNV4_NODE;
+
+ else
+ vty->node = BGP_IPV4_NODE;
-DEFUNSH (VTYSH_BGPD,
- address_family_ipv4_vpn,
- address_family_ipv4_vpn_cmd,
- "address-family ipv4 vpn",
- "Enter Address Family command mode\n"
- "Address family\n"
- "Address Family Modifier\n")
-{
- vty->node = BGP_VPNV4_NODE;
return CMD_SUCCESS;
}
-
DEFUNSH (VTYSH_BGPD,
address_family_ipv6,
address_family_ipv6_cmd,
- "address-family ipv6",
+ "address-family ipv6 [<unicast|multicast|vpn|encap>]",
"Enter Address Family command mode\n"
- "Address family\n")
+ "Address Family\n"
+ "Address Family Modifier\n"
+ "Address Family Modifier\n"
+ "Address Family Modifier\n"
+ "Address Family Modifier\n")
{
- vty->node = BGP_IPV6_NODE;
- return CMD_SUCCESS;
-}
+ int idx = 0;
-DEFUNSH (VTYSH_BGPD,
- address_family_ipv6_unicast,
- address_family_ipv6_unicast_cmd,
- "address-family ipv6 unicast",
- "Enter Address Family command mode\n"
- "Address family\n"
- "Address Family Modifier\n")
-{
- vty->node = BGP_IPV6_NODE;
- return CMD_SUCCESS;
-}
+ if (argv_find (argv, argc, "multicast", &idx))
+ vty->node = BGP_IPV6M_NODE;
-DEFUNSH (VTYSH_BGPD,
- address_family_ipv6_multicast,
- address_family_ipv6_multicast_cmd,
- "address-family ipv6 multicast",
- "Enter Address Family command mode\n"
- "Address family\n"
- "Address Family Modifier\n")
-{
- vty->node = BGP_IPV6M_NODE;
- return CMD_SUCCESS;
-}
+ else if (argv_find (argv, argc, "encap", &idx))
+ vty->node = BGP_ENCAPV6_NODE;
-DEFUNSH (VTYSH_BGPD,
- address_family_ipv6_encap,
- address_family_ipv6_encap_cmd,
- "address-family ipv6 encap",
- "Enter Address Family command mode\n"
- "Address family\n"
- "Address Family Modifier\n")
-{
- vty->node = BGP_ENCAPV6_NODE;
- return CMD_SUCCESS;
-}
+ else if (argv_find (argv, argc, "vpn", &idx))
+ vty->node = BGP_VPNV6_NODE;
+
+ else
+ vty->node = BGP_IPV6_NODE;
-DEFUNSH (VTYSH_BGPD,
- address_family_ipv6_vpn,
- address_family_ipv6_vpn_cmd,
- "address-family ipv6 vpn",
- "Enter Address Family command mode\n"
- "Address family\n"
- "Address Family Modifier\n")
-{
- vty->node = BGP_VPNV6_NODE;
return CMD_SUCCESS;
}
@@ -1324,6 +1228,17 @@ DEFUNSH (VTYSH_BGPD,
}
DEFUNSH (VTYSH_BGPD,
+ vnc_vrf_policy,
+ vnc_vrf_policy_cmd,
+ "vrf-policy NAME",
+ "Configure a VRF policy group\n"
+ "Group name\n")
+{
+ vty->node = BGP_VRF_POLICY_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUNSH (VTYSH_BGPD,
vnc_l2_group,
vnc_l2_group_cmd,
"vnc l2-group NAME",
@@ -1351,7 +1266,7 @@ DEFUNSH (VTYSH_RIPD,
DEFUNSH (VTYSH_RIPD,
key,
key_cmd,
- "key <0-2147483647>",
+ "key (0-2147483647)",
"Configure a key\n"
"Key identifier number\n")
{
@@ -1384,27 +1299,20 @@ DEFUNSH (VTYSH_RIPNGD,
DEFUNSH (VTYSH_OSPFD,
router_ospf,
router_ospf_cmd,
- "router ospf",
+ "router ospf [(1-65535)]",
"Enable a routing process\n"
- "Start OSPF configuration\n")
+ "Start OSPF configuration\n"
+ "Instance ID\n")
{
vty->node = OSPF_NODE;
return CMD_SUCCESS;
}
-ALIAS_SH (VTYSH_OSPFD,
- router_ospf,
- router_ospf_instance_cmd,
- "router ospf <1-65535>",
- "Enable a routing process\n"
- "Start OSPF configuration\n"
- "Instance ID\n")
-
DEFUNSH (VTYSH_OSPF6D,
router_ospf6,
router_ospf6_cmd,
"router ospf6",
- OSPF6_ROUTER_STR
+ ROUTER_STR
OSPF6_STR)
{
vty->node = OSPF6_NODE;
@@ -1508,7 +1416,7 @@ DEFUNSH (VTYSH_ISISD,
DEFUNSH (VTYSH_RMAP,
vtysh_route_map,
vtysh_route_map_cmd,
- "route-map WORD (deny|permit) <1-65535>",
+ "route-map WORD <deny|permit> (1-65535)",
"Create route-map or enter route-map command mode\n"
"Route map tag\n"
"Route map denies set operations\n"
@@ -1602,6 +1510,7 @@ vtysh_exit (struct vty *vty)
case BGP_IPV4M_NODE:
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
+ case BGP_VRF_POLICY_NODE:
case BGP_VNC_DEFAULTS_NODE:
case BGP_VNC_NVE_GROUP_NODE:
case BGP_VNC_L2_GROUP_NODE:
@@ -1641,10 +1550,14 @@ DEFUNSH (VTYSH_REALLYALL,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_all,
- vtysh_quit_all_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_ALL,
+ vtysh_quit_all,
+ vtysh_quit_all_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_all (self, vty, argc, argv);
+}
DEFUNSH (VTYSH_BGPD,
exit_address_family,
@@ -1677,20 +1590,17 @@ DEFUNSH (VTYSH_BGPD,
return CMD_SUCCESS;
}
-DEFUNSH (VTYSH_ZEBRA,
- vtysh_exit_zebra,
- vtysh_exit_zebra_cmd,
- "exit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_BGPD,
+ exit_vrf_policy,
+ exit_vrf_policy_cmd,
+ "exit-vrf-policy",
+ "Exit from VRF configuration mode\n")
{
- return vtysh_exit (vty);
+ if (vty->node == BGP_VRF_POLICY_NODE)
+ vty->node = BGP_NODE;
+ return CMD_SUCCESS;
}
-ALIAS (vtysh_exit_zebra,
- vtysh_quit_zebra_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
-
DEFUNSH (VTYSH_RIPD,
vtysh_exit_ripd,
vtysh_exit_ripd_cmd,
@@ -1700,10 +1610,14 @@ DEFUNSH (VTYSH_RIPD,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_ripd,
- vtysh_quit_ripd_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_RIPD,
+ vtysh_quit_ripd,
+ vtysh_quit_ripd_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_ripd (self, vty, argc, argv);
+}
DEFUNSH (VTYSH_RIPNGD,
vtysh_exit_ripngd,
@@ -1714,10 +1628,14 @@ DEFUNSH (VTYSH_RIPNGD,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_ripngd,
- vtysh_quit_ripngd_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_RIPNGD,
+ vtysh_quit_ripngd,
+ vtysh_quit_ripngd_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_ripngd (self, vty, argc, argv);
+}
DEFUNSH (VTYSH_RMAP,
vtysh_exit_rmap,
@@ -1728,10 +1646,14 @@ DEFUNSH (VTYSH_RMAP,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_rmap,
- vtysh_quit_rmap_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_RMAP,
+ vtysh_quit_rmap,
+ vtysh_quit_rmap_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_rmap (self, vty, argc, argv);
+}
DEFUNSH (VTYSH_BGPD,
vtysh_exit_bgpd,
@@ -1742,10 +1664,14 @@ DEFUNSH (VTYSH_BGPD,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_bgpd,
- vtysh_quit_bgpd_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_BGPD,
+ vtysh_quit_bgpd,
+ vtysh_quit_bgpd_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_bgpd (self, vty, argc, argv);
+}
DEFUNSH (VTYSH_OSPFD,
vtysh_exit_ospfd,
@@ -1756,10 +1682,14 @@ DEFUNSH (VTYSH_OSPFD,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_ospfd,
- vtysh_quit_ospfd_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_OSPFD,
+ vtysh_quit_ospfd,
+ vtysh_quit_ospfd_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_ospfd (self, vty, argc, argv);
+}
DEFUNSH (VTYSH_OSPF6D,
vtysh_exit_ospf6d,
@@ -1770,10 +1700,14 @@ DEFUNSH (VTYSH_OSPF6D,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_ospf6d,
- vtysh_quit_ospf6d_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_OSPF6D,
+ vtysh_quit_ospf6d,
+ vtysh_quit_ospf6d_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_ospf6d (self, vty, argc, argv);
+}
#if defined (HAVE_LDPD)
DEFUNSH (VTYSH_LDPD,
@@ -1800,10 +1734,14 @@ DEFUNSH (VTYSH_ISISD,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_isisd,
- vtysh_quit_isisd_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_ISISD,
+ vtysh_quit_isisd,
+ vtysh_quit_isisd_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_isisd (self, vty, argc, argv);
+}
DEFUNSH (VTYSH_ALL,
vtysh_exit_line_vty,
@@ -1814,30 +1752,27 @@ DEFUNSH (VTYSH_ALL,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_line_vty,
- vtysh_quit_line_vty_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_ALL,
+ vtysh_quit_line_vty,
+ vtysh_quit_line_vty_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_line_vty (self, vty, argc, argv);
+}
DEFUNSH (VTYSH_INTERFACE,
vtysh_interface,
vtysh_interface_cmd,
- "interface IFNAME",
+ "interface IFNAME [vrf NAME]",
"Select an interface to configure\n"
- "Interface's name\n")
+ "Interface's name\n"
+ VRF_CMD_HELP_STR)
{
vty->node = INTERFACE_NODE;
return CMD_SUCCESS;
}
-ALIAS_SH (VTYSH_ZEBRA,
- vtysh_interface,
- vtysh_interface_vrf_cmd,
- "interface IFNAME " VRF_CMD_STR,
- "Select an interface to configure\n"
- "Interface's name\n"
- VRF_CMD_HELP_STR)
-
/* TODO Implement "no interface command in isisd. */
DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD,
vtysh_no_interface_cmd,
@@ -1848,7 +1783,7 @@ DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD,
DEFSH (VTYSH_ZEBRA,
vtysh_no_interface_vrf_cmd,
- "no interface IFNAME " VRF_CMD_STR,
+ "no interface IFNAME vrf NAME",
NO_STR
"Delete a pseudo interface's configuration\n"
"Interface's name\n"
@@ -1857,7 +1792,7 @@ DEFSH (VTYSH_ZEBRA,
DEFUNSH (VTYSH_NS,
vtysh_ns,
vtysh_ns_cmd,
- "logical-router <1-65535 ns NAME",
+ "logical-router (1-65535) ns NAME",
"Enable a logical-router\n"
"Specify the logical-router indentifier\n"
"The Name Space\n"
@@ -1894,10 +1829,14 @@ DEFUNSH (VTYSH_NS,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_ns,
- vtysh_quit_ns_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_NS,
+ vtysh_quit_ns,
+ vtysh_quit_ns_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_ns(self, vty, argc, argv);
+}
DEFUNSH (VTYSH_VRF,
vtysh_exit_vrf,
@@ -1908,16 +1847,20 @@ DEFUNSH (VTYSH_VRF,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_vrf,
- vtysh_quit_vrf_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_VRF,
+ vtysh_quit_vrf,
+ vtysh_quit_vrf_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_vrf (self, vty, argc, argv);
+}
/* TODO Implement interface description commands in ripngd, ospf6d
* and isisd. */
DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_LDPD,
vtysh_interface_desc_cmd,
- "description .LINE",
+ "description LINE...",
"Interface specific description\n"
"Characters describing this interface\n")
@@ -1936,10 +1879,14 @@ DEFUNSH (VTYSH_INTERFACE,
return vtysh_exit (vty);
}
-ALIAS (vtysh_exit_interface,
- vtysh_quit_interface_cmd,
- "quit",
- "Exit current mode and down to previous mode\n")
+DEFUNSH (VTYSH_INTERFACE,
+ vtysh_quit_interface,
+ vtysh_quit_interface_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_interface (self, vty, argc, argv);
+}
DEFUN (vtysh_show_thread,
vtysh_show_thread_cmd,
@@ -1949,11 +1896,12 @@ DEFUN (vtysh_show_thread,
"Thread CPU usage\n"
"Display filter (rwtexb)\n")
{
+ int idx_filter = 3;
unsigned int i;
int ret = CMD_SUCCESS;
char line[100];
- sprintf(line, "show thread cpu %s\n", (argc == 1) ? argv[0] : "");
+ sprintf(line, "show thread cpu %s\n", (argc == 4) ? argv[idx_filter]->arg : "");
for (i = 0; i < array_size(vtysh_client); i++)
if ( vtysh_client[i].fd >= 0 )
{
@@ -1989,7 +1937,7 @@ DEFUN (vtysh_show_work_queues,
DEFUN (vtysh_show_work_queues_daemon,
vtysh_show_work_queues_daemon_cmd,
- "show work-queues (zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd)",
+ "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd>",
SHOW_STR
"Work Queue information\n"
"For the zebra daemon\n"
@@ -2000,12 +1948,13 @@ DEFUN (vtysh_show_work_queues_daemon,
"For the bgp daemon\n"
"For the isis daemon\n")
{
+ int idx_protocol = 2;
unsigned int i;
int ret = CMD_SUCCESS;
for (i = 0; i < array_size(vtysh_client); i++)
{
- if (begins_with(vtysh_client[i].name, argv[0]))
+ if (strmatch(vtysh_client[i].name, argv[idx_protocol]->text))
break;
}
@@ -2095,7 +2044,7 @@ DEFUNSH (VTYSH_ALL,
DEFUNSH (VTYSH_ALL,
vtysh_log_stdout_level,
vtysh_log_stdout_level_cmd,
- "log stdout "LOG_LEVELS,
+ "log stdout <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
"Logging control\n"
"Set stdout logging level\n"
LOG_LEVEL_DESC)
@@ -2129,7 +2078,7 @@ DEFUNSH (VTYSH_ALL,
DEFUNSH (VTYSH_ALL,
vtysh_log_file_level,
vtysh_log_file_level_cmd,
- "log file FILENAME "LOG_LEVELS,
+ "log file FILENAME <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
"Logging control\n"
"Logging to file\n"
"Logging filename\n"
@@ -2141,42 +2090,23 @@ DEFUNSH (VTYSH_ALL,
DEFUNSH (VTYSH_ALL,
no_vtysh_log_file,
no_vtysh_log_file_cmd,
- "no log file [FILENAME]",
+ "no log file [FILENAME [LEVEL]]",
NO_STR
"Logging control\n"
"Cancel logging to file\n"
- "Logging file name\n")
+ "Logging file name\n"
+ "Logging level\n")
{
return CMD_SUCCESS;
}
-ALIAS_SH (VTYSH_ALL,
- no_vtysh_log_file,
- no_vtysh_log_file_level_cmd,
- "no log file FILENAME LEVEL",
- NO_STR
- "Logging control\n"
- "Cancel logging to file\n"
- "Logging file name\n"
- "Logging level\n")
-
DEFUNSH (VTYSH_ALL,
vtysh_log_monitor,
vtysh_log_monitor_cmd,
- "log monitor",
- "Logging control\n"
- "Set terminal line (monitor) logging level\n")
-{
- return CMD_SUCCESS;
-}
-
-DEFUNSH (VTYSH_ALL,
- vtysh_log_monitor_level,
- vtysh_log_monitor_level_cmd,
- "log monitor "LOG_LEVELS,
+ "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
"Logging control\n"
"Set terminal line (monitor) logging level\n"
- LOG_LEVEL_DESC)
+ LOG_LEVEL_DESC)
{
return CMD_SUCCESS;
}
@@ -2196,20 +2126,10 @@ DEFUNSH (VTYSH_ALL,
DEFUNSH (VTYSH_ALL,
vtysh_log_syslog,
vtysh_log_syslog_cmd,
- "log syslog",
- "Logging control\n"
- "Set syslog logging level\n")
-{
- return CMD_SUCCESS;
-}
-
-DEFUNSH (VTYSH_ALL,
- vtysh_log_syslog_level,
- vtysh_log_syslog_level_cmd,
- "log syslog "LOG_LEVELS,
+ "log syslog <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
"Logging control\n"
"Set syslog logging level\n"
- LOG_LEVEL_DESC)
+ LOG_LEVEL_DESC)
{
return CMD_SUCCESS;
}
@@ -2229,7 +2149,7 @@ DEFUNSH (VTYSH_ALL,
DEFUNSH (VTYSH_ALL,
vtysh_log_facility,
vtysh_log_facility_cmd,
- "log facility "LOG_FACILITIES,
+ "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>",
"Logging control\n"
"Facility parameter for syslog messages\n"
LOG_FACILITY_DESC)
@@ -2254,7 +2174,7 @@ DEFUNSH (VTYSH_ALL,
DEFUNSH_DEPRECATED (VTYSH_ALL,
vtysh_log_trap,
vtysh_log_trap_cmd,
- "log trap "LOG_LEVELS,
+ "log trap <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
"Logging control\n"
"(Deprecated) Set logging level and default for all destinations\n"
LOG_LEVEL_DESC)
@@ -2299,7 +2219,7 @@ DEFUNSH (VTYSH_ALL,
DEFUNSH (VTYSH_ALL,
vtysh_log_timestamp_precision,
vtysh_log_timestamp_precision_cmd,
- "log timestamp precision <0-6>",
+ "log timestamp precision (0-6)",
"Logging control\n"
"Timestamp configuration\n"
"Set the timestamp precision\n"
@@ -2344,7 +2264,7 @@ DEFUNSH (VTYSH_ALL,
DEFUNSH (VTYSH_ALL,
vtysh_config_password,
vtysh_password_cmd,
- "password (8|) WORD",
+ "password (8-8) WORD",
"Assign the terminal connection password\n"
"Specifies a HIDDEN password will follow\n"
"dummy string \n"
@@ -2366,11 +2286,10 @@ DEFUNSH (VTYSH_ALL,
DEFUNSH (VTYSH_ALL,
vtysh_config_enable_password,
vtysh_enable_password_cmd,
- "enable password (8|) WORD",
+ "enable password (8-8) WORD",
"Modify enable password parameters\n"
"Assign the privileged level password\n"
"Specifies a HIDDEN password will follow\n"
- "dummy string \n"
"The HIDDEN 'enable' password string\n")
{
return CMD_SUCCESS;
@@ -2400,9 +2319,18 @@ DEFUNSH (VTYSH_ALL,
DEFUN (vtysh_write_terminal,
vtysh_write_terminal_cmd,
- "write terminal",
+ "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
"Write running configuration to memory, network, or terminal\n"
- "Write to terminal\n")
+ "Write to terminal\n"
+ "For the zebra daemon\n"
+ "For the rip daemon\n"
+ "For the ripng daemon\n"
+ "For the ospf daemon\n"
+ "For the ospfv6 daemon\n"
+ "For the ldpd daemon\n"
+ "For the bgp daemon\n"
+ "For the isis daemon\n"
+ "For the pim daemon\n")
{
u_int i;
char line[] = "write terminal\n";
@@ -2412,21 +2340,21 @@ DEFUN (vtysh_write_terminal,
{
fp = popen (vtysh_pager_name, "w");
if (fp == NULL)
- {
- perror ("popen");
- exit (1);
- }
+ {
+ perror ("popen");
+ exit (1);
+ }
}
else
fp = stdout;
vty_out (vty, "Building configuration...%s", VTY_NEWLINE);
vty_out (vty, "%sCurrent configuration:%s", VTY_NEWLINE,
- VTY_NEWLINE);
+ VTY_NEWLINE);
vty_out (vty, "!%s", VTY_NEWLINE);
for (i = 0; i < array_size(vtysh_client); i++)
- if ((argc < 1 ) || (begins_with(vtysh_client[i].name, argv[0])))
+ if ((argc < 3 ) || (strmatch (vtysh_client[i].name, argv[2]->text)))
vtysh_client_config (&vtysh_client[i], line);
/* Integrate vtysh specific configuration. */
@@ -2438,23 +2366,22 @@ DEFUN (vtysh_write_terminal,
{
fflush (fp);
if (pclose (fp) == -1)
- {
- perror ("pclose");
- exit (1);
- }
+ {
+ perror ("pclose");
+ exit (1);
+ }
fp = NULL;
}
vty_out (vty, "end%s", VTY_NEWLINE);
-
return CMD_SUCCESS;
}
-DEFUN (vtysh_write_terminal_daemon,
- vtysh_write_terminal_daemon_cmd,
- "write terminal (zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd)",
- "Write running configuration to memory, network, or terminal\n"
- "Write to terminal\n"
+DEFUN (vtysh_show_running_config,
+ vtysh_show_running_config_cmd,
+ "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
+ SHOW_STR
+ "Current operating configuration\n"
"For the zebra daemon\n"
"For the rip daemon\n"
"For the ripng daemon\n"
@@ -2465,21 +2392,7 @@ DEFUN (vtysh_write_terminal_daemon,
"For the isis daemon\n"
"For the pim daemon\n")
{
- unsigned int i;
- int ret = CMD_SUCCESS;
-
- for (i = 0; i < array_size(vtysh_client); i++)
- {
- if (begins_with(vtysh_client[i].name, argv[0]))
- break;
- }
-
- if (i == array_size(vtysh_client))
- return CMD_ERR_NO_MATCH;
-
- ret = vtysh_client_execute(&vtysh_client[i], "show running-config\n", stdout);
-
- return ret;
+ return vtysh_write_terminal (self, vty, argc, argv);
}
DEFUN (vtysh_integrated_config,
@@ -2626,9 +2539,10 @@ static bool want_config_integrated(void)
DEFUN (vtysh_write_memory,
vtysh_write_memory_cmd,
- "write memory",
+ "write [<memory|file>]",
"Write running configuration to memory, network, or terminal\n"
- "Write configuration to the file (same as write file)\n")
+ "Write configuration to the file (same as write file)\n"
+ "Write configuration to the file (same as write memory)\n")
{
int ret = CMD_SUCCESS;
char line[] = "write memory\n";
@@ -2664,57 +2578,29 @@ DEFUN (vtysh_write_memory,
return ret;
}
-ALIAS (vtysh_write_memory,
- vtysh_copy_runningconfig_startupconfig_cmd,
- "copy running-config startup-config",
+DEFUN (vtysh_copy_running_config,
+ vtysh_copy_running_config_cmd,
+ "copy running-config startup-config",
"Copy from one file to another\n"
"Copy from current system configuration\n"
"Copy to startup configuration\n")
-
-ALIAS (vtysh_write_memory,
- vtysh_write_file_cmd,
- "write file",
- "Write running configuration to memory, network, or terminal\n"
- "Write configuration to the file (same as write memory)\n")
-
-ALIAS (vtysh_write_memory,
- vtysh_write_cmd,
- "write",
- "Write running configuration to memory, network, or terminal\n")
-
-ALIAS (vtysh_write_terminal,
- vtysh_show_running_config_cmd,
- "show running-config",
- SHOW_STR
- "Current operating configuration\n")
-
-ALIAS (vtysh_write_terminal,
- vtysh_show_running_config_daemon_cmd,
- "show running-config (zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd)",
- SHOW_STR
- "Current operating configuration\n"
- "For the zebra daemon\n"
- "For the rip daemon\n"
- "For the ripng daemon\n"
- "For the ospf daemon\n"
- "For the ospfv6 daemon\n"
- "For the ldp daemon\n"
- "For the bgp daemon\n"
- "For the isis daemon\n"
- "For the pim daemon\n")
+{
+ return vtysh_write_memory (self, vty, argc, argv);
+}
DEFUN (vtysh_terminal_length,
vtysh_terminal_length_cmd,
- "terminal length <0-512>",
+ "terminal length (0-512)",
"Set terminal line parameters\n"
"Set number of lines on a screen\n"
"Number of lines on screen (0 for no pausing)\n")
{
+ int idx_number = 2;
int lines;
char *endptr = NULL;
char default_pager[10];
- lines = strtol (argv[0], &endptr, 10);
+ lines = strtol (argv[idx_number]->arg, &endptr, 10);
if (lines < 0 || lines > 512 || *endptr != '\0')
{
vty_out (vty, "length is malformed%s", VTY_NEWLINE);
@@ -2771,7 +2657,7 @@ DEFUN (vtysh_show_daemons,
/* Execute command in child process. */
static void
-execute_command (const char *command, int argc, const char *arg1,
+execute_command (const char *command, int argc, struct cmd_token *arg1,
const char *arg2)
{
pid_t pid;
@@ -2933,6 +2819,15 @@ DEFUN (vtysh_start_zsh,
}
#endif
+DEFUN (config_list,
+ config_list_cmd,
+ "list [permutations]",
+ "Print command list\n"
+ "Print all possible command permutations\n")
+{
+ return cmd_list_cmds (vty, argc == 2);
+}
+
static void
vtysh_install_default (enum node_type node)
{
@@ -3162,6 +3057,7 @@ void
vtysh_readline_init (void)
{
/* readline related settings. */
+ rl_initialize ();
rl_bind_key ('?', (rl_command_func_t *) vtysh_rl_describe);
rl_completion_entry_function = vtysh_completion_entry_function;
rl_attempted_completion_function = (rl_completion_func_t *)new_completion;
@@ -3217,6 +3113,7 @@ vtysh_init_vty (void)
install_node (&bgp_ipv4m_node, NULL);
install_node (&bgp_ipv6_node, NULL);
install_node (&bgp_ipv6m_node, NULL);
+ install_node (&bgp_vrf_policy_node, NULL);
install_node (&bgp_vnc_defaults_node, NULL);
install_node (&bgp_vnc_nve_group_node, NULL);
install_node (&bgp_vnc_l2_group_node, NULL);
@@ -3254,6 +3151,7 @@ vtysh_init_vty (void)
vtysh_install_default (BGP_IPV6_NODE);
vtysh_install_default (BGP_IPV6M_NODE);
#if ENABLE_BGP_VNC
+ vtysh_install_default (BGP_VRF_POLICY_NODE);
vtysh_install_default (BGP_VNC_DEFAULTS_NODE);
vtysh_install_default (BGP_VNC_NVE_GROUP_NODE);
vtysh_install_default (BGP_VNC_L2_GROUP_NODE);
@@ -3279,9 +3177,9 @@ vtysh_init_vty (void)
/* "exit" command. */
install_element (VIEW_NODE, &vtysh_exit_all_cmd);
- install_element (VIEW_NODE, &vtysh_quit_all_cmd);
install_element (CONFIG_NODE, &vtysh_exit_all_cmd);
- /* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */
+ install_element (VIEW_NODE, &vtysh_quit_all_cmd);
+ install_element (CONFIG_NODE, &vtysh_quit_all_cmd);
install_element (RIP_NODE, &vtysh_exit_ripd_cmd);
install_element (RIP_NODE, &vtysh_quit_ripd_cmd);
install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd);
@@ -3325,6 +3223,8 @@ vtysh_init_vty (void)
install_element (BGP_IPV6M_NODE, &vtysh_exit_bgpd_cmd);
install_element (BGP_IPV6M_NODE, &vtysh_quit_bgpd_cmd);
#if defined (ENABLE_BGP_VNC)
+ install_element (BGP_VRF_POLICY_NODE, &vtysh_exit_bgpd_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &vtysh_quit_bgpd_cmd);
install_element (BGP_VNC_DEFAULTS_NODE, &vtysh_exit_bgpd_cmd);
install_element (BGP_VNC_DEFAULTS_NODE, &vtysh_quit_bgpd_cmd);
install_element (BGP_VNC_NVE_GROUP_NODE, &vtysh_exit_bgpd_cmd);
@@ -3366,6 +3266,7 @@ vtysh_init_vty (void)
install_element (BGP_ENCAPV6_NODE, &vtysh_end_all_cmd);
install_element (BGP_IPV6_NODE, &vtysh_end_all_cmd);
install_element (BGP_IPV6M_NODE, &vtysh_end_all_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &vtysh_end_all_cmd);
install_element (BGP_VNC_DEFAULTS_NODE, &vtysh_end_all_cmd);
install_element (BGP_VNC_NVE_GROUP_NODE, &vtysh_end_all_cmd);
install_element (BGP_VNC_L2_GROUP_NODE, &vtysh_end_all_cmd);
@@ -3385,6 +3286,8 @@ vtysh_init_vty (void)
install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
install_element (NS_NODE, &vtysh_end_all_cmd);
+
+ install_element (CONFIG_NODE, &vtysh_ns_cmd);
install_element (NS_NODE, &vtysh_exit_ns_cmd);
install_element (NS_NODE, &vtysh_quit_ns_cmd);
@@ -3395,7 +3298,6 @@ vtysh_init_vty (void)
install_element (CONFIG_NODE, &router_rip_cmd);
install_element (CONFIG_NODE, &router_ripng_cmd);
install_element (CONFIG_NODE, &router_ospf_cmd);
- install_element (CONFIG_NODE, &router_ospf_instance_cmd);
install_element (CONFIG_NODE, &router_ospf6_cmd);
#if defined (HAVE_LDPD)
install_element (CONFIG_NODE, &ldp_mpls_ldp_cmd);
@@ -3408,27 +3310,18 @@ vtysh_init_vty (void)
#endif
install_element (CONFIG_NODE, &router_isis_cmd);
install_element (CONFIG_NODE, &router_bgp_cmd);
- install_element (CONFIG_NODE, &router_bgp_asn_cmd);
- install_element (CONFIG_NODE, &router_bgp_view_cmd);
install_element (BGP_NODE, &address_family_vpnv4_cmd);
- install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd);
install_element (BGP_NODE, &address_family_vpnv6_cmd);
- install_element (BGP_NODE, &address_family_vpnv6_unicast_cmd);
- install_element (BGP_NODE, &address_family_encap_cmd);
+ install_element (BGP_NODE, &address_family_encapv4_cmd);
install_element (BGP_NODE, &address_family_encapv6_cmd);
#if defined(ENABLE_BGP_VNC)
+ install_element (BGP_NODE, &vnc_vrf_policy_cmd);
install_element (BGP_NODE, &vnc_defaults_cmd);
install_element (BGP_NODE, &vnc_nve_group_cmd);
+ install_element (BGP_NODE, &vnc_l2_group_cmd);
#endif
install_element (BGP_NODE, &address_family_ipv4_unicast_cmd);
- install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);
- install_element (BGP_NODE, &address_family_ipv4_encap_cmd);
- install_element (BGP_NODE, &address_family_ipv4_vpn_cmd);
install_element (BGP_NODE, &address_family_ipv6_cmd);
- install_element (BGP_NODE, &address_family_ipv6_unicast_cmd);
- install_element (BGP_NODE, &address_family_ipv6_multicast_cmd);
- install_element (BGP_NODE, &address_family_ipv6_encap_cmd);
- install_element (BGP_NODE, &address_family_ipv6_vpn_cmd);
install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);
install_element (BGP_VPNV6_NODE, &exit_address_family_cmd);
install_element (BGP_ENCAP_NODE, &exit_address_family_cmd);
@@ -3438,6 +3331,7 @@ vtysh_init_vty (void)
install_element (BGP_IPV6_NODE, &exit_address_family_cmd);
install_element (BGP_IPV6M_NODE, &exit_address_family_cmd);
+ install_element (BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd);
install_element (BGP_VNC_DEFAULTS_NODE, &exit_vnc_config_cmd);
install_element (BGP_VNC_NVE_GROUP_NODE, &exit_vnc_config_cmd);
install_element (BGP_VNC_L2_GROUP_NODE, &exit_vnc_config_cmd);
@@ -3450,21 +3344,16 @@ vtysh_init_vty (void)
install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
install_element (CONFIG_NODE, &vtysh_interface_cmd);
install_element (CONFIG_NODE, &vtysh_no_interface_cmd);
- install_element (CONFIG_NODE, &vtysh_interface_vrf_cmd);
install_element (CONFIG_NODE, &vtysh_no_interface_vrf_cmd);
install_element (INTERFACE_NODE, &vtysh_link_params_cmd);
install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
- install_element (ENABLE_NODE, &vtysh_show_running_config_daemon_cmd);
- install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);
- install_element (ENABLE_NODE, &vtysh_write_file_cmd);
- install_element (ENABLE_NODE, &vtysh_write_cmd);
+ install_element (ENABLE_NODE, &vtysh_copy_running_config_cmd);
install_element (CONFIG_NODE, &vtysh_vrf_cmd);
install_element (CONFIG_NODE, &vtysh_no_vrf_cmd);
/* "write terminal" command. */
install_element (ENABLE_NODE, &vtysh_write_terminal_cmd);
- install_element (ENABLE_NODE, &vtysh_write_terminal_daemon_cmd);
install_element (CONFIG_NODE, &vtysh_integrated_config_cmd);
install_element (CONFIG_NODE, &no_vtysh_integrated_config_cmd);
@@ -3508,12 +3397,9 @@ vtysh_init_vty (void)
install_element (CONFIG_NODE, &vtysh_log_file_cmd);
install_element (CONFIG_NODE, &vtysh_log_file_level_cmd);
install_element (CONFIG_NODE, &no_vtysh_log_file_cmd);
- install_element (CONFIG_NODE, &no_vtysh_log_file_level_cmd);
install_element (CONFIG_NODE, &vtysh_log_monitor_cmd);
- install_element (CONFIG_NODE, &vtysh_log_monitor_level_cmd);
install_element (CONFIG_NODE, &no_vtysh_log_monitor_cmd);
install_element (CONFIG_NODE, &vtysh_log_syslog_cmd);
- install_element (CONFIG_NODE, &vtysh_log_syslog_level_cmd);
install_element (CONFIG_NODE, &no_vtysh_log_syslog_cmd);
install_element (CONFIG_NODE, &vtysh_log_trap_cmd);
install_element (CONFIG_NODE, &no_vtysh_log_trap_cmd);
@@ -3532,5 +3418,4 @@ vtysh_init_vty (void)
install_element (CONFIG_NODE, &vtysh_enable_password_cmd);
install_element (CONFIG_NODE, &vtysh_enable_password_text_cmd);
install_element (CONFIG_NODE, &no_vtysh_enable_password_cmd);
-
}
diff --git a/vtysh/vtysh_user.c b/vtysh/vtysh_user.c
index 73f7c1be98..cce797c932 100644
--- a/vtysh/vtysh_user.c
+++ b/vtysh/vtysh_user.c
@@ -173,7 +173,8 @@ DEFUN (vtysh_banner_motd_file,
"Banner from a file\n"
"Filename\n")
{
- return cmd_banner_motd_file (argv[0]);
+ int idx_file = 3;
+ return cmd_banner_motd_file (argv[idx_file]->arg);
}
DEFUN (username_nopassword,
@@ -183,8 +184,9 @@ DEFUN (username_nopassword,
"\n"
"\n")
{
+ int idx_word = 1;
struct vtysh_user *user;
- user = user_get (argv[0]);
+ user = user_get (argv[idx_word]->arg);
user->nopassword = 1;
return CMD_SUCCESS;
}
diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c
index 83f00252c8..f61dd3858b 100644
--- a/watchfrr/watchfrr.c
+++ b/watchfrr/watchfrr.c
@@ -65,149 +65,136 @@
/* Needs to be global, referenced somewhere inside libfrr. */
struct thread_master *master;
-typedef enum
-{
- MODE_MONITOR = 0,
- MODE_GLOBAL_RESTART,
- MODE_SEPARATE_RESTART,
- MODE_PHASED_ZEBRA_RESTART,
- MODE_PHASED_ALL_RESTART
+typedef enum {
+ MODE_MONITOR = 0,
+ MODE_GLOBAL_RESTART,
+ MODE_SEPARATE_RESTART,
+ MODE_PHASED_ZEBRA_RESTART,
+ MODE_PHASED_ALL_RESTART
} watch_mode_t;
-static const char *mode_str[] =
-{
- "monitor",
- "global restart",
- "individual daemon restart",
- "phased zebra restart",
- "phased global restart for any failure",
+static const char *mode_str[] = {
+ "monitor",
+ "global restart",
+ "individual daemon restart",
+ "phased zebra restart",
+ "phased global restart for any failure",
};
-typedef enum
-{
- PHASE_NONE = 0,
- PHASE_STOPS_PENDING,
- PHASE_WAITING_DOWN,
- PHASE_ZEBRA_RESTART_PENDING,
- PHASE_WAITING_ZEBRA_UP
+typedef enum {
+ PHASE_NONE = 0,
+ PHASE_STOPS_PENDING,
+ PHASE_WAITING_DOWN,
+ PHASE_ZEBRA_RESTART_PENDING,
+ PHASE_WAITING_ZEBRA_UP
} restart_phase_t;
-static const char *phase_str[] =
-{
- "None",
- "Stop jobs running",
- "Waiting for other daemons to come down",
- "Zebra restart job running",
- "Waiting for zebra to come up",
- "Start jobs running",
+static const char *phase_str[] = {
+ "None",
+ "Stop jobs running",
+ "Waiting for other daemons to come down",
+ "Zebra restart job running",
+ "Waiting for zebra to come up",
+ "Start jobs running",
};
#define PHASE_TIMEOUT (3*gs.restart_timeout)
-struct restart_info
-{
- const char *name;
- const char *what;
- pid_t pid;
- struct timeval time;
- long interval;
- struct thread *t_kill;
- int kills;
+struct restart_info {
+ const char *name;
+ const char *what;
+ pid_t pid;
+ struct timeval time;
+ long interval;
+ struct thread *t_kill;
+ int kills;
};
-static struct global_state
-{
- watch_mode_t mode;
- restart_phase_t phase;
- struct thread *t_phase_hanging;
- const char *vtydir;
- long period;
- long timeout;
- long restart_timeout;
- long min_restart_interval;
- long max_restart_interval;
- int do_ping;
- struct daemon *daemons;
- const char *restart_command;
- const char *start_command;
- const char *stop_command;
- struct restart_info restart;
- int unresponsive_restart;
- int loglevel;
- struct daemon *special; /* points to zebra when doing phased restart */
- int numdaemons;
- int numpids;
- int numdown; /* # of daemons that are not UP or UNRESPONSIVE */
+static struct global_state {
+ watch_mode_t mode;
+ restart_phase_t phase;
+ struct thread *t_phase_hanging;
+ const char *vtydir;
+ long period;
+ long timeout;
+ long restart_timeout;
+ long min_restart_interval;
+ long max_restart_interval;
+ int do_ping;
+ struct daemon *daemons;
+ const char *restart_command;
+ const char *start_command;
+ const char *stop_command;
+ struct restart_info restart;
+ int unresponsive_restart;
+ int loglevel;
+ struct daemon *special; /* points to zebra when doing phased restart */
+ int numdaemons;
+ int numpids;
+ int numdown; /* # of daemons that are not UP or UNRESPONSIVE */
} gs = {
- .mode = MODE_MONITOR,
- .phase = PHASE_NONE,
- .vtydir = VTYDIR,
- .period = 1000*DEFAULT_PERIOD,
- .timeout = DEFAULT_TIMEOUT,
- .restart_timeout = DEFAULT_RESTART_TIMEOUT,
- .loglevel = DEFAULT_LOGLEVEL,
- .min_restart_interval = DEFAULT_MIN_RESTART,
- .max_restart_interval = DEFAULT_MAX_RESTART,
- .do_ping = 1,
-};
-
-typedef enum
-{
- DAEMON_INIT,
- DAEMON_DOWN,
- DAEMON_CONNECTING,
- DAEMON_UP,
- DAEMON_UNRESPONSIVE
+.mode = MODE_MONITOR,.phase = PHASE_NONE,.vtydir = VTYDIR,.period =
+ 1000 * DEFAULT_PERIOD,.timeout =
+ DEFAULT_TIMEOUT,.restart_timeout =
+ DEFAULT_RESTART_TIMEOUT,.loglevel =
+ DEFAULT_LOGLEVEL,.min_restart_interval =
+ DEFAULT_MIN_RESTART,.max_restart_interval =
+ DEFAULT_MAX_RESTART,.do_ping = 1,};
+
+typedef enum {
+ DAEMON_INIT,
+ DAEMON_DOWN,
+ DAEMON_CONNECTING,
+ DAEMON_UP,
+ DAEMON_UNRESPONSIVE
} daemon_state_t;
#define IS_UP(DMN) \
(((DMN)->state == DAEMON_UP) || ((DMN)->state == DAEMON_UNRESPONSIVE))
-static const char *state_str[] =
-{
- "Init",
- "Down",
- "Connecting",
- "Up",
- "Unresponsive",
+static const char *state_str[] = {
+ "Init",
+ "Down",
+ "Connecting",
+ "Up",
+ "Unresponsive",
};
struct daemon {
- const char *name;
- daemon_state_t state;
- int fd;
- struct timeval echo_sent;
- u_int connect_tries;
- struct thread *t_wakeup;
- struct thread *t_read;
- struct thread *t_write;
- struct daemon *next;
- struct restart_info restart;
+ const char *name;
+ daemon_state_t state;
+ int fd;
+ struct timeval echo_sent;
+ u_int connect_tries;
+ struct thread *t_wakeup;
+ struct thread *t_read;
+ struct thread *t_write;
+ struct daemon *next;
+ struct restart_info restart;
};
-static const struct option longopts[] =
-{
- { "daemon", no_argument, NULL, 'd'},
- { "statedir", required_argument, NULL, 'S'},
- { "no-echo", no_argument, NULL, 'e'},
- { "loglevel", required_argument, NULL, 'l'},
- { "interval", required_argument, NULL, 'i'},
- { "timeout", required_argument, NULL, 't'},
- { "restart-timeout", required_argument, NULL, 'T'},
- { "restart", required_argument, NULL, 'r'},
- { "start-command", required_argument, NULL, 's'},
- { "kill-command", required_argument, NULL, 'k'},
- { "restart-all", required_argument, NULL, 'R'},
- { "all-restart", no_argument, NULL, 'a'},
- { "always-all-restart", no_argument, NULL, 'A'},
- { "unresponsive-restart", no_argument, NULL, 'z'},
- { "min-restart-interval", required_argument, NULL, 'm'},
- { "max-restart-interval", required_argument, NULL, 'M'},
- { "pid-file", required_argument, NULL, 'p'},
- { "blank-string", required_argument, NULL, 'b'},
- { "help", no_argument, NULL, 'h'},
- { "version", no_argument, NULL, 'v'},
- { NULL, 0, NULL, 0 }
+static const struct option longopts[] = {
+ {"daemon", no_argument, NULL, 'd'},
+ {"statedir", required_argument, NULL, 'S'},
+ {"no-echo", no_argument, NULL, 'e'},
+ {"loglevel", required_argument, NULL, 'l'},
+ {"interval", required_argument, NULL, 'i'},
+ {"timeout", required_argument, NULL, 't'},
+ {"restart-timeout", required_argument, NULL, 'T'},
+ {"restart", required_argument, NULL, 'r'},
+ {"start-command", required_argument, NULL, 's'},
+ {"kill-command", required_argument, NULL, 'k'},
+ {"restart-all", required_argument, NULL, 'R'},
+ {"all-restart", no_argument, NULL, 'a'},
+ {"always-all-restart", no_argument, NULL, 'A'},
+ {"unresponsive-restart", no_argument, NULL, 'z'},
+ {"min-restart-interval", required_argument, NULL, 'm'},
+ {"max-restart-interval", required_argument, NULL, 'M'},
+ {"pid-file", required_argument, NULL, 'p'},
+ {"blank-string", required_argument, NULL, 'b'},
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
+ {NULL, 0, NULL, 0}
};
static int try_connect(struct daemon *dmn);
@@ -215,14 +202,13 @@ static int wakeup_send_echo(struct thread *t_wakeup);
static void try_restart(struct daemon *dmn);
static void phase_check(void);
-static int
-usage(const char *progname, int status)
+static int usage(const char *progname, int status)
{
- if (status != 0)
- fprintf(stderr, "Try `%s --help' for more information.\n", progname);
- else
- {
- printf("Usage : %s [OPTION...] <daemon name> ...\n\n\
+ if (status != 0)
+ fprintf(stderr, "Try `%s --help' for more information.\n",
+ progname);
+ else {
+ printf("Usage : %s [OPTION...] <daemon name> ...\n\n\
Watchdog program to monitor status of frr daemons and try to restart\n\
them if they are down or unresponsive. It determines whether a daemon is\n\
up based on whether it can connect to the daemon's vty unix stream socket.\n\
@@ -266,12 +252,9 @@ the -m and -M options allow you to control the minimum delay between\n\
restart commands. The minimum restart delay is recalculated each time\n\
a restart is attempted: if the time since the last restart attempt exceeds\n\
twice the -M value, then the restart delay is set to the -m value.\n\
-Otherwise, the interval is doubled (but capped at the -M value).\n\n",
- progname,mode_str[0],progname,mode_str[1],progname,mode_str[2],
- progname,mode_str[3],progname,mode_str[4],progname,mode_str[2],
- mode_str[3]);
+Otherwise, the interval is doubled (but capped at the -M value).\n\n", progname, mode_str[0], progname, mode_str[1], progname, mode_str[2], progname, mode_str[3], progname, mode_str[4], progname, mode_str[2], mode_str[3]);
- printf("Options:\n\
+ printf("Options:\n\
-d, --daemon Run in daemon mode. In this mode, error messages are sent\n\
to syslog instead of stdout.\n\
-S, --statedir Set the vty socket directory (default is %s)\n\
@@ -329,221 +312,203 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n",
it with a space. This is an ugly hack to circumvent problems\n\
passing command-line arguments with embedded spaces.\n\
-v, --version Print program version\n\
--h, --help Display this help and exit\n",
- VTYDIR,DEFAULT_LOGLEVEL,LOG_EMERG,LOG_DEBUG,LOG_DEBUG,
- DEFAULT_MIN_RESTART,DEFAULT_MAX_RESTART,
- DEFAULT_PERIOD,DEFAULT_TIMEOUT,DEFAULT_RESTART_TIMEOUT,
- DEFAULT_PIDFILE);
- }
-
- return status;
+-h, --help Display this help and exit\n", VTYDIR, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG, LOG_DEBUG, DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART, DEFAULT_PERIOD, DEFAULT_TIMEOUT, DEFAULT_RESTART_TIMEOUT, DEFAULT_PIDFILE);
+ }
+
+ return status;
}
-static pid_t
-run_background(char *shell_cmd)
+static pid_t run_background(char *shell_cmd)
{
- pid_t child;
-
- switch (child = fork())
- {
- case -1:
- zlog_err("fork failed, cannot run command [%s]: %s",
- shell_cmd,safe_strerror(errno));
- return -1;
- case 0:
- /* Child process. */
- /* Use separate process group so child processes can be killed easily. */
- if (setpgid(0,0) < 0)
- zlog_warn("warning: setpgid(0,0) failed: %s",safe_strerror(errno));
- {
- char shell[] = "sh";
- char dashc[] = "-c";
- char * const argv[4] = { shell, dashc, shell_cmd, NULL};
- execv("/bin/sh", argv);
- zlog_err("execv(/bin/sh -c '%s') failed: %s",
- shell_cmd,safe_strerror(errno));
- _exit(127);
- }
- default:
- /* Parent process: we will reap the child later. */
- zlog_err("Forked background command [pid %d]: %s",(int)child,shell_cmd);
- return child;
- }
+ pid_t child;
+
+ switch (child = fork()) {
+ case -1:
+ zlog_err("fork failed, cannot run command [%s]: %s",
+ shell_cmd, safe_strerror(errno));
+ return -1;
+ case 0:
+ /* Child process. */
+ /* Use separate process group so child processes can be killed easily. */
+ if (setpgid(0, 0) < 0)
+ zlog_warn("warning: setpgid(0,0) failed: %s",
+ safe_strerror(errno));
+ {
+ char shell[] = "sh";
+ char dashc[] = "-c";
+ char *const argv[4] = { shell, dashc, shell_cmd, NULL };
+ execv("/bin/sh", argv);
+ zlog_err("execv(/bin/sh -c '%s') failed: %s",
+ shell_cmd, safe_strerror(errno));
+ _exit(127);
+ }
+ default:
+ /* Parent process: we will reap the child later. */
+ zlog_err("Forked background command [pid %d]: %s", (int)child,
+ shell_cmd);
+ return child;
+ }
}
-static struct timeval *
-time_elapsed(struct timeval *result, const struct timeval *start_time)
+static struct timeval *time_elapsed(struct timeval *result,
+ const struct timeval *start_time)
{
- gettimeofday(result,NULL);
- result->tv_sec -= start_time->tv_sec;
- result->tv_usec -= start_time->tv_usec;
- while (result->tv_usec < 0)
- {
- result->tv_usec += 1000000L;
- result->tv_sec--;
- }
- return result;
+ gettimeofday(result, NULL);
+ result->tv_sec -= start_time->tv_sec;
+ result->tv_usec -= start_time->tv_usec;
+ while (result->tv_usec < 0) {
+ result->tv_usec += 1000000L;
+ result->tv_sec--;
+ }
+ return result;
}
-static int
-restart_kill(struct thread *t_kill)
+static int restart_kill(struct thread *t_kill)
{
- struct restart_info *restart = THREAD_ARG(t_kill);
- struct timeval delay;
-
- time_elapsed(&delay,&restart->time);
- zlog_warn("Warning: %s %s child process %d still running after "
- "%ld seconds, sending signal %d",
- restart->what,restart->name,(int)restart->pid, (long)delay.tv_sec,
- (restart->kills ? SIGKILL : SIGTERM));
- kill(-restart->pid,(restart->kills ? SIGKILL : SIGTERM));
- restart->kills++;
- restart->t_kill = thread_add_timer(master,restart_kill,restart,
- gs.restart_timeout);
- return 0;
+ struct restart_info *restart = THREAD_ARG(t_kill);
+ struct timeval delay;
+
+ time_elapsed(&delay, &restart->time);
+ zlog_warn("Warning: %s %s child process %d still running after "
+ "%ld seconds, sending signal %d",
+ restart->what, restart->name, (int)restart->pid,
+ (long)delay.tv_sec, (restart->kills ? SIGKILL : SIGTERM));
+ kill(-restart->pid, (restart->kills ? SIGKILL : SIGTERM));
+ restart->kills++;
+ restart->t_kill = thread_add_timer(master, restart_kill, restart,
+ gs.restart_timeout);
+ return 0;
}
-static struct restart_info *
-find_child(pid_t child)
+static struct restart_info *find_child(pid_t child)
{
- if (gs.mode == MODE_GLOBAL_RESTART)
- {
- if (gs.restart.pid == child)
- return &gs.restart;
- }
- else
- {
- struct daemon *dmn;
- for (dmn = gs.daemons; dmn; dmn = dmn->next)
- {
- if (dmn->restart.pid == child)
- return &dmn->restart;
- }
- }
- return NULL;
+ if (gs.mode == MODE_GLOBAL_RESTART) {
+ if (gs.restart.pid == child)
+ return &gs.restart;
+ } else {
+ struct daemon *dmn;
+ for (dmn = gs.daemons; dmn; dmn = dmn->next) {
+ if (dmn->restart.pid == child)
+ return &dmn->restart;
+ }
+ }
+ return NULL;
}
-static void
-sigchild(void)
+static void sigchild(void)
{
- pid_t child;
- int status;
- const char *name;
- const char *what;
- struct restart_info *restart;
-
- switch (child = waitpid(-1,&status,WNOHANG))
- {
- case -1:
- zlog_err("waitpid failed: %s",safe_strerror(errno));
- return;
- case 0:
- zlog_warn("SIGCHLD received, but waitpid did not reap a child");
- return;
- }
-
- if (child == integrated_write_pid)
- {
- integrated_write_sigchld(status);
- return;
- }
-
- if ((restart = find_child(child)) != NULL)
- {
- name = restart->name;
- what = restart->what;
- restart->pid = 0;
- gs.numpids--;
- thread_cancel(restart->t_kill);
- restart->t_kill = NULL;
- /* Update restart time to reflect the time the command completed. */
- gettimeofday(&restart->time,NULL);
- }
- else
- {
- zlog_err("waitpid returned status for an unknown child process %d",
- (int)child);
- name = "(unknown)";
- what = "background";
- }
- if (WIFSTOPPED(status))
- zlog_warn("warning: %s %s process %d is stopped",
- what,name,(int)child);
- else if (WIFSIGNALED(status))
- zlog_warn("%s %s process %d terminated due to signal %d",
- what,name,(int)child,WTERMSIG(status));
- else if (WIFEXITED(status))
- {
- if (WEXITSTATUS(status) != 0)
- zlog_warn("%s %s process %d exited with non-zero status %d",
- what,name,(int)child,WEXITSTATUS(status));
- else
- zlog_debug("%s %s process %d exited normally",what,name,(int)child);
- }
- else
- zlog_err("cannot interpret %s %s process %d wait status 0x%x",
- what,name,(int)child,status);
- phase_check();
+ pid_t child;
+ int status;
+ const char *name;
+ const char *what;
+ struct restart_info *restart;
+
+ switch (child = waitpid(-1, &status, WNOHANG)) {
+ case -1:
+ zlog_err("waitpid failed: %s", safe_strerror(errno));
+ return;
+ case 0:
+ zlog_warn("SIGCHLD received, but waitpid did not reap a child");
+ return;
+ }
+
+ if (child == integrated_write_pid) {
+ integrated_write_sigchld(status);
+ return;
+ }
+
+ if ((restart = find_child(child)) != NULL) {
+ name = restart->name;
+ what = restart->what;
+ restart->pid = 0;
+ gs.numpids--;
+ thread_cancel(restart->t_kill);
+ restart->t_kill = NULL;
+ /* Update restart time to reflect the time the command completed. */
+ gettimeofday(&restart->time, NULL);
+ } else {
+ zlog_err
+ ("waitpid returned status for an unknown child process %d",
+ (int)child);
+ name = "(unknown)";
+ what = "background";
+ }
+ if (WIFSTOPPED(status))
+ zlog_warn("warning: %s %s process %d is stopped",
+ what, name, (int)child);
+ else if (WIFSIGNALED(status))
+ zlog_warn("%s %s process %d terminated due to signal %d",
+ what, name, (int)child, WTERMSIG(status));
+ else if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0)
+ zlog_warn
+ ("%s %s process %d exited with non-zero status %d",
+ what, name, (int)child, WEXITSTATUS(status));
+ else
+ zlog_debug("%s %s process %d exited normally", what,
+ name, (int)child);
+ } else
+ zlog_err("cannot interpret %s %s process %d wait status 0x%x",
+ what, name, (int)child, status);
+ phase_check();
}
static int
run_job(struct restart_info *restart, const char *cmdtype, const char *command,
int force, int update_interval)
{
- struct timeval delay;
-
- if (gs.loglevel > LOG_DEBUG+1)
- zlog_debug("attempting to %s %s",cmdtype,restart->name);
-
- if (restart->pid)
- {
- if (gs.loglevel > LOG_DEBUG+1)
- zlog_debug("cannot %s %s, previous pid %d still running",
- cmdtype,restart->name,(int)restart->pid);
- return -1;
- }
-
- /* Note: time_elapsed test must come before the force test, since we need
- to make sure that delay is initialized for use below in updating the
- restart interval. */
- if ((time_elapsed(&delay,&restart->time)->tv_sec < restart->interval) &&
- !force)
- {
- if (gs.loglevel > LOG_DEBUG+1)
- zlog_debug("postponing %s %s: "
- "elapsed time %ld < retry interval %ld",
- cmdtype,restart->name,(long)delay.tv_sec,restart->interval);
- return -1;
- }
-
- gettimeofday(&restart->time,NULL);
- restart->kills = 0;
- {
- char cmd[strlen(command)+strlen(restart->name)+1];
- snprintf(cmd,sizeof(cmd),command,restart->name);
- if ((restart->pid = run_background(cmd)) > 0)
- {
- restart->t_kill = thread_add_timer(master,restart_kill,restart,
- gs.restart_timeout);
- restart->what = cmdtype;
- gs.numpids++;
- }
- else
- restart->pid = 0;
- }
-
- /* Calculate the new restart interval. */
- if (update_interval)
- {
- if (delay.tv_sec > 2*gs.max_restart_interval)
- restart->interval = gs.min_restart_interval;
- else if ((restart->interval *= 2) > gs.max_restart_interval)
- restart->interval = gs.max_restart_interval;
- if (gs.loglevel > LOG_DEBUG+1)
- zlog_debug("restart %s interval is now %ld",
- restart->name,restart->interval);
- }
- return restart->pid;
+ struct timeval delay;
+
+ if (gs.loglevel > LOG_DEBUG + 1)
+ zlog_debug("attempting to %s %s", cmdtype, restart->name);
+
+ if (restart->pid) {
+ if (gs.loglevel > LOG_DEBUG + 1)
+ zlog_debug
+ ("cannot %s %s, previous pid %d still running",
+ cmdtype, restart->name, (int)restart->pid);
+ return -1;
+ }
+
+ /* Note: time_elapsed test must come before the force test, since we need
+ to make sure that delay is initialized for use below in updating the
+ restart interval. */
+ if ((time_elapsed(&delay, &restart->time)->tv_sec < restart->interval)
+ && !force) {
+ if (gs.loglevel > LOG_DEBUG + 1)
+ zlog_debug("postponing %s %s: "
+ "elapsed time %ld < retry interval %ld",
+ cmdtype, restart->name, (long)delay.tv_sec,
+ restart->interval);
+ return -1;
+ }
+
+ gettimeofday(&restart->time, NULL);
+ restart->kills = 0;
+ {
+ char cmd[strlen(command) + strlen(restart->name) + 1];
+ snprintf(cmd, sizeof(cmd), command, restart->name);
+ if ((restart->pid = run_background(cmd)) > 0) {
+ restart->t_kill =
+ thread_add_timer(master, restart_kill, restart,
+ gs.restart_timeout);
+ restart->what = cmdtype;
+ gs.numpids++;
+ } else
+ restart->pid = 0;
+ }
+
+ /* Calculate the new restart interval. */
+ if (update_interval) {
+ if (delay.tv_sec > 2 * gs.max_restart_interval)
+ restart->interval = gs.min_restart_interval;
+ else if ((restart->interval *= 2) > gs.max_restart_interval)
+ restart->interval = gs.max_restart_interval;
+ if (gs.loglevel > LOG_DEBUG + 1)
+ zlog_debug("restart %s interval is now %ld",
+ restart->name, restart->interval);
+ }
+ return restart->pid;
}
#define SET_READ_HANDLER(DMN) \
@@ -551,889 +516,874 @@ run_job(struct restart_info *restart, const char *cmdtype, const char *command,
#define SET_WAKEUP_DOWN(DMN) \
(DMN)->t_wakeup = thread_add_timer_msec(master,wakeup_down,(DMN), \
- FUZZY(gs.period))
+ FUZZY(gs.period))
#define SET_WAKEUP_UNRESPONSIVE(DMN) \
(DMN)->t_wakeup = thread_add_timer_msec(master,wakeup_unresponsive,(DMN), \
- FUZZY(gs.period))
+ FUZZY(gs.period))
#define SET_WAKEUP_ECHO(DMN) \
(DMN)->t_wakeup = thread_add_timer_msec(master,wakeup_send_echo,(DMN), \
FUZZY(gs.period))
-static int
-wakeup_down(struct thread *t_wakeup)
+static int wakeup_down(struct thread *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
-
- dmn->t_wakeup = NULL;
- if (try_connect(dmn) < 0)
- SET_WAKEUP_DOWN(dmn);
- if ((dmn->connect_tries > 1) && (dmn->state != DAEMON_UP))
- try_restart(dmn);
- return 0;
+ struct daemon *dmn = THREAD_ARG(t_wakeup);
+
+ dmn->t_wakeup = NULL;
+ if (try_connect(dmn) < 0)
+ SET_WAKEUP_DOWN(dmn);
+ if ((dmn->connect_tries > 1) && (dmn->state != DAEMON_UP))
+ try_restart(dmn);
+ return 0;
}
-static int
-wakeup_init(struct thread *t_wakeup)
+static int wakeup_init(struct thread *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
-
- dmn->t_wakeup = NULL;
- if (try_connect(dmn) < 0)
- {
- SET_WAKEUP_DOWN(dmn);
- zlog_err("%s state -> down : initial connection attempt failed",
- dmn->name);
- dmn->state = DAEMON_DOWN;
- }
- return 0;
+ struct daemon *dmn = THREAD_ARG(t_wakeup);
+
+ dmn->t_wakeup = NULL;
+ if (try_connect(dmn) < 0) {
+ SET_WAKEUP_DOWN(dmn);
+ zlog_err("%s state -> down : initial connection attempt failed",
+ dmn->name);
+ dmn->state = DAEMON_DOWN;
+ }
+ return 0;
}
-static void
-daemon_down(struct daemon *dmn, const char *why)
+static void daemon_down(struct daemon *dmn, const char *why)
{
- if (IS_UP(dmn) || (dmn->state == DAEMON_INIT))
- zlog_err("%s state -> down : %s",dmn->name,why);
- else if (gs.loglevel > LOG_DEBUG)
- zlog_debug("%s still down : %s",dmn->name,why);
- if (IS_UP(dmn))
- gs.numdown++;
- dmn->state = DAEMON_DOWN;
- if (dmn->fd >= 0)
- {
- close(dmn->fd);
- dmn->fd = -1;
- }
- THREAD_OFF(dmn->t_read);
- THREAD_OFF(dmn->t_write);
- THREAD_OFF(dmn->t_wakeup);
- if (try_connect(dmn) < 0)
- SET_WAKEUP_DOWN(dmn);
- phase_check();
+ if (IS_UP(dmn) || (dmn->state == DAEMON_INIT))
+ zlog_err("%s state -> down : %s", dmn->name, why);
+ else if (gs.loglevel > LOG_DEBUG)
+ zlog_debug("%s still down : %s", dmn->name, why);
+ if (IS_UP(dmn))
+ gs.numdown++;
+ dmn->state = DAEMON_DOWN;
+ if (dmn->fd >= 0) {
+ close(dmn->fd);
+ dmn->fd = -1;
+ }
+ THREAD_OFF(dmn->t_read);
+ THREAD_OFF(dmn->t_write);
+ THREAD_OFF(dmn->t_wakeup);
+ if (try_connect(dmn) < 0)
+ SET_WAKEUP_DOWN(dmn);
+ phase_check();
}
-static int
-handle_read(struct thread *t_read)
+static int handle_read(struct thread *t_read)
{
- struct daemon *dmn = THREAD_ARG(t_read);
- static const char resp[sizeof(PING_TOKEN)+4] = PING_TOKEN "\n";
- char buf[sizeof(resp)+100];
- ssize_t rc;
- struct timeval delay;
-
- dmn->t_read = NULL;
- if ((rc = read(dmn->fd,buf,sizeof(buf))) < 0)
- {
- char why[100];
-
- if (ERRNO_IO_RETRY(errno))
- {
- /* Pretend it never happened. */
- SET_READ_HANDLER(dmn);
- return 0;
+ struct daemon *dmn = THREAD_ARG(t_read);
+ static const char resp[sizeof(PING_TOKEN) + 4] = PING_TOKEN "\n";
+ char buf[sizeof(resp) + 100];
+ ssize_t rc;
+ struct timeval delay;
+
+ dmn->t_read = NULL;
+ if ((rc = read(dmn->fd, buf, sizeof(buf))) < 0) {
+ char why[100];
+
+ if (ERRNO_IO_RETRY(errno)) {
+ /* Pretend it never happened. */
+ SET_READ_HANDLER(dmn);
+ return 0;
+ }
+ snprintf(why, sizeof(why), "unexpected read error: %s",
+ safe_strerror(errno));
+ daemon_down(dmn, why);
+ return 0;
}
- snprintf(why,sizeof(why),"unexpected read error: %s",
- safe_strerror(errno));
- daemon_down(dmn,why);
- return 0;
- }
- if (rc == 0)
- {
- daemon_down(dmn,"read returned EOF");
- return 0;
- }
- if (!dmn->echo_sent.tv_sec)
- {
- char why[sizeof(buf)+100];
- snprintf(why,sizeof(why),"unexpected read returns %d bytes: %.*s",
- (int)rc,(int)rc,buf);
- daemon_down(dmn,why);
- return 0;
- }
-
- /* We are expecting an echo response: is there any chance that the
- response would not be returned entirely in the first read? That
- seems inconceivable... */
- if ((rc != sizeof(resp)) || memcmp(buf,resp,sizeof(resp)))
- {
- char why[100+sizeof(buf)];
- snprintf(why,sizeof(why),"read returned bad echo response of %d bytes "
- "(expecting %u): %.*s",
- (int)rc,(u_int)sizeof(resp),(int)rc,buf);
- daemon_down(dmn,why);
- return 0;
- }
-
- time_elapsed(&delay,&dmn->echo_sent);
- dmn->echo_sent.tv_sec = 0;
- if (dmn->state == DAEMON_UNRESPONSIVE)
- {
- if (delay.tv_sec < gs.timeout)
- {
- dmn->state = DAEMON_UP;
- zlog_warn("%s state -> up : echo response received after %ld.%06ld "
- "seconds", dmn->name,
- (long)delay.tv_sec, (long)delay.tv_usec);
+ if (rc == 0) {
+ daemon_down(dmn, "read returned EOF");
+ return 0;
+ }
+ if (!dmn->echo_sent.tv_sec) {
+ char why[sizeof(buf) + 100];
+ snprintf(why, sizeof(why),
+ "unexpected read returns %d bytes: %.*s", (int)rc,
+ (int)rc, buf);
+ daemon_down(dmn, why);
+ return 0;
}
- else
- zlog_warn("%s: slow echo response finally received after %ld.%06ld "
- "seconds", dmn->name,
- (long)delay.tv_sec, (long)delay.tv_usec);
- }
- else if (gs.loglevel > LOG_DEBUG+1)
- zlog_debug("%s: echo response received after %ld.%06ld seconds",
- dmn->name, (long)delay.tv_sec, (long)delay.tv_usec);
-
- SET_READ_HANDLER(dmn);
- if (dmn->t_wakeup)
- thread_cancel(dmn->t_wakeup);
- SET_WAKEUP_ECHO(dmn);
-
- return 0;
+
+ /* We are expecting an echo response: is there any chance that the
+ response would not be returned entirely in the first read? That
+ seems inconceivable... */
+ if ((rc != sizeof(resp)) || memcmp(buf, resp, sizeof(resp))) {
+ char why[100 + sizeof(buf)];
+ snprintf(why, sizeof(why),
+ "read returned bad echo response of %d bytes "
+ "(expecting %u): %.*s", (int)rc, (u_int) sizeof(resp),
+ (int)rc, buf);
+ daemon_down(dmn, why);
+ return 0;
+ }
+
+ time_elapsed(&delay, &dmn->echo_sent);
+ dmn->echo_sent.tv_sec = 0;
+ if (dmn->state == DAEMON_UNRESPONSIVE) {
+ if (delay.tv_sec < gs.timeout) {
+ dmn->state = DAEMON_UP;
+ zlog_warn
+ ("%s state -> up : echo response received after %ld.%06ld "
+ "seconds", dmn->name, (long)delay.tv_sec,
+ (long)delay.tv_usec);
+ } else
+ zlog_warn
+ ("%s: slow echo response finally received after %ld.%06ld "
+ "seconds", dmn->name, (long)delay.tv_sec,
+ (long)delay.tv_usec);
+ } else if (gs.loglevel > LOG_DEBUG + 1)
+ zlog_debug("%s: echo response received after %ld.%06ld seconds",
+ dmn->name, (long)delay.tv_sec, (long)delay.tv_usec);
+
+ SET_READ_HANDLER(dmn);
+ if (dmn->t_wakeup)
+ thread_cancel(dmn->t_wakeup);
+ SET_WAKEUP_ECHO(dmn);
+
+ return 0;
}
/*
* Wait till we notice that all daemons are ready before
* we send we are ready to systemd
*/
-static void
-daemon_send_ready (void)
+static void daemon_send_ready(void)
{
- static int sent = 0;
- if (!sent && gs.numdown == 0)
- {
+ static int sent = 0;
+ if (!sent && gs.numdown == 0) {
#if defined (HAVE_CUMULUS)
- FILE *fp;
+ FILE *fp;
- fp = fopen(DAEMON_VTY_DIR "/watchfrr.started", "w");
- fclose(fp);
+ fp = fopen(DAEMON_VTY_DIR "/watchfrr.started", "w");
+ fclose(fp);
#endif
- zlog_notice ("Watchfrr: Notifying Systemd we are up and running");
- systemd_send_started(master, 0);
- sent = 1;
- }
+ zlog_notice
+ ("Watchfrr: Notifying Systemd we are up and running");
+ systemd_send_started(master, 0);
+ sent = 1;
+ }
}
-static void
-daemon_up(struct daemon *dmn, const char *why)
+static void daemon_up(struct daemon *dmn, const char *why)
{
- dmn->state = DAEMON_UP;
- gs.numdown--;
- dmn->connect_tries = 0;
- zlog_notice("%s state -> up : %s",dmn->name,why);
- daemon_send_ready();
- if (gs.do_ping)
- SET_WAKEUP_ECHO(dmn);
- phase_check();
+ dmn->state = DAEMON_UP;
+ gs.numdown--;
+ dmn->connect_tries = 0;
+ zlog_notice("%s state -> up : %s", dmn->name, why);
+ daemon_send_ready();
+ if (gs.do_ping)
+ SET_WAKEUP_ECHO(dmn);
+ phase_check();
}
-static int
-check_connect(struct thread *t_write)
+static int check_connect(struct thread *t_write)
{
- struct daemon *dmn = THREAD_ARG(t_write);
- int sockerr;
- socklen_t reslen = sizeof(sockerr);
-
- dmn->t_write = NULL;
- if (getsockopt(dmn->fd,SOL_SOCKET,SO_ERROR,(char *)&sockerr,&reslen) < 0)
- {
- zlog_warn("%s: check_connect: getsockopt failed: %s",
- dmn->name,safe_strerror(errno));
- daemon_down(dmn,"getsockopt failed checking connection success");
- return 0;
- }
- if ((reslen == sizeof(sockerr)) && sockerr)
- {
- char why[100];
- snprintf(why,sizeof(why),
- "getsockopt reports that connection attempt failed: %s",
- safe_strerror(sockerr));
- daemon_down(dmn,why);
- return 0;
- }
-
- daemon_up(dmn,"delayed connect succeeded");
- return 0;
+ struct daemon *dmn = THREAD_ARG(t_write);
+ int sockerr;
+ socklen_t reslen = sizeof(sockerr);
+
+ dmn->t_write = NULL;
+ if (getsockopt(dmn->fd, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &reslen)
+ < 0) {
+ zlog_warn("%s: check_connect: getsockopt failed: %s", dmn->name,
+ safe_strerror(errno));
+ daemon_down(dmn,
+ "getsockopt failed checking connection success");
+ return 0;
+ }
+ if ((reslen == sizeof(sockerr)) && sockerr) {
+ char why[100];
+ snprintf(why, sizeof(why),
+ "getsockopt reports that connection attempt failed: %s",
+ safe_strerror(sockerr));
+ daemon_down(dmn, why);
+ return 0;
+ }
+
+ daemon_up(dmn, "delayed connect succeeded");
+ return 0;
}
-static int
-wakeup_connect_hanging(struct thread *t_wakeup)
+static int wakeup_connect_hanging(struct thread *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
- char why[100];
-
- dmn->t_wakeup = NULL;
- snprintf(why,sizeof(why),"connection attempt timed out after %ld seconds",
- gs.timeout);
- daemon_down(dmn,why);
- return 0;
+ struct daemon *dmn = THREAD_ARG(t_wakeup);
+ char why[100];
+
+ dmn->t_wakeup = NULL;
+ snprintf(why, sizeof(why),
+ "connection attempt timed out after %ld seconds", gs.timeout);
+ daemon_down(dmn, why);
+ return 0;
}
/* Making connection to protocol daemon. */
-static int
-try_connect(struct daemon *dmn)
+static int try_connect(struct daemon *dmn)
{
- int sock;
- struct sockaddr_un addr;
- socklen_t len;
-
- if (gs.loglevel > LOG_DEBUG+1)
- zlog_debug("%s: attempting to connect",dmn->name);
- dmn->connect_tries++;
-
- memset (&addr, 0, sizeof (struct sockaddr_un));
- addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s.vty",
- gs.vtydir,dmn->name);
+ int sock;
+ struct sockaddr_un addr;
+ socklen_t len;
+
+ if (gs.loglevel > LOG_DEBUG + 1)
+ zlog_debug("%s: attempting to connect", dmn->name);
+ dmn->connect_tries++;
+
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_UNIX;
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s.vty",
+ gs.vtydir, dmn->name);
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
- len = addr.sun_len = SUN_LEN(&addr);
+ len = addr.sun_len = SUN_LEN(&addr);
#else
- len = sizeof (addr.sun_family) + strlen (addr.sun_path);
-#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
-
- /* Quick check to see if we might succeed before we go to the trouble
- of creating a socket. */
- if (access(addr.sun_path, W_OK) < 0)
- {
- if (errno != ENOENT)
- zlog_err("%s: access to socket %s denied: %s",
- dmn->name,addr.sun_path,safe_strerror(errno));
- return -1;
- }
-
- if ((sock = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
- {
- zlog_err("%s(%s): cannot make socket: %s",
- __func__,addr.sun_path, safe_strerror(errno));
- return -1;
- }
-
- if (set_nonblocking(sock) < 0 || set_cloexec(sock) < 0)
- {
- zlog_err("%s(%s): set_nonblocking/cloexec(%d) failed",
- __func__, addr.sun_path, sock);
- close(sock);
- return -1;
- }
-
- if (connect (sock, (struct sockaddr *) &addr, len) < 0)
- {
- if ((errno != EINPROGRESS) && (errno != EWOULDBLOCK))
- {
- if (gs.loglevel > LOG_DEBUG)
- zlog_debug("%s(%s): connect failed: %s",
- __func__,addr.sun_path, safe_strerror(errno));
- close (sock);
- return -1;
+ len = sizeof(addr.sun_family) + strlen(addr.sun_path);
+#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
+
+ /* Quick check to see if we might succeed before we go to the trouble
+ of creating a socket. */
+ if (access(addr.sun_path, W_OK) < 0) {
+ if (errno != ENOENT)
+ zlog_err("%s: access to socket %s denied: %s",
+ dmn->name, addr.sun_path,
+ safe_strerror(errno));
+ return -1;
+ }
+
+ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ zlog_err("%s(%s): cannot make socket: %s",
+ __func__, addr.sun_path, safe_strerror(errno));
+ return -1;
+ }
+
+ if (set_nonblocking(sock) < 0 || set_cloexec(sock) < 0) {
+ zlog_err("%s(%s): set_nonblocking/cloexec(%d) failed",
+ __func__, addr.sun_path, sock);
+ close(sock);
+ return -1;
}
- if (gs.loglevel > LOG_DEBUG)
- zlog_debug("%s: connection in progress",dmn->name);
- dmn->state = DAEMON_CONNECTING;
- dmn->fd = sock;
- dmn->t_write = thread_add_write(master,check_connect,dmn,dmn->fd);
- dmn->t_wakeup = thread_add_timer(master,wakeup_connect_hanging,dmn,
- gs.timeout);
- SET_READ_HANDLER(dmn);
- return 0;
- }
-
- dmn->fd = sock;
- SET_READ_HANDLER(dmn);
- daemon_up(dmn,"connect succeeded");
- return 1;
+
+ if (connect(sock, (struct sockaddr *)&addr, len) < 0) {
+ if ((errno != EINPROGRESS) && (errno != EWOULDBLOCK)) {
+ if (gs.loglevel > LOG_DEBUG)
+ zlog_debug("%s(%s): connect failed: %s",
+ __func__, addr.sun_path,
+ safe_strerror(errno));
+ close(sock);
+ return -1;
+ }
+ if (gs.loglevel > LOG_DEBUG)
+ zlog_debug("%s: connection in progress", dmn->name);
+ dmn->state = DAEMON_CONNECTING;
+ dmn->fd = sock;
+ dmn->t_write =
+ thread_add_write(master, check_connect, dmn, dmn->fd);
+ dmn->t_wakeup =
+ thread_add_timer(master, wakeup_connect_hanging, dmn,
+ gs.timeout);
+ SET_READ_HANDLER(dmn);
+ return 0;
+ }
+
+ dmn->fd = sock;
+ SET_READ_HANDLER(dmn);
+ daemon_up(dmn, "connect succeeded");
+ return 1;
}
-static int
-phase_hanging(struct thread *t_hanging)
+static int phase_hanging(struct thread *t_hanging)
{
- gs.t_phase_hanging = NULL;
- zlog_err("Phase [%s] hanging for %ld seconds, aborting phased restart",
- phase_str[gs.phase],PHASE_TIMEOUT);
- gs.phase = PHASE_NONE;
- return 0;
+ gs.t_phase_hanging = NULL;
+ zlog_err("Phase [%s] hanging for %ld seconds, aborting phased restart",
+ phase_str[gs.phase], PHASE_TIMEOUT);
+ gs.phase = PHASE_NONE;
+ return 0;
}
-static void
-set_phase(restart_phase_t new_phase)
+static void set_phase(restart_phase_t new_phase)
{
- gs.phase = new_phase;
- if (gs.t_phase_hanging)
- thread_cancel(gs.t_phase_hanging);
- gs.t_phase_hanging = thread_add_timer(master,phase_hanging,NULL,
- PHASE_TIMEOUT);
+ gs.phase = new_phase;
+ if (gs.t_phase_hanging)
+ thread_cancel(gs.t_phase_hanging);
+ gs.t_phase_hanging = thread_add_timer(master, phase_hanging, NULL,
+ PHASE_TIMEOUT);
}
-static void
-phase_check(void)
+static void phase_check(void)
{
- switch (gs.phase)
- {
- case PHASE_NONE:
- break;
- case PHASE_STOPS_PENDING:
- if (gs.numpids)
- break;
- zlog_info("Phased restart: all routing daemon stop jobs have completed.");
- set_phase(PHASE_WAITING_DOWN);
- /*FALLTHRU*/
- case PHASE_WAITING_DOWN:
- if (gs.numdown+IS_UP(gs.special) < gs.numdaemons)
- break;
- zlog_info("Phased restart: all routing daemons now down.");
- run_job(&gs.special->restart,"restart",gs.restart_command,1,1);
- set_phase(PHASE_ZEBRA_RESTART_PENDING);
- /*FALLTHRU*/
- case PHASE_ZEBRA_RESTART_PENDING:
- if (gs.special->restart.pid)
- break;
- zlog_info("Phased restart: %s restart job completed.",gs.special->name);
- set_phase(PHASE_WAITING_ZEBRA_UP);
- /*FALLTHRU*/
- case PHASE_WAITING_ZEBRA_UP:
- if (!IS_UP(gs.special))
- break;
- zlog_info("Phased restart: %s is now up.",gs.special->name);
- {
- struct daemon *dmn;
- for (dmn = gs.daemons; dmn; dmn = dmn->next)
- {
- if (dmn != gs.special)
- run_job(&dmn->restart,"start",gs.start_command,1,0);
- }
- }
- gs.phase = PHASE_NONE;
- THREAD_OFF(gs.t_phase_hanging);
- zlog_notice("Phased global restart has completed.");
- break;
- }
+ switch (gs.phase) {
+ case PHASE_NONE:
+ break;
+ case PHASE_STOPS_PENDING:
+ if (gs.numpids)
+ break;
+ zlog_info
+ ("Phased restart: all routing daemon stop jobs have completed.");
+ set_phase(PHASE_WAITING_DOWN);
+
+ /*FALLTHRU*/
+ case PHASE_WAITING_DOWN:
+ if (gs.numdown + IS_UP(gs.special) < gs.numdaemons)
+ break;
+ zlog_info("Phased restart: all routing daemons now down.");
+ run_job(&gs.special->restart, "restart", gs.restart_command, 1,
+ 1);
+ set_phase(PHASE_ZEBRA_RESTART_PENDING);
+
+ /*FALLTHRU*/
+ case PHASE_ZEBRA_RESTART_PENDING:
+ if (gs.special->restart.pid)
+ break;
+ zlog_info("Phased restart: %s restart job completed.",
+ gs.special->name);
+ set_phase(PHASE_WAITING_ZEBRA_UP);
+
+ /*FALLTHRU*/
+ case PHASE_WAITING_ZEBRA_UP:
+ if (!IS_UP(gs.special))
+ break;
+ zlog_info("Phased restart: %s is now up.", gs.special->name);
+ {
+ struct daemon *dmn;
+ for (dmn = gs.daemons; dmn; dmn = dmn->next) {
+ if (dmn != gs.special)
+ run_job(&dmn->restart, "start",
+ gs.start_command, 1, 0);
+ }
+ }
+ gs.phase = PHASE_NONE;
+ THREAD_OFF(gs.t_phase_hanging);
+ zlog_notice("Phased global restart has completed.");
+ break;
+ }
}
-static void
-try_restart(struct daemon *dmn)
+static void try_restart(struct daemon *dmn)
{
- switch (gs.mode)
- {
- case MODE_MONITOR:
- return;
- case MODE_GLOBAL_RESTART:
- run_job(&gs.restart,"restart",gs.restart_command,0,1);
- break;
- case MODE_SEPARATE_RESTART:
- run_job(&dmn->restart,"restart",gs.restart_command,0,1);
- break;
- case MODE_PHASED_ZEBRA_RESTART:
- if (dmn != gs.special)
- {
- if ((gs.special->state == DAEMON_UP) && (gs.phase == PHASE_NONE))
- run_job(&dmn->restart,"restart",gs.restart_command,0,1);
- else
- zlog_debug("%s: postponing restart attempt because master %s daemon "
- "not up [%s], or phased restart in progress",
- dmn->name,gs.special->name,state_str[gs.special->state]);
- break;
- }
- /*FALLTHRU*/
- case MODE_PHASED_ALL_RESTART:
- if ((gs.phase != PHASE_NONE) || gs.numpids)
- {
- if (gs.loglevel > LOG_DEBUG+1)
- zlog_debug("postponing phased global restart: restart already in "
- "progress [%s], or outstanding child processes [%d]",
- phase_str[gs.phase],gs.numpids);
- break;
- }
- /* Is it too soon for a restart? */
- {
- struct timeval delay;
- if (time_elapsed(&delay,&gs.special->restart.time)->tv_sec <
- gs.special->restart.interval)
- {
- if (gs.loglevel > LOG_DEBUG+1)
- zlog_debug("postponing phased global restart: "
- "elapsed time %ld < retry interval %ld",
- (long)delay.tv_sec,gs.special->restart.interval);
- break;
+ switch (gs.mode) {
+ case MODE_MONITOR:
+ return;
+ case MODE_GLOBAL_RESTART:
+ run_job(&gs.restart, "restart", gs.restart_command, 0, 1);
+ break;
+ case MODE_SEPARATE_RESTART:
+ run_job(&dmn->restart, "restart", gs.restart_command, 0, 1);
+ break;
+ case MODE_PHASED_ZEBRA_RESTART:
+ if (dmn != gs.special) {
+ if ((gs.special->state == DAEMON_UP)
+ && (gs.phase == PHASE_NONE))
+ run_job(&dmn->restart, "restart",
+ gs.restart_command, 0, 1);
+ else
+ zlog_debug
+ ("%s: postponing restart attempt because master %s daemon "
+ "not up [%s], or phased restart in progress",
+ dmn->name, gs.special->name,
+ state_str[gs.special->state]);
+ break;
+ }
+
+ /*FALLTHRU*/
+ case MODE_PHASED_ALL_RESTART:
+ if ((gs.phase != PHASE_NONE) || gs.numpids) {
+ if (gs.loglevel > LOG_DEBUG + 1)
+ zlog_debug
+ ("postponing phased global restart: restart already in "
+ "progress [%s], or outstanding child processes [%d]",
+ phase_str[gs.phase], gs.numpids);
+ break;
+ }
+ /* Is it too soon for a restart? */
+ {
+ struct timeval delay;
+ if (time_elapsed(&delay, &gs.special->restart.time)->
+ tv_sec < gs.special->restart.interval) {
+ if (gs.loglevel > LOG_DEBUG + 1)
+ zlog_debug
+ ("postponing phased global restart: "
+ "elapsed time %ld < retry interval %ld",
+ (long)delay.tv_sec,
+ gs.special->restart.interval);
+ break;
+ }
+ }
+ run_job(&gs.restart, "restart", gs.restart_command, 0, 1);
+ break;
+ default:
+ zlog_err("error: unknown restart mode %d", gs.mode);
+ break;
}
- }
- run_job(&gs.restart,"restart",gs.restart_command,0,1);
- break;
- default:
- zlog_err("error: unknown restart mode %d",gs.mode);
- break;
- }
}
-static int
-wakeup_unresponsive(struct thread *t_wakeup)
+static int wakeup_unresponsive(struct thread *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
-
- dmn->t_wakeup = NULL;
- if (dmn->state != DAEMON_UNRESPONSIVE)
- zlog_err("%s: no longer unresponsive (now %s), "
- "wakeup should have been cancelled!",
- dmn->name,state_str[dmn->state]);
- else
- {
- SET_WAKEUP_UNRESPONSIVE(dmn);
- try_restart(dmn);
- }
- return 0;
+ struct daemon *dmn = THREAD_ARG(t_wakeup);
+
+ dmn->t_wakeup = NULL;
+ if (dmn->state != DAEMON_UNRESPONSIVE)
+ zlog_err("%s: no longer unresponsive (now %s), "
+ "wakeup should have been cancelled!",
+ dmn->name, state_str[dmn->state]);
+ else {
+ SET_WAKEUP_UNRESPONSIVE(dmn);
+ try_restart(dmn);
+ }
+ return 0;
}
-static int
-wakeup_no_answer(struct thread *t_wakeup)
+static int wakeup_no_answer(struct thread *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
-
- dmn->t_wakeup = NULL;
- dmn->state = DAEMON_UNRESPONSIVE;
- zlog_err("%s state -> unresponsive : no response yet to ping "
- "sent %ld seconds ago",dmn->name,gs.timeout);
- if (gs.unresponsive_restart)
- {
- SET_WAKEUP_UNRESPONSIVE(dmn);
- try_restart(dmn);
- }
- return 0;
+ struct daemon *dmn = THREAD_ARG(t_wakeup);
+
+ dmn->t_wakeup = NULL;
+ dmn->state = DAEMON_UNRESPONSIVE;
+ zlog_err("%s state -> unresponsive : no response yet to ping "
+ "sent %ld seconds ago", dmn->name, gs.timeout);
+ if (gs.unresponsive_restart) {
+ SET_WAKEUP_UNRESPONSIVE(dmn);
+ try_restart(dmn);
+ }
+ return 0;
}
-static int
-wakeup_send_echo(struct thread *t_wakeup)
+static int wakeup_send_echo(struct thread *t_wakeup)
{
- static const char echocmd[] = "echo " PING_TOKEN;
- ssize_t rc;
- struct daemon *dmn = THREAD_ARG(t_wakeup);
-
- dmn->t_wakeup = NULL;
- if (((rc = write(dmn->fd,echocmd,sizeof(echocmd))) < 0) ||
- ((size_t)rc != sizeof(echocmd)))
- {
- char why[100+sizeof(echocmd)];
- snprintf(why,sizeof(why),"write '%s' returned %d instead of %u",
- echocmd,(int)rc,(u_int)sizeof(echocmd));
- daemon_down(dmn,why);
- }
- else
- {
- gettimeofday(&dmn->echo_sent,NULL);
- dmn->t_wakeup = thread_add_timer(master,wakeup_no_answer,dmn,gs.timeout);
- }
- return 0;
+ static const char echocmd[] = "echo " PING_TOKEN;
+ ssize_t rc;
+ struct daemon *dmn = THREAD_ARG(t_wakeup);
+
+ dmn->t_wakeup = NULL;
+ if (((rc = write(dmn->fd, echocmd, sizeof(echocmd))) < 0) ||
+ ((size_t) rc != sizeof(echocmd))) {
+ char why[100 + sizeof(echocmd)];
+ snprintf(why, sizeof(why),
+ "write '%s' returned %d instead of %u", echocmd,
+ (int)rc, (u_int) sizeof(echocmd));
+ daemon_down(dmn, why);
+ } else {
+ gettimeofday(&dmn->echo_sent, NULL);
+ dmn->t_wakeup =
+ thread_add_timer(master, wakeup_no_answer, dmn, gs.timeout);
+ }
+ return 0;
}
-static void
-sigint(void)
+static void sigint(void)
{
- zlog_notice("Terminating on signal");
- systemd_send_stopping ();
- exit(0);
+ zlog_notice("Terminating on signal");
+ systemd_send_stopping();
+ exit(0);
}
-static int
-valid_command(const char *cmd)
+static int valid_command(const char *cmd)
{
- char *p;
+ char *p;
- return ((p = strchr(cmd,'%')) != NULL) && (*(p+1) == 's') && !strchr(p+1,'%');
+ return ((p = strchr(cmd, '%')) != NULL) && (*(p + 1) == 's')
+ && !strchr(p + 1, '%');
}
/* This is an ugly hack to circumvent problems with passing command-line
arguments that contain spaces. The fix is to use a configuration file. */
-static char *
-translate_blanks(const char *cmd, const char *blankstr)
+static char *translate_blanks(const char *cmd, const char *blankstr)
{
- char *res;
- char *p;
- size_t bslen = strlen(blankstr);
-
- if (!(res = strdup(cmd)))
- {
- perror("strdup");
- exit(1);
- }
- while ((p = strstr(res,blankstr)) != NULL)
- {
- *p = ' ';
- if (bslen != 1)
- memmove(p+1,p+bslen,strlen(p+bslen)+1);
- }
- return res;
+ char *res;
+ char *p;
+ size_t bslen = strlen(blankstr);
+
+ if (!(res = strdup(cmd))) {
+ perror("strdup");
+ exit(1);
+ }
+ while ((p = strstr(res, blankstr)) != NULL) {
+ *p = ' ';
+ if (bslen != 1)
+ memmove(p + 1, p + bslen, strlen(p + bslen) + 1);
+ }
+ return res;
}
-struct zebra_privs_t watchfrr_privs =
-{
+struct zebra_privs_t watchfrr_privs = {
#ifdef VTY_GROUP
- .vty_group = VTY_GROUP,
+ .vty_group = VTY_GROUP,
#endif
};
-int
-main(int argc, char **argv)
+int main(int argc, char **argv)
{
- const char *progname;
- int opt;
- int daemon_mode = 0;
- const char *pidfile = DEFAULT_PIDFILE;
- const char *special = "zebra";
- const char *blankstr = NULL;
- static struct quagga_signal_t my_signals[] =
- {
- {
- .signal = SIGINT,
- .handler = sigint,
- },
- {
- .signal = SIGTERM,
- .handler = sigint,
- },
- {
- .signal = SIGCHLD,
- .handler = sigchild,
- },
- };
-
- if ((progname = strrchr (argv[0], '/')) != NULL)
- progname++;
- else
- progname = argv[0];
-
- gs.restart.name = "all";
- while ((opt = getopt_long(argc, argv, "aAb:dek:l:m:M:i:p:r:R:S:s:t:T:zvh",
- longopts, 0)) != EOF)
- {
- switch (opt)
- {
- case 0:
- break;
- case 'a':
- if ((gs.mode != MODE_MONITOR) && (gs.mode != MODE_SEPARATE_RESTART))
- {
- fputs("Ambiguous operating mode selected.\n",stderr);
- return usage(progname,1);
- }
- gs.mode = MODE_PHASED_ZEBRA_RESTART;
- break;
- case 'A':
- if ((gs.mode != MODE_MONITOR) && (gs.mode != MODE_SEPARATE_RESTART))
- {
- fputs("Ambiguous operating mode selected.\n",stderr);
- return usage(progname,1);
- }
- gs.mode = MODE_PHASED_ALL_RESTART;
- break;
- case 'b':
- blankstr = optarg;
- break;
- case 'd':
- daemon_mode = 1;
- break;
- case 'e':
- gs.do_ping = 0;
- break;
- case 'k':
- if (!valid_command(optarg))
- {
- fprintf(stderr,"Invalid kill command, must contain '%%s': %s\n",
- optarg);
- return usage(progname,1);
- }
- gs.stop_command = optarg;
- break;
- case 'l':
- {
- char garbage[3];
- if ((sscanf(optarg,"%d%1s",&gs.loglevel,garbage) != 1) ||
- (gs.loglevel < LOG_EMERG))
- {
- fprintf(stderr,"Invalid loglevel argument: %s\n",optarg);
- return usage(progname,1);
- }
- }
- break;
- case 'm':
- {
- char garbage[3];
- if ((sscanf(optarg,"%ld%1s",
- &gs.min_restart_interval,garbage) != 1) ||
- (gs.min_restart_interval < 0))
- {
- fprintf(stderr,"Invalid min_restart_interval argument: %s\n",
- optarg);
- return usage(progname,1);
- }
- }
- break;
- case 'M':
- {
- char garbage[3];
- if ((sscanf(optarg,"%ld%1s",
- &gs.max_restart_interval,garbage) != 1) ||
- (gs.max_restart_interval < 0))
- {
- fprintf(stderr,"Invalid max_restart_interval argument: %s\n",
- optarg);
- return usage(progname,1);
- }
- }
- break;
- case 'i':
- {
- char garbage[3];
- int period;
- if ((sscanf(optarg,"%d%1s",&period,garbage) != 1) ||
- (gs.period < 1))
- {
- fprintf(stderr,"Invalid interval argument: %s\n",optarg);
- return usage(progname,1);
- }
- gs.period = 1000*period;
- }
- break;
- case 'p':
- pidfile = optarg;
- break;
- case 'r':
- if ((gs.mode == MODE_GLOBAL_RESTART) ||
- (gs.mode == MODE_SEPARATE_RESTART))
- {
- fputs("Ambiguous operating mode selected.\n",stderr);
- return usage(progname,1);
- }
- if (!valid_command(optarg))
- {
- fprintf(stderr,
- "Invalid restart command, must contain '%%s': %s\n",
- optarg);
- return usage(progname,1);
- }
- gs.restart_command = optarg;
- if (gs.mode == MODE_MONITOR)
- gs.mode = MODE_SEPARATE_RESTART;
- break;
- case 'R':
- if (gs.mode != MODE_MONITOR)
- {
- fputs("Ambiguous operating mode selected.\n",stderr);
- return usage(progname,1);
- }
- if (strchr(optarg,'%'))
- {
- fprintf(stderr,
- "Invalid restart-all arg, must not contain '%%s': %s\n",
- optarg);
- return usage(progname,1);
- }
- gs.restart_command = optarg;
- gs.mode = MODE_GLOBAL_RESTART;
- break;
- case 's':
- if (!valid_command(optarg))
- {
- fprintf(stderr,"Invalid start command, must contain '%%s': %s\n",
- optarg);
- return usage(progname,1);
- }
- gs.start_command = optarg;
- break;
- case 'S':
- gs.vtydir = optarg;
- break;
- case 't':
- {
- char garbage[3];
- if ((sscanf(optarg,"%ld%1s",&gs.timeout,garbage) != 1) ||
- (gs.timeout < 1))
- {
- fprintf(stderr,"Invalid timeout argument: %s\n",optarg);
- return usage(progname,1);
- }
- }
- break;
- case 'T':
- {
- char garbage[3];
- if ((sscanf(optarg,"%ld%1s",&gs.restart_timeout,garbage) != 1) ||
- (gs.restart_timeout < 1))
- {
- fprintf(stderr,"Invalid restart timeout argument: %s\n",optarg);
- return usage(progname,1);
- }
- }
- break;
- case 'z':
- gs.unresponsive_restart = 1;
- break;
- case 'v':
- printf ("%s version %s\n", progname, FRR_VERSION);
- puts("Copyright 2004 Andrew J. Schorr");
- return 0;
- case 'h':
- return usage(progname,0);
- default:
- fputs("Invalid option.\n",stderr);
- return usage(progname,1);
- }
- }
-
- if (gs.unresponsive_restart && (gs.mode == MODE_MONITOR))
- {
- fputs("Option -z requires a -r or -R restart option.\n",stderr);
- return usage(progname,1);
- }
- switch (gs.mode)
- {
- case MODE_MONITOR:
- if (gs.restart_command || gs.start_command || gs.stop_command)
- {
- fprintf(stderr,"No kill/(re)start commands needed for %s mode.\n",
- mode_str[gs.mode]);
- return usage(progname,1);
+ const char *progname;
+ int opt;
+ int daemon_mode = 0;
+ const char *pidfile = DEFAULT_PIDFILE;
+ const char *special = "zebra";
+ const char *blankstr = NULL;
+ static struct quagga_signal_t my_signals[] = {
+ {
+ .signal = SIGINT,
+ .handler = sigint,
+ },
+ {
+ .signal = SIGTERM,
+ .handler = sigint,
+ },
+ {
+ .signal = SIGCHLD,
+ .handler = sigchild,
+ },
+ };
+
+ if ((progname = strrchr(argv[0], '/')) != NULL)
+ progname++;
+ else
+ progname = argv[0];
+
+ gs.restart.name = "all";
+ while ((opt =
+ getopt_long(argc, argv, "aAb:dek:l:m:M:i:p:r:R:S:s:t:T:zvh",
+ longopts, 0)) != EOF) {
+ switch (opt) {
+ case 0:
+ break;
+ case 'a':
+ if ((gs.mode != MODE_MONITOR)
+ && (gs.mode != MODE_SEPARATE_RESTART)) {
+ fputs("Ambiguous operating mode selected.\n",
+ stderr);
+ return usage(progname, 1);
+ }
+ gs.mode = MODE_PHASED_ZEBRA_RESTART;
+ break;
+ case 'A':
+ if ((gs.mode != MODE_MONITOR)
+ && (gs.mode != MODE_SEPARATE_RESTART)) {
+ fputs("Ambiguous operating mode selected.\n",
+ stderr);
+ return usage(progname, 1);
+ }
+ gs.mode = MODE_PHASED_ALL_RESTART;
+ break;
+ case 'b':
+ blankstr = optarg;
+ break;
+ case 'd':
+ daemon_mode = 1;
+ break;
+ case 'e':
+ gs.do_ping = 0;
+ break;
+ case 'k':
+ if (!valid_command(optarg)) {
+ fprintf(stderr,
+ "Invalid kill command, must contain '%%s': %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ gs.stop_command = optarg;
+ break;
+ case 'l':
+ {
+ char garbage[3];
+ if ((sscanf
+ (optarg, "%d%1s", &gs.loglevel,
+ garbage) != 1)
+ || (gs.loglevel < LOG_EMERG)) {
+ fprintf(stderr,
+ "Invalid loglevel argument: %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ }
+ break;
+ case 'm':
+ {
+ char garbage[3];
+ if ((sscanf(optarg, "%ld%1s",
+ &gs.min_restart_interval,
+ garbage) != 1)
+ || (gs.min_restart_interval < 0)) {
+ fprintf(stderr,
+ "Invalid min_restart_interval argument: %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ }
+ break;
+ case 'M':
+ {
+ char garbage[3];
+ if ((sscanf(optarg, "%ld%1s",
+ &gs.max_restart_interval,
+ garbage) != 1)
+ || (gs.max_restart_interval < 0)) {
+ fprintf(stderr,
+ "Invalid max_restart_interval argument: %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ }
+ break;
+ case 'i':
+ {
+ char garbage[3];
+ int period;
+ if ((sscanf(optarg, "%d%1s", &period, garbage)
+ != 1) || (gs.period < 1)) {
+ fprintf(stderr,
+ "Invalid interval argument: %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ gs.period = 1000 * period;
+ }
+ break;
+ case 'p':
+ pidfile = optarg;
+ break;
+ case 'r':
+ if ((gs.mode == MODE_GLOBAL_RESTART) ||
+ (gs.mode == MODE_SEPARATE_RESTART)) {
+ fputs("Ambiguous operating mode selected.\n",
+ stderr);
+ return usage(progname, 1);
+ }
+ if (!valid_command(optarg)) {
+ fprintf(stderr,
+ "Invalid restart command, must contain '%%s': %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ gs.restart_command = optarg;
+ if (gs.mode == MODE_MONITOR)
+ gs.mode = MODE_SEPARATE_RESTART;
+ break;
+ case 'R':
+ if (gs.mode != MODE_MONITOR) {
+ fputs("Ambiguous operating mode selected.\n",
+ stderr);
+ return usage(progname, 1);
+ }
+ if (strchr(optarg, '%')) {
+ fprintf(stderr,
+ "Invalid restart-all arg, must not contain '%%s': %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ gs.restart_command = optarg;
+ gs.mode = MODE_GLOBAL_RESTART;
+ break;
+ case 's':
+ if (!valid_command(optarg)) {
+ fprintf(stderr,
+ "Invalid start command, must contain '%%s': %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ gs.start_command = optarg;
+ break;
+ case 'S':
+ gs.vtydir = optarg;
+ break;
+ case 't':
+ {
+ char garbage[3];
+ if ((sscanf
+ (optarg, "%ld%1s", &gs.timeout,
+ garbage) != 1) || (gs.timeout < 1)) {
+ fprintf(stderr,
+ "Invalid timeout argument: %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ }
+ break;
+ case 'T':
+ {
+ char garbage[3];
+ if ((sscanf
+ (optarg, "%ld%1s", &gs.restart_timeout,
+ garbage) != 1)
+ || (gs.restart_timeout < 1)) {
+ fprintf(stderr,
+ "Invalid restart timeout argument: %s\n",
+ optarg);
+ return usage(progname, 1);
+ }
+ }
+ break;
+ case 'z':
+ gs.unresponsive_restart = 1;
+ break;
+ case 'v':
+ printf("%s version %s\n", progname, FRR_VERSION);
+ puts("Copyright 2004 Andrew J. Schorr");
+ return 0;
+ case 'h':
+ return usage(progname, 0);
+ default:
+ fputs("Invalid option.\n", stderr);
+ return usage(progname, 1);
+ }
}
- break;
- case MODE_GLOBAL_RESTART:
- case MODE_SEPARATE_RESTART:
- if (!gs.restart_command || gs.start_command || gs.stop_command)
- {
- fprintf(stderr,"No start/kill commands needed in [%s] mode.\n",
- mode_str[gs.mode]);
- return usage(progname,1);
+
+ if (gs.unresponsive_restart && (gs.mode == MODE_MONITOR)) {
+ fputs("Option -z requires a -r or -R restart option.\n",
+ stderr);
+ return usage(progname, 1);
}
- break;
- case MODE_PHASED_ZEBRA_RESTART:
- case MODE_PHASED_ALL_RESTART:
- if (!gs.restart_command || !gs.start_command || !gs.stop_command)
- {
- fprintf(stderr,
- "Need start, kill, and restart commands in [%s] mode.\n",
- mode_str[gs.mode]);
- return usage(progname,1);
+ switch (gs.mode) {
+ case MODE_MONITOR:
+ if (gs.restart_command || gs.start_command || gs.stop_command) {
+ fprintf(stderr,
+ "No kill/(re)start commands needed for %s mode.\n",
+ mode_str[gs.mode]);
+ return usage(progname, 1);
+ }
+ break;
+ case MODE_GLOBAL_RESTART:
+ case MODE_SEPARATE_RESTART:
+ if (!gs.restart_command || gs.start_command || gs.stop_command) {
+ fprintf(stderr,
+ "No start/kill commands needed in [%s] mode.\n",
+ mode_str[gs.mode]);
+ return usage(progname, 1);
+ }
+ break;
+ case MODE_PHASED_ZEBRA_RESTART:
+ case MODE_PHASED_ALL_RESTART:
+ if (!gs.restart_command || !gs.start_command
+ || !gs.stop_command) {
+ fprintf(stderr,
+ "Need start, kill, and restart commands in [%s] mode.\n",
+ mode_str[gs.mode]);
+ return usage(progname, 1);
+ }
+ break;
}
- break;
- }
-
- if (blankstr)
- {
- if (gs.restart_command)
- gs.restart_command = translate_blanks(gs.restart_command,blankstr);
- if (gs.start_command)
- gs.start_command = translate_blanks(gs.start_command,blankstr);
- if (gs.stop_command)
- gs.stop_command = translate_blanks(gs.stop_command,blankstr);
- }
-
- gs.restart.interval = gs.min_restart_interval;
-
- zprivs_init (&watchfrr_privs);
-
- master = thread_master_create();
- cmd_init(-1);
- memory_init();
- vty_init(master);
- watchfrr_vty_init();
- vty_serv_sock(NULL, 0, WATCHFRR_VTYSH_PATH);
-
- signal_init (master, array_size(my_signals), my_signals);
- srandom(time(NULL));
-
- {
- int i;
- struct daemon *tail = NULL;
-
- for (i = optind; i < argc; i++)
- {
- struct daemon *dmn;
-
- if (!(dmn = (struct daemon *)calloc(1,sizeof(*dmn))))
- {
- fprintf(stderr,"calloc(1,%u) failed: %s\n",
- (u_int)sizeof(*dmn), safe_strerror(errno));
- return 1;
- }
- dmn->name = dmn->restart.name = argv[i];
- dmn->state = DAEMON_INIT;
- gs.numdaemons++;
- gs.numdown++;
- dmn->fd = -1;
- dmn->t_wakeup = thread_add_timer_msec(master,wakeup_init,dmn,
- 100+(random() % 900));
- dmn->restart.interval = gs.min_restart_interval;
- if (tail)
- tail->next = dmn;
- else
- gs.daemons = dmn;
- tail = dmn;
- if (((gs.mode == MODE_PHASED_ZEBRA_RESTART) ||
- (gs.mode == MODE_PHASED_ALL_RESTART)) &&
- !strcmp(dmn->name,special))
- gs.special = dmn;
- }
- }
- if (!gs.daemons)
- {
- fputs("Must specify one or more daemons to monitor.\n",stderr);
- return usage(progname,1);
- }
- if (((gs.mode == MODE_PHASED_ZEBRA_RESTART) ||
- (gs.mode == MODE_PHASED_ALL_RESTART)) && !gs.special)
- {
- fprintf(stderr,"In mode [%s], but cannot find master daemon %s\n",
- mode_str[gs.mode],special);
- return usage(progname,1);
- }
-
- zlog_default = openzlog(progname, ZLOG_WATCHFRR, 0,
- LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
- zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
- if (daemon_mode)
- {
- zlog_set_level(NULL, ZLOG_DEST_SYSLOG, MIN(gs.loglevel,LOG_DEBUG));
- if (daemon (0, 0) < 0)
- {
- fprintf(stderr, "Watchfrr daemon failed: %s", strerror(errno));
- exit (1);
+ if (blankstr) {
+ if (gs.restart_command)
+ gs.restart_command =
+ translate_blanks(gs.restart_command, blankstr);
+ if (gs.start_command)
+ gs.start_command =
+ translate_blanks(gs.start_command, blankstr);
+ if (gs.stop_command)
+ gs.stop_command =
+ translate_blanks(gs.stop_command, blankstr);
}
- }
- else
- zlog_set_level(NULL, ZLOG_DEST_STDOUT, MIN(gs.loglevel,LOG_DEBUG));
- /* Make sure we're not already running. */
- pid_output (pidfile);
+ gs.restart.interval = gs.min_restart_interval;
- /* Announce which daemons are being monitored. */
- {
- struct daemon *dmn;
- size_t len = 0;
+ zprivs_init(&watchfrr_privs);
- for (dmn = gs.daemons; dmn; dmn = dmn->next)
- len += strlen(dmn->name)+1;
+ master = thread_master_create();
+ cmd_init(-1);
+ memory_init();
+ vty_init(master);
+ watchfrr_vty_init();
+ vty_serv_sock(NULL, 0, WATCHFRR_VTYSH_PATH);
- {
- char buf[len+1];
- char *p = buf;
+ signal_init(master, array_size(my_signals), my_signals);
+ srandom(time(NULL));
- for (dmn = gs.daemons; dmn; dmn = dmn->next)
{
- if (p != buf)
- *p++ = ' ';
- strcpy(p,dmn->name);
- p += strlen(p);
+ int i;
+ struct daemon *tail = NULL;
+
+ for (i = optind; i < argc; i++) {
+ struct daemon *dmn;
+
+ if (!(dmn = (struct daemon *)calloc(1, sizeof(*dmn)))) {
+ fprintf(stderr, "calloc(1,%u) failed: %s\n",
+ (u_int) sizeof(*dmn),
+ safe_strerror(errno));
+ return 1;
+ }
+ dmn->name = dmn->restart.name = argv[i];
+ dmn->state = DAEMON_INIT;
+ gs.numdaemons++;
+ gs.numdown++;
+ dmn->fd = -1;
+ dmn->t_wakeup =
+ thread_add_timer_msec(master, wakeup_init, dmn,
+ 100 + (random() % 900));
+ dmn->restart.interval = gs.min_restart_interval;
+ if (tail)
+ tail->next = dmn;
+ else
+ gs.daemons = dmn;
+ tail = dmn;
+
+ if (((gs.mode == MODE_PHASED_ZEBRA_RESTART) ||
+ (gs.mode == MODE_PHASED_ALL_RESTART)) &&
+ !strcmp(dmn->name, special))
+ gs.special = dmn;
+ }
+ }
+ if (!gs.daemons) {
+ fputs("Must specify one or more daemons to monitor.\n", stderr);
+ return usage(progname, 1);
+ }
+ if (((gs.mode == MODE_PHASED_ZEBRA_RESTART) ||
+ (gs.mode == MODE_PHASED_ALL_RESTART)) && !gs.special) {
+ fprintf(stderr,
+ "In mode [%s], but cannot find master daemon %s\n",
+ mode_str[gs.mode], special);
+ return usage(progname, 1);
}
- zlog_notice("%s %s watching [%s], mode [%s]",
- progname, FRR_VERSION, buf, mode_str[gs.mode]);
- }
- }
- {
- struct thread thread;
+ zlog_default = openzlog(progname, ZLOG_WATCHFRR, 0,
+ LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
+ zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
+ if (daemon_mode) {
+ zlog_set_level(NULL, ZLOG_DEST_SYSLOG,
+ MIN(gs.loglevel, LOG_DEBUG));
+ if (daemon(0, 0) < 0) {
+ fprintf(stderr, "Watchfrr daemon failed: %s",
+ strerror(errno));
+ exit(1);
+ }
+ } else
+ zlog_set_level(NULL, ZLOG_DEST_STDOUT,
+ MIN(gs.loglevel, LOG_DEBUG));
+
+ /* Make sure we're not already running. */
+ pid_output(pidfile);
+
+ /* Announce which daemons are being monitored. */
+ {
+ struct daemon *dmn;
+ size_t len = 0;
+
+ for (dmn = gs.daemons; dmn; dmn = dmn->next)
+ len += strlen(dmn->name) + 1;
+
+ {
+ char buf[len + 1];
+ char *p = buf;
+
+ for (dmn = gs.daemons; dmn; dmn = dmn->next) {
+ if (p != buf)
+ *p++ = ' ';
+ strcpy(p, dmn->name);
+ p += strlen(p);
+ }
+ zlog_notice("%s %s watching [%s], mode [%s]",
+ progname, FRR_VERSION, buf,
+ mode_str[gs.mode]);
+ }
+ }
- while (thread_fetch (master, &thread))
- thread_call (&thread);
- }
+ {
+ struct thread thread;
+
+ while (thread_fetch(master, &thread))
+ thread_call(&thread);
+ }
- systemd_send_stopping ();
- /* Not reached. */
- return 0;
+ systemd_send_stopping();
+ /* Not reached. */
+ return 0;
}
diff --git a/watchfrr/watchfrr.h b/watchfrr/watchfrr.h
index 4a479c72e6..719ad4dfd8 100644
--- a/watchfrr/watchfrr.h
+++ b/watchfrr/watchfrr.h
@@ -26,4 +26,4 @@ extern void watchfrr_vty_init(void);
extern pid_t integrated_write_pid;
extern void integrated_write_sigchld(int status);
-#endif /* FRR_WATCHFRR_H */
+#endif /* FRR_WATCHFRR_H */
diff --git a/watchfrr/watchfrr_vty.c b/watchfrr/watchfrr_vty.c
index 4fffb020d7..bf3e1510a7 100644
--- a/watchfrr/watchfrr_vty.c
+++ b/watchfrr/watchfrr_vty.c
@@ -31,18 +31,18 @@
pid_t integrated_write_pid;
static int integrated_result_fd;
-DEFUN (config_write_integrated,
- config_write_integrated_cmd,
- "write integrated",
- "Write running configuration to memory, network, or terminal\n"
- "Write integrated all-daemon Frr.conf file\n")
+DEFUN(config_write_integrated,
+ config_write_integrated_cmd,
+ "write integrated",
+ "Write running configuration to memory, network, or terminal\n"
+ "Write integrated all-daemon Frr.conf file\n")
{
pid_t child;
sigset_t oldmask, sigmask;
if (integrated_write_pid != -1) {
vty_out(vty, "%% configuration write already in progress.%s",
- VTY_NEWLINE);
+ VTY_NEWLINE);
return CMD_WARNING;
}
@@ -61,20 +61,20 @@ DEFUN (config_write_integrated,
child = fork();
if (child == -1) {
vty_out(vty, "%% configuration write fork() failed: %s.%s",
- safe_strerror(errno), VTY_NEWLINE);
+ safe_strerror(errno), VTY_NEWLINE);
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return CMD_WARNING;
}
if (child != 0) {
- /* note: the VTY won't write a command return value to vtysh; the
- * session temporarily enters an intentional "hang" state. This is
- * to make sure latency in vtysh doing the config write (several
- * seconds is not rare to see) does not interfere with watchfrr's
- * supervisor job.
- *
- * The fd is duplicated here so we don't need to hold a vty pointer
- * (which could become invalid in the meantime).
- */
+ /* note: the VTY won't write a command return value to vtysh; the
+ * session temporarily enters an intentional "hang" state. This is
+ * to make sure latency in vtysh doing the config write (several
+ * seconds is not rare to see) does not interfere with watchfrr's
+ * supervisor job.
+ *
+ * The fd is duplicated here so we don't need to hold a vty pointer
+ * (which could become invalid in the meantime).
+ */
integrated_write_pid = child;
integrated_result_fd = dup(vty->wfd);
sigprocmask(SIG_SETMASK, &oldmask, NULL);
@@ -93,7 +93,7 @@ DEFUN (config_write_integrated,
/* unbuffered write; we just messed with stdout... */
char msg[512];
snprintf(msg, sizeof(msg), "error executing %s: %s\n",
- VTYSH_BIN_PATH, safe_strerror(errno));
+ VTYSH_BIN_PATH, safe_strerror(errno));
write(1, msg, strlen(msg));
exit(1);
}
@@ -104,11 +104,11 @@ void integrated_write_sigchld(int status)
if (WIFEXITED(status)) {
zlog_info("configuration write completed with exit code %d",
- WEXITSTATUS(status));
+ WEXITSTATUS(status));
reply[3] = WEXITSTATUS(status);
} else if (WIFSIGNALED(status)) {
zlog_warn("configuration write terminated by signal %d",
- WTERMSIG(status));
+ WTERMSIG(status));
} else {
zlog_warn("configuration write terminated");
}
diff --git a/zebra/Makefile.am b/zebra/Makefile.am
index f6a056e3f0..1910e7b80f 100644
--- a/zebra/Makefile.am
+++ b/zebra/Makefile.am
@@ -2,8 +2,7 @@ include ../common.am
## Process this file with automake to produce Makefile.in.
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \
- -DVTY_DEPRECATE_INDEX
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
@@ -45,7 +44,7 @@ zebra_SOURCES = \
irdp_main.c irdp_interface.c irdp_packet.c router-id.c zebra_fpm.c \
$(othersrc) zebra_ptm.c zebra_rnh.c zebra_ptm_redistribute.c \
zebra_ns.c zebra_vrf.c zebra_static.c zebra_mpls.c zebra_mpls_vty.c \
- $(protobuf_srcs) \
+ $(protobuf_srcs) zebra_mroute.c \
$(dev_srcs)
testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
@@ -61,7 +60,7 @@ noinst_HEADERS = \
rt_netlink.h zebra_fpm.h zebra_fpm_private.h zebra_rnh.h \
zebra_ptm_redistribute.h zebra_ptm.h zebra_routemap.h \
zebra_ns.h zebra_vrf.h ioctl_solaris.h zebra_static.h zebra_mpls.h \
- kernel_netlink.h if_netlink.h
+ kernel_netlink.h if_netlink.h zebra_mroute.h
zebra_LDADD = $(otherobj) ../lib/libfrr.la $(LIBCAP) $(Q_FPM_PB_CLIENT_LDOPTS)
diff --git a/zebra/client_main.c b/zebra/client_main.c
index 8290eafc4d..f40d995466 100644
--- a/zebra/client_main.c
+++ b/zebra/client_main.c
@@ -79,7 +79,6 @@ zebra_test_ipv4 (int command, int type, char *prefix, char *gateway,
}
}
-#ifdef HAVE_IPV6
/* IPv6 route add and delete test. */
void
zebra_test_v6 (int sock)
@@ -95,7 +94,6 @@ zebra_test_v6 (int sock)
sleep (5);
/* zebra_ipv6_delete (sock, ZEBRA_ROUTE_STATIC, 0, &p, &nexthop, 1); */
}
-#endif /* HAVE_IPV6 */
/* Print out usage and exit. */
void
diff --git a/zebra/connected.c b/zebra/connected.c
index 55c3792d4f..0ceaddc8e3 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -32,6 +32,7 @@
#include "memory.h"
#include "zebra_memory.h"
+#include "vty.h"
#include "zebra/debug.h"
#include "zebra/zserv.h"
#include "zebra/redistribute.h"
@@ -58,10 +59,8 @@ connected_withdraw (struct connected *ifc)
if (ifc->address->family == AF_INET)
connected_down_ipv4 (ifc->ifp, ifc);
-#ifdef HAVE_IPV6
else
connected_down_ipv6 (ifc->ifp, ifc);
-#endif
UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
}
@@ -102,10 +101,8 @@ connected_announce (struct interface *ifp, struct connected *ifc)
{
if (ifc->address->family == AF_INET)
connected_up_ipv4 (ifp, ifc);
-#ifdef HAVE_IPV6
else
connected_up_ipv6 (ifp, ifc);
-#endif
}
}
@@ -204,11 +201,11 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
return;
rib_add (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, NULL, ifp->ifindex,
+ 0, 0, &p, NULL, NULL, NULL, ifp->ifindex,
RT_TABLE_MAIN, ifp->metric, 0, 0);
rib_add (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, NULL, ifp->ifindex,
+ 0, 0, &p, NULL, NULL, NULL, ifp->ifindex,
RT_TABLE_MAIN, ifp->metric, 0, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
@@ -334,10 +331,10 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
/* Same logic as for connected_up_ipv4(): push the changes into the head. */
rib_delete (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, ifp->ifindex, 0);
+ 0, 0, &p, NULL, NULL, ifp->ifindex, 0);
rib_delete (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, ifp->ifindex, 0);
+ 0, 0, &p, NULL, NULL, ifp->ifindex, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug ("%u: IF %s IPv4 address down, scheduling RIB processing",
@@ -410,7 +407,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
#endif
rib_add (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, NULL, ifp->ifindex,
+ 0, 0, &p, NULL, NULL, NULL, ifp->ifindex,
RT_TABLE_MAIN, ifp->metric, 0, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
@@ -510,7 +507,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
return;
rib_delete (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, ifp->ifindex, 0);
+ 0, 0, &p, NULL, NULL, ifp->ifindex, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing",
diff --git a/zebra/connected.h b/zebra/connected.h
index f35f47fb6a..bdcf6085e4 100644
--- a/zebra/connected.h
+++ b/zebra/connected.h
@@ -41,7 +41,6 @@ connected_delete_ipv4_unnumbered (struct connected *ifc);
extern void connected_up_ipv4 (struct interface *, struct connected *);
extern void connected_down_ipv4 (struct interface *, struct connected *);
-#ifdef HAVE_IPV6
extern void
connected_add_ipv6 (struct interface *ifp, int flags, struct in6_addr *address,
u_char prefixlen, struct in6_addr *broad,
@@ -53,8 +52,6 @@ connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
extern void connected_up_ipv6 (struct interface *, struct connected *);
extern void connected_down_ipv6 (struct interface *ifp, struct connected *);
-#endif /* HAVE_IPV6 */
-
extern int connected_is_unnumbered (struct interface *);
#endif /*_ZEBRA_CONNECTED_H */
diff --git a/zebra/debug.c b/zebra/debug.c
index 93cd4dd9c6..2e9fef292b 100644
--- a/zebra/debug.c
+++ b/zebra/debug.c
@@ -124,52 +124,31 @@ DEFUN (debug_zebra_mpls,
DEFUN (debug_zebra_packet,
debug_zebra_packet_cmd,
- "debug zebra packet",
- DEBUG_STR
- "Zebra configuration\n"
- "Debug option set for zebra packet\n")
-{
- zebra_debug_packet = ZEBRA_DEBUG_PACKET;
- SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND);
- SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV);
- return CMD_SUCCESS;
-}
-
-DEFUN (debug_zebra_packet_direct,
- debug_zebra_packet_direct_cmd,
- "debug zebra packet (recv|send|detail)",
+ "debug zebra packet [<recv|send>] [detail]",
DEBUG_STR
"Zebra configuration\n"
"Debug option set for zebra packet\n"
"Debug option set for receive packet\n"
- "Debug option set for send packet\n")
+ "Debug option set for send packet\n"
+ "Debug option set for detailed info\n")
{
+ int idx = 0;
zebra_debug_packet = ZEBRA_DEBUG_PACKET;
- if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
+
+ if (argv_find (argv, argc, "send", &idx))
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND);
- if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
+ idx = 0;
+ if (argv_find (argv, argc, "recv", &idx))
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV);
- if (strncmp ("detail", argv[0], strlen (argv[0])) == 0)
+ idx = 0;
+ if (argv_find (argv, argc, "detail", &idx))
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_DETAIL);
- return CMD_SUCCESS;
-}
-DEFUN (debug_zebra_packet_detail,
- debug_zebra_packet_detail_cmd,
- "debug zebra packet (recv|send) detail",
- DEBUG_STR
- "Zebra configuration\n"
- "Debug option set for zebra packet\n"
- "Debug option set for receive packet\n"
- "Debug option set for send packet\n"
- "Debug option set detailed information\n")
-{
- zebra_debug_packet = ZEBRA_DEBUG_PACKET;
- if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
+ if (!(zebra_debug_packet & ZEBRA_DEBUG_SEND & ZEBRA_DEBUG_RECV))
+ {
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND);
- if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV);
- SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_DETAIL);
+ }
return CMD_SUCCESS;
}
@@ -186,7 +165,7 @@ DEFUN (debug_zebra_kernel,
DEFUN (debug_zebra_kernel_msgdump,
debug_zebra_kernel_msgdump_cmd,
- "debug zebra kernel msgdump {recv|send}",
+ "debug zebra kernel msgdump [<recv|send>]",
DEBUG_STR
"Zebra configuration\n"
"Debug option set for zebra between kernel interface\n"
@@ -194,9 +173,10 @@ DEFUN (debug_zebra_kernel_msgdump,
"Dump raw netlink messages received\n"
"Dump raw netlink messages sent\n")
{
- if (!argv[1] || (argv[0] && strncmp(argv[0], "recv", strlen(argv[0])) == 0))
+ int idx_recv_send = 4;
+ if (argv[idx_recv_send]->arg && strncmp(argv[idx_recv_send]->arg, "recv", strlen(argv[idx_recv_send]->arg)) == 0)
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
- if (!argv[0] || (argv[1] && strncmp(argv[1], "send", strlen(argv[1])) == 0))
+ if (!argv[idx_recv_send]->arg || strncmp(argv[idx_recv_send]->arg, "send", strlen(argv[idx_recv_send]->arg)) == 0)
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
return CMD_SUCCESS;
}
@@ -273,19 +253,7 @@ DEFUN (no_debug_zebra_mpls,
DEFUN (no_debug_zebra_packet,
no_debug_zebra_packet_cmd,
- "no debug zebra packet",
- NO_STR
- DEBUG_STR
- "Zebra configuration\n"
- "Debug option set for zebra packet\n")
-{
- zebra_debug_packet = 0;
- return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_zebra_packet_direct,
- no_debug_zebra_packet_direct_cmd,
- "no debug zebra packet (recv|send)",
+ "no debug zebra packet [<recv|send>]",
NO_STR
DEBUG_STR
"Zebra configuration\n"
@@ -293,9 +261,10 @@ DEFUN (no_debug_zebra_packet_direct,
"Debug option set for receive packet\n"
"Debug option set for send packet\n")
{
- if (strncmp ("send", argv[0], strlen (argv[0])) == 0)
+ int idx = 0;
+ if (argc == 4 || argv_find (argv, argc, "send", &idx))
UNSET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND);
- if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
+ if (argc == 4 || argv_find (argv, argc, "recv", &idx))
UNSET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV);
return CMD_SUCCESS;
}
@@ -314,7 +283,8 @@ DEFUN (no_debug_zebra_kernel,
DEFUN (no_debug_zebra_kernel_msgdump,
no_debug_zebra_kernel_msgdump_cmd,
- "no debug zebra kernel msgdump {recv|send}",
+ "no debug zebra kernel msgdump [<recv|send>]",
+ NO_STR
DEBUG_STR
"Zebra configuration\n"
"Debug option set for zebra between kernel interface\n"
@@ -322,10 +292,12 @@ DEFUN (no_debug_zebra_kernel_msgdump,
"Dump raw netlink messages received\n"
"Dump raw netlink messages sent\n")
{
- if (!argv[1] || (argv[0] && strncmp(argv[0], "recv", strlen(argv[0])) == 0))
+ int idx = 0;
+ if (argc == 5 || argv_find (argv, argc, "recv", &idx))
UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
- if (!argv[0] || (argv[1] && strncmp(argv[1], "send", strlen(argv[1])) == 0))
+ if (argc == 5 || argv_find (argv, argc, "send", &idx))
UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
+
return CMD_SUCCESS;
}
@@ -453,8 +425,6 @@ zebra_debug_init (void)
install_element (ENABLE_NODE, &debug_zebra_nht_cmd);
install_element (ENABLE_NODE, &debug_zebra_mpls_cmd);
install_element (ENABLE_NODE, &debug_zebra_packet_cmd);
- install_element (ENABLE_NODE, &debug_zebra_packet_direct_cmd);
- install_element (ENABLE_NODE, &debug_zebra_packet_detail_cmd);
install_element (ENABLE_NODE, &debug_zebra_kernel_cmd);
install_element (ENABLE_NODE, &debug_zebra_kernel_msgdump_cmd);
install_element (ENABLE_NODE, &debug_zebra_rib_cmd);
@@ -474,8 +444,6 @@ zebra_debug_init (void)
install_element (CONFIG_NODE, &debug_zebra_nht_cmd);
install_element (CONFIG_NODE, &debug_zebra_mpls_cmd);
install_element (CONFIG_NODE, &debug_zebra_packet_cmd);
- install_element (CONFIG_NODE, &debug_zebra_packet_direct_cmd);
- install_element (CONFIG_NODE, &debug_zebra_packet_detail_cmd);
install_element (CONFIG_NODE, &debug_zebra_kernel_cmd);
install_element (CONFIG_NODE, &debug_zebra_kernel_msgdump_cmd);
install_element (CONFIG_NODE, &debug_zebra_rib_cmd);
diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c
index cc348fc237..a4498a84f6 100644
--- a/zebra/if_ioctl.c
+++ b/zebra/if_ioctl.c
@@ -105,7 +105,7 @@ interface_list_ioctl (void)
#ifdef OPEN_BSD
for (n = 0; n < ifconf.ifc_len; )
{
- int size;
+ unsigned int size;
ifreq = (struct ifreq *)((caddr_t) ifconf.ifc_req + n);
ifp = if_get_by_name_len(ifreq->ifr_name,
@@ -244,7 +244,6 @@ if_getaddrs (void)
connected_add_ipv4 (ifp, flags, &addr->sin_addr,
prefixlen, dest_pnt, NULL);
}
-#ifdef HAVE_IPV6
if (ifap->ifa_addr->sa_family == AF_INET6)
{
struct sockaddr_in6 *addr;
@@ -289,7 +288,6 @@ if_getaddrs (void)
connected_add_ipv6 (ifp, flags, &addr->sin6_addr, prefixlen,
dest_pnt, NULL);
}
-#endif /* HAVE_IPV6 */
}
freeifaddrs (ifapfree);
@@ -336,9 +334,9 @@ interface_list (struct zebra_ns *zns)
if_getaddrs ();
-#if defined(HAVE_IPV6) && defined(HAVE_PROC_NET_IF_INET6)
+#if defined(HAVE_PROC_NET_IF_INET6)
/* Linux provides interface's IPv6 address via
/proc/net/if_inet6. */
ifaddr_proc_ipv6 ();
-#endif /* HAVE_IPV6 && HAVE_PROC_NET_IF_INET6 */
+#endif /* HAVE_PROC_NET_IF_INET6 */
}
diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c
index 0e727b9dc4..f27dc89007 100644
--- a/zebra/if_ioctl_solaris.c
+++ b/zebra/if_ioctl_solaris.c
@@ -177,12 +177,7 @@ calculate_lifc_len: /* must hold privileges to enter here */
if (lifreq->lifr_addr.ss_family == AF_INET6)
{
-#ifdef HAVE_IPV6
ifp->flags |= IFF_IPV6;
-#else
- lifreq++;
- continue;
-#endif /* HAVE_IPV6 */
}
if_add_update (ifp);
@@ -309,7 +304,6 @@ if_get_addr (struct interface *ifp, struct sockaddr *addr, const char *label)
dest_pnt = (char *) &SIN (&dest)->sin_addr;
}
}
-#ifdef HAVE_IPV6
else if (af == AF_INET6)
{
if (if_ioctl_ipv6 (SIOCGLIFSUBNET, (caddr_t) & lifreq) < 0)
@@ -325,17 +319,14 @@ if_get_addr (struct interface *ifp, struct sockaddr *addr, const char *label)
prefixlen = lifreq.lifr_addrlen;
}
}
-#endif /* HAVE_IPV6 */
/* Set address to the interface. */
if (af == AF_INET)
connected_add_ipv4 (ifp, flags, &SIN (addr)->sin_addr, prefixlen,
(struct in_addr *) dest_pnt, label);
-#ifdef HAVE_IPV6
else if (af == AF_INET6)
connected_add_ipv6 (ifp, flags, &SIN6 (addr)->sin6_addr, prefixlen,
(struct in6_addr *) dest_pnt, label);
-#endif /* HAVE_IPV6 */
return 0;
}
@@ -367,7 +358,6 @@ interface_list (struct zebra_ns *zns)
struct connected *
if_lookup_linklocal (struct interface *ifp)
{
-#ifdef HAVE_IPV6
struct listnode *node;
struct connected *ifc;
@@ -380,7 +370,6 @@ if_lookup_linklocal (struct interface *ifp)
(IN6_IS_ADDR_LINKLOCAL (&ifc->address->u.prefix6)))
return ifc;
}
-#endif /* HAVE_IPV6 */
return NULL;
}
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index be7a5ac78d..660fad6530 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -38,6 +38,7 @@
#include "vrf.h"
#include "mpls.h"
+#include "vty.h"
#include "zebra/zserv.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
@@ -172,6 +173,48 @@ netlink_to_zebra_link_type (unsigned int hwt)
}
}
+
+//Temporary Assignments to compile on older platforms.
+#ifndef IFLA_BR_MAX
+#define IFLA_BR_MAX 39
+#endif
+
+#ifndef IFLA_VXLAN_ID
+#define IFLA_VXLAN_ID 1
+#endif
+
+#ifndef IFLA_VXLAN_LOCAL
+#define IFLA_VXLAN_LOCAL 4
+#endif
+
+#ifndef IFLA_VXLAN_MAX
+#define IFLA_VXLAN_MAX 26
+#endif
+
+#ifndef IFLA_BRIDGE_MAX
+#define IFLA_BRIDGE_MAX 2
+#endif
+
+#ifndef IFLA_BRIDGE_VLAN_INFO
+#define IFLA_BRIDGE_VLAN_INFO 2
+#endif
+
+#ifndef BRIDGE_VLAN_INFO_PVID
+#define BRIDGE_VLAN_INFO_PVID (1<<1)
+#endif
+
+#ifndef RTEXT_FILTER_BRVLAN
+#define RTEXT_FILTER_BRVLAN (1<<1)
+#endif
+
+#ifndef NTF_SELF
+#define NTF_SELF 0x02
+#endif
+
+#ifndef IFLA_BR_VLAN_FILTERING
+#define IFLA_BR_VLAN_FILTERING 7
+#endif
+
#define parse_rtattr_nested(tb, max, rta) \
netlink_parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))
@@ -372,7 +415,6 @@ interface_lookup_netlink (struct zebra_ns *zns)
if (ret < 0)
return ret;
-#ifdef HAVE_IPV6
/* Get IPv6 address of the interfaces. */
ret = netlink_request (AF_INET6, RTM_GETADDR, &zns->netlink_cmd);
if (ret < 0)
@@ -380,7 +422,6 @@ interface_lookup_netlink (struct zebra_ns *zns)
ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0);
if (ret < 0)
return ret;
-#endif /* HAVE_IPV6 */
return 0;
}
@@ -434,7 +475,7 @@ netlink_address (int cmd, int family, struct interface *ifp,
addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
strlen (ifc->label) + 1);
- return netlink_talk (&req.n, &zns->netlink_cmd, zns);
+ return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns);
}
int
@@ -466,11 +507,7 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
zns = zebra_ns_lookup (ns_id);
ifa = NLMSG_DATA (h);
- if (ifa->ifa_family != AF_INET
-#ifdef HAVE_IPV6
- && ifa->ifa_family != AF_INET6
-#endif /* HAVE_IPV6 */
- )
+ if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6)
return 0;
if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
@@ -570,7 +607,6 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
(struct in_addr *) addr, ifa->ifa_prefixlen,
(struct in_addr *) broad);
}
-#ifdef HAVE_IPV6
if (ifa->ifa_family == AF_INET6)
{
if (h->nlmsg_type == RTM_NEWADDR)
@@ -588,7 +624,6 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
(struct in6_addr *) addr, ifa->ifa_prefixlen,
(struct in6_addr *) broad);
}
-#endif /* HAVE_IPV6 */
return 0;
}
diff --git a/zebra/interface.c b/zebra/interface.c
index 39c20e6289..5a9de5b70b 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -439,7 +439,6 @@ if_addr_wakeup (struct interface *ifp)
* from the kernel has been received.
* It will also be added to the interface's subnet list then. */
}
-#ifdef HAVE_IPV6
if (p->family == AF_INET6)
{
if (! if_is_up (ifp))
@@ -461,7 +460,6 @@ if_addr_wakeup (struct interface *ifp)
/* The address will be advertised to zebra clients when the notification
* from the kernel has been received. */
}
-#endif /* HAVE_IPV6 */
}
}
}
@@ -1060,10 +1058,8 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
vty_out (vty, " index %d metric %d mtu %d ",
ifp->ifindex, ifp->metric, ifp->mtu);
-#ifdef HAVE_IPV6
if (ifp->mtu6 != ifp->mtu)
vty_out (vty, "mtu6 %d ", ifp->mtu6);
-#endif
vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
if_flag_dump (ifp->flags), VTY_NEWLINE);
@@ -1107,7 +1103,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
int i;
struct if_link_params *iflp = ifp->link_params;
vty_out(vty, " Traffic Engineering Link Parameters:%s", VTY_NEWLINE);
- if (IS_PARAM_SET(iflp, LP_TE))
+ if (IS_PARAM_SET(iflp, LP_TE_METRIC))
vty_out(vty, " TE metric %u%s",iflp->te_metric, VTY_NEWLINE);
if (IS_PARAM_SET(iflp, LP_MAX_BW))
vty_out(vty, " Maximum Bandwidth %g (Byte/s)%s", iflp->max_bw, VTY_NEWLINE);
@@ -1237,39 +1233,6 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
#endif /* HAVE_NET_RT_IFLIST */
}
-/* Wrapper hook point for zebra daemon so that ifindex can be set
- * DEFUN macro not used as extract.pl HAS to ignore this
- * See also interface_cmd in lib/if.c
- */
-DEFUN_NOSH (zebra_interface,
- zebra_interface_cmd,
- "interface IFNAME",
- "Select an interface to configure\n"
- "Interface's name\n")
-{
- int ret;
-
- /* Call lib interface() */
- if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
- return ret;
-
- VTY_DECLVAR_CONTEXT (interface, ifp);
-
- if (ifp->ifindex == IFINDEX_INTERNAL)
- /* Is this really necessary? Shouldn't status be initialized to 0
- in that case? */
- UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
-
- return ret;
-}
-
-ALIAS (zebra_interface,
- zebra_interface_vrf_cmd,
- "interface IFNAME " VRF_CMD_STR,
- "Select an interface to configure\n"
- "Interface's name\n"
- VRF_CMD_HELP_STR)
-
static void
interface_update_stats (void)
{
@@ -1291,10 +1254,12 @@ struct cmd_node interface_node =
};
/* Show all interfaces to vty. */
-DEFUN (show_interface, show_interface_cmd,
- "show interface",
+DEFUN (show_interface,
+ show_interface_cmd,
+ "show interface [vrf NAME]",
SHOW_STR
- "Interface status and configuration\n")
+ "Interface status and configuration\n"
+ VRF_CMD_HELP_STR)
{
struct listnode *node;
struct interface *ifp;
@@ -1302,8 +1267,8 @@ DEFUN (show_interface, show_interface_cmd,
interface_update_stats ();
- if (argc > 0)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (argc > 2)
+ VRF_GET_ID (vrf_id, argv[3]->arg);
/* All interface print. */
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
@@ -1312,16 +1277,11 @@ DEFUN (show_interface, show_interface_cmd,
return CMD_SUCCESS;
}
-ALIAS (show_interface,
- show_interface_vrf_cmd,
- "show interface " VRF_CMD_STR,
- SHOW_STR
- "Interface status and configuration\n"
- VRF_CMD_HELP_STR)
/* Show all interfaces to vty. */
-DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
- "show interface " VRF_ALL_CMD_STR,
+DEFUN (show_interface_vrf_all,
+ show_interface_vrf_all_cmd,
+ "show interface vrf all",
SHOW_STR
"Interface status and configuration\n"
VRF_ALL_CMD_HELP_STR)
@@ -1344,25 +1304,26 @@ DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
DEFUN (show_interface_name_vrf,
show_interface_name_vrf_cmd,
- "show interface IFNAME " VRF_CMD_STR,
+ "show interface IFNAME vrf NAME",
SHOW_STR
"Interface status and configuration\n"
"Interface name\n"
VRF_CMD_HELP_STR)
{
+ int idx_ifname = 2;
+ int idx_name = 4;
struct interface *ifp;
vrf_id_t vrf_id = VRF_DEFAULT;
interface_update_stats ();
- if (argc > 1)
- VRF_GET_ID (vrf_id, argv[1]);
+ VRF_GET_ID (vrf_id, argv[idx_name]->arg);
/* Specified interface print. */
- ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
+ ifp = if_lookup_by_name_vrf (argv[idx_ifname]->arg, vrf_id);
if (ifp == NULL)
{
- vty_out (vty, "%% Can't find interface %s%s", argv[0],
+ vty_out (vty, "%% Can't find interface %s%s", argv[idx_ifname]->arg,
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1372,13 +1333,15 @@ DEFUN (show_interface_name_vrf,
}
/* Show specified interface to vty. */
-DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
- "show interface IFNAME " VRF_ALL_CMD_STR,
+DEFUN (show_interface_name_vrf_all,
+ show_interface_name_vrf_all_cmd,
+ "show interface IFNAME [vrf all]",
SHOW_STR
"Interface status and configuration\n"
"Interface name\n"
VRF_ALL_CMD_HELP_STR)
{
+ int idx_ifname = 2;
struct vrf *vrf;
struct interface *ifp;
int found = 0;
@@ -1389,7 +1352,7 @@ DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
/* Specified interface print. */
- ifp = if_lookup_by_name_vrf (argv[0], vrf->vrf_id);
+ ifp = if_lookup_by_name_vrf (argv[idx_ifname]->arg, vrf->vrf_id);
if (ifp)
{
if_dump_vty (vty, ifp);
@@ -1399,18 +1362,13 @@ DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
if (!found)
{
- vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
+ vty_out (vty, "%% Can't find interface %s%s", argv[idx_ifname]->arg, VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
-ALIAS (show_interface_name_vrf_all, show_interface_name_cmd,
- "show interface IFNAME",
- SHOW_STR
- "Interface status and configuration\n"
- "Interface name\n")
static void
if_show_description (struct vty *vty, vrf_id_t vrf_id)
@@ -1454,32 +1412,26 @@ if_show_description (struct vty *vty, vrf_id_t vrf_id)
DEFUN (show_interface_desc,
show_interface_desc_cmd,
- "show interface description",
+ "show interface description [vrf NAME]",
SHOW_STR
"Interface status and configuration\n"
- "Interface description\n")
+ "Interface description\n"
+ VRF_CMD_HELP_STR)
{
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 0)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (argc > 3)
+ VRF_GET_ID (vrf_id, argv[4]->arg);
if_show_description (vty, vrf_id);
return CMD_SUCCESS;
}
-ALIAS (show_interface_desc,
- show_interface_desc_vrf_cmd,
- "show interface description " VRF_CMD_STR,
- SHOW_STR
- "Interface status and configuration\n"
- "Interface description\n"
- VRF_CMD_HELP_STR)
DEFUN (show_interface_desc_vrf_all,
show_interface_desc_vrf_all_cmd,
- "show interface description " VRF_ALL_CMD_STR,
+ "show interface description vrf all",
SHOW_STR
"Interface status and configuration\n"
"Interface description\n"
@@ -1556,7 +1508,7 @@ DEFUN (linkdetect,
{
VTY_DECLVAR_CONTEXT (interface, ifp);
int if_was_operative;
-
+
if_was_operative = if_is_no_ptm_operative(ifp);
SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
@@ -1649,14 +1601,15 @@ DEFUN (no_shutdown_if,
DEFUN (bandwidth_if,
bandwidth_if_cmd,
- "bandwidth <1-100000>",
+ "bandwidth (1-100000)",
"Set bandwidth informational parameter\n"
"Bandwidth in megabits\n")
{
+ int idx_number = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
unsigned int bandwidth;
-
- bandwidth = strtol(argv[0], NULL, 10);
+
+ bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
/* bandwidth range is <1-100000> */
if (bandwidth < 1 || bandwidth > 100000)
@@ -1676,9 +1629,10 @@ DEFUN (bandwidth_if,
DEFUN (no_bandwidth_if,
no_bandwidth_if_cmd,
- "no bandwidth",
+ "no bandwidth [(1-100000)]",
NO_STR
- "Set bandwidth informational parameter\n")
+ "Set bandwidth informational parameter\n"
+ "Bandwidth in megabits\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
@@ -1691,12 +1645,6 @@ DEFUN (no_bandwidth_if,
return CMD_SUCCESS;
}
-ALIAS (no_bandwidth_if,
- no_bandwidth_if_val_cmd,
- "no bandwidth <1-100000>",
- NO_STR
- "Set bandwidth informational parameter\n"
- "Bandwidth in megabits\n")
struct cmd_node link_params_node =
{
@@ -1821,18 +1769,19 @@ DEFUN (no_link_params_enable,
/* STANDARD TE metrics */
DEFUN (link_params_metric,
link_params_metric_cmd,
- "metric <0-4294967295>",
+ "metric (0-4294967295)",
"Link metric for MPLS-TE purpose\n"
"Metric value in decimal\n")
{
+ int idx_number = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
u_int32_t metric;
- VTY_GET_ULONG("metric", metric, argv[0]);
+ VTY_GET_ULONG("metric", metric, argv[idx_number]->arg);
/* Update TE metric if needed */
- link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE | LP_TE_METRIC, metric);
+ link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE_METRIC, metric);
return CMD_SUCCESS;
}
@@ -1846,7 +1795,7 @@ DEFUN (no_link_params_metric,
VTY_DECLVAR_CONTEXT (interface, ifp);
/* Unset TE Metric */
- link_param_cmd_unset(ifp, LP_TE | LP_TE_METRIC);
+ link_param_cmd_unset(ifp, LP_TE_METRIC);
return CMD_SUCCESS;
}
@@ -1857,12 +1806,13 @@ DEFUN (link_params_maxbw,
"Maximum bandwidth that can be used\n"
"Bytes/second (IEEE floating point format)\n")
{
+ int idx_bandwidth = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
float bw;
- if (sscanf (argv[0], "%g", &bw) != 1)
+ if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
{
vty_out (vty, "link_params_maxbw: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -1901,11 +1851,12 @@ DEFUN (link_params_max_rsv_bw,
"Maximum bandwidth that may be reserved\n"
"Bytes/second (IEEE floating point format)\n")
{
+ int idx_bandwidth = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
float bw;
- if (sscanf (argv[0], "%g", &bw) != 1)
+ if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
{
vty_out (vty, "link_params_max_rsv_bw: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -1929,25 +1880,27 @@ DEFUN (link_params_max_rsv_bw,
DEFUN (link_params_unrsv_bw,
link_params_unrsv_bw_cmd,
- "unrsv-bw <0-7> BANDWIDTH",
+ "unrsv-bw (0-7) BANDWIDTH",
"Unreserved bandwidth at each priority level\n"
"Priority\n"
"Bytes/second (IEEE floating point format)\n")
{
+ int idx_number = 1;
+ int idx_bandwidth = 2;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
int priority;
float bw;
/* We don't have to consider about range check here. */
- if (sscanf (argv[0], "%d", &priority) != 1)
+ if (sscanf (argv[idx_number]->arg, "%d", &priority) != 1)
{
vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
return CMD_WARNING;
}
- if (sscanf (argv[1], "%g", &bw) != 1)
+ if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
{
vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -1975,11 +1928,12 @@ DEFUN (link_params_admin_grp,
"Administrative group membership\n"
"32-bit Hexadecimal value (e.g. 0xa1)\n")
{
+ int idx_bitpattern = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
unsigned long value;
- if (sscanf (argv[0], "0x%lx", &value) != 1)
+ if (sscanf (argv[idx_bitpattern]->arg, "0x%lx", &value) != 1)
{
vty_out (vty, "link_params_admin_grp: fscanf: %s%s",
safe_strerror (errno), VTY_NEWLINE);
@@ -2009,24 +1963,27 @@ DEFUN (no_link_params_admin_grp,
/* RFC5392 & RFC5316: INTER-AS */
DEFUN (link_params_inter_as,
link_params_inter_as_cmd,
- "neighbor A.B.C.D as <1-4294967295>",
+ "neighbor A.B.C.D as (1-4294967295)",
"Configure remote ASBR information (Neighbor IP address and AS number)\n"
"Remote IP address in dot decimal A.B.C.D\n"
"Remote AS number\n"
"AS number in the range <1-4294967295>\n")
{
+ int idx_ipv4 = 1;
+ int idx_number = 3;
+
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
struct in_addr addr;
u_int32_t as;
- if (!inet_aton (argv[0], &addr))
+ if (!inet_aton (argv[idx_ipv4]->arg, &addr))
{
vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
return CMD_WARNING;
}
- VTY_GET_ULONG("AS number", as, argv[1]);
+ VTY_GET_ULONG("AS number", as, argv[idx_number]->arg);
/* Update Remote IP and Remote AS fields if needed */
if (IS_PARAM_UNSET(iflp, LP_RMT_AS)
@@ -2069,78 +2026,77 @@ DEFUN (no_link_params_inter_as,
/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */
DEFUN (link_params_delay,
link_params_delay_cmd,
- "delay <0-16777215>",
+ "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
"Unidirectional Average Link Delay\n"
- "Average delay in micro-second as decimal (0...16777215)\n")
+ "Average delay in micro-second as decimal (0...16777215)\n"
+ "Minimum delay\n"
+ "Minimum delay in micro-second as decimal (0...16777215)\n"
+ "Maximum delay\n"
+ "Maximum delay in micro-second as decimal (0...16777215)\n")
{
+ /* Get and Check new delay values */
+ u_int32_t delay = 0, low = 0, high = 0;
+ VTY_GET_ULONG("delay", delay, argv[1]->arg);
+ if (argc == 6)
+ {
+ VTY_GET_ULONG("minimum delay", low, argv[3]->arg);
+ VTY_GET_ULONG("maximum delay", high, argv[5]->arg);
+ }
+
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
- u_int32_t delay = 0, low = 0, high = 0;
u_int8_t update = 0;
- /* Get and Check new delay values */
- VTY_GET_ULONG("delay", delay, argv[0]);
- switch (argc)
- {
- case 1:
- /* Check new delay value against old Min and Max delays if set */
- if (IS_PARAM_SET(iflp, LP_MM_DELAY)
- && (delay <= iflp->min_delay || delay >= iflp->max_delay))
- {
- vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
- iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
- return CMD_WARNING;
- }
- /* Update delay if value is not set or change */
- if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
- {
- iflp->av_delay = delay;
- SET_PARAM(iflp, LP_DELAY);
- update = 1;
- }
- /* Unset Min and Max delays if already set */
- if (IS_PARAM_SET(iflp, LP_MM_DELAY))
- {
- iflp->min_delay = 0;
- iflp->max_delay = 0;
- UNSET_PARAM(iflp, LP_MM_DELAY);
- update = 1;
- }
- break;
- case 2:
- vty_out (vty, "You should specify both Minimum and Maximum delay with Average delay%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- break;
- case 3:
- VTY_GET_ULONG("minimum delay", low, argv[1]);
- VTY_GET_ULONG("maximum delay", high, argv[2]);
- /* Check new delays value coherency */
- if (delay <= low || delay >= high)
- {
- vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
- low, high, VTY_NEWLINE);
- return CMD_WARNING;
- }
- /* Update Delays if needed */
- if (IS_PARAM_UNSET(iflp, LP_DELAY)
- || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
- || iflp->av_delay != delay
- || iflp->min_delay != low
- || iflp->max_delay != high)
- {
- iflp->av_delay = delay;
- SET_PARAM(iflp, LP_DELAY);
- iflp->min_delay = low;
- iflp->max_delay = high;
- SET_PARAM(iflp, LP_MM_DELAY);
- update = 1;
- }
- break;
- default:
- return CMD_WARNING;
- break;
- }
+ if (argc == 2)
+ {
+ /* Check new delay value against old Min and Max delays if set */
+ if (IS_PARAM_SET(iflp, LP_MM_DELAY)
+ && (delay <= iflp->min_delay || delay >= iflp->max_delay))
+ {
+ vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
+ iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ /* Update delay if value is not set or change */
+ if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
+ {
+ iflp->av_delay = delay;
+ SET_PARAM(iflp, LP_DELAY);
+ update = 1;
+ }
+ /* Unset Min and Max delays if already set */
+ if (IS_PARAM_SET(iflp, LP_MM_DELAY))
+ {
+ iflp->min_delay = 0;
+ iflp->max_delay = 0;
+ UNSET_PARAM(iflp, LP_MM_DELAY);
+ update = 1;
+ }
+ }
+ else
+ {
+ /* Check new delays value coherency */
+ if (delay <= low || delay >= high)
+ {
+ vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
+ low, high, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ /* Update Delays if needed */
+ if (IS_PARAM_UNSET(iflp, LP_DELAY)
+ || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
+ || iflp->av_delay != delay
+ || iflp->min_delay != low
+ || iflp->max_delay != high)
+ {
+ iflp->av_delay = delay;
+ SET_PARAM(iflp, LP_DELAY);
+ iflp->min_delay = low;
+ iflp->max_delay = high;
+ SET_PARAM(iflp, LP_MM_DELAY);
+ update = 1;
+ }
+ }
/* force protocols to update LINK STATE due to parameters change */
if (update == 1 && if_is_operative (ifp))
@@ -2149,16 +2105,6 @@ DEFUN (link_params_delay,
return CMD_SUCCESS;
}
-ALIAS (link_params_delay,
- link_params_delay_mm_cmd,
- "delay <0-16777215> min <0-16777215> max <0-16777215>",
- "Unidirectional Average Link Delay (optionally Minimum and Maximum delays)\n"
- "Average delay in micro-second as decimal (0...16777215)\n"
- "Minimum delay\n"
- "Minimum delay in micro-second as decimal (0...16777215)\n"
- "Maximum delay\n"
- "Maximum delay in micro-second as decimal (0...16777215)\n")
-
DEFUN (no_link_params_delay,
no_link_params_delay_cmd,
"no delay",
@@ -2184,15 +2130,16 @@ DEFUN (no_link_params_delay,
DEFUN (link_params_delay_var,
link_params_delay_var_cmd,
- "delay-variation <0-16777215>",
+ "delay-variation (0-16777215)",
"Unidirectional Link Delay Variation\n"
"delay variation in micro-second as decimal (0...16777215)\n")
{
+ int idx_number = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
u_int32_t value;
- VTY_GET_ULONG("delay variation", value, argv[0]);
+ VTY_GET_ULONG("delay variation", value, argv[idx_number]->arg);
/* Update Delay Variation if needed */
link_param_cmd_set_uint32 (ifp, &iflp->delay_var, LP_DELAY_VAR, value);
@@ -2220,11 +2167,12 @@ DEFUN (link_params_pkt_loss,
"Unidirectional Link Packet Loss\n"
"percentage of total traffic by 0.000003% step and less than 50.331642%\n")
{
+ int idx_percentage = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
float fval;
- if (sscanf (argv[0], "%g", &fval) != 1)
+ if (sscanf (argv[idx_percentage]->arg, "%g", &fval) != 1)
{
vty_out (vty, "link_params_pkt_loss: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -2260,11 +2208,12 @@ DEFUN (link_params_res_bw,
"Unidirectional Residual Bandwidth\n"
"Bytes/second (IEEE floating point format)\n")
{
+ int idx_bandwidth = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
float bw;
- if (sscanf (argv[0], "%g", &bw) != 1)
+ if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
{
vty_out (vty, "link_params_res_bw: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -2306,11 +2255,12 @@ DEFUN (link_params_ava_bw,
"Unidirectional Available Bandwidth\n"
"Bytes/second (IEEE floating point format)\n")
{
+ int idx_bandwidth = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
float bw;
- if (sscanf (argv[0], "%g", &bw) != 1)
+ if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
{
vty_out (vty, "link_params_ava_bw: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -2352,11 +2302,12 @@ DEFUN (link_params_use_bw,
"Unidirectional Utilised Bandwidth\n"
"Bytes/second (IEEE floating point format)\n")
{
+ int idx_bandwidth = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct if_link_params *iflp = if_link_params_get (ifp);
float bw;
- if (sscanf (argv[0], "%g", &bw) != 1)
+ if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
{
vty_out (vty, "link_params_use_bw: fscanf: %s%s", safe_strerror (errno),
VTY_NEWLINE);
@@ -2540,8 +2491,9 @@ DEFUN (ip_address,
"Set the IP address of an interface\n"
"IP address (e.g. 10.0.0.1/8)\n")
{
+ int idx_ipv4_prefixlen = 2;
VTY_DECLVAR_CONTEXT (interface, ifp);
- return ip_address_install (vty, ifp, argv[0], NULL, NULL);
+ return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
}
DEFUN (no_ip_address,
@@ -2552,8 +2504,9 @@ DEFUN (no_ip_address,
"Set the IP address of an interface\n"
"IP Address (e.g. 10.0.0.1/8)")
{
+ int idx_ipv4_prefixlen = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
- return ip_address_uninstall (vty, ifp, argv[0], NULL, NULL);
+ return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
}
@@ -2567,8 +2520,10 @@ DEFUN (ip_address_label,
"Label of this address\n"
"Label\n")
{
+ int idx_ipv4_prefixlen = 2;
+ int idx_line = 4;
VTY_DECLVAR_CONTEXT (interface, ifp);
- return ip_address_install (vty, ifp, argv[0], NULL, argv[1]);
+ return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
}
DEFUN (no_ip_address_label,
@@ -2581,12 +2536,13 @@ DEFUN (no_ip_address_label,
"Label of this address\n"
"Label\n")
{
+ int idx_ipv4_prefixlen = 3;
+ int idx_line = 5;
VTY_DECLVAR_CONTEXT (interface, ifp);
- return ip_address_uninstall (vty, ifp, argv[0], NULL, argv[1]);
+ return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
}
#endif /* HAVE_NETLINK */
-#ifdef HAVE_IPV6
static int
ipv6_address_install (struct vty *vty, struct interface *ifp,
const char *addr_str, const char *peer_str,
@@ -2745,8 +2701,9 @@ DEFUN (ipv6_address,
"Set the IP address of an interface\n"
"IPv6 address (e.g. 3ffe:506::1/48)\n")
{
+ int idx_ipv6_prefixlen = 2;
VTY_DECLVAR_CONTEXT (interface, ifp);
- return ipv6_address_install (vty, ifp, argv[0], NULL, NULL, 0);
+ return ipv6_address_install (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
}
DEFUN (no_ipv6_address,
@@ -2757,10 +2714,10 @@ DEFUN (no_ipv6_address,
"Set the IP address of an interface\n"
"IPv6 address (e.g. 3ffe:506::1/48)\n")
{
+ int idx_ipv6_prefixlen = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
- return ipv6_address_uninstall (vty, ifp, argv[0], NULL, NULL, 0);
+ return ipv6_address_uninstall (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
}
-#endif /* HAVE_IPV6 */
static int
link_params_config_write (struct vty *vty, struct interface *ifp)
@@ -2774,7 +2731,7 @@ link_params_config_write (struct vty *vty, struct interface *ifp)
vty_out (vty, " link-params%s", VTY_NEWLINE);
vty_out(vty, " enable%s", VTY_NEWLINE);
- if (IS_PARAM_SET(iflp, LP_TE) && IS_PARAM_SET(iflp, LP_TE_METRIC))
+ if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
vty_out(vty, " metric %u%s",iflp->te_metric, VTY_NEWLINE);
if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
vty_out(vty, " max-bw %g%s", iflp->max_bw, VTY_NEWLINE);
@@ -2914,23 +2871,15 @@ zebra_if_init (void)
/* Install configuration write function. */
install_node (&interface_node, if_config_write);
install_node (&link_params_node, NULL);
+ if_cmd_init ();
install_element (VIEW_NODE, &show_interface_cmd);
- install_element (VIEW_NODE, &show_interface_vrf_cmd);
install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
- install_element (VIEW_NODE, &show_interface_name_cmd);
install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
+
install_element (ENABLE_NODE, &show_interface_desc_cmd);
- install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd);
install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
- install_element (CONFIG_NODE, &zebra_interface_cmd);
- install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
- install_element (CONFIG_NODE, &no_interface_cmd);
- install_element (CONFIG_NODE, &no_interface_vrf_cmd);
- install_default (INTERFACE_NODE);
- install_element (INTERFACE_NODE, &interface_desc_cmd);
- install_element (INTERFACE_NODE, &no_interface_desc_cmd);
install_element (INTERFACE_NODE, &multicast_cmd);
install_element (INTERFACE_NODE, &no_multicast_cmd);
install_element (INTERFACE_NODE, &linkdetect_cmd);
@@ -2939,13 +2888,10 @@ zebra_if_init (void)
install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
install_element (INTERFACE_NODE, &bandwidth_if_cmd);
install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
- install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
install_element (INTERFACE_NODE, &ip_address_cmd);
install_element (INTERFACE_NODE, &no_ip_address_cmd);
-#ifdef HAVE_IPV6
install_element (INTERFACE_NODE, &ipv6_address_cmd);
install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
-#endif /* HAVE_IPV6 */
#ifdef HAVE_NETLINK
install_element (INTERFACE_NODE, &ip_address_label_cmd);
install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
@@ -2955,6 +2901,7 @@ zebra_if_init (void)
install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
+ install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
@@ -2964,7 +2911,6 @@ zebra_if_init (void)
install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_delay_mm_cmd);
install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
diff --git a/zebra/ioctl.c b/zebra/ioctl.c
index f91ee2438d..1125043310 100644
--- a/zebra/ioctl.c
+++ b/zebra/ioctl.c
@@ -29,6 +29,7 @@
#include "log.h"
#include "privs.h"
+#include "vty.h"
#include "zebra/rib.h"
#include "zebra/rt.h"
#include "zebra/interface.h"
@@ -79,7 +80,6 @@ if_ioctl (u_long request, caddr_t buffer)
return 0;
}
-#ifdef HAVE_IPV6
static int
if_ioctl_ipv6 (u_long request, caddr_t buffer)
{
@@ -113,7 +113,6 @@ if_ioctl_ipv6 (u_long request, caddr_t buffer)
}
return 0;
}
-#endif /* HAVE_IPV6 */
/*
* get interface metric
@@ -436,8 +435,6 @@ if_unset_flags (struct interface *ifp, uint64_t flags)
return 0;
}
-#ifdef HAVE_IPV6
-
#ifdef LINUX_IPV6
#ifndef _LINUX_IN6_H
/* linux/include/net/ipv6.h */
@@ -593,5 +590,3 @@ if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc)
#endif /* HAVE_STRUCT_IN6_ALIASREQ */
#endif /* LINUX_IPV6 */
-
-#endif /* HAVE_IPV6 */
diff --git a/zebra/ioctl.h b/zebra/ioctl.h
index fee9b725c4..9e3fd5b3fb 100644
--- a/zebra/ioctl.h
+++ b/zebra/ioctl.h
@@ -37,10 +37,8 @@ extern int if_unset_prefix (struct interface *, struct connected *);
extern void if_get_metric (struct interface *);
extern void if_get_mtu (struct interface *);
-#ifdef HAVE_IPV6
extern int if_prefix_add_ipv6 (struct interface *, struct connected *);
extern int if_prefix_delete_ipv6 (struct interface *, struct connected *);
-#endif /* HAVE_IPV6 */
#ifdef SOLARIS_IPV6
extern int if_ioctl_ipv6(u_long, caddr_t);
diff --git a/zebra/ioctl_solaris.c b/zebra/ioctl_solaris.c
index b5bf1ccb0a..1de583577d 100644
--- a/zebra/ioctl_solaris.c
+++ b/zebra/ioctl_solaris.c
@@ -85,7 +85,6 @@ if_ioctl (u_long request, caddr_t buffer)
int
if_ioctl_ipv6 (u_long request, caddr_t buffer)
{
-#ifdef HAVE_IPV6
int sock;
int ret;
int err;
@@ -117,7 +116,6 @@ if_ioctl_ipv6 (u_long request, caddr_t buffer)
errno = err;
return ret;
}
-#endif /* HAVE_IPV6 */
return 0;
}
@@ -177,7 +175,6 @@ if_get_mtu (struct interface *ifp)
}
}
-#ifdef HAVE_IPV6
if (ifp->flags & IFF_IPV6)
{
memset(&lifreq, 0, sizeof(lifreq));
@@ -195,7 +192,6 @@ if_get_mtu (struct interface *ifp)
changed = 1;
}
}
-#endif /* HAVE_IPV6 */
if (changed)
zebra_interface_up_update(ifp);
@@ -403,8 +399,6 @@ if_unset_flags (struct interface *ifp, uint64_t flags)
return ret;
}
-#ifdef HAVE_IPV6
-
/* Interface's address add/delete functions. */
int
if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc)
@@ -431,5 +425,3 @@ if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc)
return 0;
}
-
-#endif /* HAVE_IPV6 */
diff --git a/zebra/ipforward.h b/zebra/ipforward.h
index 8a935c139f..a75073cb36 100644
--- a/zebra/ipforward.h
+++ b/zebra/ipforward.h
@@ -26,10 +26,8 @@ extern int ipforward (void);
extern int ipforward_on (void);
extern int ipforward_off (void);
-#ifdef HAVE_IPV6
extern int ipforward_ipv6 (void);
extern int ipforward_ipv6_on (void);
extern int ipforward_ipv6_off (void);
-#endif /* HAVE_IPV6 */
#endif /* _ZEBRA_IPFORWARD_H */
diff --git a/zebra/ipforward_proc.c b/zebra/ipforward_proc.c
index 2876eded37..910fd61d06 100644
--- a/zebra/ipforward_proc.c
+++ b/zebra/ipforward_proc.c
@@ -123,7 +123,6 @@ ipforward_off (void)
return ipforward ();
}
-#ifdef HAVE_IPV6
char proc_ipv6_forwarding[] = "/proc/sys/net/ipv6/conf/all/forwarding";
@@ -152,7 +151,7 @@ ipforward_ipv6_on (void)
FILE *fp;
if ( zserv_privs.change(ZPRIVS_RAISE) )
- zlog_err ("Can't raise privileges, %s", safe_strerror (errno));
+ zlog_err ("Can't raise privileges, %s", safe_strerror (errno));
fp = fopen (proc_ipv6_forwarding, "w");
@@ -172,13 +171,14 @@ ipforward_ipv6_on (void)
return ipforward_ipv6 ();
}
+
int
ipforward_ipv6_off (void)
{
FILE *fp;
if ( zserv_privs.change(ZPRIVS_RAISE) )
- zlog_err ("Can't raise privileges, %s", safe_strerror (errno));
+ zlog_err ("Can't raise privileges, %s", safe_strerror (errno));
fp = fopen (proc_ipv6_forwarding, "w");
@@ -197,4 +197,3 @@ ipforward_ipv6_off (void)
return ipforward_ipv6 ();
}
-#endif /* HAVE_IPV6 */
diff --git a/zebra/ipforward_solaris.c b/zebra/ipforward_solaris.c
index 4aa1b797af..8eccfe133c 100644
--- a/zebra/ipforward_solaris.c
+++ b/zebra/ipforward_solaris.c
@@ -145,7 +145,6 @@ ipforward_off (void)
(void) solaris_nd_set("ip_forwarding", 0);
return ipforward();
}
-#ifdef HAVE_IPV6
int ipforward_ipv6(void)
{
return solaris_nd_get("ip6_forwarding");
@@ -162,4 +161,3 @@ ipforward_ipv6_off (void)
(void) solaris_nd_set("ip6_forwarding", 0);
return ipforward_ipv6();
}
-#endif /* HAVE_IPV6 */
diff --git a/zebra/ipforward_sysctl.c b/zebra/ipforward_sysctl.c
index 57ed185785..be4c9cd99c 100644
--- a/zebra/ipforward_sysctl.c
+++ b/zebra/ipforward_sysctl.c
@@ -95,8 +95,6 @@ ipforward_off (void)
return ipforwarding;
}
-#ifdef HAVE_IPV6
-
/* IPv6 forwarding control MIB. */
int mib_ipv6[MIB_SIZ] =
{
@@ -173,4 +171,3 @@ ipforward_ipv6_off (void)
zlog (NULL, LOG_ERR, "Can't lower privileges");
return ip6forwarding;
}
-#endif /* HAVE_IPV6 */
diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c
index 9d8c2e67bf..5cabe7e62f 100644
--- a/zebra/irdp_interface.c
+++ b/zebra/irdp_interface.c
@@ -18,17 +18,17 @@
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
-/*
+/*
* This work includes work with the following copywrite:
*
* Copyright (C) 1997, 2000 Kunihiro Ishiguro
*
*/
-/*
+/*
* Thanks to Jens Låås at Swedish University of Agricultural Sciences
* for reviewing and tests.
*/
@@ -36,7 +36,7 @@
#include <zebra.h>
-#ifdef HAVE_IRDP
+#ifdef HAVE_IRDP
#include "if.h"
#include "vty.h"
@@ -81,7 +81,7 @@ irdp_get_prefix(struct interface *ifp)
{
struct listnode *node;
struct connected *ifc;
-
+
if (ifp->connected)
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
return ifc->address;
@@ -91,9 +91,9 @@ irdp_get_prefix(struct interface *ifp)
/* Join to the add/leave multicast group. */
static int
-if_group (struct interface *ifp,
- int sock,
- u_int32_t group,
+if_group (struct interface *ifp,
+ int sock,
+ u_int32_t group,
int add_leave)
{
struct ip_mreq m;
@@ -116,7 +116,7 @@ if_group (struct interface *ifp,
(char *) &m, sizeof (struct ip_mreq));
if (ret < 0)
zlog_warn ("IRDP: %s can't setsockopt %s: %s",
- add_leave == IP_ADD_MEMBERSHIP? "join group":"leave group",
+ add_leave == IP_ADD_MEMBERSHIP? "join group":"leave group",
inet_2a(group, b1),
safe_strerror (errno));
@@ -137,7 +137,7 @@ if_add_group (struct interface *ifp)
}
if(irdp->flags & IF_DEBUG_MISC )
- zlog_debug("IRDP: Adding group %s for %s",
+ zlog_debug("IRDP: Adding group %s for %s",
inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1),
ifp->name);
return 0;
@@ -156,7 +156,7 @@ if_drop_group (struct interface *ifp)
return ret;
if(irdp->flags & IF_DEBUG_MISC)
- zlog_debug("IRDP: Leaving group %s for %s",
+ zlog_debug("IRDP: Leaving group %s for %s",
inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1),
ifp->name);
return 0;
@@ -206,7 +206,7 @@ irdp_if_start(struct interface *ifp, int multicast, int set_defaults)
}
irdp->flags |= IF_ACTIVE;
- if(!multicast)
+ if(!multicast)
irdp->flags |= IF_BROADCAST;
if_add_update(ifp);
@@ -219,13 +219,13 @@ irdp_if_start(struct interface *ifp, int multicast, int set_defaults)
if( multicast) {
if_add_group(ifp);
-
+
if (! (ifp->flags & (IFF_MULTICAST|IFF_ALLMULTI))) {
zlog_warn("IRDP: Interface not multicast enabled %s", ifp->name);
}
}
- if(set_defaults)
+ if(set_defaults)
if_set_defaults(ifp);
irdp->irdp_sent = 0;
@@ -239,9 +239,9 @@ irdp_if_start(struct interface *ifp, int multicast, int set_defaults)
seed = ifc->address->u.prefix4.s_addr;
break;
}
-
+
srandom(seed);
- timer = (random () % IRDP_DEFAULT_INTERVAL) + 1;
+ timer = (random () % IRDP_DEFAULT_INTERVAL) + 1;
irdp->AdvPrefList = list_new();
irdp->AdvPrefList->del = (void (*)(void *)) Adv_free; /* Destructor */
@@ -250,18 +250,18 @@ irdp_if_start(struct interface *ifp, int multicast, int set_defaults)
/* And this for startup. Speed limit from 1991 :-). But it's OK*/
if(irdp->irdp_sent < MAX_INITIAL_ADVERTISEMENTS &&
- timer > MAX_INITIAL_ADVERT_INTERVAL )
+ timer > MAX_INITIAL_ADVERT_INTERVAL )
timer= MAX_INITIAL_ADVERT_INTERVAL;
-
+
if(irdp->flags & IF_DEBUG_MISC)
- zlog_debug("IRDP: Init timer for %s set to %u",
- ifp->name,
+ zlog_debug("IRDP: Init timer for %s set to %u",
+ ifp->name,
timer);
- irdp->t_advertise = thread_add_timer(zebrad.master,
- irdp_send_thread,
- ifp,
+ irdp->t_advertise = thread_add_timer(zebrad.master,
+ irdp_send_thread,
+ ifp,
timer);
}
@@ -270,7 +270,7 @@ irdp_if_stop(struct interface *ifp)
{
struct zebra_if *zi=ifp->info;
struct irdp_interface *irdp=&zi->irdp;
-
+
if (irdp == NULL) {
zlog_warn ("Interface %s structure is NULL", ifp->name);
return;
@@ -281,7 +281,7 @@ irdp_if_stop(struct interface *ifp)
return;
}
- if(! (irdp->flags & IF_BROADCAST))
+ if(! (irdp->flags & IF_BROADCAST))
if_drop_group(ifp);
irdp_advert_off(ifp);
@@ -307,9 +307,9 @@ irdp_if_shutdown(struct interface *ifp)
irdp->flags |= IF_SHUTDOWN;
irdp->flags &= ~IF_ACTIVE;
- if(! (irdp->flags & IF_BROADCAST))
+ if(! (irdp->flags & IF_BROADCAST))
if_drop_group(ifp);
-
+
/* Tell the hosts we are out of service */
irdp_advert_off(ifp);
}
@@ -327,7 +327,7 @@ irdp_if_no_shutdown(struct interface *ifp)
irdp->flags &= ~IF_SHUTDOWN;
- irdp_if_start(ifp, irdp->flags & IF_BROADCAST? FALSE : TRUE, FALSE);
+ irdp_if_start(ifp, irdp->flags & IF_BROADCAST? FALSE : TRUE, FALSE);
}
@@ -344,30 +344,30 @@ void irdp_config_write (struct vty *vty, struct interface *ifp)
if(irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) {
- if( irdp->flags & IF_SHUTDOWN)
+ if( irdp->flags & IF_SHUTDOWN)
vty_out (vty, " ip irdp shutdown %s", VTY_NEWLINE);
- if( irdp->flags & IF_BROADCAST)
+ if( irdp->flags & IF_BROADCAST)
vty_out (vty, " ip irdp broadcast%s", VTY_NEWLINE);
- else
+ else
vty_out (vty, " ip irdp multicast%s", VTY_NEWLINE);
- vty_out (vty, " ip irdp preference %ld%s",
+ vty_out (vty, " ip irdp preference %ld%s",
irdp->Preference, VTY_NEWLINE);
for (ALL_LIST_ELEMENTS_RO (irdp->AdvPrefList, node, adv))
vty_out (vty, " ip irdp address %s preference %d%s",
inet_2a(adv->ip.s_addr, b1),
- adv->pref,
+ adv->pref,
VTY_NEWLINE);
- vty_out (vty, " ip irdp holdtime %d%s",
+ vty_out (vty, " ip irdp holdtime %d%s",
irdp->Lifetime, VTY_NEWLINE);
- vty_out (vty, " ip irdp minadvertinterval %ld%s",
+ vty_out (vty, " ip irdp minadvertinterval %ld%s",
irdp->MinAdvertInterval, VTY_NEWLINE);
- vty_out (vty, " ip irdp maxadvertinterval %ld%s",
+ vty_out (vty, " ip irdp maxadvertinterval %ld%s",
irdp->MaxAdvertInterval, VTY_NEWLINE);
}
@@ -378,7 +378,8 @@ DEFUN (ip_irdp_multicast,
ip_irdp_multicast_cmd,
"ip irdp multicast",
IP_STR
- "ICMP Router discovery on this interface using multicast\n")
+ "ICMP Router discovery on this interface\n"
+ "Use multicast mode\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
@@ -390,7 +391,8 @@ DEFUN (ip_irdp_broadcast,
ip_irdp_broadcast_cmd,
"ip irdp broadcast",
IP_STR
- "ICMP Router discovery on this interface using broadcast\n")
+ "ICMP Router discovery on this interface\n"
+ "Use broadcast mode\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
@@ -415,6 +417,7 @@ DEFUN (ip_irdp_shutdown,
ip_irdp_shutdown_cmd,
"ip irdp shutdown",
IP_STR
+ "ICMP Router discovery on this interface\n"
"ICMP Router discovery shutdown on this interface\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
@@ -428,6 +431,7 @@ DEFUN (no_ip_irdp_shutdown,
"no ip irdp shutdown",
NO_STR
IP_STR
+ "ICMP Router discovery on this interface\n"
"ICMP Router discovery no shutdown on this interface\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
@@ -438,12 +442,13 @@ DEFUN (no_ip_irdp_shutdown,
DEFUN (ip_irdp_holdtime,
ip_irdp_holdtime_cmd,
- "ip irdp holdtime <0-9000>",
+ "ip irdp holdtime (0-9000)",
IP_STR
"ICMP Router discovery on this interface\n"
"Set holdtime value\n"
"Holdtime value in seconds. Default is 1800 seconds\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zi;
struct irdp_interface *irdp;
@@ -451,18 +456,19 @@ DEFUN (ip_irdp_holdtime,
zi=ifp->info;
irdp=&zi->irdp;
- irdp->Lifetime = atoi(argv[0]);
+ irdp->Lifetime = atoi(argv[idx_number]->arg);
return CMD_SUCCESS;
}
DEFUN (ip_irdp_minadvertinterval,
ip_irdp_minadvertinterval_cmd,
- "ip irdp minadvertinterval <3-1800>",
+ "ip irdp minadvertinterval (3-1800)",
IP_STR
"ICMP Router discovery on this interface\n"
"Set minimum time between advertisement\n"
"Minimum advertisement interval in seconds\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zi;
struct irdp_interface *irdp;
@@ -470,28 +476,29 @@ DEFUN (ip_irdp_minadvertinterval,
zi=ifp->info;
irdp=&zi->irdp;
- if( (unsigned) atoi(argv[0]) <= irdp->MaxAdvertInterval) {
- irdp->MinAdvertInterval = atoi(argv[0]);
+ if( (unsigned) atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) {
+ irdp->MinAdvertInterval = atoi(argv[idx_number]->arg);
return CMD_SUCCESS;
}
- vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s",
+ vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s",
VTY_NEWLINE);
- vty_out (vty, "Please correct!%s",
+ vty_out (vty, "Please correct!%s",
VTY_NEWLINE);
return CMD_WARNING;
}
DEFUN (ip_irdp_maxadvertinterval,
ip_irdp_maxadvertinterval_cmd,
- "ip irdp maxadvertinterval <4-1800>",
+ "ip irdp maxadvertinterval (4-1800)",
IP_STR
"ICMP Router discovery on this interface\n"
"Set maximum time between advertisement\n"
"Maximum advertisement interval in seconds\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zi;
struct irdp_interface *irdp;
@@ -500,16 +507,16 @@ DEFUN (ip_irdp_maxadvertinterval,
irdp=&zi->irdp;
- if( irdp->MinAdvertInterval <= (unsigned) atoi(argv[0]) ) {
- irdp->MaxAdvertInterval = atoi(argv[0]);
+ if( irdp->MinAdvertInterval <= (unsigned) atoi(argv[idx_number]->arg) ) {
+ irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg);
return CMD_SUCCESS;
}
- vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s",
+ vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s",
VTY_NEWLINE);
- vty_out (vty, "Please correct!%s",
+ vty_out (vty, "Please correct!%s",
VTY_NEWLINE);
return CMD_WARNING;
}
@@ -521,12 +528,13 @@ DEFUN (ip_irdp_maxadvertinterval,
DEFUN (ip_irdp_preference,
ip_irdp_preference_cmd,
- "ip irdp preference <0-2147483647>",
+ "ip irdp preference (0-2147483647)",
IP_STR
"ICMP Router discovery on this interface\n"
"Set default preference level for this interface\n"
"Preference level\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zi;
struct irdp_interface *irdp;
@@ -534,22 +542,25 @@ DEFUN (ip_irdp_preference,
zi=ifp->info;
irdp=&zi->irdp;
- irdp->Preference = atoi(argv[0]);
+ irdp->Preference = atoi(argv[idx_number]->arg);
return CMD_SUCCESS;
}
DEFUN (ip_irdp_address_preference,
ip_irdp_address_preference_cmd,
- "ip irdp address A.B.C.D preference <0-2147483647>",
+ "ip irdp address A.B.C.D preference (0-2147483647)",
IP_STR
- "Alter ICMP Router discovery preference this interface\n"
- "Specify IRDP non-default preference to advertise\n"
+ "Alter ICMP Router discovery preference on this interface\n"
"Set IRDP address for advertise\n"
+ "IPv4 address\n"
+ "Specify IRDP non-default preference to advertise\n"
"Preference level\n")
{
+ int idx_ipv4 = 3;
+ int idx_number = 5;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct listnode *node;
- struct in_addr ip;
+ struct in_addr ip;
int pref;
int ret;
struct zebra_if *zi;
@@ -559,13 +570,13 @@ DEFUN (ip_irdp_address_preference,
zi=ifp->info;
irdp=&zi->irdp;
- ret = inet_aton(argv[0], &ip);
+ ret = inet_aton(argv[idx_ipv4]->arg, &ip);
if(!ret) return CMD_WARNING;
- pref = atoi(argv[1]);
+ pref = atoi(argv[idx_number]->arg);
for (ALL_LIST_ELEMENTS_RO (irdp->AdvPrefList, node, adv))
- if(adv->ip.s_addr == ip.s_addr)
+ if(adv->ip.s_addr == ip.s_addr)
return CMD_SUCCESS;
adv = Adv_new();
@@ -579,17 +590,19 @@ DEFUN (ip_irdp_address_preference,
DEFUN (no_ip_irdp_address_preference,
no_ip_irdp_address_preference_cmd,
- "no ip irdp address A.B.C.D preference <0-2147483647>",
+ "no ip irdp address A.B.C.D preference (0-2147483647)",
NO_STR
IP_STR
- "Alter ICMP Router discovery preference this interface\n"
- "Removes IRDP non-default preference\n"
+ "Alter ICMP Router discovery preference on this interface\n"
"Select IRDP address\n"
+ "IPv4 address\n"
+ "Reset ICMP Router discovery preference on this interface\n"
"Old preference level\n")
{
+ int idx_ipv4 = 4;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct listnode *node, *nnode;
- struct in_addr ip;
+ struct in_addr ip;
int ret;
struct zebra_if *zi;
struct irdp_interface *irdp;
@@ -598,8 +611,8 @@ DEFUN (no_ip_irdp_address_preference,
zi=ifp->info;
irdp=&zi->irdp;
- ret = inet_aton(argv[0], &ip);
- if (!ret)
+ ret = inet_aton(argv[idx_ipv4]->arg, &ip);
+ if (!ret)
return CMD_WARNING;
for (ALL_LIST_ELEMENTS (irdp->AdvPrefList, node, nnode, adv))
@@ -610,7 +623,7 @@ DEFUN (no_ip_irdp_address_preference,
break;
}
}
-
+
return CMD_SUCCESS;
}
@@ -618,7 +631,9 @@ DEFUN (ip_irdp_debug_messages,
ip_irdp_debug_messages_cmd,
"ip irdp debug messages",
IP_STR
- "ICMP Router discovery debug Averts. and Solicits (short)\n")
+ "ICMP Router discovery debug Averts. and Solicits (short)\n"
+ "IRDP debugging options\n"
+ "Enable debugging for IRDP messages\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zi;
@@ -636,7 +651,9 @@ DEFUN (ip_irdp_debug_misc,
ip_irdp_debug_misc_cmd,
"ip irdp debug misc",
IP_STR
- "ICMP Router discovery debug Averts. and Solicits (short)\n")
+ "ICMP Router discovery debug Averts. and Solicits (short)\n"
+ "IRDP debugging options\n"
+ "Enable debugging for miscellaneous IRDP events\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zi;
@@ -654,7 +671,9 @@ DEFUN (ip_irdp_debug_packet,
ip_irdp_debug_packet_cmd,
"ip irdp debug packet",
IP_STR
- "ICMP Router discovery debug Averts. and Solicits (short)\n")
+ "ICMP Router discovery debug Averts. and Solicits (short)\n"
+ "IRDP debugging options\n"
+ "Enable debugging for IRDP packets\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zi;
@@ -673,7 +692,9 @@ DEFUN (ip_irdp_debug_disable,
ip_irdp_debug_disable_cmd,
"ip irdp debug disable",
IP_STR
- "ICMP Router discovery debug Averts. and Solicits (short)\n")
+ "ICMP Router discovery debug Averts. and Solicits (short)\n"
+ "IRDP debugging options\n"
+ "Disable debugging for all IRDP events\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zi;
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 9f9a62f384..058d14481e 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -63,6 +63,14 @@
((struct rtattr *) (((u_char *) (rta)) + RTA_ALIGN((rta)->rta_len)))
#endif
+#ifndef RTNL_FAMILY_IP6MR
+#define RTNL_FAMILY_IP6MR 129
+#endif
+
+#ifndef RTPROT_MROUTED
+#define RTPROT_MROUTED 17
+#endif
+
static const struct message nlmsg_str[] = {
{RTM_NEWROUTE, "RTM_NEWROUTE"},
{RTM_DELROUTE, "RTM_DELROUTE"},
@@ -91,15 +99,31 @@ static const struct message rtproto_str[] = {
#ifdef RTPROT_BIRD
{RTPROT_BIRD, "BIRD"},
#endif /* RTPROT_BIRD */
+ {RTPROT_MROUTED, "mroute"},
{0, NULL}
};
+static const struct message family_str[] = {
+ {AF_INET, "ipv4"},
+ {AF_INET6, "ipv6"},
+ {AF_BRIDGE, "bridge"},
+ {RTNL_FAMILY_IPMR, "ipv4MR"},
+ {RTNL_FAMILY_IP6MR, "ipv6MR"},
+ {0, NULL},
+};
+
+static const struct message rttype_str[] = {
+ {RTN_UNICAST, "unicast"},
+ {RTN_MULTICAST, "multicast"},
+ {0, NULL},
+};
+
extern struct thread_master *master;
extern u_int32_t nl_rcvbufsize;
extern struct zebra_privs_t zserv_privs;
-static int
+int
netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h,
ns_id_t ns_id)
{
@@ -321,7 +345,12 @@ addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type,
rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
rta->rta_type = type;
rta->rta_len = len;
- memcpy (RTA_DATA (rta), data, alen);
+
+ if (data)
+ memcpy (RTA_DATA (rta), data, alen);
+ else
+ assert (alen == 0);
+
n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len);
return 0;
@@ -342,7 +371,12 @@ rta_addattr_l (struct rtattr *rta, unsigned int maxlen, int type,
subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
subrta->rta_type = type;
subrta->rta_len = len;
- memcpy (RTA_DATA (subrta), data, alen);
+
+ if (data)
+ memcpy (RTA_DATA (subrta), data, alen);
+ else
+ assert (alen == 0);
+
rta->rta_len = NLMSG_ALIGN (rta->rta_len) + RTA_ALIGN (len);
return 0;
@@ -397,6 +431,19 @@ nl_rtproto_to_str (u_char rtproto)
{
return lookup (rtproto_str, rtproto);
}
+
+const char *
+nl_family_to_str (u_char family)
+{
+ return lookup (family_str, family);
+}
+
+const char *
+nl_rttype_to_str (u_char rttype)
+{
+ return lookup (rttype_str, rttype);
+}
+
/* Receive message from netlink interface and pass those information
to the given function. */
int
@@ -592,7 +639,9 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
/* sendmsg() to netlink socket then recvmsg(). */
int
-netlink_talk (struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns)
+netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
+ ns_id_t),
+ struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns)
{
int status;
struct sockaddr_nl snl;
@@ -648,7 +697,7 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns)
* Get reply from netlink socket.
* The reply should either be an acknowlegement or an error.
*/
- return netlink_parse_info (netlink_talk_filter, nl, zns, 0);
+ return netlink_parse_info (filter, nl, zns, 0);
}
/* Get type specified information from netlink. */
@@ -718,7 +767,8 @@ kernel_init (struct zebra_ns *zns)
/* Initialize netlink sockets */
groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR |
- RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
+ RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR |
+ RTMGRP_IPV4_MROUTE;
snprintf (zns->netlink.name, sizeof (zns->netlink.name),
"netlink-listen (NS %u)", zns->ns_id);
diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h
index 890236c047..f17f1380c2 100644
--- a/zebra/kernel_netlink.h
+++ b/zebra/kernel_netlink.h
@@ -40,11 +40,17 @@ extern struct rtattr * rta_nest(struct rtattr *rta, int maxlen, int type);
extern int rta_nest_end(struct rtattr *rta, struct rtattr *nest);
extern const char * nl_msg_type_to_str (uint16_t msg_type);
extern const char * nl_rtproto_to_str (u_char rtproto);
+extern const char * nl_family_to_str (u_char family);
+extern const char * nl_rttype_to_str (u_char rttype);
extern int netlink_parse_info (int (*filter) (struct sockaddr_nl *,
struct nlmsghdr *, ns_id_t), struct nlsock *nl,
struct zebra_ns *zns, int count);
-extern int netlink_talk (struct nlmsghdr *n, struct nlsock *nl,
+extern int netlink_talk_filter (struct sockaddr_nl *, struct nlmsghdr *,
+ ns_id_t);
+extern int netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
+ ns_id_t),
+ struct nlmsghdr *n, struct nlsock *nl,
struct zebra_ns *zns);
extern int netlink_request (int family, int type, struct nlsock *nl);
diff --git a/zebra/kernel_null.c b/zebra/kernel_null.c
index d02939882c..fea79ffe8c 100644
--- a/zebra/kernel_null.c
+++ b/zebra/kernel_null.c
@@ -24,6 +24,7 @@
#include <zebra.h>
#include <log.h>
+#include "vty.h"
#include "zebra/zserv.h"
#include "zebra/rt.h"
#include "zebra/redistribute.h"
@@ -31,7 +32,8 @@
#include "zebra/rt_netlink.h"
#include "zebra/rib.h"
-int kernel_route_rib (struct prefix *a, struct rib *old, struct rib *new) { return 0; }
+int kernel_route_rib (struct prefix *a, struct prefix *b,
+ struct rib *old, struct rib *new) { return 0; }
int kernel_address_add_ipv4 (struct interface *a, struct connected *b)
{
@@ -59,3 +61,5 @@ int kernel_neigh_update (int a, int b, uint32_t c, char *d, int e)
void kernel_init (struct zebra_ns *zns) { return; }
void kernel_terminate (struct zebra_ns *zns) { return; }
void route_read (struct zebra_ns *zns) { return; }
+
+int kernel_get_ipmr_sg_stats (void *m) { return 0; }
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index bcd92e15fe..20a0472195 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -111,7 +111,7 @@ extern struct zebra_privs_t zserv_privs;
*/
#if defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
#define SAROUNDUP(X) ROUNDUP(((struct sockaddr *)(X))->sa_len)
-#elif defined(HAVE_IPV6)
+#else
/*
* One would hope all fixed-size structure definitions are aligned,
* but round them up nonetheless.
@@ -123,12 +123,6 @@ extern struct zebra_privs_t zserv_privs;
ROUNDUP(sizeof(struct sockaddr_in6)) : \
(((struct sockaddr *)(X))->sa_family == AF_LINK ? \
ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr))))
-#else /* HAVE_IPV6 */
-#define SAROUNDUP(X) \
- (((struct sockaddr *)(X))->sa_family == AF_INET ? \
- ROUNDUP(sizeof(struct sockaddr_in)):\
- (((struct sockaddr *)(X))->sa_family == AF_LINK ? \
- ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr)))
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#endif /* !SA_SIZE */
@@ -299,10 +293,8 @@ af_check (int family)
{
if (family == AF_INET)
return 1;
-#ifdef HAVE_IPV6
if (family == AF_INET6)
return 1;
-#endif /* HAVE_IPV6 */
return 0;
}
@@ -682,9 +674,7 @@ ifam_read_mesg (struct ifa_msghdr *ifm,
switch (family)
{
case AF_INET:
-#ifdef HAVE_IPV6
case AF_INET6:
-#endif
{
char buf[4][INET6_ADDRSTRLEN];
zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, "
@@ -772,7 +762,6 @@ ifam_read (struct ifa_msghdr *ifam)
ip_masklen (mask.sin.sin_addr),
&brd.sin.sin_addr);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
/* Unset interface index from link-local address when IPv6 stack
is KAME. */
@@ -792,7 +781,6 @@ ifam_read (struct ifa_msghdr *ifam)
ip6_masklen (mask.sin6.sin6_addr),
&brd.sin6.sin6_addr);
break;
-#endif /* HAVE_IPV6 */
default:
/* Unsupported family silently ignore... */
break;
@@ -939,7 +927,7 @@ rtm_read (struct rt_msghdr *rtm)
int ret;
if (! IS_ZEBRA_DEBUG_RIB)
return;
- ret = rib_lookup_ipv4_route (&p, &gate, VRF_DEFAULT);
+ ret = rib_lookup_ipv4_route ((struct prefix_ipv4 *)&p, &gate, VRF_DEFAULT);
prefix2str (&p, buf, sizeof(buf));
switch (rtm->rtm_type)
{
@@ -963,7 +951,7 @@ rtm_read (struct rt_msghdr *rtm)
case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */
zlog_debug ("%s: %s %s: done Ok",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p, VRF_DEFAULT);
+ rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT);
return;
break;
}
@@ -976,18 +964,18 @@ rtm_read (struct rt_msghdr *rtm)
case ZEBRA_RIB_FOUND_EXACT:
zlog_debug ("%s: %s %s: desync: RR is still in RIB, while already not in FIB",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p, VRF_DEFAULT);
+ rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT);
break;
case ZEBRA_RIB_FOUND_CONNECTED:
case ZEBRA_RIB_FOUND_NOGATE:
zlog_debug ("%s: %s %s: desync: RR is still in RIB, plus gate differs",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p, VRF_DEFAULT);
+ rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT);
break;
case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */
zlog_debug ("%s: %s %s: done Ok",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p, VRF_DEFAULT);
+ rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT);
return;
break;
}
@@ -1004,17 +992,17 @@ rtm_read (struct rt_msghdr *rtm)
*/
if (rtm->rtm_type == RTM_CHANGE)
rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, NULL, 0, 0);
+ 0, zebra_flags, &p, NULL, NULL, 0, 0);
union g_addr ggate = { .ipv4 = gate.sin.sin_addr };
if (rtm->rtm_type == RTM_GET
|| rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
- &p, &ggate, NULL, 0, 0, 0, 0, 0);
+ &p, NULL, &ggate, NULL, 0, 0, 0, 0, 0);
else
rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, &ggate, 0, 0);
+ 0, zebra_flags, &p, NULL, &ggate, 0, 0);
}
if (dest.sa.sa_family == AF_INET6)
{
@@ -1046,18 +1034,18 @@ rtm_read (struct rt_msghdr *rtm)
*/
if (rtm->rtm_type == RTM_CHANGE)
rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, NULL, 0, 0);
+ 0, zebra_flags, &p, NULL, NULL, 0, 0);
union g_addr ggate = { .ipv6 = gate.sin6.sin6_addr };
if (rtm->rtm_type == RTM_GET
|| rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
rib_add (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, &ggate, NULL, ifindex,
+ 0, zebra_flags, &p, NULL, &ggate, NULL, ifindex,
0, 0, 0, 0);
else
rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, &ggate, ifindex, 0);
+ 0, zebra_flags, &p, NULL, &ggate, ifindex, 0);
}
}
diff --git a/zebra/kernel_socket.h b/zebra/kernel_socket.h
index 18d69343a4..04e3054312 100644
--- a/zebra/kernel_socket.h
+++ b/zebra/kernel_socket.h
@@ -23,6 +23,14 @@
#ifndef __ZEBRA_KERNEL_SOCKET_H
#define __ZEBRA_KERNEL_SOCKET_H
+/* Error codes of zebra. */
+#define ZEBRA_ERR_NOERROR 0
+#define ZEBRA_ERR_RTEXIST -1
+#define ZEBRA_ERR_RTUNREACH -2
+#define ZEBRA_ERR_EPERM -3
+#define ZEBRA_ERR_RTNOEXIST -4
+#define ZEBRA_ERR_KERNEL -5
+
extern void rtm_read (struct rt_msghdr *);
extern int ifam_read (struct ifa_msghdr *);
extern int ifm_read (struct if_msghdr *);
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 9c7ef5f12c..c7ed209d3c 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -31,6 +31,7 @@
#include "linklist.h"
#include "log.h"
#include "vrf.h"
+#include "srcdest_table.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
@@ -63,14 +64,12 @@ is_default (struct prefix *p)
if (p->family == AF_INET)
if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
return 1;
-#ifdef HAVE_IPV6
#if 0 /* IPv6 default separation is now pending until protocol daemon
can handle that. */
if (p->family == AF_INET6)
if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
return 1;
#endif /* 0 */
-#endif /* HAVE_IPV6 */
return 0;
}
@@ -100,7 +99,7 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
RNODE_FOREACH_RIB (rn, newrib)
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
&& newrib->distance != DISTANCE_INFINITY)
- zsend_redistribute_route (1, client, &rn->p, newrib);
+ zsend_redistribute_route (1, client, &rn->p, NULL, newrib);
route_unlock_node (rn);
}
@@ -124,12 +123,15 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, newrib)
{
+ struct prefix *dst_p, *src_p;
+ srcdest_rnode_prefixes(rn, &dst_p, &src_p);
+
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, "
"zebra_check_addr=%d", __func__,
CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED),
newrib->type, newrib->distance,
- zebra_check_addr (&rn->p));
+ zebra_check_addr (dst_p));
if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED))
continue;
@@ -138,10 +140,10 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
continue;
if (newrib->distance == DISTANCE_INFINITY)
continue;
- if (! zebra_check_addr (&rn->p))
+ if (! zebra_check_addr (dst_p))
continue;
- zsend_redistribute_route (1, client, &rn->p, newrib);
+ zsend_redistribute_route (1, client, dst_p, src_p, newrib);
}
}
}
@@ -149,7 +151,8 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
/* Either advertise a route for redistribution to registered clients or */
/* withdraw redistribution if add cannot be done for client */
void
-redistribute_update (struct prefix *p, struct rib *rib, struct rib *prev_rib)
+redistribute_update (struct prefix *p, struct prefix *src_p,
+ struct rib *rib, struct rib *prev_rib)
{
struct listnode *node, *nnode;
struct zserv *client;
@@ -188,7 +191,7 @@ redistribute_update (struct prefix *p, struct rib *rib, struct rib *prev_rib)
if (send_redistribute)
{
- zsend_redistribute_route (1, client, p, rib);
+ zsend_redistribute_route (1, client, p, src_p, rib);
}
else if (prev_rib &&
((rib->instance &&
@@ -196,13 +199,13 @@ redistribute_update (struct prefix *p, struct rib *rib, struct rib *prev_rib)
rib->instance)) ||
vrf_bitmap_check (client->redist[afi][prev_rib->type], rib->vrf_id)))
{
- zsend_redistribute_route (0, client, p, prev_rib);
+ zsend_redistribute_route (0, client, p, src_p, prev_rib);
}
}
}
void
-redistribute_delete (struct prefix *p, struct rib *rib)
+redistribute_delete (struct prefix *p, struct prefix *src_p, struct rib *rib)
{
struct listnode *node, *nnode;
struct zserv *client;
@@ -237,7 +240,7 @@ redistribute_delete (struct prefix *p, struct rib *rib)
rib->instance)) ||
vrf_bitmap_check (client->redist[afi][rib->type], rib->vrf_id))
{
- zsend_redistribute_route (0, client, p, rib);
+ zsend_redistribute_route (0, client, p, src_p, rib);
}
}
}
@@ -521,7 +524,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
gate = (union g_addr *)&nhop->gate.ipv4;
rib_add (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE,
- rib->table, 0, &p, gate, (union g_addr *)&nhop->src.ipv4,
+ rib->table, 0, &p, NULL, gate, (union g_addr *)&nhop->src.ipv4,
nhop->ifindex, zebrad.rtm_table_default,
rib->metric, rib->mtu,
zebra_import_table_distance[AFI_IP][rib->table]);
@@ -543,7 +546,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
for (nhop = rib->nexthop; nhop; nhop = nhop->next)
rib_copy_nexthops(newrib, nhop);
- rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, newrib);
+ rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, NULL, newrib);
}
}
}
@@ -567,7 +570,7 @@ zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
p.u.prefix4 = rn->p.u.prefix4;
rib_delete (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE,
- rib->table, rib->flags, &p, NULL,
+ rib->table, rib->flags, &p, NULL, NULL,
0, zebrad.rtm_table_default);
}
/* DD: Add IPv6 code */
diff --git a/zebra/redistribute.h b/zebra/redistribute.h
index e3bce7af46..06afc726d1 100644
--- a/zebra/redistribute.h
+++ b/zebra/redistribute.h
@@ -36,8 +36,9 @@ extern void zebra_redistribute_default_add (int, struct zserv *, int,
extern void zebra_redistribute_default_delete (int, struct zserv *, int,
struct zebra_vrf *zvrf);
-extern void redistribute_update (struct prefix *, struct rib *, struct rib *);
-extern void redistribute_delete (struct prefix *, struct rib *);
+extern void redistribute_update (struct prefix *, struct prefix *,
+ struct rib *, struct rib *);
+extern void redistribute_delete (struct prefix *, struct prefix *, struct rib *);
extern void zebra_interface_up_update (struct interface *);
extern void zebra_interface_down_update (struct interface *);
diff --git a/zebra/redistribute_null.c b/zebra/redistribute_null.c
index 85d3bd2f1b..ffde8ed773 100644
--- a/zebra/redistribute_null.c
+++ b/zebra/redistribute_null.c
@@ -20,6 +20,7 @@
*/
#include <zebra.h>
+#include "vty.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
@@ -38,9 +39,10 @@ void zebra_redistribute_default_delete (int a, struct zserv *b, int c,
struct zebra_vrf *zvrf)
{ return; }
-void redistribute_update (struct prefix *a, struct rib *b, struct rib *c)
+void redistribute_update (struct prefix *a, struct prefix *b,
+ struct rib *c, struct rib *d)
{ return; }
-void redistribute_delete (struct prefix *a, struct rib *b)
+void redistribute_delete (struct prefix *a, struct prefix *b, struct rib *c)
{ return; }
void zebra_interface_up_update (struct interface *a)
diff --git a/zebra/rib.h b/zebra/rib.h
index d80ea6cbd8..b246b89a53 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -32,6 +32,7 @@
#include "vrf.h"
#include "if.h"
#include "mpls.h"
+#include "srcdest_table.h"
#define DISTANCE_INFINITY 255
#define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */
@@ -311,8 +312,9 @@ extern enum multicast_mode multicast_mode_ipv4_get (void);
extern int nexthop_has_fib_child(struct nexthop *);
extern void rib_lookup_and_dump (struct prefix_ipv4 *, vrf_id_t);
extern void rib_lookup_and_pushup (struct prefix_ipv4 *, vrf_id_t);
-#define rib_dump(prefix ,rib) _rib_dump(__func__, prefix, rib)
+#define rib_dump(prefix, src, rib) _rib_dump(__func__, prefix, src, rib)
extern void _rib_dump (const char *,
+ union prefix46constptr,
union prefix46constptr, const struct rib *);
extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *,
vrf_id_t);
@@ -342,17 +344,17 @@ extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib);
* also implicitly withdraw equal prefix of same type. */
extern int rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
- union g_addr *gate, union g_addr *src,
+ struct prefix_ipv6 *src_p, union g_addr *gate, union g_addr *src,
ifindex_t ifindex, u_int32_t table_id,
u_int32_t, u_int32_t, u_char);
extern int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *,
- struct rib *);
+ struct prefix_ipv6 *src_p, struct rib *);
-extern int rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
- u_short instance, int flags, struct prefix *p,
- union g_addr *gate, ifindex_t ifindex,
- u_int32_t table_id);
+extern void rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
+ u_short instance, int flags, struct prefix *p,
+ struct prefix_ipv6 *src_p, union g_addr *gate,
+ ifindex_t ifindex, u_int32_t table_id);
extern struct rib *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *,
struct route_node **rn_out);
@@ -444,7 +446,7 @@ rib_dest_af (rib_dest_t *dest)
static inline struct route_table *
rib_dest_table (rib_dest_t *dest)
{
- return dest->rnode->table;
+ return srcdest_rnode_table(dest->rnode);
}
/*
diff --git a/zebra/router-id.c b/zebra/router-id.c
index 0aa1bdc770..b1e786d0c8 100644
--- a/zebra/router-id.c
+++ b/zebra/router-id.c
@@ -216,41 +216,42 @@ router_id_write (struct vty *vty)
DEFUN (router_id,
router_id_cmd,
- "router-id A.B.C.D",
+ "router-id A.B.C.D [vrf NAME]",
"Manually set the router-id\n"
- "IP address to use for router-id\n")
+ "IP address to use for router-id\n"
+ VRF_CMD_HELP_STR)
{
+ int idx_ipv4 = 1;
+ int idx_name = 3;
+
struct prefix rid;
vrf_id_t vrf_id = VRF_DEFAULT;
- rid.u.prefix4.s_addr = inet_addr (argv[0]);
+ rid.u.prefix4.s_addr = inet_addr (argv[idx_ipv4]->arg);
if (!rid.u.prefix4.s_addr)
return CMD_WARNING;
rid.prefixlen = 32;
rid.family = AF_INET;
- if (argc > 1)
- VRF_GET_ID (vrf_id, argv[1]);
+ if (argc > 2)
+ VRF_GET_ID (vrf_id, argv[idx_name]->arg);
router_id_set (&rid, vrf_id);
return CMD_SUCCESS;
}
-ALIAS (router_id,
- router_id_vrf_cmd,
- "router-id A.B.C.D " VRF_CMD_STR,
- "Manually set the router-id\n"
- "IP address to use for router-id\n"
- VRF_CMD_HELP_STR)
-
DEFUN (no_router_id,
no_router_id_cmd,
- "no router-id",
+ "no router-id [A.B.C.D [vrf NAME]]",
NO_STR
- "Remove the manually configured router-id\n")
+ "Remove the manually configured router-id\n"
+ "IP address to use for router-id\n"
+ VRF_CMD_HELP_STR)
{
+ int idx_name = 4;
+
struct prefix rid;
vrf_id_t vrf_id = VRF_DEFAULT;
@@ -258,28 +259,15 @@ DEFUN (no_router_id,
rid.prefixlen = 0;
rid.family = AF_INET;
- if (argc > 1)
- VRF_GET_ID (vrf_id, argv[1]);
+ if (argc > 3)
+ VRF_GET_ID (vrf_id, argv[idx_name]->arg);
router_id_set (&rid, vrf_id);
return CMD_SUCCESS;
}
-ALIAS (no_router_id,
- no_router_id_val_cmd,
- "no router-id A.B.C.D",
- NO_STR
- "Remove the manually configured router-id\n"
- "IP address to use for router-id\n")
-ALIAS (no_router_id,
- no_router_id_vrf_cmd,
- "no router-id A.B.C.D " VRF_CMD_STR,
- NO_STR
- "Remove the manually configured router-id\n"
- "IP address to use for router-id\n"
- VRF_CMD_HELP_STR)
static int
router_id_cmp (void *a, void *b)
@@ -295,9 +283,6 @@ router_id_cmd_init (void)
{
install_element (CONFIG_NODE, &router_id_cmd);
install_element (CONFIG_NODE, &no_router_id_cmd);
- install_element (CONFIG_NODE, &router_id_vrf_cmd);
- install_element (CONFIG_NODE, &no_router_id_val_cmd);
- install_element (CONFIG_NODE, &no_router_id_vrf_cmd);
}
void
diff --git a/zebra/rt.h b/zebra/rt.h
index e56e3b8fe3..75d234ce83 100644
--- a/zebra/rt.h
+++ b/zebra/rt.h
@@ -29,7 +29,8 @@
#include "zebra/zebra_ns.h"
#include "zebra/zebra_mpls.h"
-extern int kernel_route_rib (struct prefix *, struct rib *, struct rib *);
+extern int kernel_route_rib (struct prefix *, struct prefix *,
+ struct rib *, struct rib *);
extern int kernel_address_add_ipv4 (struct interface *, struct connected *);
extern int kernel_address_delete_ipv4 (struct interface *, struct connected *);
@@ -40,4 +41,5 @@ extern int kernel_upd_lsp (zebra_lsp_t *);
extern int kernel_del_lsp (zebra_lsp_t *);
extern int mpls_kernel_init (void);
+extern int kernel_get_ipmr_sg_stats (void *mroute);
#endif /* _ZEBRA_RT_H */
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 4913aa878f..d88dc05b28 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
#include <zebra.h>
@@ -40,6 +40,7 @@
#include "privs.h"
#include "nexthop.h"
#include "vrf.h"
+#include "vty.h"
#include "mpls.h"
#include "zebra/zserv.h"
@@ -54,6 +55,8 @@
#include "zebra/zebra_mpls.h"
#include "zebra/kernel_netlink.h"
#include "zebra/rt_netlink.h"
+#include "zebra/zebra_mroute.h"
+
/* TODO - Temporary definitions, need to refine. */
#ifndef AF_MPLS
@@ -76,6 +79,10 @@
#define RTA_ENCAP 22
#endif
+#ifndef RTA_EXPIRES
+#define RTA_EXPIRES 23
+#endif
+
#ifndef LWTUNNEL_ENCAP_MPLS
#define LWTUNNEL_ENCAP_MPLS 1
#endif
@@ -83,6 +90,10 @@
#ifndef MPLS_IPTUNNEL_DST
#define MPLS_IPTUNNEL_DST 1
#endif
+
+#ifndef NDA_MASTER
+#define NDA_MASTER 9
+#endif
/* End of temporary definitions */
struct gw_family_t
@@ -123,18 +134,20 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
struct rtattr *tb[RTA_MAX + 1];
u_char flags = 0;
struct prefix p;
+ struct prefix_ipv6 src_p;
vrf_id_t vrf_id = VRF_DEFAULT;
char anyaddr[16] = { 0 };
- int index;
+ int index = 0;
int table;
- int metric;
+ int metric = 0;
u_int32_t mtu = 0;
- void *dest;
- void *gate;
- void *src;
+ void *dest = NULL;
+ void *gate = NULL;
+ void *prefsrc = NULL; /* IPv4 preferred source host address */
+ void *src = NULL; /* IPv6 srcdest source prefix */
rtm = NLMSG_DATA (h);
@@ -157,9 +170,6 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
if (rtm->rtm_protocol == RTPROT_KERNEL)
return 0;
- if (rtm->rtm_src_len != 0)
- return 0;
-
/* We don't care about change notifications for the MPLS table. */
/* TODO: Revisit this. */
if (rtm->rtm_family == AF_MPLS)
@@ -184,12 +194,6 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
if (rtm->rtm_protocol == RTPROT_ZEBRA)
flags |= ZEBRA_FLAG_SELFROUTE;
- index = 0;
- metric = 0;
- dest = NULL;
- gate = NULL;
- src = NULL;
-
if (tb[RTA_OIF])
index = *(int *) RTA_DATA (tb[RTA_OIF]);
@@ -198,8 +202,13 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
else
dest = anyaddr;
+ if (tb[RTA_SRC])
+ src = RTA_DATA (tb[RTA_SRC]);
+ else
+ src = anyaddr;
+
if (tb[RTA_PREFSRC])
- src = RTA_DATA (tb[RTA_PREFSRC]);
+ prefsrc = RTA_DATA (tb[RTA_PREFSRC]);
if (tb[RTA_GATEWAY])
gate = RTA_DATA (tb[RTA_GATEWAY]);
@@ -225,9 +234,12 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
memcpy (&p.u.prefix4, dest, 4);
p.prefixlen = rtm->rtm_dst_len;
+ if (rtm->rtm_src_len != 0)
+ return 0;
+
if (!tb[RTA_MULTIPATH])
rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, flags, &p, gate, src, index,
+ 0, flags, &p, NULL, gate, prefsrc, index,
table, metric, mtu, 0);
else
{
@@ -269,9 +281,9 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
if (gate)
{
if (index)
- rib_nexthop_ipv4_ifindex_add (rib, gate, src, index);
+ rib_nexthop_ipv4_ifindex_add (rib, gate, prefsrc, index);
else
- rib_nexthop_ipv4_add (rib, gate, src);
+ rib_nexthop_ipv4_add (rib, gate, prefsrc);
}
else
rib_nexthop_ifindex_add (rib, index);
@@ -285,7 +297,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
if (rib->nexthop_num == 0)
XFREE (MTYPE_RIB, rib);
else
- rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
+ rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib);
}
}
if (rtm->rtm_family == AF_INET6)
@@ -294,8 +306,12 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
memcpy (&p.u.prefix6, dest, 16);
p.prefixlen = rtm->rtm_dst_len;
+ src_p.family = AF_INET6;
+ memcpy (&src_p.prefix, src, 16);
+ src_p.prefixlen = rtm->rtm_src_len;
+
rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, flags, &p, gate, src, index,
+ 0, flags, &p, &src_p, gate, prefsrc, index,
table, metric, mtu, 0);
}
@@ -303,8 +319,8 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
}
/* Routing information change from the kernel. */
-int
-netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
+static int
+netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
ns_id_t ns_id)
{
int len;
@@ -313,49 +329,21 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
u_char zebra_flags = 0;
struct prefix p;
vrf_id_t vrf_id = VRF_DEFAULT;
-
char anyaddr[16] = { 0 };
- int index;
+ int index = 0;
int table;
- int metric;
+ int metric = 0;
u_int32_t mtu = 0;
- void *dest;
- void *gate;
- void *src;
+ void *dest = NULL;
+ void *gate = NULL;
+ void *prefsrc = NULL; /* IPv4 preferred source host address */
+ void *src = NULL; /* IPv6 srcdest source prefix */
rtm = NLMSG_DATA (h);
- if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
- {
- /* If this is not route add/delete message print warning. */
- zlog_warn ("Kernel message: %d", h->nlmsg_type);
- return 0;
- }
-
- /* Connected route. */
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("%s %s %s proto %s",
- h->nlmsg_type ==
- RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
- rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
- rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
- nl_rtproto_to_str (rtm->rtm_protocol));
-
- if (rtm->rtm_type != RTN_UNICAST)
- {
- return 0;
- }
-
- /* We don't care about change notifications for the MPLS table. */
- /* TODO: Revisit this. */
- if (rtm->rtm_family == AF_MPLS)
- return 0;
-
len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
- if (len < 0)
- return -1;
memset (tb, 0, sizeof tb);
netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
@@ -372,12 +360,6 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
if (rtm->rtm_protocol == RTPROT_ZEBRA)
SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE);
- if (rtm->rtm_src_len != 0)
- {
- zlog_warn ("netlink_route_change(): no src len");
- return 0;
- }
-
/* Table corresponding to route. */
if (tb[RTA_TABLE])
table = *(int *) RTA_DATA (tb[RTA_TABLE]);
@@ -393,12 +375,6 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
return 0;
}
- index = 0;
- metric = 0;
- dest = NULL;
- gate = NULL;
- src = NULL;
-
if (tb[RTA_OIF])
index = *(int *) RTA_DATA (tb[RTA_OIF]);
@@ -407,11 +383,16 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
else
dest = anyaddr;
+ if (tb[RTA_SRC])
+ src = RTA_DATA (tb[RTA_SRC]);
+ else
+ src = anyaddr;
+
if (tb[RTA_GATEWAY])
gate = RTA_DATA (tb[RTA_GATEWAY]);
if (tb[RTA_PREFSRC])
- src = RTA_DATA (tb[RTA_PREFSRC]);
+ prefsrc = RTA_DATA (tb[RTA_PREFSRC]);
if (h->nlmsg_type == RTM_NEWROUTE)
{
@@ -437,11 +418,18 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
memcpy (&p.u.prefix4, dest, 4);
p.prefixlen = rtm->rtm_dst_len;
+ if (rtm->rtm_src_len != 0)
+ {
+ zlog_warn ("unsupported IPv4 sourcedest route (dest %s/%d)",
+ inet_ntoa (p.u.prefix4), p.prefixlen);
+ return 0;
+ }
+
if (IS_ZEBRA_DEBUG_KERNEL)
{
char buf[PREFIX_STRLEN];
zlog_debug ("%s %s vrf %u",
- h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
+ nl_msg_type_to_str (h->nlmsg_type),
prefix2str (&p, buf, sizeof(buf)), vrf_id);
}
@@ -449,8 +437,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
{
if (!tb[RTA_MULTIPATH])
rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, 0, &p, gate, src, index,
- table, metric, mtu, 0);
+ 0, 0, &p, NULL, gate, prefsrc, index,
+ table, metric, mtu, 0);
else
{
/* This is a multipath route */
@@ -491,9 +479,9 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
if (gate)
{
if (index)
- rib_nexthop_ipv4_ifindex_add (rib, gate, src, index);
+ rib_nexthop_ipv4_ifindex_add (rib, gate, prefsrc, index);
else
- rib_nexthop_ipv4_add (rib, gate, src);
+ rib_nexthop_ipv4_add (rib, gate, prefsrc);
}
else
rib_nexthop_ifindex_add (rib, index);
@@ -508,37 +496,183 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
if (rib->nexthop_num == 0)
XFREE (MTYPE_RIB, rib);
else
- rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
+ rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib);
}
}
else
rib_delete (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
- &p, gate, index, table);
+ &p, NULL, gate, index, table);
}
if (rtm->rtm_family == AF_INET6)
{
struct prefix p;
+ struct prefix_ipv6 src_p;
p.family = AF_INET6;
memcpy (&p.u.prefix6, dest, 16);
p.prefixlen = rtm->rtm_dst_len;
+ src_p.family = AF_INET6;
+ memcpy (&src_p.prefix, src, 16);
+ src_p.prefixlen = rtm->rtm_src_len;
+
if (IS_ZEBRA_DEBUG_KERNEL)
{
char buf[PREFIX_STRLEN];
- zlog_debug ("%s %s vrf %u",
- h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
- prefix2str (&p, buf, sizeof(buf)), vrf_id);
+ char buf2[PREFIX_STRLEN];
+ zlog_debug ("%s %s%s%s vrf %u",
+ nl_msg_type_to_str (h->nlmsg_type),
+ prefix2str (&p, buf, sizeof(buf)),
+ src_p.prefixlen ? " from " : "",
+ src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2)) : "",
+ vrf_id);
}
if (h->nlmsg_type == RTM_NEWROUTE)
rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, 0, &p, gate, src, index,
+ 0, 0, &p, &src_p, gate, prefsrc, index,
table, metric, mtu, 0);
else
rib_delete (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, gate, index, table);
+ 0, zebra_flags, &p, &src_p, gate, index, table);
+ }
+
+ return 0;
+}
+
+static struct mcast_route_data *mroute = NULL;
+
+static int
+netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
+ ns_id_t ns_id)
+{
+ int len;
+ struct rtmsg *rtm;
+ struct rtattr *tb[RTA_MAX + 1];
+ struct mcast_route_data *m;
+ struct mcast_route_data mr;
+ int iif = 0;
+ int count;
+ int oif[256];
+ int oif_count = 0;
+ char sbuf[40];
+ char gbuf[40];
+ char oif_list[256] = "\0";
+ vrf_id_t vrf = ns_id;
+
+ if (mroute)
+ m = mroute;
+ else
+ {
+ memset (&mr, 0, sizeof (mr));
+ m = &mr;
+ }
+
+ rtm = NLMSG_DATA (h);
+
+ len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
+
+ memset (tb, 0, sizeof tb);
+ netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
+
+ if (tb[RTA_IIF])
+ iif = *(int *)RTA_DATA (tb[RTA_IIF]);
+
+ if (tb[RTA_SRC])
+ m->sg.src = *(struct in_addr *)RTA_DATA (tb[RTA_SRC]);
+
+ if (tb[RTA_DST])
+ m->sg.grp = *(struct in_addr *)RTA_DATA (tb[RTA_DST]);
+
+ if ((RTA_EXPIRES <= RTA_MAX) && tb[RTA_EXPIRES])
+ m->lastused = *(unsigned long long *)RTA_DATA (tb[RTA_EXPIRES]);
+
+ if (tb[RTA_MULTIPATH])
+ {
+ struct rtnexthop *rtnh =
+ (struct rtnexthop *)RTA_DATA (tb[RTA_MULTIPATH]);
+
+ len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
+ for (;;)
+ {
+ if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
+ break;
+
+ oif[oif_count] = rtnh->rtnh_ifindex;
+ oif_count++;
+
+ len -= NLMSG_ALIGN (rtnh->rtnh_len);
+ rtnh = RTNH_NEXT (rtnh);
+ }
+ }
+
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ {
+ struct interface *ifp;
+ strcpy (sbuf, inet_ntoa (m->sg.src));
+ strcpy (gbuf, inet_ntoa (m->sg.grp));
+ for (count = 0; count < oif_count; count++)
+ {
+ ifp = if_lookup_by_index_vrf (oif[count], vrf);
+ char temp[256];
+
+ sprintf (temp, "%s ", ifp->name);
+ strcat (oif_list, temp);
+ }
+ ifp = if_lookup_by_index_vrf (iif, vrf);
+ zlog_debug ("MCAST %s (%s,%s) IIF: %s OIF: %s jiffies: %lld",
+ nl_msg_type_to_str(h->nlmsg_type), sbuf, gbuf, ifp->name, oif_list, m->lastused);
+ }
+ return 0;
+}
+
+int
+netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
+ ns_id_t ns_id)
+{
+ int len;
+ vrf_id_t vrf_id = ns_id;
+ struct rtmsg *rtm;
+
+ rtm = NLMSG_DATA (h);
+
+ if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
+ {
+ /* If this is not route add/delete message print warning. */
+ zlog_warn ("Kernel message: %d vrf %u\n", h->nlmsg_type, vrf_id);
+ return 0;
+ }
+
+ /* Connected route. */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug ("%s %s %s proto %s vrf %u",
+ nl_msg_type_to_str (h->nlmsg_type),
+ nl_family_to_str (rtm->rtm_family),
+ nl_rttype_to_str (rtm->rtm_type),
+ nl_rtproto_to_str (rtm->rtm_protocol),
+ vrf_id);
+
+ /* We don't care about change notifications for the MPLS table. */
+ /* TODO: Revisit this. */
+ if (rtm->rtm_family == AF_MPLS)
+ return 0;
+
+ len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
+ if (len < 0)
+ return -1;
+
+ switch (rtm->rtm_type)
+ {
+ case RTN_UNICAST:
+ netlink_route_change_read_unicast (snl, h, ns_id);
+ break;
+ case RTN_MULTICAST:
+ netlink_route_change_read_multicast (snl, h, ns_id);
+ break;
+ default:
+ return 0;
+ break;
}
return 0;
@@ -559,7 +693,6 @@ netlink_route_read (struct zebra_ns *zns)
if (ret < 0)
return ret;
-#ifdef HAVE_IPV6
/* Get IPv6 routing table. */
ret = netlink_request (AF_INET6, RTM_GETROUTE, &zns->netlink_cmd);
if (ret < 0)
@@ -567,7 +700,6 @@ netlink_route_read (struct zebra_ns *zns)
ret = netlink_parse_info (netlink_routing_table, &zns->netlink_cmd, zns, 0);
if (ret < 0)
return ret;
-#endif /* HAVE_IPV6 */
return 0;
}
@@ -693,7 +825,7 @@ _netlink_route_build_singlepath(
int i, num_labels = 0;
u_int32_t bos;
char label_buf1[20];
-
+
for (i = 0; i < nh_label->num_labels; i++)
{
if (nh_label->label[i] != MPLS_IMP_NULL_LABEL)
@@ -1074,7 +1206,7 @@ _netlink_route_debug(
prefix2str (p, buf, sizeof(buf)), zvrf_id (zvrf),
(nexthop) ? nexthop_type_to_str (nexthop->type) : "UNK");
}
-}
+ }
static void
_netlink_mpls_debug(
@@ -1112,14 +1244,14 @@ netlink_neigh_update (int cmd, int ifindex, uint32_t addr, char *lla, int llalen
addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4);
addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen);
- return netlink_talk (&req.n, &zns->netlink_cmd, zns);
+ return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns);
}
/* Routing table change via netlink interface. */
/* Update flag indicates whether this is a "replace" or not. */
static int
-netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
- int update)
+netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
+ struct rib *rib, int update)
{
int bytelen;
struct sockaddr_nl snl;
@@ -1153,6 +1285,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_src_len = src_p ? src_p->prefixlen : 0;
req.r.rtm_protocol = RTPROT_ZEBRA;
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
@@ -1177,6 +1310,8 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
}
addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
+ if (src_p)
+ addattr_l (&req.n, sizeof req, RTA_SRC, &src_p->u.prefix, bytelen);
/* Metric. */
/* Hardcode the metric for all routes coming from zebra. Metric isn't used
@@ -1407,18 +1542,52 @@ skip:
snl.nl_family = AF_NETLINK;
/* Talk to netlink socket. */
- return netlink_talk (&req.n, &zns->netlink_cmd, zns);
+ return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns);
+}
+
+int
+kernel_get_ipmr_sg_stats (void *in)
+{
+ int suc = 0;
+ struct mcast_route_data *mr = (struct mcast_route_data *)in;
+ struct {
+ struct nlmsghdr n;
+ struct ndmsg ndm;
+ char buf[256];
+ } req;
+
+ mroute = mr;
+ struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
+
+ memset(&req.n, 0, sizeof(req.n));
+ memset(&req.ndm, 0, sizeof(req.ndm));
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.ndm.ndm_family = AF_INET;
+ req.n.nlmsg_type = RTM_GETROUTE;
+
+ addattr_l (&req.n, sizeof (req), RTA_IIF, &mroute->ifindex, 4);
+ addattr_l (&req.n, sizeof (req), RTA_OIF, &mroute->ifindex, 4);
+ addattr_l (&req.n, sizeof (req), RTA_SRC, &mroute->sg.src.s_addr, 4);
+ addattr_l (&req.n, sizeof (req), RTA_DST, &mroute->sg.grp.s_addr, 4);
+
+ suc = netlink_talk (netlink_route_change_read_multicast, &req.n, &zns->netlink_cmd, zns);
+
+ mroute = NULL;
+ return suc;
}
int
-kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
+kernel_route_rib (struct prefix *p, struct prefix *src_p,
+ struct rib *old, struct rib *new)
{
if (!old && new)
- return netlink_route_multipath (RTM_NEWROUTE, p, new, 0);
+ return netlink_route_multipath (RTM_NEWROUTE, p, src_p, new, 0);
if (old && !new)
- return netlink_route_multipath (RTM_DELROUTE, p, old, 0);
+ return netlink_route_multipath (RTM_DELROUTE, p, src_p, old, 0);
- return netlink_route_multipath (RTM_NEWROUTE, p, new, 1);
+ return netlink_route_multipath (RTM_NEWROUTE, p, src_p, new, 1);
}
int
@@ -1597,7 +1766,7 @@ netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp)
}
/* Talk to netlink socket. */
- return netlink_talk (&req.n, &zns->netlink_cmd, zns);
+ return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns);
}
/*
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index b2c99d9813..a4cc4eed06 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -182,7 +182,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib)
{
zlog_debug ("%s: %s: attention! gate not found for rib %p",
__func__, prefix_buf, rib);
- rib_dump (p, rib);
+ rib_dump (p, NULL, rib);
}
else
inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN);
@@ -391,10 +391,17 @@ kernel_rtm (int cmd, struct prefix *p, struct rib *rib)
}
int
-kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
+kernel_route_rib (struct prefix *p, struct prefix *src_p,
+ struct rib *old, struct rib *new)
{
int route = 0;
+ if (src_p && src_p->prefixlen)
+ {
+ zlog (NULL, LOG_ERR, "route add: IPv6 sourcedest routes unsupported!");
+ return 1;
+ }
+
if (zserv_privs.change(ZPRIVS_RAISE))
zlog (NULL, LOG_ERR, "Can't raise privileges");
@@ -416,3 +423,9 @@ kernel_neigh_update (int add, int ifindex, uint32_t addr, char *lla, int llalen)
/* TODO */
return 0;
}
+
+extern int
+kernel_get_ipmr_sg_stats (void *mroute)
+{
+ return 0;
+}
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 26c83bc6ac..12e4873adf 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -1,4 +1,5 @@
/* Router advertisement
+ * Copyright (C) 2016 Cumulus Networks
* Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
* Copyright (C) 1999 Kunihiro Ishiguro
*
@@ -45,7 +46,7 @@
extern struct zebra_privs_t zserv_privs;
-#if defined (HAVE_IPV6) && defined (HAVE_RTADV)
+#if defined (HAVE_RTADV)
#ifdef OPEN_BSD
#include <netinet/icmp6.h>
@@ -911,12 +912,14 @@ DEFUN (no_ipv6_nd_suppress_ra,
DEFUN (ipv6_nd_ra_interval_msec,
ipv6_nd_ra_interval_msec_cmd,
- "ipv6 nd ra-interval msec <70-1800000>",
+ "ipv6 nd ra-interval msec (70-1800000)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Router Advertisement interval\n"
+ "Router Advertisement interval in milliseconds\n"
"Router Advertisement interval in milliseconds\n")
{
+ int idx_number = 4;
VTY_DECLVAR_CONTEXT (interface, ifp);
unsigned interval;
struct zebra_if *zif = ifp->info;
@@ -924,7 +927,7 @@ DEFUN (ipv6_nd_ra_interval_msec,
struct zebra_ns *zns;
zns = zvrf->zns;
- VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
+ VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[idx_number]->arg, 70, 1800000);
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
{
vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
@@ -946,12 +949,13 @@ DEFUN (ipv6_nd_ra_interval_msec,
DEFUN (ipv6_nd_ra_interval,
ipv6_nd_ra_interval_cmd,
- "ipv6 nd ra-interval <1-1800>",
+ "ipv6 nd ra-interval (1-1800)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Router Advertisement interval\n"
"Router Advertisement interval in seconds\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
unsigned interval;
struct zebra_if *zif = ifp->info;
@@ -959,7 +963,7 @@ DEFUN (ipv6_nd_ra_interval,
struct zebra_ns *zns;
zns = zvrf->zns;
- VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
+ VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[idx_number]->arg, 1, 1800);
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
{
vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
@@ -981,11 +985,14 @@ DEFUN (ipv6_nd_ra_interval,
DEFUN (no_ipv6_nd_ra_interval,
no_ipv6_nd_ra_interval_cmd,
- "no ipv6 nd ra-interval",
+ "no ipv6 nd ra-interval [<(1-1800)|msec (1-1800000)>]",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
- "Router Advertisement interval\n")
+ "Router Advertisement interval\n"
+ "Router Advertisement interval in seconds\n"
+ "Specify millisecond router advertisement interval\n"
+ "Router Advertisement interval in milliseconds\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
@@ -1005,36 +1012,20 @@ DEFUN (no_ipv6_nd_ra_interval,
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_nd_ra_interval,
- no_ipv6_nd_ra_interval_val_cmd,
- "no ipv6 nd ra-interval <1-1800>",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Router Advertisement interval\n")
-
-ALIAS (no_ipv6_nd_ra_interval,
- no_ipv6_nd_ra_interval_msec_val_cmd,
- "no ipv6 nd ra-interval msec <1-1800000>",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Router Advertisement interval\n"
- "Router Advertisement interval in milliseconds\n")
-
DEFUN (ipv6_nd_ra_lifetime,
ipv6_nd_ra_lifetime_cmd,
- "ipv6 nd ra-lifetime <0-9000>",
+ "ipv6 nd ra-lifetime (0-9000)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Router lifetime\n"
"Router lifetime in seconds (0 stands for a non-default gw)\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
int lifetime;
- VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
+ VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[idx_number]->arg, 0, 9000);
/* The value to be placed in the Router Lifetime field
* of Router Advertisements sent from the interface,
@@ -1053,11 +1044,12 @@ DEFUN (ipv6_nd_ra_lifetime,
DEFUN (no_ipv6_nd_ra_lifetime,
no_ipv6_nd_ra_lifetime_cmd,
- "no ipv6 nd ra-lifetime",
+ "no ipv6 nd ra-lifetime [(0-9000)]",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
- "Router lifetime\n")
+ "Router lifetime\n"
+ "Router lifetime in seconds (0 stands for a non-default gw)\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
@@ -1067,36 +1059,29 @@ DEFUN (no_ipv6_nd_ra_lifetime,
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_nd_ra_lifetime,
- no_ipv6_nd_ra_lifetime_val_cmd,
- "no ipv6 nd ra-lifetime <0-9000>",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Router lifetime\n"
- "Router lifetime in seconds (0 stands for a non-default gw)\n")
-
DEFUN (ipv6_nd_reachable_time,
ipv6_nd_reachable_time_cmd,
- "ipv6 nd reachable-time <1-3600000>",
+ "ipv6 nd reachable-time (1-3600000)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Reachable time\n"
"Reachable time in milliseconds\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
- VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME);
+ VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[idx_number]->arg, 1, RTADV_MAX_REACHABLE_TIME);
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_reachable_time,
no_ipv6_nd_reachable_time_cmd,
- "no ipv6 nd reachable-time",
+ "no ipv6 nd reachable-time [(1-3600000)]",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
- "Reachable time\n")
+ "Reachable time\n"
+ "Reachable time in milliseconds\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
@@ -1106,36 +1091,29 @@ DEFUN (no_ipv6_nd_reachable_time,
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_nd_reachable_time,
- no_ipv6_nd_reachable_time_val_cmd,
- "no ipv6 nd reachable-time <1-3600000>",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Reachable time\n"
- "Reachable time in milliseconds\n")
-
DEFUN (ipv6_nd_homeagent_preference,
ipv6_nd_homeagent_preference_cmd,
- "ipv6 nd home-agent-preference <0-65535>",
+ "ipv6 nd home-agent-preference (0-65535)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Home Agent preference\n"
"preference value (default is 0, least preferred)\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
- VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535);
+ VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[idx_number]->arg, 0, 65535);
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_homeagent_preference,
no_ipv6_nd_homeagent_preference_cmd,
- "no ipv6 nd home-agent-preference",
+ "no ipv6 nd home-agent-preference [(0-65535)]",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
- "Home Agent preference\n")
+ "Home Agent preference\n"
+ "preference value (default is 0, least preferred)\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
@@ -1145,36 +1123,29 @@ DEFUN (no_ipv6_nd_homeagent_preference,
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_nd_homeagent_preference,
- no_ipv6_nd_homeagent_preference_val_cmd,
- "no ipv6 nd home-agent-preference <0-65535>",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Home Agent preference\n"
- "preference value (default is 0, least preferred)\n")
-
DEFUN (ipv6_nd_homeagent_lifetime,
ipv6_nd_homeagent_lifetime_cmd,
- "ipv6 nd home-agent-lifetime <0-65520>",
+ "ipv6 nd home-agent-lifetime (0-65520)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Home Agent lifetime\n"
"Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
- VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME);
+ VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[idx_number]->arg, 0, RTADV_MAX_HALIFETIME);
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_homeagent_lifetime,
no_ipv6_nd_homeagent_lifetime_cmd,
- "no ipv6 nd home-agent-lifetime",
+ "no ipv6 nd home-agent-lifetime [(0-65520)]",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
- "Home Agent lifetime\n")
+ "Home Agent lifetime\n"
+ "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
@@ -1184,15 +1155,6 @@ DEFUN (no_ipv6_nd_homeagent_lifetime,
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_nd_homeagent_lifetime,
- no_ipv6_nd_homeagent_lifetime_val_cmd,
- "no ipv6 nd home-agent-lifetime <0-65520>",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Home Agent lifetime\n"
- "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
-
DEFUN (ipv6_nd_managed_config_flag,
ipv6_nd_managed_config_flag_cmd,
"ipv6 nd managed-config-flag",
@@ -1319,8 +1281,7 @@ DEFUN (no_ipv6_nd_other_config_flag,
DEFUN (ipv6_nd_prefix,
ipv6_nd_prefix_cmd,
- "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
- "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
+ "ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Prefix information\n"
@@ -1329,77 +1290,75 @@ DEFUN (ipv6_nd_prefix,
"Infinite valid lifetime\n"
"Preferred lifetime in seconds\n"
"Infinite preferred lifetime\n"
+ "Set Router Address flag\n"
"Do not use prefix for onlink determination\n"
"Do not use prefix for autoconfiguration\n"
- "Set Router Address flag\n")
+ "Do not use prefix for autoconfiguration\n"
+ "Do not use prefix for onlink determination\n")
{
+ /* prelude */
+ char *prefix = argv[3]->arg;
+ int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN || strmatch (argv[4]->text, "infinite"));
+ int routeropts = lifetimes ? argc > 6 : argc > 4;
+
+ int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0;
+
+ char *lifetime = NULL, *preflifetime = NULL;
+ int routeraddr = 0, offlink = 0, noautoconf = 0;
+ if (lifetimes)
+ {
+ lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg : argv[4]->text;
+ preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg : argv[5]->text;
+ }
+ if (routeropts)
+ {
+ routeraddr = strmatch (argv[idx_routeropts]->text, "router-address");
+ if (!routeraddr)
+ {
+ offlink = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "off-link"));
+ noautoconf = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "no-autoconfig"));
+ }
+ }
+
+ /* business */
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zebra_if = ifp->info;
- int i;
int ret;
- int cursor = 1;
struct rtadv_prefix rp;
- ret = str2prefix_ipv6 (argv[0], &rp.prefix);
+ ret = str2prefix_ipv6 (prefix, &rp.prefix);
if (!ret)
{
vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
return CMD_WARNING;
}
apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
- rp.AdvOnLinkFlag = 1;
- rp.AdvAutonomousFlag = 1;
- rp.AdvRouterAddressFlag = 0;
+ rp.AdvOnLinkFlag = !offlink;
+ rp.AdvAutonomousFlag = !noautoconf;
+ rp.AdvRouterAddressFlag = routeraddr;
rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
- if (argc > 1)
- {
- if ((isdigit((unsigned char)argv[1][0]))
- || strncmp (argv[1], "i", 1) == 0)
- {
- if ( strncmp (argv[1], "i", 1) == 0)
- rp.AdvValidLifetime = UINT32_MAX;
- else
- rp.AdvValidLifetime = (u_int32_t) strtoll (argv[1],
- (char **)NULL, 10);
-
- if ( strncmp (argv[2], "i", 1) == 0)
- rp.AdvPreferredLifetime = UINT32_MAX;
- else
- rp.AdvPreferredLifetime = (u_int32_t) strtoll (argv[2],
- (char **)NULL, 10);
-
- if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
- {
- vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- cursor = cursor + 2;
- }
- if (argc > cursor)
- {
- for (i = cursor; i < argc; i++)
- {
- if (strncmp (argv[i], "of", 2) == 0)
- rp.AdvOnLinkFlag = 0;
- if (strncmp (argv[i], "no", 2) == 0)
- rp.AdvAutonomousFlag = 0;
- if (strncmp (argv[i], "ro", 2) == 0)
- rp.AdvRouterAddressFlag = 1;
- }
- }
- }
+ if (lifetimes)
+ {
+ rp.AdvValidLifetime = strmatch (lifetime, "infinite") ? UINT32_MAX : strtoll (lifetime, NULL, 10);
+ rp.AdvPreferredLifetime = strmatch (preflifetime, "infinite") ? UINT32_MAX : strtoll (preflifetime, NULL, 10);
+ if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
+ {
+ vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
rtadv_prefix_set (zebra_if, &rp);
return CMD_SUCCESS;
}
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_val_nortaddr_cmd,
- "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
- "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
+DEFUN (no_ipv6_nd_prefix,
+ no_ipv6_nd_prefix_cmd,
+ "no ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]",
+ NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Prefix information\n"
@@ -1408,165 +1367,19 @@ ALIAS (ipv6_nd_prefix,
"Infinite valid lifetime\n"
"Preferred lifetime in seconds\n"
"Infinite preferred lifetime\n"
+ "Set Router Address flag\n"
"Do not use prefix for onlink determination\n"
- "Do not use prefix for autoconfiguration\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_val_rev_cmd,
- "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
- "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
"Do not use prefix for autoconfiguration\n"
- "Do not use prefix for onlink determination\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_val_rev_rtaddr_cmd,
- "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
- "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
"Do not use prefix for autoconfiguration\n"
- "Do not use prefix for onlink determination\n"
- "Set Router Address flag\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_val_noauto_cmd,
- "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
- "(<0-4294967295>|infinite) (no-autoconfig|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
- "Do not use prefix for autoconfiguration")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_val_offlink_cmd,
- "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
- "(<0-4294967295>|infinite) (off-link|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
"Do not use prefix for onlink determination\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_val_rtaddr_cmd,
- "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
- "(<0-4294967295>|infinite) (router-address|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
- "Set Router Address flag\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_val_cmd,
- "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
- "(<0-4294967295>|infinite)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_noval_cmd,
- "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Do not use prefix for autoconfiguration\n"
- "Do not use prefix for onlink determination\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_noval_rev_cmd,
- "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Do not use prefix for onlink determination\n"
- "Do not use prefix for autoconfiguration\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_noval_noauto_cmd,
- "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Do not use prefix for autoconfiguration\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_noval_offlink_cmd,
- "ipv6 nd prefix X:X::X:X/M (off-link|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Do not use prefix for onlink determination\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_noval_rtaddr_cmd,
- "ipv6 nd prefix X:X::X:X/M (router-address|)",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Set Router Address flag\n")
-
-ALIAS (ipv6_nd_prefix,
- ipv6_nd_prefix_prefix_cmd,
- "ipv6 nd prefix X:X::X:X/M",
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n")
-
-DEFUN (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_cmd,
- "no ipv6 nd prefix IPV6PREFIX",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zebra_if = ifp->info;
int ret;
struct rtadv_prefix rp;
+ char *prefix = argv[4]->arg;
- ret = str2prefix_ipv6 (argv[0], &rp.prefix);
+ ret = str2prefix_ipv6 (prefix, &rp.prefix);
if (!ret)
{
vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
@@ -1577,170 +1390,16 @@ DEFUN (no_ipv6_nd_prefix,
ret = rtadv_prefix_reset (zebra_if, &rp);
if (!ret)
{
- vty_out (vty, "Non-exist IPv6 prefix%s", VTY_NEWLINE);
+ vty_out (vty, "Non-existant IPv6 prefix%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_val_nortaddr_cmd,
- "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
- "Do not use prefix for onlink determination\n"
- "Do not use prefix for autoconfiguration\n"
- "Set Router Address flag\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_val_rev_cmd,
- "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
- "Do not use prefix for autoconfiguration\n"
- "Do not use prefix for onlink determination\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_val_rev_rtaddr_cmd,
- "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
- "Do not use prefix for autoconfiguration\n"
- "Do not use prefix for onlink determination\n"
- "Set Router Address flag\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_val_noauto_cmd,
- "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
- "Do not use prefix for autoconfiguration")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_val_offlink_cmd,
- "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
- "Do not use prefix for onlink determination\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_val_rtaddr_cmd,
- "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n"
- "Set Router Address flag\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_val_cmd,
- "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Valid lifetime in seconds\n"
- "Infinite valid lifetime\n"
- "Preferred lifetime in seconds\n"
- "Infinite preferred lifetime\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_noval_cmd,
- "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Do not use prefix for autoconfiguration\n"
- "Do not use prefix for onlink determination\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_noval_rev_cmd,
- "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Do not use prefix for onlink determination\n"
- "Do not use prefix for autoconfiguration\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_noval_noauto_cmd,
- "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Do not use prefix for autoconfiguration\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_noval_offlink_cmd,
- "no ipv6 nd prefix X:X::X:X/M (off-link|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Do not use prefix for onlink determination\n")
-
-ALIAS (no_ipv6_nd_prefix,
- no_ipv6_nd_prefix_noval_rtaddr_cmd,
- "no ipv6 nd prefix X:X::X:X/M (router-address|)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Prefix information\n"
- "IPv6 prefix\n"
- "Set Router Address flag\n")
-
DEFUN (ipv6_nd_router_preference,
ipv6_nd_router_preference_cmd,
- "ipv6 nd router-preference (high|medium|low)",
+ "ipv6 nd router-preference <high|medium|low>",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Default router preference\n"
@@ -1748,13 +1407,14 @@ DEFUN (ipv6_nd_router_preference,
"Low default router preference\n"
"Medium default router preference (default)\n")
{
+ int idx_high_medium_low = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
int i = 0;
while (0 != rtadv_pref_strs[i])
{
- if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
+ if (strncmp (argv[idx_high_medium_low]->arg, rtadv_pref_strs[i], 1) == 0)
{
zif->rtadv.DefaultPreference = i;
return CMD_SUCCESS;
@@ -1767,11 +1427,14 @@ DEFUN (ipv6_nd_router_preference,
DEFUN (no_ipv6_nd_router_preference,
no_ipv6_nd_router_preference_cmd,
- "no ipv6 nd router-preference",
+ "no ipv6 nd router-preference [<high|medium|low>]",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
- "Default router preference\n")
+ "Default router preference\n"
+ "High default router preference\n"
+ "Medium default router preference (default)\n"
+ "Low default router preference\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
@@ -1781,38 +1444,29 @@ DEFUN (no_ipv6_nd_router_preference,
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_nd_router_preference,
- no_ipv6_nd_router_preference_val_cmd,
- "no ipv6 nd router-preference (high|medium|low)",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Default router preference\n"
- "High default router preference\n"
- "Low default router preference\n"
- "Medium default router preference (default)\n")
-
DEFUN (ipv6_nd_mtu,
ipv6_nd_mtu_cmd,
- "ipv6 nd mtu <1-65535>",
+ "ipv6 nd mtu (1-65535)",
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
"Advertised MTU\n"
"MTU in bytes\n")
{
+ int idx_number = 3;
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
- VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
+ VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[idx_number]->arg, 1, 65535);
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_mtu,
no_ipv6_nd_mtu_cmd,
- "no ipv6 nd mtu",
+ "no ipv6 nd mtu [(1-65535)]",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
- "Advertised MTU\n")
+ "Advertised MTU\n"
+ "MTU in bytes\n")
{
VTY_DECLVAR_CONTEXT (interface, ifp);
struct zebra_if *zif = ifp->info;
@@ -1820,14 +1474,6 @@ DEFUN (no_ipv6_nd_mtu,
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_nd_mtu,
- no_ipv6_nd_mtu_val_cmd,
- "no ipv6 nd mtu <1-65535>",
- NO_STR
- "Interface IPv6 config commands\n"
- "Neighbor discovery\n"
- "Advertised MTU\n"
- "MTU in bytes\n")
/* Write configuration about router advertisement. */
void
@@ -1994,14 +1640,10 @@ rtadv_cmd_init (void)
install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_val_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_msec_val_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
@@ -2010,45 +1652,16 @@ rtadv_cmd_init (void)
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_val_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_rtaddr_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_nortaddr_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_noauto_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_offlink_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rtaddr_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rev_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_noauto_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_offlink_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rtaddr_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_prefix_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_rtaddr_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_nortaddr_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_noauto_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_offlink_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rtaddr_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rev_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_noauto_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_offlink_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rtaddr_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd);
install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd);
}
static int
@@ -2115,4 +1728,4 @@ rtadv_cmd_init (void)
{
/* Empty.*/;
}
-#endif /* HAVE_RTADV && HAVE_IPV6 */
+#endif /* HAVE_RTADV */
diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c
index c6eee75174..1007d0ac18 100644
--- a/zebra/rtread_getmsg.c
+++ b/zebra/rtread_getmsg.c
@@ -94,7 +94,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
ggateway = (union g_addr *)&gateway;
rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
- zebra_flags, &prefix, ggateway, NULL, 0, 0, 0, 0, 0);
+ zebra_flags, &prefix, NULL, ggateway, NULL, 0, 0, 0, 0, 0);
}
void
diff --git a/zebra/rtread_netlink.c b/zebra/rtread_netlink.c
index c27e6e97f1..1d41861bbd 100644
--- a/zebra/rtread_netlink.c
+++ b/zebra/rtread_netlink.c
@@ -22,6 +22,7 @@
#include <zebra.h>
+#include "vty.h"
#include "zebra/zserv.h"
#include "zebra/rt_netlink.h"
diff --git a/zebra/test_main.c b/zebra/test_main.c
index 0f7e1a22be..dea1df1697 100644
--- a/zebra/test_main.c
+++ b/zebra/test_main.c
@@ -119,15 +119,14 @@ static ifindex_t test_ifindex = 0;
/* testrib commands */
DEFUN (test_interface_state,
test_interface_state_cmd,
- "state (up|down)",
+ "state <up|down>",
"configure interface\n"
"up\n"
"down\n")
{
+ int idx_up_down = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
- if (argc < 1)
- return CMD_WARNING;
-
+
if (ifp->ifindex == IFINDEX_INTERNAL)
{
ifp->ifindex = ++test_ifindex;
@@ -135,7 +134,7 @@ DEFUN (test_interface_state,
ifp->flags = IFF_BROADCAST|IFF_MULTICAST;
}
- switch (argv[0][0])
+ switch (argv[idx_up_down]->arg[0])
{
case 'u':
SET_FLAG (ifp->flags, IFF_UP);
diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c
index 5920cde29e..afa557096c 100644
--- a/zebra/zebra_fpm.c
+++ b/zebra/zebra_fpm.c
@@ -297,20 +297,6 @@ zfpm_state_to_str (zfpm_state_t state)
}
/*
- * zfpm_get_time
- */
-static time_t
-zfpm_get_time (void)
-{
- struct timeval tv;
-
- if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv) < 0)
- zlog_warn ("FPM: quagga_gettime failed!!");
-
- return tv.tv_sec;
-}
-
-/*
* zfpm_get_elapsed_time
*
* Returns the time elapsed (in seconds) since the given time.
@@ -320,7 +306,7 @@ zfpm_get_elapsed_time (time_t reference)
{
time_t now;
- now = zfpm_get_time ();
+ now = monotime(NULL);
if (now < reference)
{
@@ -883,7 +869,9 @@ zfpm_encode_route (rib_dest_t *dest, struct rib *rib, char *in_buf,
size_t in_buf_len, fpm_msg_type_e *msg_type)
{
size_t len;
+#ifdef HAVE_NETLINK
int cmd;
+#endif
len = 0;
*msg_type = FPM_MSG_TYPE_NONE;
@@ -1177,7 +1165,7 @@ zfpm_connect_cb (struct thread *t)
*/
zfpm_g->connect_calls++;
zfpm_g->stats.connect_calls++;
- zfpm_g->last_connect_call_time = zfpm_get_time ();
+ zfpm_g->last_connect_call_time = monotime(NULL);
ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
if (ret >= 0)
@@ -1531,7 +1519,7 @@ zfpm_clear_stats (struct vty *vty)
zfpm_stop_stats_timer ();
zfpm_start_stats_timer ();
- zfpm_g->last_stats_clear_time = zfpm_get_time();
+ zfpm_g->last_stats_clear_time = monotime(NULL);
vty_out (vty, "Cleared FPM stats%s", VTY_NEWLINE);
}
@@ -1569,9 +1557,9 @@ DEFUN (clear_zebra_fpm_stats,
/*
* update fpm connection information
*/
-DEFUN ( fpm_remote_ip,
- fpm_remote_ip_cmd,
- "fpm connection ip A.B.C.D port <1-65535>",
+DEFUN ( fpm_remote_ip,
+ fpm_remote_ip_cmd,
+ "fpm connection ip A.B.C.D port (1-65535)",
"fpm connection remote ip and port\n"
"Remote fpm server ip A.B.C.D\n"
"Enter ip ")
@@ -1580,11 +1568,11 @@ DEFUN ( fpm_remote_ip,
in_addr_t fpm_server;
uint32_t port_no;
- fpm_server = inet_addr (argv[0]);
+ fpm_server = inet_addr (argv[3]->arg);
if (fpm_server == INADDR_NONE)
return CMD_ERR_INCOMPLETE;
- port_no = atoi (argv[1]);
+ port_no = atoi (argv[5]->arg);
if (port_no < TCP_MIN_PORT || port_no > TCP_MAX_PORT)
return CMD_ERR_INCOMPLETE;
@@ -1595,16 +1583,16 @@ DEFUN ( fpm_remote_ip,
return CMD_SUCCESS;
}
-DEFUN ( no_fpm_remote_ip,
- no_fpm_remote_ip_cmd,
- "no fpm connection ip A.B.C.D port <1-65535>",
+DEFUN ( no_fpm_remote_ip,
+ no_fpm_remote_ip_cmd,
+ "no fpm connection ip A.B.C.D port (1-65535)",
"fpm connection remote ip and port\n"
"Connection\n"
"Remote fpm server ip A.B.C.D\n"
"Enter ip ")
{
- if (zfpm_g->fpm_server != inet_addr (argv[0]) ||
- zfpm_g->fpm_port != atoi (argv[1]))
+ if (zfpm_g->fpm_server != inet_addr (argv[4]->arg) ||
+ zfpm_g->fpm_port != atoi (argv[6]->arg))
return CMD_ERR_NO_MATCH;
zfpm_g->fpm_server = FPM_DEFAULT_IP;
@@ -1622,14 +1610,16 @@ zfpm_init_message_format (const char *format)
{
int have_netlink, have_protobuf;
- have_netlink = have_protobuf = 0;
-
#ifdef HAVE_NETLINK
have_netlink = 1;
+#else
+ have_netlink = 0;
#endif
#ifdef HAVE_PROTOBUF
have_protobuf = 1;
+#else
+ have_protobuf = 0;
#endif
zfpm_g->message_format = ZFPM_MSG_FORMAT_NONE;
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index be77e91a53..9fffc9e611 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -27,6 +27,8 @@
#include "log.h"
#include "rib.h"
+#include "vty.h"
+#include "prefix.h"
#include "zebra/zserv.h"
#include "zebra/zebra_ns.h"
@@ -53,14 +55,13 @@ addr_to_a (u_char af, void *addr)
case AF_INET:
return inet_ntoa (*((struct in_addr *) addr));
-
-#ifdef HAVE_IPV6
+ break;
case AF_INET6:
return inet6_ntoa (*((struct in6_addr *) addr));
-#endif
-
+ break;
default:
return "<Addr in unknown AF>";
+ break;
}
}
@@ -92,12 +93,10 @@ af_addr_size (u_char af)
case AF_INET:
return 4;
-
-#ifdef HAVE_IPV6
+ break;
case AF_INET6:
return 16;
-#endif
-
+ break;
default:
assert(0);
return 16;
@@ -253,10 +252,15 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
* particularly in our communication with the FPM.
*/
if (cmd == RTM_DELROUTE && !rib)
- goto skip;
+ return 1;
+
+ if (!rib)
+ {
+ zfpm_debug ("%s: Expected non-NULL rib pointer", __PRETTY_FUNCTION__);
+ return 0;
+ }
- if (rib)
- ri->rtm_protocol = netlink_proto_from_route_type (rib->type);
+ ri->rtm_protocol = netlink_proto_from_route_type (rib->type);
if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
discard = 1;
@@ -281,9 +285,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
ri->metric = &rib->metric;
if (discard)
- {
- goto skip;
- }
+ return 1;
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
{
@@ -309,7 +311,6 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
return 0;
}
- skip:
return 1;
}
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 3333b7226a..56a6ca7afa 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -169,6 +169,7 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
struct prefix_ipv4 p;
struct route_node *rn;
struct rib *match;
+ struct nexthop *match_nh;
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
if (!table)
@@ -189,17 +190,22 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
/* Locate a valid connected route. */
RNODE_FOREACH_RIB (rn, match)
{
- if ((match->type == ZEBRA_ROUTE_CONNECT) &&
- !CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) &&
- CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
- break;
+ if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) ||
+ !CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+ continue;
+
+ for (match_nh = match->nexthop; match_nh; match_nh = match_nh->next)
+ {
+ if (match->type == ZEBRA_ROUTE_CONNECT ||
+ nexthop->ifindex == match_nh->ifindex)
+ {
+ nexthop->ifindex = match_nh->ifindex;
+ return 1;
+ }
+ }
}
- if (!match || !match->nexthop)
- return 0;
-
- nexthop->ifindex = match->nexthop->ifindex;
- return 1;
+ return 0;
}
@@ -268,6 +274,7 @@ nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe)
switch (nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
if (nhlfe_nexthop_active_ipv4 (nhlfe, nexthop))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
@@ -577,6 +584,7 @@ nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size)
switch (nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
inet_ntop (AF_INET, &nexthop->gate.ipv4, buf, size);
break;
case NEXTHOP_TYPE_IPV6:
@@ -609,8 +617,11 @@ nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
switch (nhop->type)
{
case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
cmp = memcmp(&(nhop->gate.ipv4), &(gate->ipv4),
sizeof(struct in_addr));
+ if (!cmp && nhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
+ cmp = !(nhop->ifindex == ifindex);
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -686,7 +697,10 @@ nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
switch (nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
nexthop->gate.ipv4 = gate->ipv4;
+ if (ifindex)
+ nexthop->ifindex = ifindex;
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -737,6 +751,9 @@ nhlfe_del (zebra_nhlfe_t *nhlfe)
else
lsp->nhlfe_list = nhlfe->next;
+ if (nhlfe == lsp->best_nhlfe)
+ lsp->best_nhlfe = NULL;
+
XFREE (MTYPE_NHLFE, nhlfe);
return 0;
@@ -842,6 +859,7 @@ nhlfe_json (zebra_nhlfe_t *nhlfe)
switch (nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
json_object_string_add(json_nhlfe, "nexthop",
inet_ntoa (nexthop->gate.ipv4));
break;
@@ -879,7 +897,10 @@ nhlfe_print (zebra_nhlfe_t *nhlfe, struct vty *vty)
switch (nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
+ if (nexthop->ifindex)
+ vty_out (vty, " dev %s", ifindex2ifname (nexthop->ifindex));
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -1258,7 +1279,8 @@ mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
*/
int
mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
- struct prefix *prefix, union g_addr *gate, u_int8_t distance,
+ struct prefix *prefix, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex, u_int8_t distance,
mpls_label_t out_label)
{
struct route_table *table;
@@ -1285,27 +1307,33 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
return -1;
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
- switch (prefix->family)
- {
- case AF_INET:
- if (nexthop->type != NEXTHOP_TYPE_IPV4 &&
- nexthop->type != NEXTHOP_TYPE_IPV4_IFINDEX)
+ {
+ switch (nexthop->type)
+ {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ if (gtype != NEXTHOP_TYPE_IPV4 && gtype != NEXTHOP_TYPE_IPV4_IFINDEX)
continue;
if (! IPV4_ADDR_SAME (&nexthop->gate.ipv4, &gate->ipv4))
continue;
+ if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX &&
+ nexthop->ifindex != ifindex)
+ continue;
goto found;
- break;
- case AF_INET6:
- if (nexthop->type != NEXTHOP_TYPE_IPV6 &&
- nexthop->type != NEXTHOP_TYPE_IPV6_IFINDEX)
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ if (gtype != NEXTHOP_TYPE_IPV6 && gtype != NEXTHOP_TYPE_IPV6_IFINDEX)
continue;
if (! IPV6_ADDR_SAME (&nexthop->gate.ipv6, &gate->ipv6))
continue;
+ if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX &&
+ nexthop->ifindex != ifindex)
+ continue;
goto found;
- break;
default:
break;
- }
+ }
+ }
/* nexthop not found */
return -1;
@@ -1811,6 +1839,7 @@ zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf,
switch (nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out (vty, "%15s", inet_ntoa (nexthop->gate.ipv4));
break;
case NEXTHOP_TYPE_IPV6:
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index 9f24689595..a871fac651 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -169,7 +169,8 @@ mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
*/
int
mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
- struct prefix *prefix, union g_addr *gate, u_int8_t distance,
+ struct prefix *prefix, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex, u_int8_t distance,
mpls_label_t out_label);
/*
diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c
index 8b967c3af8..fcd0fff32c 100644
--- a/zebra/zebra_mpls_vty.c
+++ b/zebra/zebra_mpls_vty.c
@@ -159,7 +159,7 @@ zebra_mpls_transit_lsp (struct vty *vty, int add_cmd, const char *inlabel_str,
DEFUN (mpls_transit_lsp,
mpls_transit_lsp_cmd,
- "mpls lsp <16-1048575> (A.B.C.D|X:X::X:X) (<16-1048575>|explicit-null|implicit-null)",
+ "mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
MPLS_STR
"Establish label switched path\n"
"Incoming MPLS label\n"
@@ -169,12 +169,12 @@ DEFUN (mpls_transit_lsp,
"Use Explicit-Null label\n"
"Use Implicit-Null label\n")
{
- return zebra_mpls_transit_lsp (vty, 1, argv[0], argv[1], argv[2], NULL);
+ return zebra_mpls_transit_lsp (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL);
}
DEFUN (no_mpls_transit_lsp,
no_mpls_transit_lsp_cmd,
- "no mpls lsp <16-1048575> (A.B.C.D|X:X::X:X)",
+ "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X>",
NO_STR
MPLS_STR
"Establish label switched path\n"
@@ -182,12 +182,12 @@ DEFUN (no_mpls_transit_lsp,
"IPv4 gateway address\n"
"IPv6 gateway address\n")
{
- return zebra_mpls_transit_lsp (vty, 0, argv[0], argv[1], NULL, NULL);
+ return zebra_mpls_transit_lsp (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL);
}
ALIAS (no_mpls_transit_lsp,
no_mpls_transit_lsp_out_label_cmd,
- "no mpls lsp <16-1048575> (A.B.C.D|X:X::X:X) (<16-1048575>|explicit-null|implicit-null)",
+ "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
NO_STR
MPLS_STR
"Establish label switched path\n"
@@ -200,19 +200,19 @@ ALIAS (no_mpls_transit_lsp,
DEFUN (no_mpls_transit_lsp_all,
no_mpls_transit_lsp_all_cmd,
- "no mpls lsp <16-1048575>",
+ "no mpls lsp (16-1048575)",
NO_STR
MPLS_STR
"Establish label switched path\n"
"Incoming MPLS label\n")
{
- return zebra_mpls_transit_lsp (vty, 0, argv[0], NULL, NULL, NULL);
+ return zebra_mpls_transit_lsp (vty, 0, argv[3]->arg, NULL, NULL, NULL);
}
/* Static route configuration. */
DEFUN (ip_route_label,
ip_route_label_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) label WORD",
+ "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> label WORD",
IP_STR
"Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
@@ -222,13 +222,13 @@ DEFUN (ip_route_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
- NULL, NULL, argv[2]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL,
+ NULL, NULL, argv[5]->arg);
}
DEFUN (ip_route_tag_label,
ip_route_tag_label_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD",
+ "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> tag (1-4294967295) label WORD",
IP_STR
"Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
@@ -240,14 +240,14 @@ DEFUN (ip_route_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
- NULL, NULL, argv[3]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg,
+ NULL, NULL, argv[7]->arg);
}
/* Mask as A.B.C.D format. */
DEFUN (ip_route_mask_label,
ip_route_mask_label_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) label WORD",
+ "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> label WORD",
IP_STR
"Establish static routes\n"
"IP destination prefix\n"
@@ -258,13 +258,13 @@ DEFUN (ip_route_mask_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
- NULL, NULL, argv[3]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL,
+ NULL, NULL, argv[6]->arg);
}
DEFUN (ip_route_mask_tag_label,
ip_route_mask_tag_label_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD",
+ "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> tag (1-4294967295) label WORD",
IP_STR
"Establish static routes\n"
"IP destination prefix\n"
@@ -278,14 +278,14 @@ DEFUN (ip_route_mask_tag_label,
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
- NULL, NULL, argv[4]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg,
+ NULL, NULL, argv[8]->arg);
}
/* Distance option value. */
DEFUN (ip_route_distance_label,
ip_route_distance_label_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> label WORD",
+ "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> (1-255) label WORD",
IP_STR
"Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
@@ -296,13 +296,13 @@ DEFUN (ip_route_distance_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
- argv[2], NULL, argv[3]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL,
+ argv[4]->arg, NULL, argv[6]->arg);
}
DEFUN (ip_route_tag_distance_label,
ip_route_tag_distance_label_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD",
+ "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> tag (1-4294967295) (1-255) label WORD",
IP_STR
"Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
@@ -316,13 +316,13 @@ DEFUN (ip_route_tag_distance_label,
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
- argv[3], NULL, argv[4]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg,
+ argv[6]->arg, NULL, argv[8]->arg);
}
DEFUN (ip_route_mask_distance_label,
ip_route_mask_distance_label_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> label WORD",
+ "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> (1-255) label WORD",
IP_STR
"Establish static routes\n"
"IP destination prefix\n"
@@ -334,13 +334,13 @@ DEFUN (ip_route_mask_distance_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
- argv[3], NULL, argv[4]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL,
+ argv[5]->arg, NULL, argv[7]->arg);
}
DEFUN (ip_route_mask_tag_distance_label,
ip_route_mask_tag_distance_label_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD",
+ "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> tag (1-4294967295) (1-255) label WORD",
IP_STR
"Establish static routes\n"
"IP destination prefix\n"
@@ -354,13 +354,13 @@ DEFUN (ip_route_mask_tag_distance_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
- argv[4], NULL, argv[5]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg,
+ argv[7]->arg, NULL, argv[9]->arg);
}
DEFUN (no_ip_route_label,
no_ip_route_label_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) label WORD",
+ "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -371,13 +371,13 @@ DEFUN (no_ip_route_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
- NULL, NULL, argv[2]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL,
+ NULL, NULL, argv[6]->arg);
}
DEFUN (no_ip_route_tag_label,
no_ip_route_tag_label_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD",
+ "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> tag (1-4294967295) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -390,13 +390,13 @@ DEFUN (no_ip_route_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
- NULL, NULL, argv[3]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg,
+ NULL, NULL, argv[8]->arg);
}
DEFUN (no_ip_route_mask_label,
no_ip_route_mask_label_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) label WORD",
+ "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -408,13 +408,13 @@ DEFUN (no_ip_route_mask_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
- NULL, NULL, argv[3]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL,
+ NULL, NULL, argv[7]->arg);
}
DEFUN (no_ip_route_mask_tag_label,
no_ip_route_mask_tag_label_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD",
+ "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> tag (1-4294967295) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -428,13 +428,13 @@ DEFUN (no_ip_route_mask_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
- NULL, NULL, argv[4]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg,
+ NULL, NULL, argv[9]->arg);
}
DEFUN (no_ip_route_distance_label,
no_ip_route_distance_label_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> label WORD",
+ "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> (1-255) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -446,13 +446,13 @@ DEFUN (no_ip_route_distance_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
- argv[2], NULL, argv[3]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL,
+ argv[5]->arg, NULL, argv[7]->arg);
}
DEFUN (no_ip_route_tag_distance_label,
no_ip_route_tag_distance_label_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD",
+ "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> tag (1-4294967295) (1-255) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -466,13 +466,13 @@ DEFUN (no_ip_route_tag_distance_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
- argv[3], NULL, argv[4]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg,
+ argv[7]->arg, NULL, argv[9]->arg);
}
DEFUN (no_ip_route_mask_distance_label,
no_ip_route_mask_distance_label_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
+ "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> (1-255)",
NO_STR
IP_STR
"Establish static routes\n"
@@ -485,13 +485,13 @@ DEFUN (no_ip_route_mask_distance_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
- argv[3], NULL, argv[5]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL,
+ argv[6]->arg, NULL, NULL);
}
DEFUN (no_ip_route_mask_tag_distance_label,
no_ip_route_mask_tag_distance_label_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD",
+ "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> tag (1-4294967295) (1-255) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -506,13 +506,13 @@ DEFUN (no_ip_route_mask_tag_distance_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
- argv[4], NULL, argv[5]);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg,
+ argv[8]->arg, NULL, argv[10]->arg);
}
DEFUN (ipv6_route_label,
ipv6_route_label_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) label WORD",
+ "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> label WORD",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
@@ -521,12 +521,12 @@ DEFUN (ipv6_route_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, argv[2]);
+ return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, NULL, NULL, argv[5]->arg);
}
DEFUN (ipv6_route_tag_label,
ipv6_route_tag_label_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> label WORD",
+ "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> tag (1-4294967295) label WORD",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
@@ -537,7 +537,7 @@ DEFUN (ipv6_route_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, argv[3]);
+ return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, NULL, NULL, argv[7]->arg);
}
DEFUN (ipv6_route_ifname_label,
@@ -551,11 +551,11 @@ DEFUN (ipv6_route_ifname_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, argv[3]);
+ return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, argv[6]->arg);
}
DEFUN (ipv6_route_ifname_tag_label,
ipv6_route_ifname_tag_label_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> label WORD",
+ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) label WORD",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
@@ -566,12 +566,12 @@ DEFUN (ipv6_route_ifname_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, argv[4]);
+ return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg);
}
DEFUN (ipv6_route_pref_label,
ipv6_route_pref_label_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> label WORD",
+ "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> (1-255) label WORD",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
@@ -581,12 +581,12 @@ DEFUN (ipv6_route_pref_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, argv[3]);
+ return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, argv[4]->arg, NULL, argv[6]->arg);
}
DEFUN (ipv6_route_pref_tag_label,
ipv6_route_pref_tag_label_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> label WORD",
+ "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> tag (1-4294967295) (1-255) label WORD",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
@@ -598,12 +598,12 @@ DEFUN (ipv6_route_pref_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, argv[4]);
+ return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, argv[6]->arg, NULL, argv[8]->arg);
}
DEFUN (ipv6_route_ifname_pref_label,
ipv6_route_ifname_pref_label_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> label WORD",
+ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (1-255) label WORD",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
@@ -613,12 +613,12 @@ DEFUN (ipv6_route_ifname_pref_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, argv[4]);
+ return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg);
}
DEFUN (ipv6_route_ifname_pref_tag_label,
ipv6_route_ifname_pref_tag_label_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> label WORD",
+ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) (1-255) label WORD",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
@@ -630,12 +630,12 @@ DEFUN (ipv6_route_ifname_pref_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, argv[5]);
+ return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg);
}
DEFUN (no_ipv6_route_label,
no_ipv6_route_label_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) label WORD",
+ "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -645,12 +645,12 @@ DEFUN (no_ipv6_route_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, argv[2]);
+ return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, NULL, NULL, argv[6]->arg);
}
DEFUN (no_ipv6_route_tag_label,
no_ipv6_route_tag_label_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> label WORD",
+ "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> tag (1-4294967295) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -662,7 +662,7 @@ DEFUN (no_ipv6_route_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, argv[3]);
+ return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg);
}
DEFUN (no_ipv6_route_ifname_label,
@@ -677,12 +677,12 @@ DEFUN (no_ipv6_route_ifname_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, argv[3]);
+ return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, NULL, NULL, argv[7]->arg);
}
DEFUN (no_ipv6_route_ifname_tag_label,
no_ipv6_route_ifname_tag_label_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> label WORD",
+ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -694,12 +694,12 @@ DEFUN (no_ipv6_route_ifname_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, argv[4]);
+ return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, NULL, NULL, argv[9]->arg);
}
DEFUN (no_ipv6_route_pref_label,
no_ipv6_route_pref_label_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> label WORD",
+ "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> (1-255) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -710,12 +710,12 @@ DEFUN (no_ipv6_route_pref_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, argv[3]);
+ return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg);
}
DEFUN (no_ipv6_route_pref_tag_label,
no_ipv6_route_pref_tag_label_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> label WORD",
+ "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> tag (1-4294967295) (1-255) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -728,12 +728,12 @@ DEFUN (no_ipv6_route_pref_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, argv[4]);
+ return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg);
}
DEFUN (no_ipv6_route_ifname_pref_label,
no_ipv6_route_ifname_pref_label_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> label WORD",
+ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (1-255) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -744,12 +744,12 @@ DEFUN (no_ipv6_route_ifname_pref_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, argv[4]);
+ return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, argv[6]->arg, NULL, argv[8]->arg);
}
DEFUN (no_ipv6_route_ifname_pref_tag_label,
no_ipv6_route_ifname_pref_tag_label_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> label WORD",
+ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) (1-255) label WORD",
NO_STR
IP_STR
"Establish static routes\n"
@@ -762,7 +762,7 @@ DEFUN (no_ipv6_route_ifname_pref_tag_label,
"Specify label(s) for this route\n"
"One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, argv[5]);
+ return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, argv[8]->arg, NULL, argv[10]->arg);
}
/* MPLS LSP configuration write function. */
@@ -782,36 +782,36 @@ zebra_mpls_config (struct vty *vty)
DEFUN (show_mpls_table,
show_mpls_table_cmd,
- "show mpls table {json}",
+ "show mpls table [json]",
SHOW_STR
MPLS_STR
"MPLS table\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
struct zebra_vrf *zvrf;
- u_char use_json = (argv[0] != NULL);
+ u_char uj = use_json (argc, argv);
zvrf = vrf_info_lookup(VRF_DEFAULT);
- zebra_mpls_print_lsp_table(vty, zvrf, use_json);
+ zebra_mpls_print_lsp_table(vty, zvrf, uj);
return CMD_SUCCESS;
}
DEFUN (show_mpls_table_lsp,
show_mpls_table_lsp_cmd,
- "show mpls table <16-1048575> {json}",
+ "show mpls table (16-1048575) [json]",
SHOW_STR
MPLS_STR
"MPLS table\n"
"LSP to display information about\n"
- "JavaScript Object Notation\n")
+ JSON_STR)
{
u_int32_t label;
struct zebra_vrf *zvrf;
- u_char use_json = (argv[1] != NULL);
+ u_char uj = use_json (argc, argv);
zvrf = vrf_info_lookup(VRF_DEFAULT);
- label = atoi(argv[0]);
- zebra_mpls_print_lsp (vty, zvrf, label, use_json);
+ label = atoi(argv[3]->arg);
+ zebra_mpls_print_lsp (vty, zvrf, label, uj);
return CMD_SUCCESS;
}
diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c
new file mode 100644
index 0000000000..86356104bd
--- /dev/null
+++ b/zebra/zebra_mroute.c
@@ -0,0 +1,68 @@
+/* zebra_mroute code
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "stream.h"
+#include "prefix.h"
+#include "vrf.h"
+#include "rib.h"
+
+#include "zebra/zserv.h"
+#include "zebra/zebra_vrf.h"
+#include "zebra/zebra_mroute.h"
+#include "zebra/rt.h"
+
+int
+zebra_ipmr_route_stats (struct zserv *client, int fd, u_short length, struct zebra_vrf *zvrf)
+{
+ struct mcast_route_data mroute;
+ struct stream *s;
+ int suc;
+
+ char sbuf[40];
+ char gbuf[40];
+
+ memset (&mroute, 0, sizeof (mroute));
+ stream_get (&mroute.sg.src, client->ibuf, 4);
+ stream_get (&mroute.sg.grp, client->ibuf, 4);
+ mroute.ifindex = stream_getl (client->ibuf);
+
+ strcpy (sbuf, inet_ntoa (mroute.sg.src));
+ strcpy (gbuf, inet_ntoa (mroute.sg.grp));
+
+ suc = kernel_get_ipmr_sg_stats (&mroute);
+
+ s = client->obuf;
+
+ stream_reset (s);
+
+ zserv_create_header (s, ZEBRA_IPMR_ROUTE_STATS, zvrf_id (zvrf));
+ stream_put_in_addr (s, &mroute.sg.src);
+ stream_put_in_addr (s, &mroute.sg.grp);
+ stream_put (s, &mroute.lastused, sizeof (mroute.lastused));
+ stream_putl (s, suc);
+
+ stream_putw_at (s, 0, stream_get_endp (s));
+ zebra_server_send_message (client);
+ return 0;
+}
diff --git a/zebra/zebra_mroute.h b/zebra/zebra_mroute.h
new file mode 100644
index 0000000000..c0bac43a81
--- /dev/null
+++ b/zebra/zebra_mroute.h
@@ -0,0 +1,35 @@
+/* zebra_mroute.h
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __ZEBRA_MROUTE_H__
+#define __ZEBRA_MROUTE_H__
+
+struct mcast_route_data {
+ struct prefix_sg sg;
+ unsigned int ifindex;
+ unsigned long long lastused;
+};
+
+int zebra_ipmr_route_stats (struct zserv *client, int sock, u_short length, struct zebra_vrf *zvf);
+
+#endif
+
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index a633ce6332..bc924842d4 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -388,7 +388,13 @@ zebra_ptm_socket_init (void)
if (sock < 0)
return -1;
if (set_nonblocking(sock) < 0)
- return -1;
+ {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug ("%s: Unable to set socket non blocking[%s]",
+ __PRETTY_FUNCTION__, safe_strerror (errno));
+ close (sock);
+ return -1;
+ }
/* Make server socket. */
memset (&addr, 0, sizeof (struct sockaddr_un));
@@ -722,13 +728,11 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf));
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf);
}
-#ifdef HAVE_IPV6
else
{
inet_ntop(AF_INET6, &dst_p.u.prefix6, buf, sizeof(buf));
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf);
}
-#endif /* HAVE_IPV6 */
min_rx_timer = stream_getl(s);
sprintf(tmp_buf, "%d", min_rx_timer);
@@ -763,14 +767,12 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
ptm_lib_append_msg(ptm_hdl, out_ctxt,
ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
}
-#ifdef HAVE_IPV6
else
{
inet_ntop(AF_INET6, &src_p.u.prefix6, buf, sizeof(buf));
ptm_lib_append_msg(ptm_hdl, out_ctxt,
ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
}
-#endif /* HAVE_IPV6 */
multi_hop_cnt = stream_getc(s);
sprintf(tmp_buf, "%d", multi_hop_cnt);
@@ -783,7 +785,6 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
}
else
{
-#ifdef HAVE_IPV6
if (dst_p.family == AF_INET6)
{
src_p.family = stream_getw(s);
@@ -807,7 +808,6 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
}
}
-#endif /* HAVE_IPV6 */
len = stream_getc(s);
stream_get(if_name, s, len);
if_name[len] = '\0';
@@ -883,17 +883,11 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length,
stream_get(&dst_p.u.prefix, s, dst_p.prefixlen);
if (dst_p.family == AF_INET)
- {
- inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf));
- ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf);
- }
-#ifdef HAVE_IPV6
+ inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf));
else
- {
- inet_ntop(AF_INET6, &dst_p.u.prefix6, buf, sizeof(buf));
- ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf);
- }
-#endif /* HAVE_IPV6 */
+ inet_ntop(AF_INET6, &dst_p.u.prefix6, buf, sizeof(buf));
+ ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf);
+
multi_hop = stream_getc(s);
if (multi_hop)
@@ -911,26 +905,18 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length,
stream_get(&src_p.u.prefix, s, src_p.prefixlen);
if (src_p.family == AF_INET)
- {
- inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf));
- ptm_lib_append_msg(ptm_hdl, out_ctxt,
- ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
- }
-#ifdef HAVE_IPV6
+ inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf));
else
- {
- inet_ntop(AF_INET6, &src_p.u.prefix6, buf, sizeof(buf));
- ptm_lib_append_msg(ptm_hdl, out_ctxt,
- ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
- }
-#endif /* HAVE_IPV6 */
+ inet_ntop(AF_INET6, &src_p.u.prefix6, buf, sizeof(buf));
+ ptm_lib_append_msg(ptm_hdl, out_ctxt,
+ ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
+
if (zvrf_id (zvrf) != VRF_DEFAULT)
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD,
zvrf_name (zvrf));
}
else
{
-#ifdef HAVE_IPV6
if (dst_p.family == AF_INET6)
{
src_p.family = stream_getw(s);
@@ -954,7 +940,6 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length,
ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
}
}
-#endif /* HAVE_IPV6 */
len = stream_getc(s);
stream_get(if_name, s, len);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index e48da0479b..13418c509e 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -37,6 +37,7 @@
#include "nexthop.h"
#include "vrf.h"
#include "mpls.h"
+#include "srcdest_table.h"
#include "zebra/rib.h"
#include "zebra/rt.h"
@@ -88,7 +89,7 @@ static void __attribute__((format (printf, 5, 6)))
_rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, int priority,
const char *msgfmt, ...)
{
- char buf[PREFIX_STRLEN + 8];
+ char buf[SRCDEST2STR_BUFFER + sizeof(" (MRIB)")];
char msgbuf[512];
va_list ap;
@@ -98,9 +99,9 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, int prior
if (rn)
{
- rib_table_info_t *info = rn->table->info;
+ rib_table_info_t *info = srcdest_rnode_table_info (rn);
+ srcdest_rnode2str(rn, buf, sizeof(buf));
- prefix2str(&rn->p, buf, sizeof(buf));
if (info->safi == SAFI_MULTICAST)
strcat(buf, " (MRIB)");
}
@@ -347,10 +348,10 @@ nexthop_has_fib_child(struct nexthop *nexthop)
/* If force flag is not set, do not modify falgs at all for uninstall
the route from FIB. */
static int
-nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
- struct route_node *top)
+nexthop_active (afi_t afi, struct rib *rib, struct nexthop *nexthop, int set,
+ struct route_node *top)
{
- struct prefix_ipv4 p;
+ struct prefix p;
struct route_table *table;
struct route_node *rn;
struct rib *match;
@@ -360,7 +361,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
int recursing = 0;
struct interface *ifp;
- if (nexthop->type == NEXTHOP_TYPE_IPV4)
+ if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6)
nexthop->ifindex = 0;
if (set)
@@ -398,13 +399,25 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
}
/* Make lookup prefix. */
- memset (&p, 0, sizeof (struct prefix_ipv4));
- p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
- p.prefix = nexthop->gate.ipv4;
-
+ memset (&p, 0, sizeof (struct prefix));
+ switch (afi)
+ {
+ case AFI_IP:
+ p.family = AF_INET;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.u.prefix4 = nexthop->gate.ipv4;
+ break;
+ case AFI_IP6:
+ p.family = AF_INET6;
+ p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.u.prefix6 = nexthop->gate.ipv6;
+ break;
+ default:
+ assert (afi != AFI_IP && afi != AFI_IP6);
+ break;
+ }
/* Lookup table. */
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id);
+ table = zebra_vrf_table (afi, SAFI_UNICAST, rib->vrf_id);
if (! table)
return 0;
@@ -457,9 +470,12 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
{
/* Directly point connected route. */
newhop = match->nexthop;
- if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
- nexthop->ifindex = newhop->ifindex;
-
+ if (newhop)
+ {
+ if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
+ nexthop->type == NEXTHOP_TYPE_IPV6)
+ nexthop->ifindex = newhop->ifindex;
+ }
return 1;
}
else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
@@ -491,6 +507,18 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
}
}
+ if (newhop->type == NEXTHOP_TYPE_IPV6
+ || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
+ {
+ resolved_hop->type = newhop->type;
+ resolved_hop->gate.ipv6 = newhop->gate.ipv6;
+
+ if (newhop->ifindex)
+ {
+ resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
+ resolved_hop->ifindex = newhop->ifindex;
+ }
+ }
/* If the resolving route is an interface route,
* it means the gateway we are looking up is connected
@@ -503,8 +531,16 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
if (newhop->type == NEXTHOP_TYPE_IFINDEX)
{
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
- resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
- resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
+ if (afi == AFI_IP)
+ {
+ resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
+ resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
+ }
+ else if (afi == AFI_IP6)
+ {
+ resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
+ resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
+ }
resolved_hop->ifindex = newhop->ifindex;
}
@@ -541,151 +577,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
}
}
-
- /* If the resolving route is an interface route,
- * it means the gateway we are looking up is connected
- * to that interface. (The actual network is _not_ onlink).
- * Therefore, the resolved route should have the original
- * gateway as nexthop as it is directly connected.
- *
- * On Linux, we have to set the onlink netlink flag because
- * otherwise, the kernel won't accept the route.
- */
- if (newhop->type == NEXTHOP_TYPE_IFINDEX)
- {
- resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
- resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
- resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
- resolved_hop->ifindex = newhop->ifindex;
- }
-
- nexthop_add(&nexthop->resolved, resolved_hop);
- }
- resolved = 1;
- }
- if (resolved && set)
- rib->nexthop_mtu = match->mtu;
- return resolved;
- }
- else
- {
- return 0;
- }
- }
- }
- return 0;
-}
-
-/* If force flag is not set, do not modify falgs at all for uninstall
- the route from FIB. */
-static int
-nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
- struct route_node *top)
-{
- struct prefix_ipv6 p;
- struct route_table *table;
- struct route_node *rn;
- struct rib *match;
- int resolved;
- struct nexthop *newhop, *tnewhop;
- int recursing = 0;
- struct nexthop *resolved_hop;
-
- if (nexthop->type == NEXTHOP_TYPE_IPV6)
- nexthop->ifindex = 0;
-
- if (set)
- {
- UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
- zebra_deregister_rnh_static_nexthops (rib->vrf_id, nexthop->resolved, top);
- nexthops_free(nexthop->resolved);
- nexthop->resolved = NULL;
- }
-
- /* Skip nexthops that have been filtered out due to route-map */
- /* The nexthops are specific to this route and so the same */
- /* nexthop for a different route may not have this flag set */
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED))
- return 0;
-
- /* Make lookup prefix. */
- memset (&p, 0, sizeof (struct prefix_ipv6));
- p.family = AF_INET6;
- p.prefixlen = IPV6_MAX_PREFIXLEN;
- p.prefix = nexthop->gate.ipv6;
-
- /* Lookup table. */
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id);
- if (! table)
- return 0;
-
- rn = route_node_match (table, (struct prefix *) &p);
- while (rn)
- {
- route_unlock_node (rn);
-
- /* If lookup self prefix return immediately. */
- if (rn == top)
- return 0;
-
- /* Pick up selected route. */
- /* However, do not resolve over default route unless explicitly allowed. */
- if (is_default_prefix (&rn->p) &&
- !nh_resolve_via_default (p.family))
- return 0;
-
- RNODE_FOREACH_RIB (rn, match)
- {
- if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
- continue;
- if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB))
- break;
- }
-
- /* If there is no selected route or matched route is EGP, go up
- tree. */
- if (! match)
- {
- do {
- rn = rn->parent;
- } while (rn && rn->info == NULL);
- if (rn)
- route_lock_node (rn);
- }
- else
- {
- /* If the longest prefix match for the nexthop yields
- * a blackhole, mark it as inactive. */
- if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE)
- || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT))
- return 0;
-
- if (match->type == ZEBRA_ROUTE_CONNECT)
- {
- /* Directly point connected route. */
- newhop = match->nexthop;
-
- if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
- nexthop->ifindex = newhop->ifindex;
-
- return 1;
- }
- else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
- {
- resolved = 0;
- for (newhop = match->nexthop; newhop; newhop = newhop->next)
- if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
- && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
- {
- if (set)
- {
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
- SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
-
- resolved_hop = nexthop_new();
- SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
- /* See nexthop_active_ipv4 for a description how the
- * resolved nexthop is constructed. */
if (newhop->type == NEXTHOP_TYPE_IPV6
|| newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
{
@@ -699,59 +590,37 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
}
}
+ /* If the resolving route is an interface route,
+ * it means the gateway we are looking up is connected
+ * to that interface. (The actual network is _not_ onlink).
+ * Therefore, the resolved route should have the original
+ * gateway as nexthop as it is directly connected.
+ *
+ * On Linux, we have to set the onlink netlink flag because
+ * otherwise, the kernel won't accept the route.
+ */
if (newhop->type == NEXTHOP_TYPE_IFINDEX)
{
- resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
- resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
- resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
- resolved_hop->ifindex = newhop->ifindex;
- }
-
- nexthop_add(&nexthop->resolved, resolved_hop);
- }
- resolved = 1;
- }
- return resolved;
- }
- else if (rib->type == ZEBRA_ROUTE_STATIC)
- {
- resolved = 0;
- for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
- if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
- {
- if (set)
- {
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
-
- resolved_hop = nexthop_new();
- SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
- /* See nexthop_active_ipv4 for a description how the
- * resolved nexthop is constructed. */
- if (newhop->type == NEXTHOP_TYPE_IPV6
- || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
- {
- resolved_hop->type = newhop->type;
- resolved_hop->gate.ipv6 = newhop->gate.ipv6;
-
- if (newhop->ifindex)
+ resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
+ if (afi == AFI_IP)
{
- resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
- resolved_hop->ifindex = newhop->ifindex;
+ resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
+ resolved_hop->gate.ipv4 = nexthop->gate.ipv4;
}
- }
-
- if (newhop->type == NEXTHOP_TYPE_IFINDEX)
- {
- resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
+ else if (afi == AFI_IP6)
+ {
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
- resolved_hop->ifindex = newhop->ifindex;
+ }
+ resolved_hop->ifindex = newhop->ifindex;
}
nexthop_add(&nexthop->resolved, resolved_hop);
}
resolved = 1;
}
+ if (resolved && set)
+ rib->nexthop_mtu = match->mtu;
return resolved;
}
else
@@ -1051,11 +920,12 @@ static unsigned
nexthop_active_check (struct route_node *rn, struct rib *rib,
struct nexthop *nexthop, int set)
{
- rib_table_info_t *info = rn->table->info;
struct interface *ifp;
route_map_result_t ret = RMAP_MATCH;
int family;
- char buf[INET6_ADDRSTRLEN+1];
+ char buf[SRCDEST2STR_BUFFER];
+ struct prefix *p, *src_p;
+ srcdest_rnode_prefixes (rn, &p, &src_p);
if (rn->p.family == AF_INET)
family = AFI_IP;
@@ -1075,14 +945,14 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
family = AFI_IP;
- if (nexthop_active_ipv4 (rib, nexthop, set, rn))
+ if (nexthop_active (AFI_IP, rib, nexthop, set, rn))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
break;
case NEXTHOP_TYPE_IPV6:
family = AFI_IP6;
- if (nexthop_active_ipv6 (rib, nexthop, set, rn))
+ if (nexthop_active (AFI_IP6, rib, nexthop, set, rn))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
@@ -1101,7 +971,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
}
else
{
- if (nexthop_active_ipv6 (rib, nexthop, set, rn))
+ if (nexthop_active (AFI_IP6, rib, nexthop, set, rn))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
@@ -1119,8 +989,8 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
/* XXX: What exactly do those checks do? Do we support
* e.g. IPv4 routes with IPv6 nexthops or vice versa? */
if (RIB_SYSTEM_ROUTE(rib) ||
- (family == AFI_IP && rn->p.family != AF_INET) ||
- (family == AFI_IP6 && rn->p.family != AF_INET6))
+ (family == AFI_IP && p->family != AF_INET) ||
+ (family == AFI_IP6 && p->family != AF_INET6))
return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
/* The original code didn't determine the family correctly
@@ -1130,20 +1000,25 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
* in every case.
*/
if (!family)
- family = info->afi;
+ {
+ rib_table_info_t *info;
+
+ info = srcdest_rnode_table_info(rn);
+ family = info->afi;
+ }
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
/* It'll get set if required inside */
- ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->vrf_id,
+ ret = zebra_route_map_check(family, rib->type, p, nexthop, rib->vrf_id,
rib->tag);
if (ret == RMAP_DENYMATCH)
{
if (IS_ZEBRA_DEBUG_RIB)
{
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
- zlog_debug("%u:%s/%d: Filtering out with NH out %s due to route map",
- rib->vrf_id, buf, rn->p.prefixlen,
+ srcdest_rnode2str(rn, buf, sizeof(buf));
+ zlog_debug("%u:%s: Filtering out with NH out %s due to route map",
+ rib->vrf_id, buf,
ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
}
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
@@ -1216,8 +1091,11 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old)
{
int ret = 0;
struct nexthop *nexthop, *tnexthop;
- rib_table_info_t *info = rn->table->info;
+ rib_table_info_t *info = srcdest_rnode_table_info(rn);
int recursing;
+ struct prefix *p, *src_p;
+
+ srcdest_rnode_prefixes (rn, &p, &src_p);
if (info->safi != SAFI_UNICAST)
{
@@ -1231,7 +1109,7 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old)
* the kernel.
*/
zfpm_trigger_update (rn, "installing in kernel");
- ret = kernel_route_rib (&rn->p, old, rib);
+ ret = kernel_route_rib (p, src_p, old, rib);
/* If install succeeds, update FIB flag for nexthops. */
if (!ret)
@@ -1257,8 +1135,11 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
{
int ret = 0;
struct nexthop *nexthop, *tnexthop;
- rib_table_info_t *info = rn->table->info;
+ rib_table_info_t *info = srcdest_rnode_table_info(rn);
int recursing;
+ struct prefix *p, *src_p;
+
+ srcdest_rnode_prefixes (rn, &p, &src_p);
if (info->safi != SAFI_UNICAST)
{
@@ -1272,7 +1153,7 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
* the kernel.
*/
zfpm_trigger_update (rn, "uninstalling from kernel");
- ret = kernel_route_rib (&rn->p, rib, NULL);
+ ret = kernel_route_rib (p, src_p, rib, NULL);
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
@@ -1284,7 +1165,7 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
static void
rib_uninstall (struct route_node *rn, struct rib *rib)
{
- rib_table_info_t *info = rn->table->info;
+ rib_table_info_t *info = srcdest_rnode_table_info(rn);
if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
{
@@ -1298,7 +1179,10 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
{
- redistribute_delete (&rn->p, rib);
+ struct prefix *p, *src_p;
+ srcdest_rnode_prefixes (rn, &p, &src_p);
+
+ redistribute_delete (p, src_p, rib);
UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
}
}
@@ -1367,8 +1251,6 @@ static void
rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
struct rib *new)
{
- char buf[INET6_ADDRSTRLEN];
-
zfpm_trigger_update (rn, "new route selected");
/* Update real nexthop. This may actually determine if nexthop is active or not. */
@@ -1381,18 +1263,20 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
SET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB);
if (IS_ZEBRA_DEBUG_RIB)
{
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)",
- zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type);
+ char buf[SRCDEST2STR_BUFFER];
+ srcdest_rnode2str(rn, buf, sizeof(buf));
+ zlog_debug ("%u:%s: Adding route rn %p, rib %p (type %d)",
+ zvrf_id (zvrf), buf, rn, new, new->type);
}
if (!RIB_SYSTEM_ROUTE (new))
{
if (rib_install_kernel (rn, new, NULL))
{
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_warn ("%u:%s/%d: Route install failed",
- zvrf_id (zvrf), buf, rn->p.prefixlen);
+ char buf[SRCDEST2STR_BUFFER];
+ srcdest_rnode2str(rn, buf, sizeof(buf));
+ zlog_warn ("%u:%s: Route install failed",
+ zvrf_id (zvrf), buf);
}
}
@@ -1403,16 +1287,15 @@ static void
rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
struct rib *old)
{
- char buf[INET6_ADDRSTRLEN];
-
zfpm_trigger_update (rn, "removing existing route");
/* Uninstall from kernel. */
if (IS_ZEBRA_DEBUG_RIB)
{
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)",
- zvrf_id (zvrf), buf, rn->p.prefixlen, rn, old, old->type);
+ char buf[SRCDEST2STR_BUFFER];
+ srcdest_rnode2str(rn, buf, sizeof(buf));
+ zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d)",
+ zvrf_id (zvrf), buf, rn, old, old->type);
}
if (!RIB_SYSTEM_ROUTE (old))
@@ -1429,15 +1312,11 @@ static void
rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
struct rib *old, struct rib *new)
{
- char buf[INET6_ADDRSTRLEN];
struct nexthop *nexthop = NULL, *tnexthop;
int recursing;
int nh_active = 0;
int installed = 1;
- if (IS_ZEBRA_DEBUG_RIB)
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
-
/*
* We have to install or update if a new route has been selected or
* something has changed.
@@ -1459,23 +1338,25 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
{
if (IS_ZEBRA_DEBUG_RIB)
{
+ char buf[SRCDEST2STR_BUFFER];
+ srcdest_rnode2str(rn, buf, sizeof(buf));
if (new != old)
- zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) "
- "old %p (type %d)", zvrf_id (zvrf), buf, rn->p.prefixlen,
+ zlog_debug ("%u:%s: Updating route rn %p, rib %p (type %d) "
+ "old %p (type %d)", zvrf_id (zvrf), buf,
rn, new, new->type, old, old->type);
else
- zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)",
- zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type);
+ zlog_debug ("%u:%s: Updating route rn %p, rib %p (type %d)",
+ zvrf_id (zvrf), buf, rn, new, new->type);
}
/* Non-system route should be installed. */
if (!RIB_SYSTEM_ROUTE (new))
{
if (rib_install_kernel (rn, new, old))
{
+ char buf[SRCDEST2STR_BUFFER];
+ srcdest_rnode2str(rn, buf, sizeof(buf));
installed = 0;
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_warn ("%u:%s/%d: Route install failed",
- zvrf_id (zvrf), buf, rn->p.prefixlen);
+ zlog_warn ("%u:%s: Route install failed", zvrf_id (zvrf), buf);
}
}
@@ -1507,14 +1388,16 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
{
if (IS_ZEBRA_DEBUG_RIB)
{
+ char buf[SRCDEST2STR_BUFFER];
+ srcdest_rnode2str(rn, buf, sizeof(buf));
if (new != old)
- zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
- "old %p (type %d) - %s", zvrf_id (zvrf), buf, rn->p.prefixlen,
+ zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d) "
+ "old %p (type %d) - %s", zvrf_id (zvrf), buf,
rn, new, new->type, old, old->type,
nh_active ? "install failed" : "nexthop inactive");
else
- zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s",
- zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type,
+ zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d) - %s",
+ zvrf_id (zvrf), buf, rn, new, new->type,
nh_active ? "install failed" : "nexthop inactive");
}
@@ -1613,9 +1496,11 @@ rib_process (struct route_node *rn)
struct rib *old_fib = NULL;
struct rib *new_fib = NULL;
struct rib *best = NULL;
- char buf[INET6_ADDRSTRLEN];
+ char buf[SRCDEST2STR_BUFFER];
rib_dest_t *dest;
struct zebra_vrf *zvrf = NULL;
+ struct prefix *p, *src_p;
+ srcdest_rnode_prefixes(rn, &p, &src_p);
vrf_id_t vrf_id = VRF_UNKNOWN;
assert (rn);
@@ -1628,17 +1513,17 @@ rib_process (struct route_node *rn)
}
if (IS_ZEBRA_DEBUG_RIB)
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
+ srcdest_rnode2str(rn, buf, sizeof(buf));
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%u:%s/%d: Processing rn %p", vrf_id, buf, rn->p.prefixlen, rn);
+ zlog_debug ("%u:%s: Processing rn %p", vrf_id, buf, rn);
- RNODE_FOREACH_RIB (rn, rib)
+ RNODE_FOREACH_RIB_SAFE (rn, rib, next)
{
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%u:%s/%d: Examine rib %p (type %d) status %x flags %x "
+ zlog_debug ("%u:%s: Examine rib %p (type %d) status %x flags %x "
"dist %d metric %d",
- vrf_id, buf, rn->p.prefixlen, rib, rib->type, rib->status,
+ vrf_id, buf, rib, rib->type, rib->status,
rib->flags, rib->distance, rib->metric);
UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
@@ -1687,9 +1572,9 @@ rib_process (struct route_node *rn)
if (rib != old_selected)
{
if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug ("%s: %s/%d: imported via import-table but denied "
+ zlog_debug ("%s: %s: imported via import-table but denied "
"by the ip protocol table route-map",
- __func__, buf, rn->p.prefixlen);
+ __func__, buf);
rib_unlink (rn, rib);
}
else
@@ -1740,8 +1625,8 @@ rib_process (struct route_node *rn)
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
{
- zlog_debug ("%u:%s/%d: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
- vrf_id, buf, rn->p.prefixlen,
+ zlog_debug ("%u:%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
+ vrf_id, buf,
(void *)old_selected,
(void *)new_selected,
(void *)old_fib,
@@ -1789,7 +1674,7 @@ rib_process (struct route_node *rn)
if (old_selected)
{
if (!new_selected)
- redistribute_delete(&rn->p, old_selected);
+ redistribute_delete(p, src_p, old_selected);
if (old_selected != new_selected)
UNSET_FLAG (old_selected->flags, ZEBRA_FLAG_SELECTED);
}
@@ -1798,185 +1683,10 @@ rib_process (struct route_node *rn)
{
/* Install new or replace existing redistributed entry */
SET_FLAG (new_selected->flags, ZEBRA_FLAG_SELECTED);
- redistribute_update (&rn->p, new_selected, old_selected);
- }
- }
-
-#if 0
- if (select && select == fib)
- {
- if (IS_ZEBRA_DEBUG_RIB)
- rnode_debug (rn, vrf_id, "Updating existing route, select %p, fib %p",
- (void *)select, (void *)fib);
- if (CHECK_FLAG (select->status, RIB_ENTRY_CHANGED))
- {
- if (info->safi == SAFI_UNICAST)
- zfpm_trigger_update (rn, "updating existing route");
-
- /* Set real nexthop. */
- /* Need to check if any NHs are active to clear the
- * the selected flag
- */
- if (nexthop_active_update (rn, select, 1))
- {
- if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)",
- vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
- if (! RIB_SYSTEM_ROUTE (select))
- {
- /* Clear FIB flag if performing a replace, will get set again
- * as part of install.
- */
- for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
- UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
- rib_install_kernel (rn, select, 1);
- }
-
- /* assuming that the receiver knows how to dedup */
- redistribute_update (&rn->p, select, NULL);
- }
- else
- {
- if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
- "- nexthop inactive",
- vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
-
- /* Withdraw unreachable redistribute route */
- redistribute_delete(&rn->p, select);
-
- /* Do the uninstall here, if not done earlier. */
- if (! RIB_SYSTEM_ROUTE (select))
- rib_uninstall_kernel (rn, select);
- UNSET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
- }
- UNSET_FLAG (select->status, RIB_ENTRY_CHANGED);
- }
- else if (! RIB_SYSTEM_ROUTE (select))
- {
- /* Housekeeping code to deal with
- race conditions in kernel with linux
- netlink reporting interface up before IPv4 or IPv6 protocol
- is ready to add routes.
- This makes sure the routes are IN the kernel.
- */
-
- for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing))
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
- {
- installed = 1;
- break;
- }
- if (! installed)
- rib_install_kernel (rn, select, 0);
+ redistribute_update (p, src_p, new_selected, old_selected);
}
- goto end;
}
- /* At this point we either haven't found the best RIB entry or it is
- * different from what we currently intend to flag with SELECTED. In both
- * cases, if a RIB block is present in FIB, it should be withdrawn.
- */
- if (fib)
- {
- if (IS_ZEBRA_DEBUG_RIB)
- rnode_debug (rn, vrf_id, "Removing existing route, fib %p", (void *)fib);
-
- if (info->safi == SAFI_UNICAST)
- zfpm_trigger_update (rn, "removing existing route");
-
- /* If there's no route to replace this with, withdraw redistribute and
- * uninstall from kernel.
- */
- if (!select)
- {
- if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)",
- vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type);
-
- redistribute_delete(&rn->p, fib);
- if (! RIB_SYSTEM_ROUTE (fib))
- rib_uninstall_kernel (rn, fib);
- }
-
- UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
-
- /* Set real nexthop. */
- nexthop_active_update (rn, fib, 1);
- UNSET_FLAG(fib->status, RIB_ENTRY_CHANGED);
- }
-
- /* Regardless of some RIB entry being SELECTED or not before, now we can
- * tell, that if a new winner exists, FIB is still not updated with this
- * data, but ready to be.
- */
- if (select)
- {
- if (IS_ZEBRA_DEBUG_RIB)
- rnode_debug (rn, "Adding route, select %p", (void *)select);
-
- if (info->safi == SAFI_UNICAST)
- zfpm_trigger_update (rn, "new route selected");
-
- /* Set real nexthop. */
- if (nexthop_active_update (rn, select, 1))
- {
- if (IS_ZEBRA_DEBUG_RIB)
- {
- if (fib)
- zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) "
- "old %p (type %d)", vrf_id, buf, rn->p.prefixlen, rn,
- select, select->type, fib, fib->type);
- else
- zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)",
- vrf_id, buf, rn->p.prefixlen, rn, select, select->type);
- }
-
- if (! RIB_SYSTEM_ROUTE (select))
- {
- /* Clear FIB flag if performing a replace, will get set again
- * as part of install.
- */
- if (fib)
- {
- for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
- UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
- }
- rib_install_kernel (rn, select, fib? 1 : 0);
- }
- else
- {
- /* Uninstall prior route here, if needed. */
- if (fib && !RIB_SYSTEM_ROUTE (fib))
- rib_uninstall_kernel (rn, fib);
- }
-
- SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
- /* Unconditionally announce, this part is exercised by new routes */
- /* If we cannot add, for example route added is learnt by the */
- /* protocol we're trying to redistribute to, delete the redist */
- /* This is notified by setting the is_update to 1 */
- redistribute_update (&rn->p, select, fib);
- }
- else
- {
- /* Uninstall prior route here and do redist delete, if needed. */
- if (fib)
- {
- if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
- "- nexthop inactive",
- vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type);
-
- if (!RIB_SYSTEM_ROUTE (fib))
- rib_uninstall_kernel (rn, fib);
- redistribute_delete(&rn->p, fib);
- }
- }
- UNSET_FLAG(select->status, RIB_ENTRY_CHANGED);
- }
-#endif
-
/* Remove all RIB entries queued for removal */
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
{
@@ -2006,7 +1716,6 @@ process_subq (struct list * subq, u_char qindex)
{
struct listnode *lnode = listhead (subq);
struct route_node *rnode;
- char buf[INET6_ADDRSTRLEN];
rib_dest_t *dest;
struct zebra_vrf *zvrf = NULL;
@@ -2022,9 +1731,10 @@ process_subq (struct list * subq, u_char qindex)
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
{
- inet_ntop (rnode->p.family, &rnode->p.u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_debug ("%u:%s/%d: rn %p dequeued from sub-queue %u",
- zvrf ? zvrf_id (zvrf) : 0, buf, rnode->p.prefixlen, rnode, qindex);
+ char buf[SRCDEST2STR_BUFFER];
+ srcdest_rnode2str(rnode, buf, sizeof(buf));
+ zlog_debug ("%u:%s: rn %p dequeued from sub-queue %u",
+ zvrf ? zvrf_id (zvrf) : 0, buf, rnode, qindex);
}
if (rnode->info)
@@ -2405,13 +2115,10 @@ rib_delnode (struct route_node *rn, struct rib *rib)
/* Just clean up if non main table */
if (IS_ZEBRA_DEBUG_RIB)
{
- char buf[INET6_ADDRSTRLEN];
- if (IS_ZEBRA_DEBUG_RIB)
- {
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_debug ("%u:%s/%d: Freeing route rn %p, rib %p (type %d)",
- rib->vrf_id, buf, rn->p.prefixlen, rn, rib, rib->type);
- }
+ char buf[SRCDEST2STR_BUFFER];
+ srcdest_rnode2str(rn, buf, sizeof(buf));
+ zlog_debug ("%u:%s: Freeing route rn %p, rib %p (type %d)",
+ rib->vrf_id, buf, rn, rib, rib->type);
}
rib_unlink(rn, rib);
@@ -2428,15 +2135,23 @@ rib_delnode (struct route_node *rn, struct rib *rib)
*/
void _rib_dump (const char * func,
- union prefix46constptr pp, const struct rib * rib)
+ union prefix46constptr pp,
+ union prefix46constptr src_pp,
+ const struct rib * rib)
{
const struct prefix *p = pp.p;
+ const struct prefix *src_p = src_pp.p;
+ bool is_srcdst = src_p && src_p->prefixlen;
char straddr[PREFIX_STRLEN];
+ char srcaddr[PREFIX_STRLEN];
struct nexthop *nexthop, *tnexthop;
int recursing;
- zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, (const void *)rib,
- prefix2str(pp, straddr, sizeof(straddr)), rib->vrf_id);
+ zlog_debug ("%s: dumping RIB entry %p for %s%s%s vrf %u", func, (const void *)rib,
+ prefix2str(pp, straddr, sizeof(straddr)),
+ is_srcdst ? " from " : "",
+ is_srcdst ? prefix2str(src_pp, srcaddr, sizeof(srcaddr)) : "",
+ rib->vrf_id);
zlog_debug
(
"%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
@@ -2527,7 +2242,7 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p, vrf_id_t vrf_id)
(CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
(CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
);
- rib_dump (p, rib);
+ rib_dump (p, NULL, rib);
}
}
@@ -2574,7 +2289,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id)
char buf[PREFIX_STRLEN];
zlog_debug ("%u:%s: freeing way for connected prefix",
rib->vrf_id, prefix2str(&rn->p, buf, sizeof(buf)));
- rib_dump (&rn->p, rib);
+ rib_dump (&rn->p, NULL, rib);
}
rib_uninstall (rn, rib);
}
@@ -2585,7 +2300,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id)
int
rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
- struct rib *rib)
+ struct prefix_ipv6 *src_p, struct rib *rib)
{
struct route_table *table;
struct route_node *rn;
@@ -2602,6 +2317,8 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
else
family = AFI_IP6;
+ assert(!src_p || family == AFI_IP6);
+
/* Lookup table. */
table = zebra_vrf_table_with_table_id (family, safi, rib->vrf_id, rib->table);
if (! table)
@@ -2609,6 +2326,8 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
/* Make it sure prefixlen is applied to the prefix. */
apply_mask (p);
+ if (src_p)
+ apply_mask_ipv6 (src_p);
/* Set default distance by route type. */
if (rib->distance == 0)
@@ -2622,7 +2341,7 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
}
/* Lookup route node.*/
- rn = route_node_get (table, p);
+ rn = srcdest_rnode_get (table, p, src_p);
/* If same type of route are installed, treat it as a implicit
withdraw. */
@@ -2645,18 +2364,11 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
/* Link new rib to node.*/
if (IS_ZEBRA_DEBUG_RIB)
{
- char buf[INET6_ADDRSTRLEN];
- if (IS_ZEBRA_DEBUG_RIB)
- {
- inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
- "existing %p",
- rib->vrf_id, buf, p->prefixlen, (void *)rn,
- (void *)rib, rib->type, (void *)same);
- }
+ rnode_debug(rn, rib->vrf_id, "Inserting route rn %p, rib %p (type %d) existing %p",
+ (void *)rn, (void *)rib, rib->type, (void *)same);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- rib_dump ((struct prefix *)p, rib);
+ rib_dump (p, src_p, rib);
}
rib_addnode (rn, rib, 1);
ret = 1;
@@ -2672,10 +2384,10 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
return ret;
}
-int
+void
rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
- int flags, struct prefix *p, union g_addr *gate, ifindex_t ifindex,
- u_int32_t table_id)
+ int flags, struct prefix *p, struct prefix_ipv6 *src_p,
+ union g_addr *gate, ifindex_t ifindex, u_int32_t table_id)
{
struct route_table *table;
struct route_node *rn;
@@ -2684,25 +2396,38 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
struct rib *same = NULL;
struct nexthop *nexthop, *tnexthop;
int recursing;
- char buf1[PREFIX_STRLEN];
char buf2[INET6_ADDRSTRLEN];
+ assert(!src_p || afi == AFI_IP6);
+
/* Lookup table. */
table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id);
if (! table)
- return 0;
+ return;
/* Apply mask. */
apply_mask (p);
+ if (src_p)
+ apply_mask_ipv6 (src_p);
/* Lookup route node. */
- rn = route_node_lookup (table, p);
+ rn = srcdest_rnode_lookup (table, p, src_p);
if (! rn)
{
+ char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN];
+
+ prefix2str(p, dst_buf, sizeof(dst_buf));
+ if (src_p && src_p->prefixlen)
+ prefix2str(src_p, src_buf, sizeof(src_buf));
+ else
+ src_buf[0] = '\0';
+
if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug ("%u:%s: doesn't exist in rib",
- vrf_id, prefix2str (p, buf1, sizeof(buf1)));
- return ZEBRA_ERR_RTNOEXIST;
+ zlog_debug ("%u:%s%s%s doesn't exist in rib",
+ vrf_id, dst_buf,
+ (src_buf[0] != '\0') ? " from " : "",
+ src_buf);
+ return;
}
/* Lookup same type route. */
@@ -2728,7 +2453,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
rib->refcnt--;
route_unlock_node (rn);
route_unlock_node (rn);
- return 0;
+ return;
}
same = rib;
break;
@@ -2761,10 +2486,8 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
{
if (IS_ZEBRA_DEBUG_RIB)
{
- zlog_debug ("%u:%s: rn %p, rib %p (type %d) was deleted "
- "from kernel, adding",
- vrf_id, prefix2str(p, buf1, INET6_ADDRSTRLEN),
- rn, fib, fib->type);
+ rnode_debug (rn, vrf_id, "rn %p, rib %p (type %d) was deleted from kernel, adding",
+ rn, fib, fib->type);
}
if (allow_delete)
{
@@ -2786,20 +2509,18 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
if (IS_ZEBRA_DEBUG_RIB)
{
if (gate)
- zlog_debug ("%u:%s: via %s ifindex %d type %d "
+ rnode_debug(rn, vrf_id, "via %s ifindex %d type %d "
"doesn't exist in rib",
- vrf_id, prefix2str (p, buf1, sizeof(buf1)),
- inet_ntop (family2afi(afi), gate, buf2, INET_ADDRSTRLEN),
+ inet_ntop (family2afi(afi), gate, buf2, INET_ADDRSTRLEN), /* FIXME */
ifindex,
type);
else
- zlog_debug ("%u:%s: ifindex %d type %d doesn't exist in rib",
- vrf_id, prefix2str (p, buf1, sizeof(buf1)),
+ rnode_debug (rn, vrf_id, "ifindex %d type %d doesn't exist in rib",
ifindex,
type);
}
route_unlock_node (rn);
- return ZEBRA_ERR_RTNOEXIST;
+ return;
}
}
@@ -2807,7 +2528,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
rib_delnode (rn, same);
route_unlock_node (rn);
- return 0;
+ return;
}
@@ -2815,7 +2536,8 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
int
rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
- union g_addr *gate, union g_addr *src, ifindex_t ifindex,
+ struct prefix_ipv6 *src_p, union g_addr *gate,
+ union g_addr *src, ifindex_t ifindex,
u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
u_char distance)
{
@@ -2825,6 +2547,8 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
struct route_node *rn;
struct nexthop *nexthop;
+ assert(!src_p || afi == AFI_IP6);
+
/* Lookup table. */
table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id);
if (! table)
@@ -2832,6 +2556,8 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
/* Make sure mask is applied. */
apply_mask (p);
+ if (src_p)
+ apply_mask_ipv6 (src_p);
/* Set default distance by route type. */
if (distance == 0)
@@ -2847,7 +2573,7 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
}
/* Lookup route node.*/
- rn = route_node_get (table, p);
+ rn = srcdest_rnode_get (table, p, src_p);
/* If same type of route are installed, treat it as a implicit
withdraw. */
@@ -2919,18 +2645,11 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
/* Link new rib to node.*/
if (IS_ZEBRA_DEBUG_RIB)
{
- char buf[INET6_ADDRSTRLEN];
- if (IS_ZEBRA_DEBUG_RIB)
- {
- inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
- "existing %p",
- vrf_id, buf, p->prefixlen, (void *)rn,
- (void *)rib, rib->type, (void *)same);
- }
+ rnode_debug (rn, vrf_id, "Inserting route rn %p, rib %p (type %d) existing %p",
+ (void *)rn, (void *)rib, rib->type, (void *)same);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- rib_dump (p, rib);
+ rib_dump (p, src_p, rib);
}
rib_addnode (rn, rib, 1);
@@ -2952,7 +2671,7 @@ rib_update_table (struct route_table *table, rib_update_event_t event)
/* Walk all routes and queue for processing, if appropriate for
* the trigger event.
*/
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
{
switch (event)
{
@@ -3028,7 +2747,7 @@ rib_weed_table (struct route_table *table)
struct rib *next;
if (table)
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
{
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
@@ -3065,7 +2784,7 @@ rib_sweep_table (struct route_table *table)
int ret = 0;
if (table)
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
{
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
@@ -3106,7 +2825,7 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table
unsigned long n = 0;
if (table)
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
{
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
@@ -3117,7 +2836,6 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table
n++;
}
}
-
return n;
}
@@ -3146,7 +2864,7 @@ rib_close_table (struct route_table *table)
struct rib *rib;
if (table)
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index c4c11f98d9..b180930a0a 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -878,6 +878,7 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr
}
if (rib)
{
+ stream_putc (s, rib->distance);
stream_putl (s, rib->metric);
num = 0;
nump = stream_get_endp(s);
@@ -900,7 +901,6 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr
stream_put_in_addr (s, &nexthop->gate.ipv4);
stream_putl (s, nexthop->ifindex);
break;
-#ifdef HAVE_IPV6
case NEXTHOP_TYPE_IPV6:
stream_put (s, &nexthop->gate.ipv6, 16);
break;
@@ -908,7 +908,6 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr
stream_put (s, &nexthop->gate.ipv6, 16);
stream_putl (s, nexthop->ifindex);
break;
-#endif /* HAVE_IPV6 */
default:
/* do nothing */
break;
@@ -919,12 +918,13 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr
}
else
{
- stream_putl (s, 0);
- stream_putc (s, 0);
+ stream_putc (s, 0); // distance
+ stream_putl (s, 0); // metric
+ stream_putc (s, 0); // nexthops
}
stream_putw_at (s, 0, stream_get_endp (s));
- client->nh_last_upd_time = quagga_monotime();
+ client->nh_last_upd_time = monotime(NULL);
client->last_write_cmd = cmd;
return zebra_server_send_message(client);
}
diff --git a/zebra/zebra_rnh_null.c b/zebra/zebra_rnh_null.c
index a97ae1a612..286290a52b 100644
--- a/zebra/zebra_rnh_null.c
+++ b/zebra/zebra_rnh_null.c
@@ -19,6 +19,7 @@
* 02111-1307, USA.
*/
#include <zebra.h>
+#include "vty.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
#include "zebra/zebra_rnh.h"
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 041f67826b..5fe4a7ab9d 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -25,6 +25,7 @@
#include "zebra_memory.h"
#include "prefix.h"
#include "rib.h"
+#include "vty.h"
#include "routemap.h"
#include "command.h"
#include "filter.h"
@@ -56,6 +57,8 @@ struct nh_rmap_obj
static void zebra_route_map_set_delay_timer(u_int32_t value);
+
+
/* Add zebra route map rule */
static int
zebra_route_match_add(struct vty *vty,
@@ -138,54 +141,6 @@ zebra_route_match_delete (struct vty *vty,
return CMD_SUCCESS;
}
-/* Add zebra route map rule. */
-static int
-zebra_route_set_add (struct vty *vty,
- const char *command, const char *arg)
-{
- VTY_DECLVAR_CONTEXT (route_map_index, index);
- int ret;
-
- ret = route_map_add_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
-/* Delete zebra route map rule. */
-static int
-zebra_route_set_delete (struct vty *vty,
- const char *command, const char *arg)
-{
- VTY_DECLVAR_CONTEXT (route_map_index, index);
- int ret;
-
- ret = route_map_delete_set (index, command, arg);
- if (ret)
- {
- switch (ret)
- {
- case RMAP_RULE_MISSING:
- vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
- case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return CMD_SUCCESS;
-}
-
/* 'match tag TAG'
* Match function return 1 if match is success else return 0
*/
@@ -210,8 +165,8 @@ route_match_tag (void *rule, struct prefix *prefix,
/* Route map commands for tag matching */
static struct route_map_rule_cmd route_match_tag_cmd =
{
- "tag",
- route_match_tag,
+ "tag",
+ route_match_tag,
route_map_rule_tag_compile,
route_map_rule_tag_free,
};
@@ -266,240 +221,9 @@ struct route_map_rule_cmd route_match_interface_cmd =
route_match_interface_free
};
-DEFUN (match_interface,
- match_interface_cmd,
- "match interface WORD",
- MATCH_STR
- "match first hop interface of route\n"
- "Interface name\n")
-{
- return zebra_route_match_add (vty, "interface", argv[0],
- RMAP_EVENT_MATCH_ADDED);
-}
-
-DEFUN (no_match_interface,
- no_match_interface_cmd,
- "no match interface",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n")
-{
- if (argc == 0)
- return zebra_route_match_delete (vty, "interface", NULL, RMAP_EVENT_MATCH_DELETED);
-
- return zebra_route_match_delete (vty, "interface", argv[0], RMAP_EVENT_MATCH_DELETED);
-}
-
-ALIAS (no_match_interface,
- no_match_interface_val_cmd,
- "no match interface WORD",
- NO_STR
- MATCH_STR
- "Match first hop interface of route\n"
- "Interface name\n")
-
-DEFUN (match_tag,
- match_tag_cmd,
- "match tag <1-4294967295>",
- MATCH_STR
- "Match tag of route\n"
- "Tag value\n")
-{
- return zebra_route_match_add (vty, "tag", argv[0],
- RMAP_EVENT_MATCH_ADDED);
-}
-
-DEFUN (no_match_tag,
- no_match_tag_cmd,
- "no match tag",
- NO_STR
- MATCH_STR
- "Match tag of route\n")
-{
- if (argc == 0)
- return zebra_route_match_delete (vty, "tag", NULL,
- RMAP_EVENT_MATCH_DELETED);
-
- return zebra_route_match_delete (vty, "tag", argv[0],
- RMAP_EVENT_MATCH_DELETED);
-}
-
-ALIAS (no_match_tag,
- no_match_tag_val_cmd,
- "no match tag <1-4294967295>",
- NO_STR
- MATCH_STR
- "Match tag of route\n")
-
-DEFUN (match_ip_next_hop,
- match_ip_next_hop_cmd,
- "match ip next-hop (<1-199>|<1300-2699>|WORD)",
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-{
- return zebra_route_match_add (vty, "ip next-hop", argv[0], RMAP_EVENT_FILTER_ADDED);
-}
-
-DEFUN (no_match_ip_next_hop,
- no_match_ip_next_hop_cmd,
- "no match ip next-hop",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n")
-{
- if (argc == 0)
- return zebra_route_match_delete (vty, "ip next-hop", NULL,
- RMAP_EVENT_FILTER_DELETED);
-
- return zebra_route_match_delete (vty, "ip next-hop", argv[0],
- RMAP_EVENT_FILTER_DELETED);
-}
-
-ALIAS (no_match_ip_next_hop,
- no_match_ip_next_hop_val_cmd,
- "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-
-DEFUN (match_ip_next_hop_prefix_list,
- match_ip_next_hop_prefix_list_cmd,
- "match ip next-hop prefix-list WORD",
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return zebra_route_match_add (vty, "ip next-hop prefix-list",
- argv[0], RMAP_EVENT_PLIST_ADDED);
-}
-
-DEFUN (no_match_ip_next_hop_prefix_list,
- no_match_ip_next_hop_prefix_list_cmd,
- "no match ip next-hop prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n")
-{
- if (argc == 0)
- return zebra_route_match_delete (vty,
- "ip next-hop prefix-list", NULL,
- RMAP_EVENT_PLIST_DELETED);
-
- return zebra_route_match_delete (vty,
- "ip next-hop prefix-list", argv[0],
- RMAP_EVENT_PLIST_DELETED);
-}
-
-ALIAS (no_match_ip_next_hop_prefix_list,
- no_match_ip_next_hop_prefix_list_val_cmd,
- "no match ip next-hop prefix-list WORD",
- NO_STR
- MATCH_STR
- IP_STR
- "Match next-hop address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-
-DEFUN (match_ip_address,
- match_ip_address_cmd,
- "match ip address (<1-199>|<1300-2699>|WORD)",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-
-{
- return zebra_route_match_add (vty, "ip address", argv[0],
- RMAP_EVENT_FILTER_ADDED);
-}
-
-DEFUN (no_match_ip_address,
- no_match_ip_address_cmd,
- "no match ip address",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n")
-{
- if (argc == 0)
- return zebra_route_match_delete (vty, "ip address", NULL,
- RMAP_EVENT_FILTER_DELETED);
-
- return zebra_route_match_delete (vty, "ip address", argv[0],
- RMAP_EVENT_FILTER_DELETED);
-}
-
-ALIAS (no_match_ip_address,
- no_match_ip_address_val_cmd,
- "no match ip address (<1-199>|<1300-2699>|WORD)",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "IP access-list number\n"
- "IP access-list number (expanded range)\n"
- "IP Access-list name\n")
-
-DEFUN (match_ip_address_prefix_list,
- match_ip_address_prefix_list_cmd,
- "match ip address prefix-list WORD",
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-{
- return zebra_route_match_add (vty, "ip address prefix-list",
- argv[0], RMAP_EVENT_PLIST_ADDED);
-}
-
-DEFUN (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_cmd,
- "no match ip address prefix-list",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n")
-{
- if (argc == 0)
- return zebra_route_match_delete (vty,
- "ip address prefix-list", NULL,
- RMAP_EVENT_PLIST_DELETED);
-
- return zebra_route_match_delete (vty,
- "ip address prefix-list", argv[0],
- RMAP_EVENT_PLIST_DELETED);
-}
-
-ALIAS (no_match_ip_address_prefix_list,
- no_match_ip_address_prefix_list_val_cmd,
- "no match ip address prefix-list WORD",
- NO_STR
- MATCH_STR
- IP_STR
- "Match address of route\n"
- "Match entries of prefix-lists\n"
- "IP prefix-list name\n")
-
DEFUN (match_ip_address_prefix_len,
match_ip_address_prefix_len_cmd,
- "match ip address prefix-len NUMBER",
+ "match ip address prefix-len (0-32)",
MATCH_STR
IP_STR
"Match prefix length of ip address\n"
@@ -507,40 +231,29 @@ DEFUN (match_ip_address_prefix_len,
"Prefix length\n")
{
return zebra_route_match_add (vty, "ip address prefix-len",
- argv[0], RMAP_EVENT_MATCH_ADDED);
+ argv[4]->arg, RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_ip_address_prefix_len,
no_match_ip_address_prefix_len_cmd,
- "no match ip address prefix-len",
+ "no match ip address prefix-len [(0-32)]",
NO_STR
MATCH_STR
IP_STR
- "Match prefixlen of ip address of route\n"
- "prefix length of ip address\n")
+ "Match prefix length of ip address\n"
+ "Match prefix length of ip address\n"
+ "Prefix length\n")
{
- if (argc == 0)
- return zebra_route_match_delete (vty,
- "ip address prefix-len", NULL,
- RMAP_EVENT_MATCH_DELETED);
-
+ char *plen = (argc == 6) ? argv[5]->arg : NULL;
return zebra_route_match_delete (vty,
- "ip address prefix-len", argv[0],
+ "ip address prefix-len", plen,
RMAP_EVENT_MATCH_DELETED);
}
-ALIAS (no_match_ip_address_prefix_len,
- no_match_ip_address_prefix_len_val_cmd,
- "no match ip address prefix-len NUMBER",
- NO_STR
- MATCH_STR
- IP_STR
- "Match prefixlen of ip address of route\n"
- "prefix length of ip address\n")
DEFUN (match_ip_nexthop_prefix_len,
match_ip_nexthop_prefix_len_cmd,
- "match ip next-hop prefix-len NUMBER",
+ "match ip next-hop prefix-len (0-32)",
MATCH_STR
IP_STR
"Match prefixlen of nexthop ip address\n"
@@ -548,96 +261,95 @@ DEFUN (match_ip_nexthop_prefix_len,
"Prefix length\n")
{
return zebra_route_match_add (vty, "ip next-hop prefix-len",
- argv[0], RMAP_EVENT_MATCH_ADDED);
+ argv[4]->arg, RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_ip_nexthop_prefix_len,
no_match_ip_nexthop_prefix_len_cmd,
- "no match ip next-hop prefix-len",
+ "no match ip next-hop prefix-len [(0-32)]",
NO_STR
MATCH_STR
IP_STR
"Match prefixlen of nexthop ip address\n"
- "Match prefix length of nexthop\n")
+ "Match prefix length of nexthop\n"
+ "Prefix length\n")
{
- if (argc == 0)
- return zebra_route_match_delete (vty,
- "ip next-hop prefix-len", NULL,
- RMAP_EVENT_MATCH_DELETED);
-
+ char *plen = (argc == 6) ? argv[5]->arg : NULL;
return zebra_route_match_delete (vty,
- "ip next-hop prefix-len", argv[0],
+ "ip next-hop prefix-len", plen,
RMAP_EVENT_MATCH_DELETED);
}
-ALIAS (no_match_ip_nexthop_prefix_len,
- no_match_ip_nexthop_prefix_len_val_cmd,
- "no match ip next-hop prefix-len NUMBER",
- MATCH_STR
- "Match prefixlen of ip address of route\n"
- "prefix length of ip address\n")
DEFUN (match_source_protocol,
match_source_protocol_cmd,
- "match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)",
+ "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static>",
MATCH_STR
- "Match protocol via which the route was learnt\n")
-{
+ "Match protocol via which the route was learnt\n"
+ "BGP protocol\n"
+ "OSPF protocol\n"
+ "RIP protocol\n"
+ "RIPNG protocol\n"
+ "ISIS protocol\n"
+ "OSPF6 protocol\n"
+ "Routes from directly connected peer\n"
+ "Routes from system configuration\n"
+ "Routes from kernel\n"
+ "Statically configured routes\n")
+{
+ char *proto = argv[2]->text;
int i;
- i = proto_name2num(argv[0]);
+ i = proto_name2num(proto);
if (i < 0)
{
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
+ vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
return CMD_WARNING;
}
- return zebra_route_match_add (vty, "source-protocol",
- argv[0], RMAP_EVENT_MATCH_ADDED);
+ return zebra_route_match_add (vty, "source-protocol", proto, RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_source_protocol,
no_match_source_protocol_cmd,
- "no match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)",
+ "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static>]",
NO_STR
MATCH_STR
- "No match protocol via which the route was learnt\n")
-{
- int i;
-
- if (argc >= 1)
- {
- i = proto_name2num(argv[0]);
- if (i < 0)
- {
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- return zebra_route_match_delete (vty,
- "source-protocol", argv[0] ? argv[0] : NULL,
- RMAP_EVENT_MATCH_DELETED);
+ "No match protocol via which the route was learnt\n"
+ "BGP protocol\n"
+ "OSPF protocol\n"
+ "RIP protocol\n"
+ "RIPNG protocol\n"
+ "ISIS protocol\n"
+ "OSPF6 protocol\n"
+ "Routes from directly connected peer\n"
+ "Routes from system configuration\n"
+ "Routes from kernel\n"
+ "Statically configured routes\n")
+{
+ char *proto = (argc == 4) ? argv[3]->text : NULL;
+ return zebra_route_match_delete (vty, "source-protocol", proto, RMAP_EVENT_MATCH_DELETED);
}
/* set functions */
DEFUN (set_src,
set_src_cmd,
- "set src (A.B.C.D|X:X::X:X)",
+ "set src <A.B.C.D|X:X::X:X>",
SET_STR
"src address for route\n"
- "src address\n")
+ "IPv4 src address\n"
+ "IPv6 src address\n")
{
+ int idx_ip = 2;
union g_addr src;
struct interface *pif = NULL;
int family;
struct prefix p;
struct vrf *vrf;
- if (inet_pton(AF_INET, argv[0], &src.ipv4) != 1)
+ if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1)
{
- if (inet_pton(AF_INET6, argv[0], &src.ipv6) != 1)
+ if (inet_pton(AF_INET6, argv[idx_ip]->arg, &src.ipv6) != 1)
{
vty_out (vty, "%% not a valid IPv4/v6 address%s", VTY_NEWLINE);
return CMD_WARNING;
@@ -656,8 +368,8 @@ DEFUN (set_src,
if (!zebra_check_addr(&p))
{
- vty_out (vty, "%% not a valid source IPv4/v6 address%s", VTY_NEWLINE);
- return CMD_WARNING;
+ vty_out (vty, "%% not a valid source IPv4/v6 address%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
@@ -678,31 +390,37 @@ DEFUN (set_src,
vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
return CMD_WARNING;
}
- return zebra_route_set_add (vty, "src", argv[0]);
+
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+ return generic_set_add (vty, index, "src", argv[idx_ip]->arg);
}
DEFUN (no_set_src,
no_set_src_cmd,
- "no set src {A.B.C.D|X:X::X:X}",
+ "no set src [<A.B.C.D|X:X::X:X>]",
NO_STR
SET_STR
- "Source address for route\n")
+ "Source address for route\n"
+ "IPv4 address\n"
+ "IPv6 address\n")
{
- if (argc == 0)
- return zebra_route_set_delete (vty, "src", NULL);
-
- return zebra_route_set_delete (vty, "src", argv[0]);
+ char *ip = (argc == 4) ? argv[3]->arg : NULL;
+ VTY_DECLVAR_CONTEXT (route_map_index, index);
+ return generic_set_delete (vty, index, "src", ip);
}
DEFUN (zebra_route_map_timer,
zebra_route_map_timer_cmd,
- "zebra route-map delay-timer <0-600>",
+ "zebra route-map delay-timer (0-600)",
+ "Zebra information\n"
+ "Set route-map parameters\n"
"Time to wait before route-map updates are processed\n"
"0 means event-driven updates are disabled\n")
{
+ int idx_number = 3;
u_int32_t rmap_delay_timer;
- VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer, argv[0], 0, 600);
+ VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer, argv[idx_number]->arg, 0, 600);
zebra_route_map_set_delay_timer(rmap_delay_timer);
return (CMD_SUCCESS);
@@ -710,23 +428,18 @@ DEFUN (zebra_route_map_timer,
DEFUN (no_zebra_route_map_timer,
no_zebra_route_map_timer_cmd,
- "no zebra route-map delay-timer",
+ "no zebra route-map delay-timer [(0-600)]",
NO_STR
- "Time to wait before route-map updates are processed\n"
- "Reset delay-timer to default value, 30 secs\n")
+ "Zebra information\n"
+ "Set route-map parameters\n"
+ "Reset delay-timer to default value, 30 secs\n"
+ "0 means event-driven updates are disabled\n")
{
zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER);
return (CMD_SUCCESS);
}
-ALIAS (no_zebra_route_map_timer,
- no_zebra_route_map_timer_val_cmd,
- "no zebra route-map delay-timer <0-600>",
- NO_STR
- "Time to wait before route-map updates are processed\n"
- "Reset delay-timer to default value, 30 secs\n"
- "0 means event-driven updates are disabled\n")
DEFUN (ip_protocol,
ip_protocol_cmd,
@@ -734,32 +447,34 @@ DEFUN (ip_protocol,
IP_STR
"Filter routing info exchanged between zebra and protocol\n"
FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
+ "Specify route-map\n"
"Route map name\n")
{
+ char *proto = argv[2]->text;
+ char *rmap = argv[4]->arg;
int i;
- if (strcasecmp(argv[0], "any") == 0)
+ if (strcasecmp(proto, "any") == 0)
i = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(argv[0]);
+ i = proto_name2num(proto);
if (i < 0)
{
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
+ vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
return CMD_WARNING;
}
if (proto_rm[AFI_IP][i])
{
- if (strcmp(proto_rm[AFI_IP][i], argv[1]) == 0)
+ if (strcmp(proto_rm[AFI_IP][i], rmap) == 0)
return CMD_SUCCESS;
XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
}
- proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
+ proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug ("%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
- VRF_DEFAULT, argv[0]);
+ VRF_DEFAULT, proto);
rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
return CMD_SUCCESS;
@@ -767,51 +482,45 @@ DEFUN (ip_protocol,
DEFUN (no_ip_protocol,
no_ip_protocol_cmd,
- "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA,
+ "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " [route-map ROUTE-MAP]",
NO_STR
IP_STR
"Stop filtering routing info between zebra and protocol\n"
FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
- "Protocol from which to stop filtering routes\n")
+ "Specify route map\n"
+ "Route map name\n")
{
+ char *proto = argv[3]->text;
+ char *rmap = (argc == 6) ? argv[5]->arg : NULL;
int i;
- if (strcasecmp(argv[0], "any") == 0)
+ if (strcasecmp(proto, "any") == 0)
i = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(argv[0]);
+ i = proto_name2num(proto);
+
if (i < 0)
{
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
+ vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
return CMD_WARNING;
}
+
if (!proto_rm[AFI_IP][i])
return CMD_SUCCESS;
- if ((argc == 2 && strcmp(argv[1], proto_rm[AFI_IP][i]) == 0) ||
- (argc < 2))
+ if (!rmap || strcmp (rmap, proto_rm[AFI_IP][i]) == 0)
{
XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
proto_rm[AFI_IP][i] = NULL;
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug ("%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
- VRF_DEFAULT, argv[0]);
+ VRF_DEFAULT, proto);
rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
}
return CMD_SUCCESS;
}
-ALIAS (no_ip_protocol,
- no_ip_protocol_val_cmd,
- "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
- NO_STR
- IP_STR
- "Stop filtering routing info between zebra and protocol\n"
- FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
- "route map name")
-
DEFUN (show_ip_protocol,
show_ip_protocol_cmd,
"show ip protocol",
@@ -847,32 +556,34 @@ DEFUN (ipv6_protocol,
IP6_STR
"Filter IPv6 routing info exchanged between zebra and protocol\n"
FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
+ "Specify route map\n"
"Route map name\n")
{
+ char *proto = argv[2]->text;
+ char *rmap = argv[4]->arg;
int i;
- if (strcasecmp(argv[0], "any") == 0)
+ if (strcasecmp(proto, "any") == 0)
i = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(argv[0]);
+ i = proto_name2num(proto);
if (i < 0)
{
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
+ vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
return CMD_WARNING;
}
if (proto_rm[AFI_IP6][i])
{
- if (strcmp(proto_rm[AFI_IP6][i], argv[1]) == 0)
+ if (strcmp(proto_rm[AFI_IP6][i], rmap) == 0)
return CMD_SUCCESS;
XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]);
}
- proto_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
+ proto_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug ("%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
- VRF_DEFAULT, argv[0]);
+ VRF_DEFAULT, proto);
rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
return CMD_SUCCESS;
@@ -880,52 +591,44 @@ DEFUN (ipv6_protocol,
DEFUN (no_ipv6_protocol,
no_ipv6_protocol_cmd,
- "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA,
+ "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " [route-map ROUTE-MAP]",
NO_STR
IP6_STR
"Stop filtering IPv6 routing info between zebra and protocol\n"
FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
- "Protocol from which to stop filtering routes\n")
+ "Specify route map\n"
+ "Route map name\n")
{
+ const char *proto = argv[3]->text;
+ const char *rmap = (argc == 6) ? argv[5]->arg : NULL;
int i;
- if (strcasecmp(argv[0], "any") == 0)
+ if (strcasecmp(proto, "any") == 0)
i = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(argv[0]);
+ i = proto_name2num(proto);
if (i < 0)
{
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
+ vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
return CMD_WARNING;
}
if (!proto_rm[AFI_IP6][i])
return CMD_SUCCESS;
- if ((argc == 2 && strcmp(argv[1], proto_rm[AFI_IP6][i]) == 0) ||
- (argc < 2))
+ if (!rmap || strcmp(rmap, proto_rm[AFI_IP6][i]) == 0)
{
XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]);
proto_rm[AFI_IP6][i] = NULL;
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug ("%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
- VRF_DEFAULT, argv[0]);
+ VRF_DEFAULT, proto);
rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
}
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_protocol,
- no_ipv6_protocol_val_cmd,
- "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
- NO_STR
- IP6_STR
- "Stop filtering IPv6 routing info between zebra and protocol\n"
- FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
- "route map name")
-
DEFUN (show_ipv6_protocol,
show_ipv6_protocol_cmd,
"show ipv6 protocol",
@@ -961,29 +664,31 @@ DEFUN (ip_protocol_nht_rmap,
IP_STR
"Filter Next Hop tracking route resolution\n"
FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
+ "Specify route map\n"
"Route map name\n")
{
+ char *proto = argv[2]->text;
+ char *rmap = argv[4]->arg;
int i;
- if (strcasecmp(argv[0], "any") == 0)
+ if (strcasecmp(proto, "any") == 0)
i = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(argv[0]);
+ i = proto_name2num(proto);
if (i < 0)
{
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
+ vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
return CMD_WARNING;
}
if (nht_rm[AFI_IP][i])
{
- if (strcmp(nht_rm[AFI_IP][i], argv[1]) == 0)
+ if (strcmp(nht_rm[AFI_IP][i], rmap) == 0)
return CMD_SUCCESS;
XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]);
}
- nht_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
+ nht_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap);
zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
return CMD_SUCCESS;
@@ -991,29 +696,30 @@ DEFUN (ip_protocol_nht_rmap,
DEFUN (no_ip_protocol_nht_rmap,
no_ip_protocol_nht_rmap_cmd,
- "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA,
+ "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " [route-map ROUTE-MAP]",
NO_STR
IP_STR
"Filter Next Hop tracking route resolution\n"
- FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA)
+ FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
+ "Specify route map\n"
+ "Route map name\n")
{
- int i;
+ int idx = 0;
+ char *proto = argv[3]->text;
+ char *rmap = argv_find (argv, argc, "ROUTE-MAP", &idx) ? argv[idx]->arg : NULL;
+
+ int i = strmatch(proto, "any") ? ZEBRA_ROUTE_MAX : proto_name2num(proto);
- if (strcasecmp(argv[0], "any") == 0)
- i = ZEBRA_ROUTE_MAX;
- else
- i = proto_name2num(argv[0]);
if (i < 0)
{
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
- return CMD_WARNING;
+ vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
+ return CMD_WARNING;
}
+
if (!nht_rm[AFI_IP][i])
return CMD_SUCCESS;
- if ((argc == 2 && strcmp(argv[1], nht_rm[AFI_IP][i]) == 0) ||
- (argc < 2))
+ if (!rmap || strcmp(rmap, nht_rm[AFI_IP][i]) == 0)
{
XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]);
nht_rm[AFI_IP][i] = NULL;
@@ -1022,19 +728,12 @@ DEFUN (no_ip_protocol_nht_rmap,
return CMD_SUCCESS;
}
-ALIAS (no_ip_protocol_nht_rmap,
- no_ip_protocol_nht_rmap_val_cmd,
- "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
- IP_STR
- "Filter Next Hop tracking route resolution\n"
- FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
- "Route map name\n")
-
DEFUN (show_ip_protocol_nht,
show_ip_protocol_nht_cmd,
"show ip nht route-map",
- SHOW_STR
- IP_STR
+ SHOW_STR
+ IP_STR
+ "IP nexthop tracking table\n"
"IP Next Hop tracking filtering status\n")
{
int i;
@@ -1065,23 +764,25 @@ DEFUN (ipv6_protocol_nht_rmap,
IP6_STR
"Filter Next Hop tracking route resolution\n"
FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
+ "Specify route map\n"
"Route map name\n")
{
+ char *proto = argv[2]->text;
+ char *rmap = argv[4]->arg;
int i;
- if (strcasecmp(argv[0], "any") == 0)
+ if (strcasecmp(proto, "any") == 0)
i = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(argv[0]);
+ i = proto_name2num(proto);
if (i < 0)
{
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
+ vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
return CMD_WARNING;
}
if (nht_rm[AFI_IP6][i])
XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]);
- nht_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
+ nht_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap);
zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
return CMD_SUCCESS;
@@ -1089,28 +790,31 @@ DEFUN (ipv6_protocol_nht_rmap,
DEFUN (no_ipv6_protocol_nht_rmap,
no_ipv6_protocol_nht_rmap_cmd,
- "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA,
+ "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " [route-map ROUTE-MAP]",
NO_STR
IP6_STR
"Filter Next Hop tracking route resolution\n"
- FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA)
+ FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
+ "Specify route map\n"
+ "Route map name\n")
{
+ char *proto = argv[3]->text;
+ char *rmap = (argc == 6) ? argv[5]->arg : NULL;
int i;
- if (strcasecmp(argv[0], "any") == 0)
+ if (strcasecmp(proto, "any") == 0)
i = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(argv[0]);
+ i = proto_name2num(proto);
if (i < 0)
{
- vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
- VTY_NEWLINE);
- return CMD_WARNING;
+ vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
+ return CMD_WARNING;
}
- if (nht_rm[AFI_IP6][i] && argc == 2 && strcmp(argv[1], nht_rm[AFI_IP6][i]))
+ if (nht_rm[AFI_IP6][i] && rmap && strcmp(rmap, nht_rm[AFI_IP6][i]))
{
- vty_out (vty, "invalid route-map \"%s\"%s", argv[1], VTY_NEWLINE);
+ vty_out (vty, "invalid route-map \"%s\"%s", rmap, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1125,21 +829,13 @@ DEFUN (no_ipv6_protocol_nht_rmap,
return CMD_SUCCESS;
}
-ALIAS (no_ipv6_protocol_nht_rmap,
- no_ipv6_protocol_nht_rmap_val_cmd,
- "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
- NO_STR
- IP6_STR
- "Filter Next Hop tracking route resolution\n"
- FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
- "Route map name\n")
-
DEFUN (show_ipv6_protocol_nht,
show_ipv6_protocol_nht_cmd,
"show ipv6 nht route-map",
- SHOW_STR
- IP6_STR
- "IPv6 protocol Next Hop filtering status\n")
+ SHOW_STR
+ IP6_STR
+ "Next Hop filtering status\n"
+ "Route-map\n")
{
int i;
@@ -1544,10 +1240,7 @@ route_set_src_compile (const char *arg)
{
union g_addr src, *psrc;
- if (
-#ifdef HAVE_IPV6
- (inet_pton(AF_INET6, arg, &src.ipv6) == 1) ||
-#endif /* HAVE_IPV6 */
+ if ((inet_pton(AF_INET6, arg, &src.ipv6) == 1) ||
(src.ipv4.s_addr && (inet_pton(AF_INET, arg, &src.ipv4) == 1)))
{
psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
@@ -1788,23 +1481,18 @@ zebra_route_map_init ()
{
install_element (CONFIG_NODE, &ip_protocol_cmd);
install_element (CONFIG_NODE, &no_ip_protocol_cmd);
- install_element (CONFIG_NODE, &no_ip_protocol_val_cmd);
install_element (VIEW_NODE, &show_ip_protocol_cmd);
install_element (CONFIG_NODE, &ipv6_protocol_cmd);
install_element (CONFIG_NODE, &no_ipv6_protocol_cmd);
- install_element (CONFIG_NODE, &no_ipv6_protocol_val_cmd);
install_element (VIEW_NODE, &show_ipv6_protocol_cmd);
install_element (CONFIG_NODE, &ip_protocol_nht_rmap_cmd);
install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd);
- install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_val_cmd);
install_element (VIEW_NODE, &show_ip_protocol_nht_cmd);
install_element (CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd);
install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_cmd);
- install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_val_cmd);
install_element (VIEW_NODE, &show_ipv6_protocol_nht_cmd);
install_element (CONFIG_NODE, &zebra_route_map_timer_cmd);
install_element (CONFIG_NODE, &no_zebra_route_map_timer_cmd);
- install_element (CONFIG_NODE, &no_zebra_route_map_timer_val_cmd);
route_map_init ();
@@ -1812,6 +1500,24 @@ zebra_route_map_init ()
route_map_delete_hook (zebra_route_map_delete);
route_map_event_hook (zebra_route_map_event);
+ route_map_match_interface_hook (generic_match_add);
+ route_map_no_match_interface_hook (generic_match_delete);
+
+ route_map_match_ip_address_hook (generic_match_add);
+ route_map_no_match_ip_address_hook (generic_match_delete);
+
+ route_map_match_ip_address_prefix_list_hook (generic_match_add);
+ route_map_no_match_ip_address_prefix_list_hook (generic_match_delete);
+
+ route_map_match_ip_next_hop_hook (generic_match_add);
+ route_map_no_match_ip_next_hop_hook (generic_match_delete);
+
+ route_map_match_ip_next_hop_prefix_list_hook (generic_match_add);
+ route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete);
+
+ route_map_match_tag_hook (generic_match_add);
+ route_map_no_match_tag_hook (generic_match_delete);
+
route_map_install_match (&route_match_tag_cmd);
route_map_install_match (&route_match_interface_cmd);
route_map_install_match (&route_match_ip_next_hop_cmd);
@@ -1824,30 +1530,10 @@ zebra_route_map_init ()
/* */
route_map_install_set (&route_set_src_cmd);
/* */
- install_element (RMAP_NODE, &match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_cmd);
- install_element (RMAP_NODE, &no_match_tag_val_cmd);
- install_element (RMAP_NODE, &match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_cmd);
- install_element (RMAP_NODE, &no_match_interface_val_cmd);
- install_element (RMAP_NODE, &match_ip_next_hop_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
- install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
- install_element (RMAP_NODE, &match_ip_address_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
- install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
install_element (RMAP_NODE, &match_ip_nexthop_prefix_len_cmd);
install_element (RMAP_NODE, &no_match_ip_nexthop_prefix_len_cmd);
- install_element (RMAP_NODE, &no_match_ip_nexthop_prefix_len_val_cmd);
install_element (RMAP_NODE, &match_ip_address_prefix_len_cmd);
install_element (RMAP_NODE, &no_match_ip_address_prefix_len_cmd);
- install_element (RMAP_NODE, &no_match_ip_address_prefix_len_val_cmd);
install_element (RMAP_NODE, &match_source_protocol_cmd);
install_element (RMAP_NODE, &no_match_source_protocol_cmd);
/* */
diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c
index 5894a8955b..4628d11091 100644
--- a/zebra/zebra_static.c
+++ b/zebra/zebra_static.c
@@ -24,7 +24,9 @@
#include <lib/nexthop.h>
#include <lib/memory.h>
+#include <lib/srcdest_table.h>
+#include "vty.h"
#include "zebra/debug.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
@@ -36,7 +38,8 @@
/* Install static route into rib. */
void
-static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
+static_install_route (afi_t afi, safi_t safi, struct prefix *p,
+ struct prefix_ipv6 *src_p, struct static_route *si)
{
struct rib *rib;
struct route_node *rn;
@@ -49,8 +52,10 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
if (! table)
return;
+ memset (&nh_p, 0, sizeof (nh_p));
+
/* Lookup existing route */
- rn = route_node_get (table, p);
+ rn = srcdest_rnode_get (table, p, src_p);
RNODE_FOREACH_RIB (rn, rib)
{
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
@@ -193,31 +198,8 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
}
static int
-static_nexthop_label_same (struct nexthop *nexthop,
- struct static_nh_label *snh_label)
-{
- int i;
-
- if ((snh_label->num_labels == 0 && nexthop->nh_label) ||
- (snh_label->num_labels != 0 && !nexthop->nh_label))
- return 0;
-
- if (snh_label->num_labels != 0)
- if (snh_label->num_labels != nexthop->nh_label->num_labels)
- return 0;
-
- for (i = 0; i < snh_label->num_labels; i++)
- if (snh_label->label[i] != nexthop->nh_label->label[i])
- return 0;
-
- return 1;
-}
-
-static int
static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
{
- int gw_match = 0;
-
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
&& si->type == STATIC_BLACKHOLE)
return 1;
@@ -225,31 +207,28 @@ static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
if (nexthop->type == NEXTHOP_TYPE_IPV4
&& si->type == STATIC_IPV4_GATEWAY
&& IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4))
- gw_match = 1;
+ return 1;
else if (nexthop->type == NEXTHOP_TYPE_IFINDEX
&& si->type == STATIC_IFINDEX
&& nexthop->ifindex == si->ifindex)
- gw_match = 1;
+ return 1;
else if (nexthop->type == NEXTHOP_TYPE_IPV6
&& si->type == STATIC_IPV6_GATEWAY
&& IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6))
- gw_match = 1;
+ return 1;
else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
&& si->type == STATIC_IPV6_GATEWAY_IFINDEX
&& IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
&& nexthop->ifindex == si->ifindex)
- gw_match = 1;
-
- if (!gw_match)
- return 0;
+ return 1;
- /* Check match on label(s), if any */
- return static_nexthop_label_same (nexthop, &si->snh_label);
+ return 0;
}
/* Uninstall static route from RIB. */
void
-static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
+static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
+ struct prefix_ipv6 *src_p, struct static_route *si)
{
struct route_node *rn;
struct rib *rib;
@@ -263,7 +242,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
return;
/* Lookup existing route with type and distance. */
- rn = route_node_lookup (table, p);
+ rn = srcdest_rnode_lookup (table, p, src_p);
if (! rn)
return;
@@ -325,16 +304,16 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
rib_install_kernel (rn, rib, rib);
/* Update redistribution if it's selected */
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
- redistribute_update (&rn->p, rib, NULL);
+ redistribute_update (p, (struct prefix*)src_p, rib, NULL);
}
else
{
/* Remove from redistribute if selected route becomes inactive */
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
- redistribute_delete (&rn->p, rib);
+ redistribute_delete (p, (struct prefix*)src_p, rib);
/* Remove from kernel if fib route becomes inactive */
if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
- rib_uninstall_kernel (rn, rib);
+ rib_uninstall_kernel (rn, rib);
}
}
@@ -361,6 +340,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
int
static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
+ struct prefix_ipv6 *src_p,
union g_addr *gate, ifindex_t ifindex,
const char *ifname, u_char flags, route_tag_t tag,
u_char distance, struct zebra_vrf *zvrf,
@@ -388,7 +368,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
return -1;
/* Lookup static route prefix. */
- rn = route_node_get (stable, p);
+ rn = srcdest_rnode_get (stable, p, src_p);
/* Do nothing if there is a same static route. */
for (si = rn->info; si; si = si->next)
@@ -400,7 +380,8 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
&& (! ifindex || ifindex == si->ifindex))
{
if ((distance == si->distance) && (tag == si->tag) &&
- !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label)))
+ !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label)) &&
+ si->flags == flags)
{
route_unlock_node (rn);
return 0;
@@ -412,7 +393,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
/* Distance or tag or label changed, delete existing first. */
if (update)
- static_delete_route (afi, safi, type, p, gate, ifindex, update->tag,
+ static_delete_route (afi, safi, type, p, src_p, gate, ifindex, update->tag,
update->distance, zvrf, &update->snh_label);
/* Make new static route structure. */
@@ -473,13 +454,14 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
si->next = cp;
/* Install into rib. */
- static_install_route (afi, safi, p, si);
+ static_install_route (afi, safi, p, src_p, si);
return 1;
}
int
static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
+ struct prefix_ipv6 *src_p,
union g_addr *gate, ifindex_t ifindex,
route_tag_t tag, u_char distance, struct zebra_vrf *zvrf,
struct static_nh_label *snh_label)
@@ -494,7 +476,7 @@ static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
return -1;
/* Lookup static route prefix. */
- rn = route_node_lookup (stable, p);
+ rn = srcdest_rnode_lookup (stable, p, src_p);
if (! rn)
return 0;
@@ -518,7 +500,7 @@ static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
}
/* Install into rib. */
- static_uninstall_route (afi, safi, p, si);
+ static_uninstall_route (afi, safi, p, src_p, si);
/* Unlink static route from linked list. */
if (si->prev)
diff --git a/zebra/zebra_static.h b/zebra/zebra_static.h
index 5e3177e3b8..adc2efff58 100644
--- a/zebra/zebra_static.h
+++ b/zebra/zebra_static.h
@@ -31,6 +31,14 @@ struct static_nh_label
mpls_label_t label[2];
};
+typedef enum {
+ STATIC_IFINDEX,
+ STATIC_IPV4_GATEWAY,
+ STATIC_BLACKHOLE,
+ STATIC_IPV6_GATEWAY,
+ STATIC_IPV6_GATEWAY_IFINDEX,
+} zebra_static_types;
+
/* Static route information. */
struct static_route
{
@@ -48,12 +56,7 @@ struct static_route
route_tag_t tag;
/* Flag for this static route's type. */
- u_char type;
-#define STATIC_IFINDEX 1
-#define STATIC_IPV4_GATEWAY 2
-#define STATIC_BLACKHOLE 3
-#define STATIC_IPV6_GATEWAY 4
-#define STATIC_IPV6_GATEWAY_IFINDEX 5
+ zebra_static_types type;
/*
* Nexthop value.
@@ -80,12 +83,15 @@ struct static_route
};
extern void
-static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si);
+static_install_route (afi_t afi, safi_t safi, struct prefix *p,
+ struct prefix_ipv6 *src_p, struct static_route *si);
extern void
-static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si);
+static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
+ struct prefix_ipv6 *src_p, struct static_route *si);
extern int
static_add_route (afi_t, safi_t safi, u_char type, struct prefix *p,
+ struct prefix_ipv6 *src_p,
union g_addr *gate, ifindex_t ifindex,
const char *ifname, u_char flags, route_tag_t tag,
u_char distance, struct zebra_vrf *zvrf,
@@ -93,6 +99,7 @@ static_add_route (afi_t, safi_t safi, u_char type, struct prefix *p,
extern int
static_delete_route (afi_t, safi_t safi, u_char type, struct prefix *p,
+ struct prefix_ipv6 *src_p,
union g_addr *gate, ifindex_t ifindex, route_tag_t tag,
u_char distance, struct zebra_vrf *zvrf,
struct static_nh_label *snh_label);
@@ -106,6 +113,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
int
static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
+ const char *src_str,
const char *gate_str, const char *ifname,
const char *flag_str, const char *tag_str,
const char *distance_str, const char *vrf_id_str,
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 4715f6e12c..6fc41c3a14 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -25,7 +25,9 @@
#include "linklist.h"
#include "command.h"
#include "memory.h"
+#include "srcdest_table.h"
+#include "vty.h"
#include "zebra/debug.h"
#include "zebra/zserv.h"
#include "zebra/rib.h"
@@ -131,7 +133,7 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp)
(si->ifindex != ifp->ifindex))
{
si->ifindex = ifp->ifindex;
- static_install_route (afi, safi, &rn->p, si);
+ static_install_route (afi, safi, &rn->p, NULL, si);
}
}
}
@@ -175,7 +177,7 @@ zebra_vrf_enable (struct vrf *vrf)
else
continue;
}
- static_install_route (afi, safi, &rn->p, si);
+ static_install_route (afi, safi, &rn->p, NULL, si);
}
}
@@ -206,7 +208,7 @@ zebra_vrf_disable (struct vrf *vrf)
for (rn = route_top (stable); rn; rn = route_next (rn))
for (si = rn->info; si; si = si->next)
- static_uninstall_route(afi, safi, &rn->p, si);
+ static_uninstall_route(afi, safi, &rn->p, NULL, si);
}
return 0;
@@ -217,7 +219,6 @@ zebra_vrf_delete (struct vrf *vrf)
{
struct zebra_vrf *zvrf = vrf->info;
struct route_table *table;
- rib_table_info_t *info;
u_int32_t table_id;
afi_t afi;
safi_t safi;
@@ -271,12 +272,14 @@ zebra_vrf_delete (struct vrf *vrf)
/* release allocated memory */
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
{
+ void *table_info;
+
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
{
table = zvrf->table[afi][safi];
- info = table->info;
+ table_info = table->info;
route_table_finish (table);
- XFREE (MTYPE_RIB_TABLE_INFO, info);
+ XFREE (MTYPE_RIB_TABLE_INFO, table_info);
table = zvrf->stable[afi][safi];
route_table_finish (table);
@@ -286,9 +289,9 @@ zebra_vrf_delete (struct vrf *vrf)
if (zvrf->other_table[afi][table_id])
{
table = zvrf->other_table[afi][table_id];
- info = table->info;
+ table_info = table->info;
route_table_finish (table);
- XFREE (MTYPE_RIB_TABLE_INFO, info);
+ XFREE (MTYPE_RIB_TABLE_INFO, table_info);
}
route_table_finish (zvrf->rnh_table[afi]);
@@ -329,8 +332,7 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
}
static void
-zebra_rtable_node_destroy (route_table_delegate_t *delegate,
- struct route_table *table, struct route_node *node)
+zebra_rtable_node_cleanup (struct route_table *table, struct route_node *node)
{
struct rib *rib, *next;
@@ -339,13 +341,10 @@ zebra_rtable_node_destroy (route_table_delegate_t *delegate,
if (node->info)
XFREE (MTYPE_RIB_DEST, node->info);
-
- route_node_destroy (delegate, table, node);
}
static void
-zebra_stable_node_destroy (route_table_delegate_t *delegate,
- struct route_table *table, struct route_node *node)
+zebra_stable_node_cleanup (struct route_table *table, struct route_node *node)
{
struct static_route *si, *next;
@@ -355,35 +354,15 @@ zebra_stable_node_destroy (route_table_delegate_t *delegate,
next = si->next;
XFREE (MTYPE_STATIC_ROUTE, si);
}
-
- route_node_destroy (delegate, table, node);
}
static void
-zebra_rnhtable_node_destroy (route_table_delegate_t *delegate,
- struct route_table *table, struct route_node *node)
+zebra_rnhtable_node_cleanup (struct route_table *table, struct route_node *node)
{
if (node->info)
zebra_free_rnh (node->info);
-
- route_node_destroy (delegate, table, node);
}
-route_table_delegate_t zebra_rtable_delegate = {
- .create_node = route_node_create,
- .destroy_node = zebra_rtable_node_destroy
-};
-
-route_table_delegate_t zebra_stable_delegate = {
- .create_node = route_node_create,
- .destroy_node = zebra_stable_node_destroy
-};
-
-route_table_delegate_t zebra_rnhtable_delegate = {
- .create_node = route_node_create,
- .destroy_node = zebra_rnhtable_node_destroy
-};
-
/*
* Create a routing table for the specific AFI/SAFI in the given VRF.
*/
@@ -395,7 +374,11 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
assert (!zvrf->table[afi][safi]);
- table = route_table_init_with_delegate (&zebra_rtable_delegate);
+ if (afi == AFI_IP6)
+ table = srcdest_table_init();
+ else
+ table = route_table_init();
+ table->cleanup = zebra_rtable_node_cleanup;
zvrf->table[afi][safi] = table;
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
@@ -412,22 +395,30 @@ zebra_vrf_alloc (void)
struct zebra_vrf *zvrf;
afi_t afi;
safi_t safi;
+ struct route_table *table;
zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
{
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
- {
- zebra_vrf_table_create (zvrf, afi, safi);
- zvrf->stable[afi][safi] =
- route_table_init_with_delegate (&zebra_stable_delegate);
- }
+ {
+ zebra_vrf_table_create (zvrf, afi, safi);
+ if (afi == AFI_IP6)
+ table = srcdest_table_init();
+ else
+ table = route_table_init();
+ table->cleanup = zebra_stable_node_cleanup;
+ zvrf->stable[afi][safi] = table;
+ }
+
+ table = route_table_init();
+ table->cleanup = zebra_rnhtable_node_cleanup;
+ zvrf->rnh_table[afi] = table;
- zvrf->rnh_table[afi] =
- route_table_init_with_delegate (&zebra_rnhtable_delegate);
- zvrf->import_check_table[afi] =
- route_table_init_with_delegate (&zebra_rnhtable_delegate);
+ table = route_table_init();
+ table->cleanup = zebra_rnhtable_node_cleanup;
+ zvrf->import_check_table[afi] = table;
}
zebra_mpls_init_tables (zvrf);
@@ -507,7 +498,7 @@ zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
{
if (zvrf->other_table[afi][table_id] == NULL)
{
- table = route_table_init();
+ table = (afi == AFI_IP6) ? srcdest_table_init() : route_table_init();
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
info->zvrf = zvrf;
info->afi = afi;
@@ -522,26 +513,6 @@ zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
return zvrf->table[afi][SAFI_UNICAST];
}
-/* Wrapper hook point for zebra daemon so that ifindex can be set
- * DEFUN macro not used as extract.pl HAS to ignore this
- * See also interface_cmd in lib/if.c
- */
-DEFUN_NOSH (zebra_vrf,
- zebra_vrf_cmd,
- "vrf NAME",
- "Select a VRF to configure\n"
- "VRF's name\n")
-{
- // VTY_DECLVAR_CONTEXT (vrf, vrfp);
- int ret;
-
- /* Call lib vrf() */
- if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
- return ret;
-
- return ret;
-}
-
static int
vrf_config_write (struct vty *vty)
{
@@ -560,13 +531,6 @@ vrf_config_write (struct vty *vty)
return 0;
}
-struct cmd_node vrf_node =
-{
- VRF_NODE,
- "%s(config-vrf)# ",
- 1
-};
-
/* Zebra VRF initialization. */
void
zebra_vrf_init (void)
@@ -577,9 +541,5 @@ zebra_vrf_init (void)
vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete);
vrf_init ();
-
- install_node (&vrf_node, vrf_config_write);
- install_default (VRF_NODE);
- install_element (CONFIG_NODE, &zebra_vrf_cmd);
- install_element (CONFIG_NODE, &no_vrf_cmd);
+ vrf_cmd_init (vrf_config_write);
}
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 40bf0eac78..17d8249906 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -14,9 +14,9 @@
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING. If not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU Zebra; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
*/
#include <zebra.h>
@@ -31,8 +31,8 @@
#include "nexthop.h"
#include "vrf.h"
#include "mpls.h"
-#include "lib/json.h"
#include "routemap.h"
+#include "srcdest_table.h"
#include "zebra/zserv.h"
#include "zebra/zebra_vrf.h"
@@ -41,6 +41,7 @@
#include "zebra/redistribute.h"
#include "zebra/zebra_routemap.h"
#include "zebra/zebra_static.h"
+#include "lib/json.h"
extern int allow_delete;
@@ -141,10 +142,10 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
return CMD_WARNING;
}
if (add_cmd)
- static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname,
+ static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname,
ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
else
- static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag,
+ static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag,
distance, zvrf, &snh_label);
return CMD_SUCCESS;
}
@@ -169,15 +170,15 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
if (gate_str == NULL)
{
if (add_cmd)
- static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname, flag,
+ static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname, flag,
tag, distance, zvrf, &snh_label);
else
- static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag, distance,
+ static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag, distance,
zvrf, &snh_label);
return CMD_SUCCESS;
}
-
+
/* When gateway is A.B.C.D format, gate is treated as nexthop
address other case gate is treated as interface name. */
ret = inet_aton (gate_str, &gate);
@@ -198,11 +199,11 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
type = STATIC_IPV4_GATEWAY;
if (add_cmd)
- static_add_route (AFI_IP, safi, type, &p,
+ static_add_route (AFI_IP, safi, type, &p, NULL,
ifindex ? NULL : (union g_addr *)&gate, ifindex, ifname,
flag, tag, distance, zvrf, &snh_label);
else
- static_delete_route (AFI_IP, safi, type, &p,
+ static_delete_route (AFI_IP, safi, type, &p, NULL,
ifindex ? NULL : (union g_addr *)&gate, ifindex, tag,
distance, zvrf, &snh_label);
@@ -212,7 +213,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
/* Static unicast routes for multicast RPF lookup. */
DEFUN (ip_mroute_dist,
ip_mroute_dist_cmd,
- "ip mroute A.B.C.D/M (A.B.C.D|INTERFACE) <1-255>",
+ "ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
IP_STR
"Configure static unicast route into MRIB for multicast RPF lookup\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
@@ -220,22 +221,17 @@ DEFUN (ip_mroute_dist,
"Nexthop interface name\n"
"Distance\n")
{
- return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, argv[0], NULL, argv[1],
- NULL, NULL, argc > 2 ? argv[2] : NULL, NULL, NULL);
-}
+ char *destprefix = argv[2]->arg;
+ char *nexthop = argv[3]->arg;
+ char *distance = (argc == 5) ? argv[4]->arg : NULL;
-ALIAS (ip_mroute_dist,
- ip_mroute_cmd,
- "ip mroute A.B.C.D/M (A.B.C.D|INTERFACE)",
- IP_STR
- "Configure static unicast route into MRIB for multicast RPF lookup\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Nexthop address\n"
- "Nexthop interface name\n")
+ return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
+}
DEFUN (no_ip_mroute_dist,
no_ip_mroute_dist_cmd,
- "no ip mroute A.B.C.D/M (A.B.C.D|INTERFACE) <1-255>",
+ "no ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
+ NO_STR
IP_STR
"Configure static unicast route into MRIB for multicast RPF lookup\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
@@ -243,23 +239,16 @@ DEFUN (no_ip_mroute_dist,
"Nexthop interface name\n"
"Distance\n")
{
- return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, argv[0], NULL, argv[1],
- NULL, NULL, argc > 2 ? argv[2] : NULL, NULL, NULL);
-}
+ char *destprefix = argv[3]->arg;
+ char *nexthop = argv[4]->arg;
+ char *distance = (argc == 6) ? argv[5]->arg : NULL;
-ALIAS (no_ip_mroute_dist,
- no_ip_mroute_cmd,
- "no ip mroute A.B.C.D/M (A.B.C.D|INTERFACE)",
- NO_STR
- IP_STR
- "Configure static unicast route into MRIB for multicast RPF lookup\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Nexthop address\n"
- "Nexthop interface name\n")
+ return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
+}
DEFUN (ip_multicast_mode,
ip_multicast_mode_cmd,
- "ip multicast rpf-lookup-mode (urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix)",
+ "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
IP_STR
"Multicast options\n"
"RPF lookup behavior\n"
@@ -269,16 +258,17 @@ DEFUN (ip_multicast_mode,
"Lookup both, use entry with lower distance\n"
"Lookup both, use entry with longer prefix\n")
{
+ char *mode = argv[3]->text;
- if (!strncmp (argv[0], "u", 1))
+ if (strmatch (mode, "urib-only"))
multicast_mode_ipv4_set (MCAST_URIB_ONLY);
- else if (!strncmp (argv[0], "mrib-o", 6))
+ else if (strmatch (mode, "mrib-only"))
multicast_mode_ipv4_set (MCAST_MRIB_ONLY);
- else if (!strncmp (argv[0], "mrib-t", 6))
+ else if (strmatch (mode, "mrib-then-urib"))
multicast_mode_ipv4_set (MCAST_MIX_MRIB_FIRST);
- else if (!strncmp (argv[0], "low", 3))
+ else if (strmatch (mode, "lower-distance"))
multicast_mode_ipv4_set (MCAST_MIX_DISTANCE);
- else if (!strncmp (argv[0], "lon", 3))
+ else if (strmatch (mode, "longer-prefix"))
multicast_mode_ipv4_set (MCAST_MIX_PFXLEN);
else
{
@@ -291,7 +281,7 @@ DEFUN (ip_multicast_mode,
DEFUN (no_ip_multicast_mode,
no_ip_multicast_mode_cmd,
- "no ip multicast rpf-lookup-mode (urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix)",
+ "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
NO_STR
IP_STR
"Multicast options\n"
@@ -306,13 +296,6 @@ DEFUN (no_ip_multicast_mode,
return CMD_SUCCESS;
}
-ALIAS (no_ip_multicast_mode,
- no_ip_multicast_mode_noarg_cmd,
- "no ip multicast rpf-lookup-mode",
- NO_STR
- IP_STR
- "Multicast options\n"
- "RPF lookup behavior\n")
DEFUN (show_ip_rpf,
show_ip_rpf_cmd,
@@ -332,12 +315,13 @@ DEFUN (show_ip_rpf_addr,
"Display RPF information for multicast source\n"
"IP multicast source address (e.g. 10.0.0.0)\n")
{
+ int idx_ipv4 = 3;
struct in_addr addr;
struct route_node *rn;
struct rib *rib;
int ret;
- ret = inet_aton (argv[0], &addr);
+ ret = inet_aton (argv[idx_ipv4]->arg, &addr);
if (ret == 0)
{
vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
@@ -354,1127 +338,109 @@ DEFUN (show_ip_rpf_addr,
return CMD_SUCCESS;
}
-/* Static route configuration. */
-DEFUN (ip_route,
- ip_route_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_tag,
- ip_route_tag_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "One or more labels separated by '/'\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_flags,
- ip_route_flags_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_flags_tag,
- ip_route_flags_tag_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n")
-
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3],
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_flags2,
- ip_route_flags2_cmd,
- "ip route A.B.C.D/M (reject|blackhole)",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_flags2_tag,
- ip_route_flags2_tag_cmd,
- "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n")
-
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2],
- NULL, NULL, NULL);
-}
-
-/* Mask as A.B.C.D format. */
-DEFUN (ip_route_mask,
- ip_route_mask_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_mask_tag,
- ip_route_mask_tag_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n")
-
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_mask_flags,
- ip_route_mask_flags_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_mask_flags_tag,
- ip_route_mask_flags_tag_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n")
-
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4],
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_mask_flags2,
- ip_route_mask_flags2_cmd,
- "ip route A.B.C.D A.B.C.D (reject|blackhole)",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (ip_route_mask_flags2_tag,
- ip_route_mask_flags2_tag_cmd,
- "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3],
- NULL, NULL, NULL);
-}
-
-/* Distance option value. */
-DEFUN (ip_route_distance,
- ip_route_distance_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
- argv[2], NULL, NULL);
-}
-
-DEFUN (ip_route_tag_distance,
- ip_route_tag_distance_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
- argv[3], NULL, NULL);
-}
-
-DEFUN (ip_route_flags_distance,
- ip_route_flags_distance_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL,
- argv[3], NULL, NULL);
-}
-
-DEFUN (ip_route_flags_tag_distance,
- ip_route_flags_tag_distance_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3],
- argv[4], NULL, NULL);
-}
-
-DEFUN (ip_route_flags_distance2,
- ip_route_flags_distance2_cmd,
- "ip route A.B.C.D/M (reject|blackhole) <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL,
- argv[2], NULL, NULL);
-}
-
-DEFUN (ip_route_flags_tag_distance2,
- ip_route_flags_tag_distance2_cmd,
- "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2],
- argv[3], NULL, NULL);
-}
-
-DEFUN (ip_route_mask_distance,
- ip_route_mask_distance_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
- argv[3], NULL, NULL);
-}
-
-DEFUN (ip_route_mask_tag_distance,
- ip_route_mask_tag_distance_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
- argv[4], NULL, NULL);
-}
-
-DEFUN (ip_route_mask_flags_tag_distance,
- ip_route_mask_flags_tag_distance_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], NULL, NULL);
-}
-
-
-DEFUN (ip_route_mask_flags_distance,
- ip_route_mask_flags_distance_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL,
- argv[4], NULL, NULL);
-}
-
-DEFUN (ip_route_mask_flags_distance2,
- ip_route_mask_flags_distance2_cmd,
- "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL,
- argv[3], NULL, NULL);
-}
-
-DEFUN (ip_route_mask_flags_tag_distance2,
- ip_route_mask_flags_tag_distance2_cmd,
- "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3],
- argv[4], NULL, NULL);
-}
-
-DEFUN (no_ip_route,
- no_ip_route_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (no_ip_route_tag,
- no_ip_route_tag_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Tag of this route\n"
- "Tag value\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
- NULL, NULL, NULL);
-}
-
-ALIAS (no_ip_route,
- no_ip_route_flags_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-
-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
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "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,
- "no ip route A.B.C.D/M (reject|blackhole)",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, NULL, NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (no_ip_route_flags2_tag,
- no_ip_route_flags2_tag_cmd,
- "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "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, NULL, NULL, argv[2],
- NULL, NULL, NULL);
-}
-
-DEFUN (no_ip_route_mask,
- no_ip_route_mask_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (no_ip_route_mask_tag,
- no_ip_route_mask_tag_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\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[3],
- NULL, NULL, NULL);
-}
-
-ALIAS (no_ip_route_mask,
- no_ip_route_mask_flags_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-
-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
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "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,
- "no ip route A.B.C.D A.B.C.D (reject|blackhole)",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, NULL, NULL,
- NULL, NULL, NULL);
-}
-
-DEFUN (no_ip_route_mask_flags2_tag,
- no_ip_route_mask_flags2_tag_cmd,
- "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "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], NULL, NULL, argv[3],
- NULL, NULL, NULL);
-}
-
-DEFUN (no_ip_route_distance,
- no_ip_route_distance_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
- argv[2], NULL, NULL);
-}
-
-DEFUN (no_ip_route_tag_distance,
- no_ip_route_tag_distance_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
- argv[3], NULL, NULL);
-}
-
-DEFUN (no_ip_route_flags_distance,
- no_ip_route_flags_distance_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], NULL,
- argv[3], NULL, NULL);
-}
-
-DEFUN (no_ip_route_flags_tag_distance,
- no_ip_route_flags_tag_distance_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], argv[3],
- argv[4], NULL, NULL);
-}
-
-DEFUN (no_ip_route_flags_distance2,
- no_ip_route_flags_distance2_cmd,
- "no ip route A.B.C.D/M (reject|blackhole) <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], NULL,
- argv[2], NULL, NULL);
-}
-
-DEFUN (no_ip_route_flags_tag_distance2,
- no_ip_route_flags_tag_distance2_cmd,
- "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], argv[2],
- argv[3], NULL, NULL);
-}
-
-DEFUN (no_ip_route_mask_distance,
- no_ip_route_mask_distance_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
- argv[3], NULL, NULL);
-}
-
-DEFUN (no_ip_route_mask_tag_distance,
- no_ip_route_mask_tag_distance_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
- argv[4], NULL, NULL);
-}
-
-DEFUN (no_ip_route_mask_flags_distance,
- no_ip_route_mask_flags_distance_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], NULL,
- argv[4], NULL, NULL);
-}
-
-DEFUN (no_ip_route_mask_flags_tag_distance,
- no_ip_route_mask_flags_tag_distance_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], NULL, NULL);
-}
-
-DEFUN (no_ip_route_mask_flags_distance2,
- no_ip_route_mask_flags_distance2_cmd,
- "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n")
+static void
+zebra_vty_ip_route_tdv_helper (int argc, struct cmd_token *argv[],
+ int idx_curr, char **tag,
+ char **distance, char **vrf, char **labels)
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], NULL,
- argv[3], NULL, NULL);
-}
+ *distance = NULL;
+ while (idx_curr < argc)
+ {
+ if (strmatch (argv[idx_curr]->text, "tag"))
+ {
+ if (tag)
+ *tag = argv[idx_curr+1]->arg;
+ idx_curr += 2;
+ }
+ else if (strmatch (argv[idx_curr]->text, "vrf"))
+ {
+ if (vrf)
+ *vrf = argv[idx_curr+1]->arg;
+ idx_curr += 2;
+ }
+ else if (strmatch (argv[idx_curr]->text, "label"))
+ {
+ if (labels)
+ *labels = argv[idx_curr+1]->arg;
+ idx_curr += 2;
+ }
+ else
+ {
+ if (distance)
+ *distance = argv[idx_curr]->arg;
+ idx_curr++;
+ }
+ }
-DEFUN (no_ip_route_mask_flags_tag_distance2,
- no_ip_route_mask_flags_tag_distance2_cmd,
- "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n")
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], argv[3],
- argv[4], NULL, NULL);
+ return;
}
/* Static route configuration. */
-DEFUN (ip_route_vrf,
- ip_route_vrf_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
- NULL, NULL, argv[2], NULL);
-}
-
-DEFUN (ip_route_tag_vrf,
- ip_route_tag_vrf_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
- argv[2], NULL, argv[3], NULL);
-}
-
-DEFUN (ip_route_flags_vrf,
- ip_route_flags_vrf_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
- argv[2], NULL, NULL, argv[3], NULL);
-}
-
-DEFUN (ip_route_flags_tag_vrf,
- ip_route_flags_tag_vrf_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
- argv[2], argv[3], NULL, argv[4], NULL);
-}
-
-DEFUN (ip_route_flags2_vrf,
- ip_route_flags2_vrf_cmd,
- "ip route A.B.C.D/M (reject|blackhole) " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
- NULL, NULL, argv[2], NULL);
-}
-
-DEFUN (ip_route_flags2_tag_vrf,
- ip_route_flags2_tag_vrf_cmd,
- "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
+DEFUN (ip_route,
+ ip_route_cmd,
+ "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
- argv[2], NULL, argv[3], NULL);
-}
-
-/* Mask as A.B.C.D format. */
-DEFUN (ip_route_mask_vrf,
- ip_route_mask_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
"IP gateway address\n"
"IP gateway interface name\n"
"Null interface\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
- NULL, NULL, NULL, argv[3], NULL);
-}
-
-DEFUN (ip_route_mask_tag_vrf,
- ip_route_mask_tag_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
- NULL, argv[3], NULL, argv[4], NULL);
-}
-
-DEFUN (ip_route_mask_flags_vrf,
- ip_route_mask_flags_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
- argv[3], NULL, NULL, argv[4], NULL);
-}
-
-DEFUN (ip_route_mask_flags_tag_vrf,
- ip_route_mask_flags_tag_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
"Set tag for this route\n"
"Tag value\n"
- VRF_CMD_HELP_STR)
-
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
- argv[3], argv[4], NULL, argv[5], NULL);
-}
-
-DEFUN (ip_route_mask_flags2_vrf,
- ip_route_mask_flags2_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (reject|blackhole) " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
- argv[2], NULL, NULL, argv[3], NULL);
-}
-
-DEFUN (ip_route_mask_flags2_tag_vrf,
- ip_route_mask_flags2_tag_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
- argv[2], argv[3], NULL, argv[4], NULL);
-}
-
-/* Distance option value. */
-DEFUN (ip_route_distance_vrf,
- ip_route_distance_vrf_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
"Distance value for this route\n"
VRF_CMD_HELP_STR)
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
- NULL, argv[2], argv[3], NULL);
-}
+ int idx_ipv4_prefixlen = 2;
+ int idx_ipv4_ifname_null = 3;
+ int idx_curr = 4;
+ char *tag, *distance, *vrf;
-DEFUN (ip_route_tag_distance_vrf,
- ip_route_tag_distance_vrf_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
- argv[2], argv[3], argv[4], NULL);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
+ argv[idx_ipv4_prefixlen]->arg,
+ NULL,
+ argv[idx_ipv4_ifname_null]->arg,
+ NULL,
+ tag, distance, vrf, NULL);
}
-DEFUN (ip_route_flags_distance_vrf,
- ip_route_flags_distance_vrf_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
- argv[2], NULL, argv[3], argv[4], NULL);
-}
-
-DEFUN (ip_route_flags_tag_distance_vrf,
- ip_route_flags_tag_distance_vrf_cmd,
- "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
+DEFUN (ip_route_flags,
+ ip_route_flags_cmd,
+ "ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
"Emit an ICMP unreachable when matched\n"
"Silently discard pkts when matched\n"
"Set tag for this route\n"
"Tag value\n"
"Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
- argv[2], argv[3], argv[4],argv[5], NULL);
-}
-
-DEFUN (ip_route_flags_distance2_vrf,
- ip_route_flags_distance2_vrf_cmd,
- "ip route A.B.C.D/M (reject|blackhole) <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
- NULL, argv[2], argv[3], NULL);
-}
+ int idx_ipv4_prefixlen = 2;
+ int idx_reject_blackhole = 3;
+ int idx_curr = 4;
+ char *tag, *distance, *vrf;
-DEFUN (ip_route_flags_tag_distance2_vrf,
- ip_route_flags_tag_distance2_vrf_cmd,
- "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
- argv[2], argv[3], argv[4], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (ip_route_mask_distance_vrf,
- ip_route_mask_distance_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
- NULL, NULL, argv[3], argv[4], NULL);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
+ argv[idx_ipv4_prefixlen]->arg,
+ NULL,
+ NULL,
+ argv[idx_reject_blackhole]->arg,
+ tag, distance, vrf, NULL);
}
-DEFUN (ip_route_mask_tag_distance_vrf,
- ip_route_mask_tag_distance_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR,
+/* Mask as A.B.C.D format. */
+DEFUN (ip_route_mask,
+ ip_route_mask_cmd,
+ "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
"IP destination prefix\n"
@@ -1485,425 +451,124 @@ DEFUN (ip_route_mask_tag_distance_vrf,
"Set tag for this route\n"
"Tag value\n"
"Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
- NULL, argv[3], argv[4], argv[5], NULL);
-}
-
-DEFUN (ip_route_mask_flags_tag_distance_vrf,
- ip_route_mask_flags_tag_distance_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[5], argv[6], NULL);
-}
+ int idx_ipv4 = 2;
+ int idx_ipv4_2 = 3;
+ int idx_ipv4_ifname_null = 4;
+ int idx_curr = 5;
+ char *tag, *distance, *vrf;
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (ip_route_mask_flags_distance_vrf,
- ip_route_mask_flags_distance_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
- argv[3], NULL, argv[4], argv[5], NULL);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
+ argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg,
+ argv[idx_ipv4_ifname_null]->arg,
+ NULL, tag, distance, vrf, NULL);
}
-DEFUN (ip_route_mask_flags_distance2_vrf,
- ip_route_mask_flags_distance2_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255> " VRF_CMD_STR,
+DEFUN (ip_route_mask_flags,
+ ip_route_mask_flags_cmd,
+ "ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
"IP destination prefix\n"
"IP destination prefix mask\n"
"Emit an ICMP unreachable when matched\n"
"Silently discard pkts when matched\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
- argv[2], NULL, argv[3], argv[4], NULL);
-}
-
-DEFUN (ip_route_mask_flags_tag_distance2_vrf,
- ip_route_mask_flags_tag_distance2_vrf_cmd,
- "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
"Set tag for this route\n"
"Tag value\n"
"Distance value for this route\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
- argv[2], argv[3], argv[4], argv[5], NULL);
-}
-
-DEFUN (no_ip_route_vrf,
- no_ip_route_vrf_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
- NULL, NULL, argv[2], NULL);
-}
-
-DEFUN (no_ip_route_flags_vrf,
- no_ip_route_flags_vrf_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
- argv[2], NULL, NULL, argv[3], NULL);
-}
-
-DEFUN (no_ip_route_tag_vrf,
- no_ip_route_tag_vrf_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Tag of this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
- argv[2], NULL, argv[3], NULL);
-}
+ int idx_ipv4 = 2;
+ int idx_ipv4_2 = 3;
+ int idx_reject_blackhole = 4;
+ int idx_curr = 5;
+ char *tag, *distance, *vrf;
-DEFUN (no_ip_route_flags_tag_vrf,
- no_ip_route_flags_tag_vrf_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
- argv[2], argv[3], NULL, argv[4], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (no_ip_route_flags2_vrf,
- no_ip_route_flags2_vrf_cmd,
- "no ip route A.B.C.D/M (reject|blackhole) " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
- NULL, NULL, argv[2], NULL);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
+ argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg,
+ NULL,
+ argv[idx_reject_blackhole]->arg,
+ tag, distance, vrf, NULL);
}
-DEFUN (no_ip_route_flags2_tag_vrf,
- no_ip_route_flags2_tag_vrf_cmd,
- "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
+DEFUN (no_ip_route,
+ no_ip_route_cmd,
+ "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR
IP_STR
"Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
- argv[2], NULL, argv[3], NULL);
-}
-
-DEFUN (no_ip_route_mask_vrf,
- no_ip_route_mask_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
- NULL, NULL, NULL, argv[3], NULL);
-}
-
-DEFUN (no_ip_route_mask_flags_vrf,
- no_ip_route_mask_flags_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
- argv[3], NULL, NULL, argv[4], NULL);
-}
-
-DEFUN (no_ip_route_mask_tag_vrf,
- no_ip_route_mask_tag_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
"IP gateway address\n"
"IP gateway interface name\n"
"Null interface\n"
"Tag of this route\n"
"Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
- NULL, argv[3], NULL, argv[4], NULL);
-}
-
-DEFUN (no_ip_route_mask_flags_tag_vrf,
- no_ip_route_mask_flags_tag_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
- argv[3], argv[4], NULL, argv[5], NULL);
-}
-
-DEFUN (no_ip_route_mask_flags2_vrf,
- no_ip_route_mask_flags2_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (reject|blackhole) " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
- argv[2], NULL, NULL, argv[3], NULL);
-}
-
-DEFUN (no_ip_route_mask_flags2_tag_vrf,
- no_ip_route_mask_flags2_tag_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
- argv[2], argv[3], NULL, argv[4], NULL);
-}
-
-
-DEFUN (no_ip_route_distance_vrf,
- no_ip_route_distance_vrf_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
"Distance value for this route\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
- NULL, argv[2], argv[3], NULL);
-}
+ int idx_ipv4_prefixlen = 3;
+ int idx_ipv4_ifname_null = 4;
+ int idx_curr = 5;
+ char *tag, *distance, *vrf;
-DEFUN (no_ip_route_tag_distance_vrf,
- no_ip_route_tag_distance_vrf_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
- argv[2], argv[3], argv[4], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (no_ip_route_flags_distance_vrf,
- no_ip_route_flags_distance_vrf_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
- argv[2], NULL, argv[3], argv[4], NULL);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
+ argv[idx_ipv4_prefixlen]->arg,
+ NULL,
+ argv[idx_ipv4_ifname_null]->arg,
+ NULL,
+ tag, distance, vrf, NULL);
}
-DEFUN (no_ip_route_flags_tag_distance_vrf,
- no_ip_route_flags_tag_distance_vrf_cmd,
- "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
+DEFUN (no_ip_route_flags,
+ no_ip_route_flags_cmd,
+ "no ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR
IP_STR
"Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
"Emit an ICMP unreachable when matched\n"
"Silently discard pkts when matched\n"
"Tag of this route\n"
"Tag value\n"
"Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
- argv[2], argv[3], argv[4],argv[5], NULL);
-}
-
-DEFUN (no_ip_route_flags_distance2_vrf,
- no_ip_route_flags_distance2_vrf_cmd,
- "no ip route A.B.C.D/M (reject|blackhole) <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
- NULL, argv[2], argv[3], NULL);
-}
+ int idx_ipv4_prefixlen = 3;
+ int idx_curr = 5;
+ char *tag, *distance, *vrf;
-DEFUN (no_ip_route_flags_tag_distance2_vrf,
- no_ip_route_flags_tag_distance2_vrf_cmd,
- "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
- argv[2] , argv[3], argv[4], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (no_ip_route_mask_distance_vrf,
- no_ip_route_mask_distance_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Null interface\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
- NULL, NULL, argv[3], argv[4], NULL);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
+ argv[idx_ipv4_prefixlen]->arg,
+ NULL, NULL, NULL,
+ tag, distance, vrf, NULL);
}
-DEFUN (no_ip_route_mask_tag_distance_vrf,
- no_ip_route_mask_tag_distance_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR,
+DEFUN (no_ip_route_mask,
+ no_ip_route_mask_cmd,
+ "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR
IP_STR
"Establish static routes\n"
@@ -1915,86 +580,57 @@ DEFUN (no_ip_route_mask_tag_distance_vrf,
"Tag of this route\n"
"Tag value\n"
"Distance value for this route\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
- NULL, argv[3], argv[4], argv[5], NULL);
-}
+ int idx_ipv4 = 3;
+ int idx_ipv4_2 = 4;
+ int idx_ipv4_ifname_null = 5;
+ int idx_curr = 6;
+ char *tag, *distance, *vrf;
-DEFUN (no_ip_route_mask_flags_distance_vrf,
- no_ip_route_mask_flags_distance_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
- argv[3], NULL, argv[4], argv[5], NULL);
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
+
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
+ argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg,
+ argv[idx_ipv4_ifname_null]->arg,
+ NULL,
+ tag, distance, vrf, NULL);
}
-DEFUN (no_ip_route_mask_flags_tag_distance_vrf,
- no_ip_route_mask_flags_tag_distance_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
+DEFUN (no_ip_route_mask_flags,
+ no_ip_route_mask_flags_cmd,
+ "no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR
IP_STR
"Establish static routes\n"
"IP destination prefix\n"
"IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
"Emit an ICMP unreachable when matched\n"
"Silently discard pkts when matched\n"
"Tag of this route\n"
"Tag value\n"
"Distance value for this route\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
- argv[3], argv[4], argv[5], argv[6], NULL);
-}
+ int idx_ipv4 = 3;
+ int idx_ipv4_2 = 4;
+ int idx_curr = 6;
+ char *tag, *distance, *vrf;
-DEFUN (no_ip_route_mask_flags_distance2_vrf,
- no_ip_route_mask_flags_distance2_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
- argv[2], NULL, argv[3], argv[4], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (no_ip_route_mask_flags_tag_distance2_vrf,
- no_ip_route_mask_flags_tag_distance2_vrf_cmd,
- "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR)
-{
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
- argv[2], argv[3], argv[4], argv[5], NULL);
+ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
+ argv[idx_ipv4]->arg,
+ argv[idx_ipv4_2]->arg,
+ NULL, NULL,
+ tag, distance, vrf, NULL);
}
/* New RIB. Detailed information for IPv4 route. */
@@ -2004,7 +640,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
struct rib *rib;
struct nexthop *nexthop, *tnexthop;
int recursing;
- char buf[PREFIX_STRLEN];
+ char buf[SRCDEST2STR_BUFFER];
struct zebra_vrf *zvrf;
RNODE_FOREACH_RIB (rn, rib)
@@ -2012,14 +648,14 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
const char *mcast_info = "";
if (mcast)
{
- rib_table_info_t *info = rn->table->info;
+ rib_table_info_t *info = srcdest_rnode_table_info(rn);
mcast_info = (info->safi == SAFI_MULTICAST)
? " using Multicast RIB"
: " using Unicast RIB";
}
-
+
vty_out (vty, "Routing entry for %s%s%s",
- prefix2str (&rn->p, buf, sizeof(buf)), mcast_info,
+ srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info,
VTY_NEWLINE);
vty_out (vty, " Known via \"%s", zebra_route_string (rib->type));
if (rib->instance)
@@ -2027,7 +663,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
vty_out (vty, "\"");
vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
if (rib->tag)
- vty_out (vty, ", tag %"ROUTE_TAG_PRI, rib->tag);
+ vty_out (vty, ", tag %d", rib->tag);
if (rib->mtu)
vty_out (vty, ", mtu %u", rib->mtu);
if (rib->vrf_id != VRF_DEFAULT)
@@ -2037,10 +673,6 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
}
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
vty_out (vty, ", best");
- else if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
- vty_out (vty, ", fib");
- if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE))
- vty_out (vty, ", fib-override");
if (rib->refcnt)
vty_out (vty, ", refcnt %ld", rib->refcnt);
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
@@ -2065,13 +697,13 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
vty_out (vty, " Last update ");
if (uptime < ONE_DAY_SECOND)
- vty_out (vty, "%02d:%02d:%02d",
+ vty_out (vty, "%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
else if (uptime < ONE_WEEK_SECOND)
- vty_out (vty, "%dd%02dh%02dm",
+ vty_out (vty, "%dd%02dh%02dm",
tm->tm_yday, tm->tm_hour, tm->tm_min);
else
- vty_out (vty, "%02dw%dd%02dh",
+ vty_out (vty, "%02dw%dd%02dh",
tm->tm_yday/7,
tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
vty_out (vty, " ago%s", VTY_NEWLINE);
@@ -2146,12 +778,12 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
}
/* Label information */
- if (nexthop->nh_label && nexthop->nh_label->num_labels)
- {
- vty_out (vty, " label %s",
- mpls_label2str (nexthop->nh_label->num_labels,
- nexthop->nh_label->label, buf, BUFSIZ));
- }
+ if (nexthop->nh_label && nexthop->nh_label->num_labels)
+ {
+ vty_out (vty, " label %s",
+ mpls_label2str (nexthop->nh_label->num_labels,
+ nexthop->nh_label->label, buf, BUFSIZ));
+ }
vty_out (vty, "%s", VTY_NEWLINE);
}
@@ -2166,7 +798,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
struct nexthop *nexthop, *tnexthop;
int recursing;
int len = 0;
- char buf[BUFSIZ];
+ char buf[SRCDEST2STR_BUFFER];
json_object *json_nexthops = NULL;
json_object *json_nexthop = NULL;
json_object *json_route = NULL;
@@ -2176,7 +808,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
json_route = json_object_new_object();
json_nexthops = json_object_new_array();
- json_object_string_add(json_route, "prefix", prefix2str (&rn->p, buf, sizeof buf));
+ json_object_string_add(json_route, "prefix", srcdest_rnode2str (rn, buf, sizeof buf));
json_object_string_add(json_route, "protocol", zebra_route_string(rib->type));
if (rib->instance)
@@ -2317,14 +949,13 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
len += vty_out (vty, "[%d]", rib->instance);
len += vty_out (vty, "%c%c %s",
CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
- ? '>' : CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)
- ? '!' : ' ',
+ ? '>' : ' ',
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
? '*' : ' ',
- prefix2str (&rn->p, buf, sizeof buf));
+ srcdest_rnode2str (rn, buf, sizeof buf));
/* Distance and metric display. */
- if (rib->type != ZEBRA_ROUTE_CONNECT
+ if (rib->type != ZEBRA_ROUTE_CONNECT
&& rib->type != ZEBRA_ROUTE_KERNEL)
len += vty_out (vty, " [%d/%d]", rib->distance,
rib->metric);
@@ -2396,11 +1027,11 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
/* Label information */
if (nexthop->nh_label && nexthop->nh_label->num_labels)
- {
- vty_out (vty, " label %s",
- mpls_label2str (nexthop->nh_label->num_labels,
- nexthop->nh_label->label, buf, BUFSIZ));
- }
+ {
+ vty_out (vty, " label %s",
+ mpls_label2str (nexthop->nh_label->num_labels,
+ nexthop->nh_label->label, buf, BUFSIZ));
+ }
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
vty_out (vty, ", bh");
@@ -2421,13 +1052,13 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
tm = gmtime (&uptime);
if (uptime < ONE_DAY_SECOND)
- vty_out (vty, ", %02d:%02d:%02d",
+ vty_out (vty, ", %02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
else if (uptime < ONE_WEEK_SECOND)
- vty_out (vty, ", %dd%02dh%02dm",
+ vty_out (vty, ", %dd%02dh%02dm",
tm->tm_yday, tm->tm_hour, tm->tm_min);
else
- vty_out (vty, ", %02dw%dd%02dh",
+ vty_out (vty, ", %02dw%dd%02dh",
tm->tm_yday/7,
tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
}
@@ -2437,10 +1068,11 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
DEFUN (show_ip_route,
show_ip_route_cmd,
- "show ip route {json}",
+ "show ip route [json]",
SHOW_STR
IP_STR
- "IP routing table\n")
+ "IP routing table\n"
+ JSON_STR)
{
return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST, use_json(argc, argv));
}
@@ -2531,47 +1163,41 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
DEFUN (show_ip_route_vrf,
show_ip_route_vrf_cmd,
- "show ip route " VRF_CMD_STR " {json}",
+ "show ip route vrf NAME [json]",
SHOW_STR
IP_STR
"IP routing table\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ JSON_STR)
{
+ int idx_vrf = 4;
u_char uj = use_json(argc, argv);
- if (argc == 1 && uj)
- return do_show_ip_route (vty, NULL, SAFI_UNICAST, uj);
- else
- return do_show_ip_route (vty, argv[0], SAFI_UNICAST, uj);
+ return do_show_ip_route (vty, argv[idx_vrf]->arg, SAFI_UNICAST, uj);
}
DEFUN (show_ip_nht,
show_ip_nht_cmd,
- "show ip nht",
+ "show ip nht [vrf NAME]",
SHOW_STR
IP_STR
- "IP nexthop tracking table\n")
+ "IP nexthop tracking table\n"
+ VRF_CMD_HELP_STR)
{
+ int idx_vrf = 4;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (argc == 5)
+ VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
return CMD_SUCCESS;
}
-ALIAS (show_ip_nht,
- show_ip_nht_vrf_cmd,
- "show ip nht " VRF_CMD_STR,
- SHOW_STR
- IP_STR
- "IP nexthop tracking table\n"
- VRF_CMD_HELP_STR)
DEFUN (show_ip_nht_vrf_all,
show_ip_nht_vrf_all_cmd,
- "show ip nht " VRF_ALL_CMD_STR,
+ "show ip nht vrf all",
SHOW_STR
IP_STR
"IP nexthop tracking table\n"
@@ -2592,31 +1218,26 @@ DEFUN (show_ip_nht_vrf_all,
DEFUN (show_ipv6_nht,
show_ipv6_nht_cmd,
- "show ipv6 nht",
+ "show ipv6 nht [vrf NAME]",
SHOW_STR
IPV6_STR
- "IPv6 nexthop tracking table\n")
+ "IPv6 nexthop tracking table\n"
+ VRF_CMD_HELP_STR)
{
+ int idx_vrf = 4;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (argc == 5)
+ VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_nht,
- show_ipv6_nht_vrf_cmd,
- "show ipv6 nht " VRF_CMD_STR,
- SHOW_STR
- IPV6_STR
- "IPv6 nexthop tracking table\n"
- VRF_CMD_HELP_STR)
DEFUN (show_ipv6_nht_vrf_all,
show_ipv6_nht_vrf_all_cmd,
- "show ipv6 nht " VRF_ALL_CMD_STR,
+ "show ipv6 nht vrf all",
SHOW_STR
IP_STR
"IPv6 nexthop tracking table\n"
@@ -2699,13 +1320,17 @@ DEFUN (no_ipv6_nht_default_route,
DEFUN (show_ip_route_tag,
show_ip_route_tag_cmd,
- "show ip route tag <1-4294967295>",
+ "show ip route [vrf NAME] tag (1-4294967295)",
SHOW_STR
IP_STR
"IP routing table\n"
+ VRF_CMD_HELP_STR
"Show only routes with tag\n"
"Tag value\n")
{
+ int idx_vrf = 3;
+ int idx_name = 4;
+ int idx_tag = 6;
struct route_table *table;
struct route_node *rn;
struct rib *rib;
@@ -2713,13 +1338,16 @@ DEFUN (show_ip_route_tag,
route_tag_t tag = 0;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1)
+ if (strmatch(argv[idx_vrf]->text, "vrf"))
{
- VTY_GET_INTEGER_RANGE("tag", tag, argv[1], 0, 4294967295);
- VRF_GET_ID (vrf_id, argv[0]);
+ VRF_GET_ID (vrf_id, argv[idx_name]->arg);
+ VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
}
else
- VTY_GET_INTEGER_RANGE("tag", tag, argv[0], 0, 4294967295);
+ {
+ idx_tag -= 2;
+ VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
+ }
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! table)
@@ -2742,22 +1370,13 @@ DEFUN (show_ip_route_tag,
return CMD_SUCCESS;
}
-ALIAS (show_ip_route_tag,
- show_ip_route_vrf_tag_cmd,
- "show ip route " VRF_CMD_STR " tag <1-4294967295>",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "Show only routes with tag\n"
- "Tag value\n")
-
DEFUN (show_ip_route_prefix_longer,
show_ip_route_prefix_longer_cmd,
- "show ip route A.B.C.D/M longer-prefixes",
+ "show ip route [vrf NAME] A.B.C.D/M longer-prefixes",
SHOW_STR
IP_STR
"IP routing table\n"
+ VRF_CMD_HELP_STR
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Show route matching the specified Network/Mask pair only\n")
{
@@ -2769,13 +1388,15 @@ DEFUN (show_ip_route_prefix_longer,
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1)
+ if (strmatch(argv[3]->text, "vrf"))
{
- ret = str2prefix (argv[1], &p);
- VRF_GET_ID (vrf_id, argv[0]);
+ VRF_GET_ID (vrf_id, argv[4]->arg);
+ ret = str2prefix (argv[5]->arg, &p);
}
else
- ret = str2prefix (argv[0], &p);
+ {
+ ret = str2prefix (argv[3]->arg, &p);
+ }
if (! ret)
{
@@ -2802,22 +1423,13 @@ DEFUN (show_ip_route_prefix_longer,
return CMD_SUCCESS;
}
-ALIAS (show_ip_route_prefix_longer,
- show_ip_route_vrf_prefix_longer_cmd,
- "show ip route " VRF_CMD_STR " A.B.C.D/M longer-prefixes",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Show route matching the specified Network/Mask pair only\n")
-
DEFUN (show_ip_route_supernets,
show_ip_route_supernets_cmd,
- "show ip route supernets-only",
+ "show ip route [vrf NAME] supernets-only",
SHOW_STR
IP_STR
"IP routing table\n"
+ VRF_CMD_HELP_STR
"Show supernet entries only\n")
{
struct route_table *table;
@@ -2827,8 +1439,8 @@ DEFUN (show_ip_route_supernets,
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 0)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (strmatch(argv[3]->text, "vrf"))
+ VRF_GET_ID (vrf_id, argv[4]->arg);
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! table)
@@ -2855,21 +1467,13 @@ DEFUN (show_ip_route_supernets,
return CMD_SUCCESS;
}
-ALIAS (show_ip_route_supernets,
- show_ip_route_vrf_supernets_cmd,
- "show ip route " VRF_CMD_STR " supernets-only",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "Show supernet entries only\n")
-
DEFUN (show_ip_route_protocol,
show_ip_route_protocol_cmd,
- "show ip route " FRR_IP_REDIST_STR_ZEBRA,
+ "show ip route [vrf NAME] " FRR_IP_REDIST_STR_ZEBRA,
SHOW_STR
IP_STR
"IP routing table\n"
+ VRF_CMD_HELP_STR
FRR_IP_REDIST_HELP_STR_ZEBRA)
{
int type;
@@ -2879,13 +1483,12 @@ DEFUN (show_ip_route_protocol,
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1)
- {
- type = proto_redistnum (AFI_IP, argv[1]);
- VRF_GET_ID (vrf_id, argv[0]);
- }
- else
- type = proto_redistnum (AFI_IP, argv[0]);
+ int idx = 0;
+ if (argv_find (argv, argc, "NAME", &idx))
+ VRF_GET_ID (vrf_id, argv[idx]->arg);
+
+ char *proto = argv[argc - 1]->text;
+ type = proto_redistnum (AFI_IP, proto);
if (type < 0)
{
@@ -2912,31 +1515,24 @@ DEFUN (show_ip_route_protocol,
return CMD_SUCCESS;
}
-ALIAS (show_ip_route_protocol,
- show_ip_route_vrf_protocol_cmd,
- "show ip route " VRF_CMD_STR " " FRR_IP_REDIST_STR_ZEBRA,
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- FRR_IP_REDIST_HELP_STR_ZEBRA)
DEFUN (show_ip_route_ospf_instance,
show_ip_route_ospf_instance_cmd,
- "show ip route ospf <1-65535>",
+ "show ip route ospf (1-65535)",
SHOW_STR
IP_STR
"IP routing table\n"
"Open Shortest Path First (OSPFv2)\n"
"Instance ID\n")
{
+ int idx_number = 4;
struct route_table *table;
struct route_node *rn;
struct rib *rib;
int first = 1;
u_short instance = 0;
- VTY_GET_INTEGER ("Instance", instance, argv[0]);
+ VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
if (! table)
@@ -2959,10 +1555,11 @@ DEFUN (show_ip_route_ospf_instance,
DEFUN (show_ip_route_addr,
show_ip_route_addr_cmd,
- "show ip route A.B.C.D",
+ "show ip route [vrf NAME] A.B.C.D",
SHOW_STR
IP_STR
"IP routing table\n"
+ VRF_CMD_HELP_STR
"Network in the IP routing table to display\n")
{
int ret;
@@ -2971,13 +1568,15 @@ DEFUN (show_ip_route_addr,
struct route_node *rn;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1)
+ if (strmatch(argv[3]->text, "vrf"))
{
- VRF_GET_ID (vrf_id, argv[0]);
- ret = str2prefix_ipv4 (argv[1], &p);
+ VRF_GET_ID (vrf_id, argv[4]->arg);
+ ret = str2prefix_ipv4 (argv[5]->arg, &p);
}
else
- ret = str2prefix_ipv4 (argv[0], &p);
+ {
+ ret = str2prefix_ipv4 (argv[3]->arg, &p);
+ }
if (ret <= 0)
{
@@ -3003,21 +1602,13 @@ DEFUN (show_ip_route_addr,
return CMD_SUCCESS;
}
-ALIAS (show_ip_route_addr,
- show_ip_route_vrf_addr_cmd,
- "show ip route " VRF_CMD_STR " A.B.C.D",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "Network in the IP routing table to display\n")
-
DEFUN (show_ip_route_prefix,
show_ip_route_prefix_cmd,
- "show ip route A.B.C.D/M",
+ "show ip route [vrf NAME] A.B.C.D/M",
SHOW_STR
IP_STR
"IP routing table\n"
+ VRF_CMD_HELP_STR
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
{
int ret;
@@ -3026,13 +1617,15 @@ DEFUN (show_ip_route_prefix,
struct route_node *rn;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1)
+ if (strmatch(argv[3]->text, "vrf"))
{
- VRF_GET_ID (vrf_id, argv[0]);
- ret = str2prefix_ipv4 (argv[1], &p);
+ VRF_GET_ID (vrf_id, argv[4]->arg);
+ ret = str2prefix_ipv4 (argv[5]->arg, &p);
}
else
- ret = str2prefix_ipv4 (argv[0], &p);
+ {
+ ret = str2prefix_ipv4 (argv[3]->arg, &p);
+ }
if (ret <= 0)
{
@@ -3058,14 +1651,6 @@ DEFUN (show_ip_route_prefix,
return CMD_SUCCESS;
}
-ALIAS (show_ip_route_prefix,
- show_ip_route_vrf_prefix_cmd,
- "show ip route " VRF_CMD_STR " A.B.C.D/M",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
static void
vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
@@ -3081,7 +1666,7 @@ vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
memset (&rib_cnt, 0, sizeof(rib_cnt));
memset (&fib_cnt, 0, sizeof(fib_cnt));
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
is_ibgp = (rib->type == ZEBRA_ROUTE_BGP &&
@@ -3106,7 +1691,7 @@ vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
"Route Source", "Routes", "FIB",
- zvrf_name (((rib_table_info_t *)table->info)->zvrf),
+ zvrf_name (((rib_table_info_t *)table->info)->zvrf),
VTY_NEWLINE);
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
@@ -3157,7 +1742,7 @@ vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
memset (&rib_cnt, 0, sizeof(rib_cnt));
memset (&fib_cnt, 0, sizeof(fib_cnt));
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
@@ -3187,7 +1772,7 @@ vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
"Route Source", "Prefix Routes", "FIB",
- zvrf_name (((rib_table_info_t *)table->info)->zvrf),
+ zvrf_name (((rib_table_info_t *)table->info)->zvrf),
VTY_NEWLINE);
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
@@ -3219,17 +1804,18 @@ vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
/* Show route summary. */
DEFUN (show_ip_route_summary,
show_ip_route_summary_cmd,
- "show ip route summary",
+ "show ip route [vrf NAME] summary",
SHOW_STR
IP_STR
"IP routing table\n"
+ VRF_CMD_HELP_STR
"Summary of all routes\n")
{
struct route_table *table;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 0)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (strmatch(argv[3]->text, "vrf"))
+ VRF_GET_ID (vrf_id, argv[4]->arg);
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! table)
@@ -3240,30 +1826,22 @@ DEFUN (show_ip_route_summary,
return CMD_SUCCESS;
}
-ALIAS (show_ip_route_summary,
- show_ip_route_vrf_summary_cmd,
- "show ip route " VRF_CMD_STR " summary",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "Summary of all routes\n")
-
/* Show route summary prefix. */
DEFUN (show_ip_route_summary_prefix,
show_ip_route_summary_prefix_cmd,
- "show ip route summary prefix",
+ "show ip route [vrf NAME] summary prefix",
SHOW_STR
IP_STR
"IP routing table\n"
+ VRF_CMD_HELP_STR
"Summary of all routes\n"
"Prefix routes\n")
{
struct route_table *table;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 0)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (strmatch(argv[3]->text, "vrf"))
+ VRF_GET_ID (vrf_id, argv[4]->arg);
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! table)
@@ -3274,19 +1852,10 @@ DEFUN (show_ip_route_summary_prefix,
return CMD_SUCCESS;
}
-ALIAS (show_ip_route_summary_prefix,
- show_ip_route_vrf_summary_prefix_cmd,
- "show ip route " VRF_CMD_STR " summary prefix",
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- "Summary of all routes\n"
- "Prefix routes\n")
DEFUN (show_ip_route_vrf_all,
show_ip_route_vrf_all_cmd,
- "show ip route " VRF_ALL_CMD_STR,
+ "show ip route vrf all",
SHOW_STR
IP_STR
"IP routing table\n"
@@ -3331,7 +1900,7 @@ DEFUN (show_ip_route_vrf_all,
DEFUN (show_ip_route_vrf_all_tag,
show_ip_route_vrf_all_tag_cmd,
- "show ip route " VRF_ALL_CMD_STR " tag <1-4294967295>",
+ "show ip route vrf all tag (1-4294967295)",
SHOW_STR
IP_STR
"IP routing table\n"
@@ -3339,6 +1908,7 @@ DEFUN (show_ip_route_vrf_all_tag,
"Show only routes with tag\n"
"Tag value\n")
{
+ int idx_number = 6;
struct route_table *table;
struct route_node *rn;
struct rib *rib;
@@ -3348,8 +1918,8 @@ DEFUN (show_ip_route_vrf_all_tag,
int vrf_header = 1;
route_tag_t tag = 0;
- if (argv[0])
- VTY_GET_INTEGER_RANGE("tag", tag, argv[0], 0, 4294967295);
+ if (argv[idx_number]->arg)
+ VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
@@ -3384,7 +1954,7 @@ DEFUN (show_ip_route_vrf_all_tag,
DEFUN (show_ip_route_vrf_all_prefix_longer,
show_ip_route_vrf_all_prefix_longer_cmd,
- "show ip route " VRF_ALL_CMD_STR " A.B.C.D/M longer-prefixes",
+ "show ip route vrf all A.B.C.D/M longer-prefixes",
SHOW_STR
IP_STR
"IP routing table\n"
@@ -3392,6 +1962,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Show route matching the specified Network/Mask pair only\n")
{
+ int idx_ipv4_prefixlen = 5;
struct route_table *table;
struct route_node *rn;
struct rib *rib;
@@ -3402,7 +1973,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
int first = 1;
int vrf_header = 1;
- ret = str2prefix (argv[0], &p);
+ ret = str2prefix (argv[idx_ipv4_prefixlen]->arg, &p);
if (! ret)
{
vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
@@ -3441,7 +2012,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
DEFUN (show_ip_route_vrf_all_supernets,
show_ip_route_vrf_all_supernets_cmd,
- "show ip route " VRF_ALL_CMD_STR " supernets-only",
+ "show ip route vrf all supernets-only",
SHOW_STR
IP_STR
"IP routing table\n"
@@ -3478,7 +2049,6 @@ DEFUN (show_ip_route_vrf_all_supernets,
vty_out (vty, SHOW_ROUTE_V4_HEADER);
first = 0;
}
-
if (vrf_header)
{
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
@@ -3495,7 +2065,7 @@ DEFUN (show_ip_route_vrf_all_supernets,
DEFUN (show_ip_route_vrf_all_protocol,
show_ip_route_vrf_all_protocol_cmd,
- "show ip route " VRF_ALL_CMD_STR " " FRR_IP_REDIST_STR_ZEBRA,
+ "show ip route vrf all " FRR_IP_REDIST_STR_ZEBRA,
SHOW_STR
IP_STR
"IP routing table\n"
@@ -3511,7 +2081,9 @@ DEFUN (show_ip_route_vrf_all_protocol,
int first = 1;
int vrf_header = 1;
- type = proto_redistnum (AFI_IP, argv[0]);
+ char *proto = argv[argc - 1]->text;
+ type = proto_redistnum (AFI_IP, proto);
+
if (type < 0)
{
vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
@@ -3550,13 +2122,14 @@ DEFUN (show_ip_route_vrf_all_protocol,
DEFUN (show_ip_route_vrf_all_addr,
show_ip_route_vrf_all_addr_cmd,
- "show ip route " VRF_ALL_CMD_STR " A.B.C.D",
+ "show ip route vrf all A.B.C.D",
SHOW_STR
IP_STR
"IP routing table\n"
VRF_ALL_CMD_HELP_STR
"Network in the IP routing table to display\n")
{
+ int idx_ipv4 = 5;
int ret;
struct prefix_ipv4 p;
struct route_table *table;
@@ -3564,7 +2137,7 @@ DEFUN (show_ip_route_vrf_all_addr,
struct vrf *vrf;
struct zebra_vrf *zvrf;
- ret = str2prefix_ipv4 (argv[0], &p);
+ ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
if (ret <= 0)
{
vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
@@ -3591,13 +2164,14 @@ DEFUN (show_ip_route_vrf_all_addr,
DEFUN (show_ip_route_vrf_all_prefix,
show_ip_route_vrf_all_prefix_cmd,
- "show ip route " VRF_ALL_CMD_STR " A.B.C.D/M",
+ "show ip route vrf all A.B.C.D/M",
SHOW_STR
IP_STR
"IP routing table\n"
VRF_ALL_CMD_HELP_STR
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
{
+ int idx_ipv4_prefixlen = 5;
int ret;
struct prefix_ipv4 p;
struct route_table *table;
@@ -3605,7 +2179,7 @@ DEFUN (show_ip_route_vrf_all_prefix,
struct vrf *vrf;
struct zebra_vrf *zvrf;
- ret = str2prefix_ipv4 (argv[0], &p);
+ ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
if (ret <= 0)
{
vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
@@ -3637,7 +2211,7 @@ DEFUN (show_ip_route_vrf_all_prefix,
DEFUN (show_ip_route_vrf_all_summary,
show_ip_route_vrf_all_summary_cmd,
- "show ip route " VRF_ALL_CMD_STR " summary ",
+ "show ip route vrf all summary ",
SHOW_STR
IP_STR
"IP routing table\n"
@@ -3656,7 +2230,7 @@ DEFUN (show_ip_route_vrf_all_summary,
DEFUN (show_ip_route_vrf_all_summary_prefix,
show_ip_route_vrf_all_summary_prefix_cmd,
- "show ip route " VRF_ALL_CMD_STR " summary prefix",
+ "show ip route vrf all summary prefix",
SHOW_STR
IP_STR
"IP routing table\n"
@@ -3688,10 +2262,8 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
- zvrf = vrf->info;
- if (! zvrf)
- continue;
-
+ if (!(zvrf = vrf->info))
+ continue;
if ((stable = zvrf->stable[AFI_IP][safi]) == NULL)
continue;
@@ -3711,6 +2283,14 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
case STATIC_BLACKHOLE:
vty_out (vty, " Null0");
break;
+ case STATIC_IPV6_GATEWAY:
+ vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
+ break;
+ case STATIC_IPV6_GATEWAY_IFINDEX:
+ vty_out (vty, " %s %s",
+ inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ),
+ ifindex2ifname_vrf (si->ifindex, si->vrf_id));
+ break;
}
/* flags are incompatible with STATIC_BLACKHOLE */
@@ -3749,14 +2329,16 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
/* General fucntion for IPv6 static route. */
int
static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
- const char *gate_str, const char *ifname,
- const char *flag_str, const char *tag_str,
+ const char *src_str,
+ const char *gate_str, const char *ifname,
+ const char *flag_str, const char *tag_str,
const char *distance_str, const char *vrf_id_str,
- const char *label_str)
+ const char *label_str)
{
int ret;
u_char distance;
- struct prefix p;
+ struct prefix p, src;
+ struct prefix_ipv6 *src_p = NULL;
struct in6_addr *gate = NULL;
struct in6_addr gate_addr;
u_char type = STATIC_BLACKHOLE;
@@ -3766,7 +2348,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
struct interface *ifp = NULL;
struct zebra_vrf *zvrf;
struct static_nh_label snh_label;
-
+
ret = str2prefix (dest_str, &p);
if (ret <= 0)
{
@@ -3774,6 +2356,17 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
return CMD_WARNING;
}
+ if (src_str)
+ {
+ ret = str2prefix (src_str, &src);
+ if (ret <= 0 || src.family != AF_INET6)
+ {
+ vty_out (vty, "%% Malformed source address%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ src_p = (struct prefix_ipv6*)&src;
+ }
+
/* Apply mask for given prefix. */
apply_mask (&p);
@@ -3805,11 +2398,11 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
if (label_str)
{
if (!mpls_enabled)
- {
- vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ {
+ vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
if (mpls_str2label (label_str, &snh_label.num_labels,
snh_label.label))
{
@@ -3827,11 +2420,11 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
return CMD_WARNING;
}
if (add_cmd)
- static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, ifindex, ifname,
- ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
+ static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, ifname,
+ ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
else
- static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, ifindex, tag,
- distance, zvrf, &snh_label);
+ static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, tag,
+ distance, zvrf, &snh_label);
return CMD_SUCCESS;
}
@@ -3857,716 +2450,211 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
/* When ifname is specified. It must be come with gateway
address. */
if (ret != 1)
- {
- vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ {
+ vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
type = STATIC_IPV6_GATEWAY_IFINDEX;
gate = &gate_addr;
ifp = if_lookup_by_name_vrf (ifname, zvrf_id (zvrf));
if (!ifp)
- {
- vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ {
+ vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
ifindex = ifp->ifindex;
}
else
{
if (ret == 1)
- {
- type = STATIC_IPV6_GATEWAY;
- gate = &gate_addr;
- }
+ {
+ type = STATIC_IPV6_GATEWAY;
+ gate = &gate_addr;
+ }
else
- {
- type = STATIC_IFINDEX;
- ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf));
- if (!ifp)
- {
- vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
+ {
+ type = STATIC_IFINDEX;
+ ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf));
+ if (!ifp)
+ {
+ vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
ifindex = IFINDEX_DELETED;
- }
+ }
else
- ifindex = ifp->ifindex;
- ifname = gate_str;
- }
+ ifindex = ifp->ifindex;
+ ifname = gate_str;
+ }
}
if (add_cmd)
- static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
- ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
+ static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
+ ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
else
- static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
- ifindex, tag, distance, zvrf, &snh_label);
+ static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
+ ifindex, tag, distance, zvrf, &snh_label);
return CMD_SUCCESS;
}
DEFUN (ipv6_route,
ipv6_route_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0)",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, NULL);
-}
-
-DEFUN (ipv6_route_tag,
- ipv6_route_tag_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, NULL);
-}
-
-DEFUN (ipv6_route_flags,
- ipv6_route_flags_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL, NULL, NULL);
-}
-
-DEFUN (ipv6_route_flags_tag,
- ipv6_route_flags_tag_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL, NULL, NULL);
-}
-
-DEFUN (ipv6_route_ifname,
- ipv6_route_ifname_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, NULL);
-}
-DEFUN (ipv6_route_ifname_tag,
- ipv6_route_ifname_tag_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, NULL);
-}
-
-DEFUN (ipv6_route_ifname_flags,
- ipv6_route_ifname_flags_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL, NULL, NULL);
-}
-
-DEFUN (ipv6_route_ifname_flags_tag,
- ipv6_route_ifname_flags_tag_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, NULL, NULL);
-}
-
-DEFUN (ipv6_route_pref,
- ipv6_route_pref_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) <1-255>",
+ "ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\n"
"Null interface\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, NULL);
-}
-
-DEFUN (ipv6_route_pref_tag,
- ipv6_route_pref_tag_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
"Null interface\n"
"Set tag for this route\n"
"Tag value\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, NULL);
-}
-
-DEFUN (ipv6_route_flags_pref,
- ipv6_route_flags_pref_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, argv[3], NULL, NULL);
-}
-
-DEFUN (ipv6_route_flags_pref_tag,
- ipv6_route_flags_pref_tag_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], NULL, NULL);
-}
-
-DEFUN (ipv6_route_ifname_pref,
- ipv6_route_ifname_pref_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, NULL);
-}
-
-DEFUN (ipv6_route_ifname_pref_tag,
- ipv6_route_ifname_pref_tag_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, NULL);
-}
-
-DEFUN (ipv6_route_ifname_flags_pref,
- ipv6_route_ifname_flags_pref_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], NULL, NULL);
-}
-
-DEFUN (ipv6_route_ifname_flags_pref_tag,
- ipv6_route_ifname_flags_pref_tag_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255>",
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], NULL, NULL);
-}
-
-DEFUN (no_ipv6_route,
- no_ipv6_route_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0)",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null Interface\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_tag,
- no_ipv6_route_tag_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) tag <1-4294967295>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_flags,
- no_ipv6_route_flags_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, NULL, NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_flags_tag,
- no_ipv6_route_flags_tag_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], NULL, NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_ifname,
- no_ipv6_route_ifname_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_ifname_tag,
- no_ipv6_route_ifname_tag_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_ifname_flags,
- no_ipv6_route_ifname_flags_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, NULL, NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_ifname_flags_tag,
- no_ipv6_route_ifname_flags_tag_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_pref,
- no_ipv6_route_pref_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_pref_tag,
- no_ipv6_route_pref_tag_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n")
+ "Distance value for this prefix\n"
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, NULL);
-}
+ int idx_ipv6_prefixlen = 2;
+ int idx_ipv6_ifname;
+ int idx_curr;
+ char *src, *tag, *distance, *vrf;
-DEFUN (no_ipv6_route_flags_pref,
- no_ipv6_route_flags_pref_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this prefix\n")
-{
- /* We do not care about argv[2] */
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, argv[3], NULL, NULL);
-}
+ if (!strcmp(argv[3]->text, "from"))
+ {
+ src = argv[4]->arg;
+ idx_ipv6_ifname = 5;
+ idx_curr = 6;
+ }
+ else
+ {
+ src = NULL;
+ idx_ipv6_ifname = 3;
+ idx_curr = 4;
+ }
-DEFUN (no_ipv6_route_flags_pref_tag,
- no_ipv6_route_flags_pref_tag_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n")
-{
- /* We do not care about argv[2] */
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], NULL, NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (no_ipv6_route_ifname_pref,
- no_ipv6_route_ifname_pref_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, NULL);
+ return static_ipv6_func (vty, 1,
+ argv[idx_ipv6_prefixlen]->arg,
+ src,
+ argv[idx_ipv6_ifname]->arg,
+ NULL, NULL,
+ tag, distance, vrf, NULL);
}
-DEFUN (no_ipv6_route_ifname_pref_tag,
- no_ipv6_route_ifname_pref_tag_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_ifname_flags_pref,
- no_ipv6_route_ifname_flags_pref_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
- NO_STR
+DEFUN (ipv6_route_flags,
+ ipv6_route_flags_cmd,
+ "ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\n"
"Emit an ICMP unreachable when matched\n"
"Silently discard pkts when matched\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], NULL, NULL);
-}
-
-DEFUN (no_ipv6_route_ifname_flags_pref_tag,
- no_ipv6_route_ifname_flags_pref_tag_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255>",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
"Silently discard pkts when matched\n"
"Set tag for this route\n"
"Tag value\n"
- "Distance value for this prefix\n")
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], NULL, NULL);
-}
-
-DEFUN (ipv6_route_vrf,
- ipv6_route_vrf_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, NULL, argv[2], NULL);
-}
-
-DEFUN (ipv6_route_tag_vrf,
- ipv6_route_tag_vrf_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], NULL, argv[3], NULL);
-}
-
-DEFUN (ipv6_route_flags_vrf,
- ipv6_route_flags_vrf_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
+ "Distance value for this prefix\n"
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL, argv[3], NULL);
-}
+ int idx_ipv6_prefixlen = 2;
+ int idx_ipv6_ifname;
+ int idx_reject_blackhole;
+ int idx_curr;
+ char *src, *tag, *distance, *vrf;
-DEFUN (ipv6_route_flags_tag_vrf,
- ipv6_route_flags_tag_vrf_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL, argv[4], NULL);
-}
+ if (!strcmp(argv[3]->text, "from"))
+ {
+ src = argv[4]->arg;
+ idx_ipv6_ifname = 5;
+ idx_reject_blackhole = 6;
+ idx_curr = 7;
+ }
+ else
+ {
+ src = NULL;
+ idx_ipv6_ifname = 3;
+ idx_reject_blackhole = 4;
+ idx_curr = 5;
+ }
-DEFUN (ipv6_route_ifname_vrf,
- ipv6_route_ifname_vrf_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3], NULL);
-}
-DEFUN (ipv6_route_ifname_tag_vrf,
- ipv6_route_ifname_tag_vrf_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (ipv6_route_ifname_flags_vrf,
- ipv6_route_ifname_flags_vrf_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL, argv[4], NULL);
+ return static_ipv6_func (vty, 1,
+ argv[idx_ipv6_prefixlen]->arg,
+ src,
+ argv[idx_ipv6_ifname]->arg,
+ NULL,
+ argv[idx_reject_blackhole]->arg,
+ tag, distance, vrf, NULL);
}
-DEFUN (ipv6_route_ifname_flags_tag_vrf,
- ipv6_route_ifname_flags_tag_vrf_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
+DEFUN (ipv6_route_ifname,
+ ipv6_route_ifname_cmd,
+ "ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
"Set tag for this route\n"
"Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, argv[5], NULL);
-}
-
-DEFUN (ipv6_route_pref_vrf,
- ipv6_route_pref_vrf_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
"Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, argv[2], argv[3], NULL);
-}
+ int idx_ipv6_prefixlen = 2;
+ int idx_ipv6 = 3;
+ int idx_interface = 4;
+ int idx_curr = 5;
+ char *src, *tag, *distance, *vrf;
-DEFUN (ipv6_route_pref_tag_vrf,
- ipv6_route_pref_tag_vrf_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], argv[3], argv[4], NULL);
-}
+ if (!strcmp(argv[3]->text, "from"))
+ {
+ src = argv[4]->arg;
+ idx_ipv6 = 5;
+ idx_interface = 6;
+ idx_curr = 7;
+ }
+ else
+ {
+ src = NULL;
+ idx_ipv6 = 3;
+ idx_interface = 4;
+ idx_curr = 5;
+ }
-DEFUN (ipv6_route_flags_pref_vrf,
- ipv6_route_flags_pref_vrf_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4], NULL);
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
+
+ return static_ipv6_func (vty, 1,
+ argv[idx_ipv6_prefixlen]->arg,
+ src,
+ argv[idx_ipv6]->arg,
+ argv[idx_interface]->arg,
+ NULL,
+ tag, distance, vrf, NULL);
}
-DEFUN (ipv6_route_flags_pref_tag_vrf,
- ipv6_route_flags_pref_tag_vrf_cmd,
- "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
+DEFUN (ipv6_route_ifname_flags,
+ ipv6_route_ifname_flags_cmd,
+ "ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\n"
"Emit an ICMP unreachable when matched\n"
@@ -4574,264 +2662,207 @@ DEFUN (ipv6_route_flags_pref_tag_vrf,
"Set tag for this route\n"
"Tag value\n"
"Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5], NULL);
-}
+ int idx_ipv6_prefixlen = 2;
+ int idx_ipv6;
+ int idx_interface;
+ int idx_reject_blackhole;
+ int idx_curr;
+ char *src, *tag, *distance, *vrf;
-DEFUN (ipv6_route_ifname_pref_vrf,
- ipv6_route_ifname_pref_vrf_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4], NULL);
-}
+ if (!strcmp(argv[3]->text, "from"))
+ {
+ src = argv[4]->arg;
+ idx_ipv6 = 5;
+ idx_interface = 6;
+ idx_reject_blackhole = 7;
+ idx_curr = 8;
+ }
+ else
+ {
+ src = NULL;
+ idx_ipv6 = 3;
+ idx_interface = 4;
+ idx_reject_blackhole = 5;
+ idx_curr = 6;
+ }
-DEFUN (ipv6_route_ifname_pref_tag_vrf,
- ipv6_route_ifname_pref_tag_vrf_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (ipv6_route_ifname_flags_pref_vrf,
- ipv6_route_ifname_flags_pref_vrf_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255> " VRF_CMD_STR,
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5], NULL);
+ return static_ipv6_func (vty, 1,
+ argv[idx_ipv6_prefixlen]->arg,
+ src,
+ argv[idx_ipv6]->arg,
+ argv[idx_interface]->arg,
+ argv[idx_reject_blackhole]->arg,
+ tag, distance, vrf, NULL);
}
-DEFUN (ipv6_route_ifname_flags_pref_tag_vrf,
- ipv6_route_ifname_flags_pref_tag_vrf_cmd,
- "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
+DEFUN (no_ipv6_route,
+ no_ipv6_route_cmd,
+ "no ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
+ NO_STR
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
+ "Null interface\n"
"Set tag for this route\n"
"Tag value\n"
"Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL);
-}
+ int idx_ipv6_prefixlen = 3;
+ int idx_ipv6_ifname;
+ int idx_curr;
+ char *src, *tag, *distance, *vrf;
-DEFUN (no_ipv6_route_vrf,
- no_ipv6_route_vrf_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, argv[2], NULL);
-}
+ if (!strcmp(argv[4]->text, "from"))
+ {
+ src = argv[5]->arg;
+ idx_ipv6_ifname = 6;
+ idx_curr = 7;
+ }
+ else
+ {
+ src = NULL;
+ idx_ipv6_ifname = 4;
+ idx_curr = 5;
+ }
-DEFUN (no_ipv6_route_tag_vrf,
- no_ipv6_route_tag_vrf_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, argv[3], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (no_ipv6_route_flags_vrf,
- no_ipv6_route_flags_vrf_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, NULL, argv[3], NULL);
+ return static_ipv6_func (vty, 0,
+ argv[idx_ipv6_prefixlen]->arg,
+ src,
+ argv[idx_ipv6_ifname]->arg,
+ NULL, NULL,
+ tag, distance, vrf, NULL);
}
-DEFUN (no_ipv6_route_flags_tag_vrf,
- no_ipv6_route_flags_tag_vrf_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
+DEFUN (no_ipv6_route_flags,
+ no_ipv6_route_flags_cmd,
+ "no ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\n"
"Emit an ICMP unreachable when matched\n"
"Silently discard pkts when matched\n"
"Set tag for this route\n"
"Tag value\n"
- VRF_CMD_HELP_STR)
+ "Distance value for this prefix\n"
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], NULL, argv[4], NULL);
-}
+ int idx_ipv6_prefixlen = 3;
+ int idx_ipv6_ifname;
+ int idx_reject_blackhole;
+ int idx_curr;
+ char *src, *tag, *distance, *vrf;
-DEFUN (no_ipv6_route_ifname_vrf,
- no_ipv6_route_ifname_vrf_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3], NULL);
-}
+ if (!strcmp(argv[4]->text, "from"))
+ {
+ src = argv[5]->arg;
+ idx_ipv6_ifname = 6;
+ idx_reject_blackhole = 7;
+ idx_curr = 8;
+ }
+ else
+ {
+ src = NULL;
+ idx_ipv6_ifname = 4;
+ idx_reject_blackhole = 5;
+ idx_curr = 6;
+ }
-DEFUN (no_ipv6_route_ifname_tag_vrf,
- no_ipv6_route_ifname_tag_vrf_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (no_ipv6_route_ifname_flags_vrf,
- no_ipv6_route_ifname_flags_vrf_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, NULL, argv[4], NULL);
+ return static_ipv6_func (vty, 0,
+ argv[idx_ipv6_prefixlen]->arg,
+ src,
+ argv[idx_ipv6_ifname]->arg,
+ NULL,
+ argv[idx_reject_blackhole]->arg,
+ tag, distance, vrf, NULL);
}
-DEFUN (no_ipv6_route_ifname_flags_tag_vrf,
- no_ipv6_route_ifname_flags_tag_vrf_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
+DEFUN (no_ipv6_route_ifname,
+ no_ipv6_route_ifname_cmd,
+ "no ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
"Set tag for this route\n"
"Tag value\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, argv[5], NULL);
-}
-
-DEFUN (no_ipv6_route_pref_vrf,
- no_ipv6_route_pref_vrf_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
"Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, argv[2], argv[3], NULL);
-}
+ int idx_ipv6_prefixlen = 3;
+ int idx_ipv6;
+ int idx_interface;
+ int idx_curr;
+ char *src, *tag, *distance, *vrf;
-DEFUN (no_ipv6_route_pref_tag_vrf,
- no_ipv6_route_pref_tag_vrf_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Null interface\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], argv[3], argv[4], NULL);
-}
+ if (!strcmp(argv[4]->text, "from"))
+ {
+ src = argv[5]->arg;
+ idx_ipv6 = 6;
+ idx_interface = 7;
+ idx_curr = 8;
+ }
+ else
+ {
+ src = NULL;
+ idx_ipv6 = 4;
+ idx_interface = 5;
+ idx_curr = 6;
+ }
-DEFUN (no_ipv6_route_flags_pref_vrf,
- no_ipv6_route_flags_pref_vrf_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- /* We do not care about argv[2] */
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4], NULL);
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
+
+ return static_ipv6_func (vty, 0,
+ argv[idx_ipv6_prefixlen]->arg,
+ src,
+ argv[idx_ipv6]->arg,
+ argv[idx_interface]->arg,
+ NULL,
+ tag, distance, vrf, NULL);
}
-DEFUN (no_ipv6_route_flags_pref_tag_vrf,
- no_ipv6_route_flags_pref_tag_vrf_cmd,
- "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
+DEFUN (no_ipv6_route_ifname_flags,
+ no_ipv6_route_ifname_flags_cmd,
+ "no ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR
IP_STR
"Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\n"
"Emit an ICMP unreachable when matched\n"
@@ -4839,86 +2870,54 @@ DEFUN (no_ipv6_route_flags_pref_tag_vrf,
"Set tag for this route\n"
"Tag value\n"
"Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- /* We do not care about argv[2] */
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5], NULL);
-}
-
-DEFUN (no_ipv6_route_ifname_pref_vrf,
- no_ipv6_route_ifname_pref_vrf_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Specify labels for this route\n"
+ "One or more labels separated by '/'\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4], NULL);
-}
+ int idx_ipv6_prefixlen = 3;
+ int idx_ipv6;
+ int idx_interface;
+ int idx_reject_blackhole;
+ int idx_curr;
+ char *src, *tag, *distance, *vrf;
-DEFUN (no_ipv6_route_ifname_pref_tag_vrf,
- no_ipv6_route_ifname_pref_tag_vrf_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5], NULL);
-}
+ if (!strcmp(argv[4]->text, "from"))
+ {
+ src = argv[5]->arg;
+ idx_ipv6 = 6;
+ idx_interface = 7;
+ idx_reject_blackhole = 8;
+ idx_curr = 9;
+ }
+ else
+ {
+ src = NULL;
+ idx_ipv6 = 4;
+ idx_interface = 5;
+ idx_reject_blackhole = 6;
+ idx_curr = 7;
+ }
-DEFUN (no_ipv6_route_ifname_flags_pref_vrf,
- no_ipv6_route_ifname_flags_pref_vrf_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5], NULL);
-}
+ tag = distance = vrf = NULL;
+ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-DEFUN (no_ipv6_route_ifname_flags_pref_tag_vrf,
- no_ipv6_route_ifname_flags_pref_tag_vrf_cmd,
- "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
- "IPv6 gateway address\n"
- "IPv6 gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this prefix\n"
- VRF_CMD_HELP_STR)
-{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL);
+ return static_ipv6_func (vty, 0,
+ argv[idx_ipv6_prefixlen]->arg,
+ src,
+ argv[idx_ipv6]->arg,
+ argv[idx_interface]->arg,
+ argv[idx_reject_blackhole]->arg,
+ tag, distance, vrf, NULL);
}
DEFUN (show_ipv6_route,
show_ipv6_route_cmd,
- "show ipv6 route {json}",
+ "show ipv6 route [vrf NAME] [json]",
SHOW_STR
IP_STR
- "IPv6 routing table\n")
+ "IPv6 routing table\n"
+ VRF_CMD_HELP_STR
+ "Output JSON\n")
{
struct route_table *table;
struct route_node *rn;
@@ -4926,36 +2925,39 @@ DEFUN (show_ipv6_route,
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
struct zebra_vrf *zvrf = NULL;
- char buf[BUFSIZ];
+ char buf[SRCDEST2STR_BUFFER];
json_object *json = NULL;
json_object *json_prefix = NULL;
- u_char uj = use_json(argc, argv);
- if (argc > 0 && argv[0] && strcmp(argv[0], "json") != 0)
- {
- if (!(zvrf = zebra_vrf_lookup_by_name (argv[0])))
- {
- if (uj)
- vty_out (vty, "{}%s", VTY_NEWLINE);
- else
- vty_out (vty, "vrf %s not defined%s", argv[0], VTY_NEWLINE);
- return CMD_SUCCESS;
- }
+ int vrf = (argc > 3 && strmatch (argv[3]->text, "vrf"));
+ int uj = vrf ? argc == 6 : argc == 4;
+ char *vrfname = vrf ? argv[4]->arg : NULL;
- if (zvrf_id (zvrf) == VRF_UNKNOWN)
- {
- if (uj)
- vty_out (vty, "{}%s", VTY_NEWLINE);
- else
- vty_out (vty, "vrf %s inactive%s", argv[0], VTY_NEWLINE);
- return CMD_SUCCESS;
- }
- else
- vrf_id = zvrf_id (zvrf);
- }
+ if (vrf)
+ {
+ if (!(zvrf = zebra_vrf_lookup_by_name (vrfname)))
+ {
+ if (uj)
+ vty_out (vty, "{}%s", VTY_NEWLINE);
+ else
+ vty_out (vty, "vrf %s not defined%s", vrfname, VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ if (zvrf_id (zvrf) == VRF_UNKNOWN)
+ {
+ if (uj)
+ vty_out (vty, "{}%s", VTY_NEWLINE);
+ else
+ vty_out (vty, "vrf %s inactive%s", vrfname, VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+ else
+ vrf_id = zvrf_id (zvrf);
+ }
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
- if (! table)
+ if (!table)
{
if (uj)
vty_out (vty, "{}%s", VTY_NEWLINE);
@@ -4967,7 +2969,7 @@ DEFUN (show_ipv6_route,
json = json_object_new_object();
/* Show all IPv6 route. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
{
RNODE_FOREACH_RIB (rn, rib)
{
@@ -4978,7 +2980,7 @@ DEFUN (show_ipv6_route,
if (json_prefix)
{
- prefix2str (&rn->p, buf, sizeof buf);
+ srcdest_rnode2str (rn, buf, sizeof buf);
json_object_object_add(json, buf, json_prefix);
json_prefix = NULL;
}
@@ -4990,7 +2992,7 @@ DEFUN (show_ipv6_route,
else
{
/* Show all IPv6 route. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
{
RNODE_FOREACH_RIB (rn, rib)
{
@@ -5007,23 +3009,19 @@ DEFUN (show_ipv6_route,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_route,
- show_ipv6_route_vrf_cmd,
- "show ipv6 route " VRF_CMD_STR " {json}",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR)
-
DEFUN (show_ipv6_route_tag,
show_ipv6_route_tag_cmd,
- "show ipv6 route tag <1-4294967295>",
+ "show ipv6 route [vrf NAME] tag (1-4294967295)",
SHOW_STR
IP_STR
"IPv6 routing table\n"
+ VRF_CMD_HELP_STR
"Show only routes with tag\n"
"Tag value\n")
{
+ int idx_vrf = 3;
+ int idx_name = 4;
+ int idx_tag = 6;
struct route_table *table;
struct route_node *rn;
struct rib *rib;
@@ -5031,20 +3029,23 @@ DEFUN (show_ipv6_route_tag,
route_tag_t tag = 0;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1)
+ if (strmatch(argv[idx_vrf]->text, "vrf"))
{
- VRF_GET_ID (vrf_id, argv[0]);
- VTY_GET_INTEGER_RANGE("tag", tag, argv[1], 0, 4294967295);
+ VRF_GET_ID (vrf_id, argv[idx_name]->arg);
+ VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
}
else
- VTY_GET_INTEGER_RANGE("tag", tag, argv[0], 0, 4294967295);
+ {
+ idx_tag -= 2;
+ VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
+ }
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
if (! table)
return CMD_SUCCESS;
/* Show all IPv6 routes with matching tag value. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
if (rib->tag != tag)
@@ -5060,22 +3061,13 @@ DEFUN (show_ipv6_route_tag,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_route_tag,
- show_ipv6_route_vrf_tag_cmd,
- "show ipv6 route " VRF_CMD_STR " tag <1-4294967295>",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "Show only routes with tag\n"
- "Tag value\n")
-
DEFUN (show_ipv6_route_prefix_longer,
show_ipv6_route_prefix_longer_cmd,
- "show ipv6 route X:X::X:X/M longer-prefixes",
+ "show ipv6 route [vrf NAME] X:X::X:X/M longer-prefixes",
SHOW_STR
IP_STR
"IPv6 routing table\n"
+ VRF_CMD_HELP_STR
"IPv6 prefix\n"
"Show route matching the specified Network/Mask pair only\n")
{
@@ -5087,13 +3079,15 @@ DEFUN (show_ipv6_route_prefix_longer,
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1)
+ if (strmatch(argv[3]->text, "vrf"))
{
- VRF_GET_ID (vrf_id, argv[0]);
- ret = str2prefix (argv[1], &p);
+ VRF_GET_ID (vrf_id, argv[4]->arg);
+ ret = str2prefix (argv[5]->arg, &p);
}
else
- ret = str2prefix (argv[0], &p);
+ {
+ ret = str2prefix (argv[3]->arg, &p);
+ }
if (! ret)
{
@@ -5106,37 +3100,33 @@ DEFUN (show_ipv6_route_prefix_longer,
return CMD_SUCCESS;
/* Show matched type IPv6 routes. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
- if (prefix_match (&p, &rn->p))
- {
- if (first)
- {
- vty_out (vty, SHOW_ROUTE_V6_HEADER);
- first = 0;
- }
- vty_show_ip_route (vty, rn, rib, NULL);
- }
+ {
+ struct prefix *p, *src_p;
+ srcdest_rnode_prefixes(rn, &p, &src_p);
+
+ if (prefix_match (p, &rn->p))
+ {
+ if (first)
+ {
+ vty_out (vty, SHOW_ROUTE_V6_HEADER);
+ first = 0;
+ }
+ vty_show_ip_route (vty, rn, rib, NULL);
+ }
+ }
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_route_prefix_longer,
- show_ipv6_route_vrf_prefix_longer_cmd,
- "show ipv6 route " VRF_CMD_STR " X:X::X:X/M longer-prefixes",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "IPv6 prefix\n"
- "Show route matching the specified Network/Mask pair only\n")
-
DEFUN (show_ipv6_route_protocol,
show_ipv6_route_protocol_cmd,
- "show ipv6 route " FRR_IP6_REDIST_STR_ZEBRA,
+ "show ipv6 route [vrf NAME] " FRR_IP6_REDIST_STR_ZEBRA,
SHOW_STR
IP_STR
"IP routing table\n"
- FRR_IP6_REDIST_HELP_STR_ZEBRA)
+ VRF_CMD_HELP_STR
+ FRR_IP6_REDIST_HELP_STR_ZEBRA)
{
int type;
struct route_table *table;
@@ -5145,13 +3135,12 @@ DEFUN (show_ipv6_route_protocol,
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
- if ( argc >1 )
- {
- VRF_GET_ID (vrf_id, argv[0]);
- type = proto_redistnum (AFI_IP6, argv[1]);
- }
- else
- type = proto_redistnum (AFI_IP6, argv[0]);
+ int idx = 0;
+ if (argv_find (argv, argc, "NAME", &idx))
+ VRF_GET_ID (vrf_id, argv[idx]->arg);
+
+ char *proto = argv[argc - 1]->text;
+ type = proto_redistnum (AFI_IP, proto);
if (type < 0)
{
@@ -5164,7 +3153,7 @@ DEFUN (show_ipv6_route_protocol,
return CMD_SUCCESS;
/* Show matched type IPv6 routes. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
if (rib->type == type)
{
@@ -5178,21 +3167,13 @@ DEFUN (show_ipv6_route_protocol,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_route_protocol,
- show_ipv6_route_vrf_protocol_cmd,
- "show ipv6 route " VRF_CMD_STR " " FRR_IP6_REDIST_STR_ZEBRA,
- SHOW_STR
- IP_STR
- "IP routing table\n"
- VRF_CMD_HELP_STR
- FRR_IP6_REDIST_HELP_STR_ZEBRA)
-
DEFUN (show_ipv6_route_addr,
show_ipv6_route_addr_cmd,
- "show ipv6 route X:X::X:X",
+ "show ipv6 route [vrf NAME] X:X::X:X",
SHOW_STR
IP_STR
"IPv6 routing table\n"
+ VRF_CMD_HELP_STR
"IPv6 Address\n")
{
int ret;
@@ -5201,13 +3182,15 @@ DEFUN (show_ipv6_route_addr,
struct route_node *rn;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1 )
+ if (strmatch(argv[3]->text, "vrf"))
{
- VRF_GET_ID (vrf_id, argv[0]);
- ret = str2prefix_ipv6 (argv[1], &p);
+ VRF_GET_ID (vrf_id, argv[4]->arg);
+ ret = str2prefix_ipv6 (argv[5]->arg, &p);
}
else
- ret = str2prefix_ipv6 (argv[0], &p);
+ {
+ ret = str2prefix_ipv6 (argv[3]->arg, &p);
+ }
if (ret <= 0)
{
@@ -5233,21 +3216,13 @@ DEFUN (show_ipv6_route_addr,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_route_addr,
- show_ipv6_route_vrf_addr_cmd,
- "show ipv6 route " VRF_CMD_STR " X:X::X:X",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "IPv6 Address\n")
-
DEFUN (show_ipv6_route_prefix,
show_ipv6_route_prefix_cmd,
- "show ipv6 route X:X::X:X/M",
+ "show ipv6 route [vrf NAME] X:X::X:X/M",
SHOW_STR
IP_STR
"IPv6 routing table\n"
+ VRF_CMD_HELP_STR
"IPv6 prefix\n")
{
int ret;
@@ -5256,13 +3231,13 @@ DEFUN (show_ipv6_route_prefix,
struct route_node *rn;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 1)
+ if (strmatch(argv[3]->text, "vrf"))
{
- VRF_GET_ID (vrf_id, argv[0]);
- ret = str2prefix_ipv6 (argv[1], &p);
+ VRF_GET_ID (vrf_id, argv[4]->arg);
+ ret = str2prefix_ipv6 (argv[5]->arg, &p);
}
else
- ret = str2prefix_ipv6 (argv[0], &p);
+ ret = str2prefix_ipv6 (argv[3]->arg, &p);
if (ret <= 0)
{
@@ -5288,29 +3263,22 @@ DEFUN (show_ipv6_route_prefix,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_route_prefix,
- show_ipv6_route_vrf_prefix_cmd,
- "show ipv6 route " VRF_CMD_STR " X:X::X:X/M ",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "IPv6 prefix\n")
/* Show route summary. */
DEFUN (show_ipv6_route_summary,
show_ipv6_route_summary_cmd,
- "show ipv6 route summary",
+ "show ipv6 route [vrf NAME] summary",
SHOW_STR
IP_STR
"IPv6 routing table\n"
+ VRF_CMD_HELP_STR
"Summary of all IPv6 routes\n")
{
struct route_table *table;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 0)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (strmatch(argv[3]->text, "vrf"))
+ VRF_GET_ID (vrf_id, argv[4]->arg);
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
if (! table)
@@ -5321,30 +3289,23 @@ DEFUN (show_ipv6_route_summary,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_route_summary,
- show_ipv6_route_vrf_summary_cmd,
- "show ipv6 route " VRF_CMD_STR " summary",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "Summary of all IPv6 routes\n")
/* Show ipv6 route summary prefix. */
DEFUN (show_ipv6_route_summary_prefix,
show_ipv6_route_summary_prefix_cmd,
- "show ipv6 route summary prefix",
+ "show ipv6 route [vrf NAME] summary prefix",
SHOW_STR
IP_STR
"IPv6 routing table\n"
+ VRF_CMD_HELP_STR
"Summary of all IPv6 routes\n"
"Prefix routes\n")
{
struct route_table *table;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 0)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (strmatch(argv[3]->text, "vrf"))
+ VRF_GET_ID (vrf_id, argv[4]->arg);
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
if (! table)
@@ -5355,27 +3316,18 @@ DEFUN (show_ipv6_route_summary_prefix,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_route_summary_prefix,
- show_ipv6_route_vrf_summary_prefix_cmd,
- "show ipv6 route " VRF_CMD_STR " summary prefix",
- SHOW_STR
- IP_STR
- "IPv6 routing table\n"
- VRF_CMD_HELP_STR
- "Summary of all IPv6 routes\n"
- "Prefix routes\n")
/*
* Show IPv6 mroute command.Used to dump
* the Multicast routing table.
*/
-
DEFUN (show_ipv6_mroute,
show_ipv6_mroute_cmd,
- "show ipv6 mroute",
+ "show ipv6 mroute [vrf NAME]",
SHOW_STR
IP_STR
- "IPv6 Multicast routing table\n")
+ "IPv6 Multicast routing table\n"
+ VRF_CMD_HELP_STR)
{
struct route_table *table;
struct route_node *rn;
@@ -5383,15 +3335,15 @@ DEFUN (show_ipv6_mroute,
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
- if (argc > 0)
- VRF_GET_ID (vrf_id, argv[0]);
+ if (strmatch(argv[3]->text, "vrf"))
+ VRF_GET_ID (vrf_id, argv[4]->arg);
table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, vrf_id);
if (! table)
return CMD_SUCCESS;
/* Show all IPv6 route. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
if (first)
@@ -5404,17 +3356,10 @@ DEFUN (show_ipv6_mroute,
return CMD_SUCCESS;
}
-ALIAS (show_ipv6_mroute,
- show_ipv6_mroute_vrf_cmd,
- "show ipv6 mroute " VRF_CMD_STR,
- SHOW_STR
- IP_STR
- "IPv6 Multicast routing table\n"
- VRF_CMD_HELP_STR)
DEFUN (show_ipv6_route_vrf_all,
show_ipv6_route_vrf_all_cmd,
- "show ipv6 route " VRF_ALL_CMD_STR,
+ "show ipv6 route vrf all",
SHOW_STR
IP_STR
"IPv6 routing table\n"
@@ -5435,7 +3380,7 @@ DEFUN (show_ipv6_route_vrf_all,
continue;
/* Show all IPv6 route. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
if (first)
@@ -5459,7 +3404,7 @@ DEFUN (show_ipv6_route_vrf_all,
DEFUN (show_ipv6_route_vrf_all_tag,
show_ipv6_route_vrf_all_tag_cmd,
- "show ipv6 route " VRF_ALL_CMD_STR " tag <1-4294967295>",
+ "show ipv6 route vrf all tag (1-4294967295)",
SHOW_STR
IP_STR
"IPv6 routing table\n"
@@ -5467,6 +3412,7 @@ DEFUN (show_ipv6_route_vrf_all_tag,
"Show only routes with tag\n"
"Tag value\n")
{
+ int idx_number = 6;
struct route_table *table;
struct route_node *rn;
struct rib *rib;
@@ -5476,8 +3422,8 @@ DEFUN (show_ipv6_route_vrf_all_tag,
int vrf_header = 1;
route_tag_t tag = 0;
- if (argv[0])
- VTY_GET_INTEGER_RANGE("tag", tag, argv[0], 0, 4294967295);
+ if (argv[idx_number]->arg)
+ VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
@@ -5486,7 +3432,7 @@ DEFUN (show_ipv6_route_vrf_all_tag,
continue;
/* Show all IPv6 routes with matching tag value. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
if (rib->tag != tag)
@@ -5513,7 +3459,7 @@ DEFUN (show_ipv6_route_vrf_all_tag,
DEFUN (show_ipv6_route_vrf_all_prefix_longer,
show_ipv6_route_vrf_all_prefix_longer_cmd,
- "show ipv6 route " VRF_ALL_CMD_STR " X:X::X:X/M longer-prefixes",
+ "show ipv6 route vrf all X:X::X:X/M longer-prefixes",
SHOW_STR
IP_STR
"IPv6 routing table\n"
@@ -5521,6 +3467,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
"IPv6 prefix\n"
"Show route matching the specified Network/Mask pair only\n")
{
+ int idx_ipv6_prefixlen = 5;
struct route_table *table;
struct route_node *rn;
struct rib *rib;
@@ -5531,7 +3478,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
int first = 1;
int vrf_header = 1;
- ret = str2prefix (argv[0], &p);
+ ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &p);
if (! ret)
{
vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
@@ -5545,23 +3492,27 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
continue;
/* Show matched type IPv6 routes. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
- if (prefix_match (&p, &rn->p))
- {
- if (first)
- {
- vty_out (vty, SHOW_ROUTE_V6_HEADER);
- first = 0;
- }
-
- if (vrf_header)
+ {
+ struct prefix *p, *src_p;
+ srcdest_rnode_prefixes(rn, &p, &src_p);
+ if (prefix_match (p, &rn->p))
{
- vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
- vrf_header = 0;
+ if (first)
+ {
+ vty_out (vty, SHOW_ROUTE_V6_HEADER);
+ first = 0;
+ }
+
+ if (vrf_header)
+ {
+ vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
+ vrf_header = 0;
+ }
+ vty_show_ip_route (vty, rn, rib, NULL);
}
- vty_show_ip_route (vty, rn, rib, NULL);
- }
+ }
vrf_header = 1;
}
@@ -5570,7 +3521,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
DEFUN (show_ipv6_route_vrf_all_protocol,
show_ipv6_route_vrf_all_protocol_cmd,
- "show ipv6 route " VRF_ALL_CMD_STR " " FRR_IP6_REDIST_STR_ZEBRA,
+ "show ipv6 route vrf all " FRR_IP6_REDIST_STR_ZEBRA,
SHOW_STR
IP_STR
"IP routing table\n"
@@ -5586,7 +3537,9 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
int first = 1;
int vrf_header = 1;
- type = proto_redistnum (AFI_IP6, argv[0]);
+ char *proto = argv[argc - 1]->text;
+ type = proto_redistnum (AFI_IP, proto);
+
if (type < 0)
{
vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
@@ -5600,7 +3553,7 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
continue;
/* Show matched type IPv6 routes. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
if (rib->type == type)
{
@@ -5625,13 +3578,14 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
DEFUN (show_ipv6_route_vrf_all_addr,
show_ipv6_route_vrf_all_addr_cmd,
- "show ipv6 route " VRF_ALL_CMD_STR " X:X::X:X",
+ "show ipv6 route vrf all X:X::X:X",
SHOW_STR
IP_STR
"IPv6 routing table\n"
VRF_ALL_CMD_HELP_STR
"IPv6 Address\n")
{
+ int idx_ipv6 = 5;
int ret;
struct prefix_ipv6 p;
struct route_table *table;
@@ -5639,7 +3593,7 @@ DEFUN (show_ipv6_route_vrf_all_addr,
struct vrf *vrf;
struct zebra_vrf *zvrf;
- ret = str2prefix_ipv6 (argv[0], &p);
+ ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p);
if (ret <= 0)
{
vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
@@ -5666,13 +3620,14 @@ DEFUN (show_ipv6_route_vrf_all_addr,
DEFUN (show_ipv6_route_vrf_all_prefix,
show_ipv6_route_vrf_all_prefix_cmd,
- "show ipv6 route " VRF_ALL_CMD_STR " X:X::X:X/M",
+ "show ipv6 route vrf all X:X::X:X/M",
SHOW_STR
IP_STR
"IPv6 routing table\n"
VRF_ALL_CMD_HELP_STR
"IPv6 prefix\n")
{
+ int idx_ipv6_prefixlen = 5;
int ret;
struct prefix_ipv6 p;
struct route_table *table;
@@ -5680,7 +3635,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix,
struct vrf *vrf;
struct zebra_vrf *zvrf;
- ret = str2prefix_ipv6 (argv[0], &p);
+ ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p);
if (ret <= 0)
{
vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
@@ -5712,7 +3667,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix,
DEFUN (show_ipv6_route_vrf_all_summary,
show_ipv6_route_vrf_all_summary_cmd,
- "show ipv6 route " VRF_ALL_CMD_STR " summary",
+ "show ipv6 route vrf all summary",
SHOW_STR
IP_STR
"IPv6 routing table\n"
@@ -5731,7 +3686,7 @@ DEFUN (show_ipv6_route_vrf_all_summary,
DEFUN (show_ipv6_mroute_vrf_all,
show_ipv6_mroute_vrf_all_cmd,
- "show ipv6 mroute " VRF_ALL_CMD_STR,
+ "show ipv6 mroute vrf all",
SHOW_STR
IP_STR
"IPv6 Multicast routing table\n"
@@ -5751,7 +3706,7 @@ DEFUN (show_ipv6_mroute_vrf_all,
continue;
/* Show all IPv6 route. */
- for (rn = route_top (table); rn; rn = route_next (rn))
+ for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
if (first)
@@ -5767,7 +3722,7 @@ DEFUN (show_ipv6_mroute_vrf_all,
DEFUN (show_ipv6_route_vrf_all_summary_prefix,
show_ipv6_route_vrf_all_summary_prefix_cmd,
- "show ipv6 route " VRF_ALL_CMD_STR " summary prefix",
+ "show ipv6 route vrf all summary prefix",
SHOW_STR
IP_STR
"IPv6 routing table\n"
@@ -5792,27 +3747,28 @@ static_config_ipv6 (struct vty *vty)
struct route_node *rn;
struct static_route *si;
int write = 0;
- char buf[PREFIX_STRLEN];
+ char buf[SRCDEST2STR_BUFFER];
struct route_table *stable;
struct vrf *vrf;
struct zebra_vrf *zvrf;
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
- zvrf = vrf->info;
- if (! zvrf)
- continue;
-
+ if (!(zvrf = vrf->info))
+ continue;
if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
- for (rn = route_top (stable); rn; rn = route_next (rn))
+ for (rn = route_top (stable); rn; rn = srcdest_route_next (rn))
for (si = rn->info; si; si = si->next)
{
- vty_out (vty, "ipv6 route %s", prefix2str (&rn->p, buf, sizeof buf));
+ vty_out (vty, "ipv6 route %s", srcdest_rnode2str (rn, buf, sizeof buf));
switch (si->type)
{
+ case STATIC_IPV4_GATEWAY:
+ vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
+ break;
case STATIC_IPV6_GATEWAY:
vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
break;
@@ -5895,9 +3851,10 @@ DEFUN (show_vrf,
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
- zvrf = vrf->info;
- if (! zvrf || ! zvrf_id (zvrf))
- continue;
+ if (!(zvrf = vrf->info))
+ continue;
+ if (!zvrf_id (zvrf))
+ continue;
vty_out (vty, "vrf %s ", zvrf_name (zvrf));
if (zvrf_id (zvrf) == VRF_UNKNOWN)
@@ -5919,9 +3876,7 @@ zebra_ip_config (struct vty *vty)
write += static_config_ipv4 (vty, SAFI_UNICAST, "ip route");
write += static_config_ipv4 (vty, SAFI_MULTICAST, "ip mroute");
-#ifdef HAVE_IPV6
write += static_config_ipv6 (vty);
-#endif /* HAVE_IPV6 */
write += zebra_import_table_config (vty);
return write;
@@ -5929,49 +3884,7 @@ zebra_ip_config (struct vty *vty)
DEFUN (ip_zebra_import_table_distance,
ip_zebra_import_table_distance_cmd,
- "ip import-table <1-252> distance <1-255>",
- IP_STR
- "import routes from non-main kernel table\n"
- "kernel routing table id\n"
- "Distance for imported routes\n"
- "Default distance value\n")
-{
- u_int32_t table_id = 0;
- int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
-
- if (argc)
- VTY_GET_INTEGER("table", table_id, argv[0]);
-
- if (!is_zebra_valid_kernel_table(table_id))
- {
- vty_out(vty, "Invalid routing table ID, %d. Must be in range 1-252%s",
- table_id, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (is_zebra_main_routing_table(table_id))
- {
- vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
- table_id, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (argc > 1)
- VTY_GET_INTEGER_RANGE("distance", distance, argv[1], 1, 255);
- return (zebra_import_table(AFI_IP, table_id, distance, NULL, 1));
-
-}
-
-ALIAS (ip_zebra_import_table_distance,
- ip_zebra_import_table_cmd,
- "ip import-table <1-252>",
- IP_STR
- "import routes from non-main kernel table\n"
- "kernel routing table id\n")
-
-DEFUN (ip_zebra_import_table_distance_routemap,
- ip_zebra_import_table_distance_routemap_cmd,
- "ip import-table <1-252> distance <1-255> route-map WORD",
+ "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
IP_STR
"import routes from non-main kernel table\n"
"kernel routing table id\n"
@@ -5981,11 +3894,13 @@ DEFUN (ip_zebra_import_table_distance_routemap,
"route-map name\n")
{
u_int32_t table_id = 0;
- int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
- const char *rmap_name;
- if (argc)
- VTY_GET_INTEGER("table", table_id, argv[0]);
+ VTY_GET_INTEGER("table", table_id, argv[2]->arg);
+ int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
+ char *rmap = strmatch (argv[argc - 2]->text, "route-map") ?
+ XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) : NULL;
+ if (argc == 7 || (argc == 5 && !rmap))
+ VTY_GET_INTEGER_RANGE("distance", distance, argv[4]->arg, 1, 255);
if (!is_zebra_valid_kernel_table(table_id))
{
@@ -5997,42 +3912,27 @@ DEFUN (ip_zebra_import_table_distance_routemap,
if (is_zebra_main_routing_table(table_id))
{
vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
- table_id, VTY_NEWLINE);
+ table_id, VTY_NEWLINE);
return CMD_WARNING;
}
- if (argc > 2)
- {
- VTY_GET_INTEGER_RANGE("distance", distance, argv[1], 1, 255);
- rmap_name = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[2]);
- }
- else
- rmap_name = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
-
- return (zebra_import_table(AFI_IP, table_id, distance, rmap_name, 1));
+ return (zebra_import_table(AFI_IP, table_id, distance, rmap, 1));
}
-ALIAS (ip_zebra_import_table_distance_routemap,
- ip_zebra_import_table_routemap_cmd,
- "ip import-table <1-252> route-map WORD",
- IP_STR
- "import routes from non-main kernel table\n"
- "kernel routing table id\n"
- "route-map for filtering\n"
- "route-map name\n")
-
DEFUN (no_ip_zebra_import_table,
no_ip_zebra_import_table_cmd,
- "no ip import-table <1-252> {route-map NAME}",
+ "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
NO_STR
IP_STR
"import routes from non-main kernel table\n"
- "kernel routing table id\n")
+ "kernel routing table id\n"
+ "Distance for imported routes\n"
+ "Default distance value\n"
+ "route-map for filtering\n"
+ "route-map name\n")
{
u_int32_t table_id = 0;
-
- if (argc)
- VTY_GET_INTEGER("table", table_id, argv[0]);
+ VTY_GET_INTEGER("table", table_id, argv[3]->arg);
if (!is_zebra_valid_kernel_table(table_id))
{
@@ -6054,14 +3954,6 @@ DEFUN (no_ip_zebra_import_table,
return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
}
-ALIAS (no_ip_zebra_import_table,
- no_ip_zebra_import_table_distance_cmd,
- "no ip import-table <1-252> distance <1-255> {route-map NAME}",
- IP_STR
- "import routes from non-main kernel table to main table"
- "kernel routing table id\n"
- "distance to be used\n")
-
static int
config_write_protocol (struct vty *vty)
{
@@ -6103,77 +3995,26 @@ zebra_vty_init (void)
install_element (CONFIG_NODE, &allow_external_route_update_cmd);
install_element (CONFIG_NODE, &no_allow_external_route_update_cmd);
- install_element (CONFIG_NODE, &ip_mroute_cmd);
install_element (CONFIG_NODE, &ip_mroute_dist_cmd);
- install_element (CONFIG_NODE, &no_ip_mroute_cmd);
install_element (CONFIG_NODE, &no_ip_mroute_dist_cmd);
install_element (CONFIG_NODE, &ip_multicast_mode_cmd);
install_element (CONFIG_NODE, &no_ip_multicast_mode_cmd);
- install_element (CONFIG_NODE, &no_ip_multicast_mode_noarg_cmd);
install_element (CONFIG_NODE, &ip_route_cmd);
- install_element (CONFIG_NODE, &ip_route_tag_cmd);
install_element (CONFIG_NODE, &ip_route_flags_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_tag_cmd);
- install_element (CONFIG_NODE, &ip_route_flags2_cmd);
- install_element (CONFIG_NODE, &ip_route_flags2_tag_cmd);
install_element (CONFIG_NODE, &ip_route_mask_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_tag_cmd);
install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_tag_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags2_tag_cmd);
install_element (CONFIG_NODE, &no_ip_route_cmd);
- install_element (CONFIG_NODE, &no_ip_route_tag_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_tag_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags2_tag_cmd);
install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_tag_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags2_tag_cmd);
- install_element (CONFIG_NODE, &ip_route_distance_cmd);
- install_element (CONFIG_NODE, &ip_route_tag_distance_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_tag_distance_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_tag_distance2_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_tag_distance_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_tag_distance_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_tag_distance2_cmd);
- install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
- install_element (CONFIG_NODE, &no_ip_route_tag_distance_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_tag_distance_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_tag_distance2_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_distance_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_tag_distance_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance2_cmd);
- install_element (CONFIG_NODE, &ip_zebra_import_table_cmd);
install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
- install_element (CONFIG_NODE, &ip_zebra_import_table_routemap_cmd);
- install_element (CONFIG_NODE, &ip_zebra_import_table_distance_routemap_cmd);
install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
- install_element (CONFIG_NODE, &no_ip_zebra_import_table_distance_cmd);
install_element (VIEW_NODE, &show_vrf_cmd);
install_element (VIEW_NODE, &show_ip_route_cmd);
install_element (VIEW_NODE, &show_ip_route_ospf_instance_cmd);
install_element (VIEW_NODE, &show_ip_route_tag_cmd);
install_element (VIEW_NODE, &show_ip_nht_cmd);
- install_element (VIEW_NODE, &show_ip_nht_vrf_cmd);
install_element (VIEW_NODE, &show_ip_nht_vrf_all_cmd);
install_element (VIEW_NODE, &show_ipv6_nht_cmd);
- install_element (VIEW_NODE, &show_ipv6_nht_vrf_cmd);
install_element (VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
install_element (VIEW_NODE, &show_ip_route_addr_cmd);
install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
@@ -6188,64 +4029,10 @@ zebra_vty_init (void)
/* Commands for VRF */
- install_element (CONFIG_NODE, &ip_route_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_flags2_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_flags2_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags2_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags2_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags2_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags2_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags2_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags2_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_distance_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_tag_distance_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_distance_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_tag_distance_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_distance2_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_flags_tag_distance2_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_distance_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_tag_distance_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_distance_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_tag_distance_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_vrf_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags_tag_distance2_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_distance_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_tag_distance_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_distance_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_tag_distance_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_distance2_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags_tag_distance2_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_distance_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_tag_distance_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_vrf_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance2_vrf_cmd);
+ install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
+ install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
install_element (VIEW_NODE, &show_ip_route_vrf_cmd);
- install_element (VIEW_NODE, &show_ip_route_vrf_addr_cmd);
- install_element (VIEW_NODE, &show_ip_route_vrf_tag_cmd);
- install_element (VIEW_NODE, &show_ip_route_vrf_prefix_cmd);
- install_element (VIEW_NODE, &show_ip_route_vrf_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_ip_route_vrf_protocol_cmd);
- install_element (VIEW_NODE, &show_ip_route_vrf_supernets_cmd);
- install_element (VIEW_NODE, &show_ip_route_vrf_summary_cmd);
- install_element (VIEW_NODE, &show_ip_route_vrf_summary_prefix_cmd);
install_element (VIEW_NODE, &show_ip_route_vrf_all_cmd);
install_element (VIEW_NODE, &show_ip_route_vrf_all_tag_cmd);
@@ -6257,7 +4044,6 @@ zebra_vty_init (void)
install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
-#ifdef HAVE_IPV6
install_element (CONFIG_NODE, &ipv6_route_cmd);
install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
@@ -6266,30 +4052,6 @@ zebra_vty_init (void)
install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
- install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
- install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
- install_element (CONFIG_NODE, &ipv6_route_tag_cmd);
- install_element (CONFIG_NODE, &ipv6_route_flags_tag_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_tag_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_flags_tag_cmd);
- install_element (CONFIG_NODE, &ipv6_route_pref_tag_cmd);
- install_element (CONFIG_NODE, &ipv6_route_flags_pref_tag_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_pref_tag_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_tag_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_tag_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_flags_tag_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_tag_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_tag_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_pref_tag_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_tag_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_tag_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_tag_cmd);
install_element (CONFIG_NODE, &ip_nht_default_route_cmd);
install_element (CONFIG_NODE, &no_ip_nht_default_route_cmd);
install_element (CONFIG_NODE, &ipv6_nht_default_route_cmd);
@@ -6306,50 +4068,6 @@ zebra_vty_init (void)
install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
/* Commands for VRF */
-
- install_element (CONFIG_NODE, &ipv6_route_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_flags_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_flags_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_flags_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_pref_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_flags_pref_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_pref_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_pref_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_flags_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_flags_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_pref_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_flags_pref_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_pref_tag_vrf_cmd);
- install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_flags_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_pref_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_tag_vrf_cmd);
- install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_tag_vrf_cmd);
-
-
- install_element (VIEW_NODE, &show_ipv6_route_vrf_cmd);
- install_element (VIEW_NODE, &show_ipv6_route_vrf_tag_cmd);
- install_element (VIEW_NODE, &show_ipv6_route_vrf_summary_cmd);
- install_element (VIEW_NODE, &show_ipv6_route_vrf_summary_prefix_cmd);
- install_element (VIEW_NODE, &show_ipv6_route_vrf_protocol_cmd);
- install_element (VIEW_NODE, &show_ipv6_route_vrf_addr_cmd);
- install_element (VIEW_NODE, &show_ipv6_route_vrf_prefix_cmd);
- install_element (VIEW_NODE, &show_ipv6_route_vrf_prefix_longer_cmd);
-
install_element (VIEW_NODE, &show_ipv6_route_vrf_all_cmd);
install_element (VIEW_NODE, &show_ipv6_route_vrf_all_tag_cmd);
install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd);
@@ -6359,8 +4077,5 @@ zebra_vty_init (void)
install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_longer_cmd);
- install_element (VIEW_NODE, &show_ipv6_mroute_vrf_cmd);
-
install_element (VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
-#endif /* HAVE_IPV6 */
}
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 83d7d0f811..37c048f627 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -54,6 +54,7 @@
#include "zebra/rtadv.h"
#include "zebra/zebra_mpls.h"
#include "zebra/zebra_fpm.h"
+#include "zebra/zebra_mroute.h"
/* Event list of zebra. */
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
@@ -91,6 +92,7 @@ zserv_flush_data(struct thread *thread)
zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
"closing", __func__, client->sock);
zebra_client_close(client);
+ client = NULL;
break;
case BUFFER_PENDING:
client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
@@ -100,7 +102,8 @@ zserv_flush_data(struct thread *thread)
break;
}
- client->last_write_time = quagga_monotime();
+ if (client)
+ client->last_write_time = monotime(NULL);
return 0;
}
@@ -134,7 +137,7 @@ zebra_server_send_message(struct zserv *client)
break;
}
- client->last_write_time = quagga_monotime();
+ client->last_write_time = monotime(NULL);
return 0;
}
@@ -600,7 +603,7 @@ zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
*/
int
zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
- struct rib *rib)
+ struct prefix *src_p, struct rib *rib)
{
afi_t afi;
int cmd;
@@ -666,6 +669,14 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
stream_putc (s, p->prefixlen);
stream_write (s, (u_char *) & p->u.prefix, psize);
+ if (src_p)
+ {
+ SET_FLAG (zapi_flags, ZAPI_MESSAGE_SRCPFX);
+ psize = PSIZE (src_p->prefixlen);
+ stream_putc (s, src_p->prefixlen);
+ stream_write (s, (u_char *) & src_p->u.prefix, psize);
+ }
+
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
{
/* We don't send any nexthops when there's a multipath */
@@ -742,7 +753,7 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
/* ldpd needs all nexthops */
if (client->proto != ZEBRA_ROUTE_LDP)
- break;
+ break;
}
}
@@ -785,8 +796,6 @@ zsend_write_nexthop (struct stream *s, struct nexthop *nexthop)
switch (nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
- stream_put_in_addr (s, &nexthop->gate.ipv4);
- break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
stream_put_in_addr (s, &nexthop->gate.ipv4);
stream_putl (s, nexthop->ifindex);
@@ -826,7 +835,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
s = client->ibuf;
- client->nh_reg_time = quagga_monotime();
+ client->nh_reg_time = monotime(NULL);
while (l < length)
{
@@ -914,7 +923,7 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type);
if (rnh)
{
- client->nh_dereg_time = quagga_monotime();
+ client->nh_dereg_time = monotime(NULL);
zebra_remove_rnh_client(rnh, client, type);
}
}
@@ -1150,7 +1159,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
/* Table */
rib->table = zvrf->table_id;
- ret = rib_add_multipath (AFI_IP, safi, &p, rib);
+ ret = rib_add_multipath (AFI_IP, safi, &p, NULL, rib);
/* Stats */
if (ret > 0)
@@ -1244,7 +1253,7 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
table_id = zvrf->table_id;
rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance,
- api.flags, &p, nexthop_p, ifindex, table_id);
+ api.flags, &p, NULL, nexthop_p, ifindex, table_id);
client->v4_route_del_cnt++;
return 0;
}
@@ -1379,7 +1388,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
/* Table */
rib->table = zvrf->table_id;
- ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
+ ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, rib);
/* Stats */
if (ret > 0)
client->v4_route_add_cnt++;
@@ -1400,6 +1409,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
u_char nexthop_num;
u_char nexthop_type;
struct prefix p;
+ struct prefix_ipv6 src_p, *src_pp;
safi_t safi;
static struct in6_addr nexthops[MULTIPATH_NUM];
static unsigned int ifindices[MULTIPATH_NUM];
@@ -1427,6 +1437,17 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
p.prefixlen = stream_getc (s);
stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
+ if (CHECK_FLAG (message, ZAPI_MESSAGE_SRCPFX))
+ {
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ src_pp = &src_p;
+ }
+ else
+ src_pp = NULL;
+
/* We need to give nh-addr, nh-ifindex with the same next-hop object
* to the rib to ensure that IPv6 multipathing works; need to coalesce
* these. Clients should send the same number of paired set of
@@ -1501,7 +1522,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
rib->vrf_id = zvrf_id (zvrf);
rib->table = zvrf->table_id;
- ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
+ ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, rib);
/* Stats */
if (ret > 0)
client->v6_route_add_cnt++;
@@ -1519,9 +1540,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
struct stream *s;
struct zapi_ipv6 api;
struct in6_addr nexthop;
- union g_addr *pnexthop;
+ union g_addr *pnexthop = NULL;
unsigned long ifindex;
struct prefix p;
+ struct prefix_ipv6 src_p, *src_pp;
s = client->ibuf;
ifindex = 0;
@@ -1540,6 +1562,17 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
p.prefixlen = stream_getc (s);
stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
+ {
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ src_pp = &src_p;
+ }
+ else
+ src_pp = NULL;
+
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
@@ -1583,10 +1616,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
- api.flags, &p, NULL, ifindex, client->rtm_table);
+ api.flags, &p, src_pp, NULL, ifindex, client->rtm_table);
else
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
- api.flags, &p, pnexthop, ifindex, client->rtm_table);
+ api.flags, &p, src_pp, pnexthop, ifindex, client->rtm_table);
client->v6_route_del_cnt++;
return 0;
@@ -1665,6 +1698,7 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
struct prefix prefix;
enum nexthop_types_t gtype;
union g_addr gate;
+ ifindex_t ifindex;
mpls_label_t in_label, out_label;
u_int8_t distance;
struct zebra_vrf *zvrf;
@@ -1684,37 +1718,56 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
case AF_INET:
prefix.u.prefix4.s_addr = stream_get_ipv4 (s);
prefix.prefixlen = stream_getc (s);
- gtype = NEXTHOP_TYPE_IPV4;
gate.ipv4.s_addr = stream_get_ipv4 (s);
break;
case AF_INET6:
stream_get (&prefix.u.prefix6, s, 16);
prefix.prefixlen = stream_getc (s);
- gtype = NEXTHOP_TYPE_IPV6;
stream_get (&gate.ipv6, s, 16);
break;
default:
return;
}
+ ifindex = stream_getl (s);
distance = stream_getc (s);
in_label = stream_getl (s);
out_label = stream_getl (s);
+ switch (prefix.family)
+ {
+ case AF_INET:
+ if (ifindex)
+ gtype = NEXTHOP_TYPE_IPV4_IFINDEX;
+ else
+ gtype = NEXTHOP_TYPE_IPV4;
+ break;
+ case AF_INET6:
+ if (ifindex)
+ gtype = NEXTHOP_TYPE_IPV6_IFINDEX;
+ else
+ gtype = NEXTHOP_TYPE_IPV6;
+ break;
+ default:
+ return;
+ }
+
if (! mpls_enabled)
return;
if (command == ZEBRA_MPLS_LABELS_ADD)
{
mpls_lsp_install (zvrf, type, in_label, out_label, gtype, &gate,
- NULL, 0);
+ NULL, ifindex);
if (out_label != MPLS_IMP_NULL_LABEL)
- mpls_ftn_update (1, zvrf, type, &prefix, &gate, distance, out_label);
+ mpls_ftn_update (1, zvrf, type, &prefix, gtype, &gate, ifindex,
+ distance, out_label);
}
else if (command == ZEBRA_MPLS_LABELS_DELETE)
{
- mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, NULL, 0);
+ mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, NULL, ifindex);
if (out_label != MPLS_IMP_NULL_LABEL)
- mpls_ftn_update (0, zvrf, type, &prefix, &gate, distance, out_label);
+ mpls_ftn_update (0, zvrf, type, &prefix, gtype, &gate, ifindex,
+ distance, out_label);
}
}
@@ -1806,7 +1859,7 @@ zebra_client_create (int sock)
/* Set table number. */
client->rtm_table = zebrad.rtm_table_default;
- client->connect_time = quagga_monotime();
+ client->connect_time = monotime(NULL);
/* Initialize flags */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
@@ -1932,7 +1985,7 @@ zebra_client_read (struct thread *thread)
zlog_debug ("zebra message received [%s] %d in VRF %u",
zserv_command_string (command), length, vrf_id);
- client->last_read_time = quagga_monotime();
+ client->last_read_time = monotime(NULL);
client->last_read_cmd = command;
zvrf = zebra_vrf_lookup_by_id (vrf_id);
@@ -2031,6 +2084,9 @@ zebra_client_read (struct thread *thread)
case ZEBRA_MPLS_LABELS_DELETE:
zread_mpls_labels (command, client, length, vrf_id);
break;
+ case ZEBRA_IPMR_ROUTE_STATS:
+ zebra_ipmr_route_stats (client, sock, length, zvrf);
+ break;
default:
zlog_info ("Zebra received unknown command %d", command);
break;
@@ -2243,7 +2299,7 @@ zserv_time_buf(time_t *time1, char *buf, int buflen)
return (buf);
}
- now = quagga_monotime();
+ now = monotime(NULL);
now -= *time1;
tm = gmtime(&now);
@@ -2351,7 +2407,22 @@ zebra_show_client_brief (struct vty *vty, struct zserv *client)
}
+struct zserv *
+zebra_find_client (u_char proto)
+{
+ struct listnode *node, *nnode;
+ struct zserv *client;
+ for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
+ {
+ if (client->proto == proto)
+ return client;
+ }
+
+ return NULL;
+}
+
+#ifdef HAVE_NETLINK
/* Display default rtm_table for all clients. */
DEFUN (show_table,
show_table_cmd,
@@ -2364,19 +2435,19 @@ DEFUN (show_table,
return CMD_SUCCESS;
}
-DEFUN (config_table,
+DEFUN (config_table,
config_table_cmd,
"table TABLENO",
"Configure target kernel routing table\n"
"TABLE integer\n")
{
- zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
+ zebrad.rtm_table_default = strtol (argv[1]->arg, (char**)0, 10);
return CMD_SUCCESS;
}
DEFUN (no_config_table,
no_config_table_cmd,
- "no table TABLENO",
+ "no table [TABLENO]",
NO_STR
"Configure target kernel routing table\n"
"TABLE integer\n")
@@ -2384,6 +2455,7 @@ DEFUN (no_config_table,
zebrad.rtm_table_default = 0;
return CMD_SUCCESS;
}
+#endif
DEFUN (ip_forwarding,
ip_forwarding_cmd,
@@ -2433,8 +2505,8 @@ DEFUN (show_zebra_client,
show_zebra_client_cmd,
"show zebra client",
SHOW_STR
- "Zebra information"
- "Client information")
+ "Zebra information\n"
+ "Client information\n")
{
struct listnode *node;
struct zserv *client;
@@ -2450,8 +2522,9 @@ DEFUN (show_zebra_client_summary,
show_zebra_client_summary_cmd,
"show zebra client summary",
SHOW_STR
- "Zebra information brief"
- "Client information brief")
+ "Zebra information brief\n"
+ "Client information brief\n"
+ "Brief Summary\n")
{
struct listnode *node;
struct zserv *client;
@@ -2505,7 +2578,6 @@ DEFUN (show_ip_forwarding,
return CMD_SUCCESS;
}
-#ifdef HAVE_IPV6
/* Only display ipv6 forwarding is enabled or not. */
DEFUN (show_ipv6_forwarding,
show_ipv6_forwarding_cmd,
@@ -2579,8 +2651,6 @@ DEFUN (no_ipv6_forwarding,
return CMD_SUCCESS;
}
-#endif /* HAVE_IPV6 */
-
/* IPForwarding configuration write function. */
static int
config_write_forwarding (struct vty *vty)
@@ -2590,10 +2660,8 @@ config_write_forwarding (struct vty *vty)
if (!ipforward ())
vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
-#ifdef HAVE_IPV6
if (!ipforward_ipv6 ())
vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);
-#endif /* HAVE_IPV6 */
vty_out (vty, "!%s", VTY_NEWLINE);
return 0;
}
@@ -2651,11 +2719,9 @@ zebra_init (void)
install_element (CONFIG_NODE, &no_config_table_cmd);
#endif /* HAVE_NETLINK */
-#ifdef HAVE_IPV6
install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
-#endif /* HAVE_IPV6 */
/* Route-map */
zebra_route_map_init ();
diff --git a/zebra/zserv.h b/zebra/zserv.h
index ce243dd6ac..a5a9979468 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -25,10 +25,10 @@
#include "rib.h"
#include "if.h"
#include "workqueue.h"
+#include "vrf.h"
#include "routemap.h"
#include "vty.h"
#include "zclient.h"
-#include "vrf.h"
#include "zebra/zebra_ns.h"
/* Default port information. */
@@ -162,7 +162,7 @@ extern void nbr_connected_add_ipv6 (struct interface *, struct in6_addr *);
extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *);
extern int zsend_interface_update (int, struct zserv *, struct interface *);
extern int zsend_redistribute_route (int, struct zserv *, struct prefix *,
- struct rib *);
+ struct prefix *, struct rib *);
extern int zsend_router_id_update (struct zserv *, struct prefix *,
vrf_id_t);
extern int zsend_interface_vrf_update (struct zserv *, struct interface *,
@@ -176,4 +176,6 @@ extern void zserv_create_header(struct stream *s, uint16_t cmd, vrf_id_t vrf_id)
extern void zserv_nexthop_num_warn(const char *, const struct prefix *, const unsigned int);
extern int zebra_server_send_message(struct zserv *client);
+extern struct zserv *zebra_find_client (u_char proto);
+
#endif /* _ZEBRA_ZEBRA_H */
diff --git a/zebra/zserv_null.c b/zebra/zserv_null.c
index acab22d96f..4b52abb222 100644
--- a/zebra/zserv_null.c
+++ b/zebra/zserv_null.c
@@ -23,6 +23,7 @@
#include <zebra.h>
#include <vrf.h>
+#include <vty.h>
#include <zserv.h>
#include <zebra_ns.h>