summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--COMMUNITY.md39
-rw-r--r--COPYING32
-rw-r--r--Makefile.am6
-rw-r--r--README3
-rw-r--r--bgpd/Makefile.am5
-rw-r--r--bgpd/bgp_advertise.c36
-rw-r--r--bgpd/bgp_advertise.h36
-rw-r--r--bgpd/bgp_aspath.c38
-rw-r--r--bgpd/bgp_aspath.h36
-rw-r--r--bgpd/bgp_attr.c270
-rw-r--r--bgpd/bgp_attr.h56
-rw-r--r--bgpd/bgp_attr_evpn.c36
-rw-r--r--bgpd/bgp_attr_evpn.h36
-rw-r--r--bgpd/bgp_bfd.c7
-rw-r--r--bgpd/bgp_bfd.h7
-rw-r--r--bgpd/bgp_btoa.c36
-rw-r--r--bgpd/bgp_clist.c54
-rw-r--r--bgpd/bgp_clist.h36
-rw-r--r--bgpd/bgp_community.c36
-rw-r--r--bgpd/bgp_community.h36
-rw-r--r--bgpd/bgp_damp.c45
-rw-r--r--bgpd/bgp_damp.h36
-rw-r--r--bgpd/bgp_debug.c45
-rw-r--r--bgpd/bgp_debug.h38
-rw-r--r--bgpd/bgp_dump.c48
-rw-r--r--bgpd/bgp_dump.h36
-rw-r--r--bgpd/bgp_ecommunity.c36
-rw-r--r--bgpd/bgp_ecommunity.h36
-rw-r--r--bgpd/bgp_encap.c36
-rw-r--r--bgpd/bgp_encap.h7
-rw-r--r--bgpd/bgp_encap_tlv.c7
-rw-r--r--bgpd/bgp_encap_tlv.h7
-rw-r--r--bgpd/bgp_encap_types.h7
-rw-r--r--bgpd/bgp_evpn.c36
-rw-r--r--bgpd/bgp_evpn.h36
-rw-r--r--bgpd/bgp_evpn_vty.c36
-rw-r--r--bgpd/bgp_evpn_vty.h36
-rw-r--r--bgpd/bgp_filter.c36
-rw-r--r--bgpd/bgp_filter.h36
-rw-r--r--bgpd/bgp_fsm.c55
-rw-r--r--bgpd/bgp_fsm.h110
-rw-r--r--bgpd/bgp_label.c341
-rw-r--r--bgpd/bgp_label.h125
-rw-r--r--bgpd/bgp_lcommunity.c4
-rw-r--r--bgpd/bgp_lcommunity.h4
-rw-r--r--bgpd/bgp_main.c53
-rw-r--r--bgpd/bgp_memory.c7
-rw-r--r--bgpd/bgp_memory.h7
-rw-r--r--bgpd/bgp_mpath.c7
-rw-r--r--bgpd/bgp_mpath.h7
-rw-r--r--bgpd/bgp_mplsvpn.c36
-rw-r--r--bgpd/bgp_mplsvpn.h36
-rw-r--r--bgpd/bgp_network.c43
-rw-r--r--bgpd/bgp_network.h36
-rw-r--r--bgpd/bgp_nexthop.c36
-rw-r--r--bgpd/bgp_nexthop.h36
-rw-r--r--bgpd/bgp_nht.c25
-rw-r--r--bgpd/bgp_nht.h7
-rw-r--r--bgpd/bgp_open.c96
-rw-r--r--bgpd/bgp_open.h36
-rw-r--r--bgpd/bgp_packet.c49
-rw-r--r--bgpd/bgp_packet.h36
-rw-r--r--bgpd/bgp_regex.c36
-rw-r--r--bgpd/bgp_regex.h36
-rw-r--r--bgpd/bgp_route.c462
-rw-r--r--bgpd/bgp_route.h55
-rw-r--r--bgpd/bgp_routemap.c42
-rw-r--r--bgpd/bgp_snmp.c36
-rw-r--r--bgpd/bgp_table.c36
-rw-r--r--bgpd/bgp_table.h40
-rw-r--r--bgpd/bgp_updgrp.c14
-rw-r--r--bgpd/bgp_updgrp.h7
-rw-r--r--bgpd/bgp_updgrp_adv.c13
-rw-r--r--bgpd/bgp_updgrp_packet.c74
-rw-r--r--bgpd/bgp_vnc_types.h7
-rw-r--r--bgpd/bgp_vpn.c36
-rw-r--r--bgpd/bgp_vpn.h36
-rw-r--r--bgpd/bgp_vty.c1329
-rw-r--r--bgpd/bgp_vty.h40
-rw-r--r--bgpd/bgp_zebra.c196
-rw-r--r--bgpd/bgp_zebra.h42
-rw-r--r--bgpd/bgpd.c116
-rw-r--r--bgpd/bgpd.conf.sample7
-rw-r--r--bgpd/bgpd.conf.vnc.sample6
-rw-r--r--bgpd/bgpd.h60
-rw-r--r--bgpd/rfapi/bgp_rfapi_cfg.c7
-rw-r--r--bgpd/rfapi/bgp_rfapi_cfg.h7
-rw-r--r--bgpd/rfapi/rfapi.c8
-rw-r--r--bgpd/rfapi/rfapi.h7
-rw-r--r--bgpd/rfapi/rfapi_ap.c7
-rw-r--r--bgpd/rfapi/rfapi_ap.h7
-rw-r--r--bgpd/rfapi/rfapi_backend.h7
-rw-r--r--bgpd/rfapi/rfapi_descriptor_rfp_utils.c7
-rw-r--r--bgpd/rfapi/rfapi_descriptor_rfp_utils.h7
-rw-r--r--bgpd/rfapi/rfapi_encap_tlv.c7
-rw-r--r--bgpd/rfapi/rfapi_encap_tlv.h7
-rw-r--r--bgpd/rfapi/rfapi_import.c20
-rw-r--r--bgpd/rfapi/rfapi_import.h7
-rw-r--r--bgpd/rfapi/rfapi_monitor.c17
-rw-r--r--bgpd/rfapi/rfapi_monitor.h11
-rw-r--r--bgpd/rfapi/rfapi_nve_addr.c7
-rw-r--r--bgpd/rfapi/rfapi_nve_addr.h7
-rw-r--r--bgpd/rfapi/rfapi_private.h7
-rw-r--r--bgpd/rfapi/rfapi_rib.c12
-rw-r--r--bgpd/rfapi/rfapi_rib.h9
-rw-r--r--bgpd/rfapi/rfapi_vty.c7
-rw-r--r--bgpd/rfapi/rfapi_vty.h7
-rw-r--r--bgpd/rfapi/vnc_debug.c7
-rw-r--r--bgpd/rfapi/vnc_debug.h7
-rw-r--r--bgpd/rfapi/vnc_export_bgp.c13
-rw-r--r--bgpd/rfapi/vnc_export_bgp.h7
-rw-r--r--bgpd/rfapi/vnc_export_bgp_p.h7
-rw-r--r--bgpd/rfapi/vnc_export_table.c7
-rw-r--r--bgpd/rfapi/vnc_export_table.h7
-rw-r--r--bgpd/rfapi/vnc_import_bgp.c7
-rw-r--r--bgpd/rfapi/vnc_import_bgp.h7
-rw-r--r--bgpd/rfapi/vnc_import_bgp_p.h7
-rw-r--r--bgpd/rfapi/vnc_zebra.c7
-rw-r--r--bgpd/rfapi/vnc_zebra.h7
-rw-r--r--bgpd/rfp-example/librfp/rfp.h7
-rw-r--r--bgpd/rfp-example/librfp/rfp_example.c7
-rw-r--r--bgpd/rfp-example/librfp/rfp_internal.h7
-rw-r--r--bgpd/rfp-example/rfptest/rfptest.c7
-rw-r--r--bgpd/rfp-example/rfptest/rfptest.h7
-rwxr-xr-xconfigure.ac138
-rw-r--r--cumulus/.gitignore2
-rw-r--r--cumulus/Makefile.am5
-rw-r--r--debian/README.Debian2
-rw-r--r--debian/README.Maintainer2
-rw-r--r--debian/changelog6
-rw-r--r--debian/control2
-rw-r--r--debian/frr.dirs1
-rw-r--r--debian/frr.install2
-rw-r--r--defaults.h10
-rw-r--r--doc/Building_FRR_on_Ubuntu1204.md2
-rw-r--r--doc/Building_FRR_on_Ubuntu1404.md2
-rw-r--r--doc/Building_FRR_on_Ubuntu1604.md4
-rw-r--r--doc/Makefile.am6
-rw-r--r--doc/bgpd.texi76
-rw-r--r--doc/cli.md111
-rw-r--r--doc/eigrpd.8.in122
-rw-r--r--doc/eigrpd.texi216
-rw-r--r--doc/install.texi3
-rw-r--r--doc/nhrpd.texi2
-rw-r--r--doc/vnc.texi35
-rw-r--r--eigrpd/.gitignore18
-rw-r--r--eigrpd/EIGRP-MIB.txt1321
-rw-r--r--eigrpd/Makefile.am46
-rw-r--r--eigrpd/eigrp_const.h432
-rw-r--r--eigrpd/eigrp_dump.c651
-rw-r--r--eigrpd/eigrp_dump.h164
-rw-r--r--eigrpd/eigrp_filter.c382
-rw-r--r--eigrpd/eigrp_filter.h43
-rw-r--r--eigrpd/eigrp_fsm.c586
-rw-r--r--eigrpd/eigrp_fsm.h36
-rw-r--r--eigrpd/eigrp_hello.c780
-rw-r--r--eigrpd/eigrp_interface.c622
-rw-r--r--eigrpd/eigrp_interface.h72
-rw-r--r--eigrpd/eigrp_macros.h84
-rw-r--r--eigrpd/eigrp_main.c230
-rw-r--r--eigrpd/eigrp_memory.c42
-rw-r--r--eigrpd/eigrp_memory.h43
-rw-r--r--eigrpd/eigrp_neighbor.c381
-rw-r--r--eigrpd/eigrp_neighbor.h54
-rw-r--r--eigrpd/eigrp_network.c460
-rw-r--r--eigrpd/eigrp_network.h51
-rw-r--r--eigrpd/eigrp_packet.c1419
-rw-r--r--eigrpd/eigrp_packet.h142
-rw-r--r--eigrpd/eigrp_pkt_tlv1.c0
-rw-r--r--eigrpd/eigrp_pkt_tlv2.c0
-rw-r--r--eigrpd/eigrp_query.c228
-rw-r--r--eigrpd/eigrp_reply.c249
-rw-r--r--eigrpd/eigrp_routemap.c1242
-rw-r--r--eigrpd/eigrp_routemap.h18
-rw-r--r--eigrpd/eigrp_siaquery.c167
-rw-r--r--eigrpd/eigrp_siareply.c168
-rw-r--r--eigrpd/eigrp_snmp.c1388
-rw-r--r--eigrpd/eigrp_snmp.h35
-rw-r--r--eigrpd/eigrp_structs.h532
-rw-r--r--eigrpd/eigrp_topology.c572
-rw-r--r--eigrpd/eigrp_topology.h61
-rw-r--r--eigrpd/eigrp_update.c1125
-rw-r--r--eigrpd/eigrp_vty.c1568
-rw-r--r--eigrpd/eigrp_vty.h41
-rw-r--r--eigrpd/eigrp_zebra.c560
-rw-r--r--eigrpd/eigrp_zebra.h42
-rw-r--r--eigrpd/eigrpd.c320
-rw-r--r--eigrpd/eigrpd.conf.sample13
-rw-r--r--eigrpd/eigrpd.h54
-rw-r--r--fpm/fpm_pb.c7
-rw-r--r--fpm/fpm_pb.h7
-rw-r--r--isisd/Makefile.am4
-rw-r--r--isisd/isis_adjacency.c34
-rw-r--r--isisd/isis_adjacency.h11
-rw-r--r--isisd/isis_bpf.c41
-rw-r--r--isisd/isis_circuit.c65
-rw-r--r--isisd/isis_circuit.h11
-rw-r--r--isisd/isis_common.h8
-rw-r--r--isisd/isis_constants.h18
-rw-r--r--isisd/isis_csm.c6
-rw-r--r--isisd/isis_csm.h8
-rw-r--r--isisd/isis_dlpi.c8
-rw-r--r--isisd/isis_dr.c66
-rw-r--r--isisd/isis_dr.h8
-rw-r--r--isisd/isis_dynhn.c10
-rw-r--r--isisd/isis_dynhn.h6
-rw-r--r--isisd/isis_events.c42
-rw-r--r--isisd/isis_events.h8
-rw-r--r--isisd/isis_flags.c6
-rw-r--r--isisd/isis_flags.h8
-rw-r--r--isisd/isis_lsp.c489
-rw-r--r--isisd/isis_lsp.h10
-rw-r--r--isisd/isis_main.c10
-rw-r--r--isisd/isis_memory.c7
-rw-r--r--isisd/isis_memory.h7
-rw-r--r--isisd/isis_misc.c8
-rw-r--r--isisd/isis_misc.h8
-rw-r--r--isisd/isis_mt.c743
-rw-r--r--isisd/isis_mt.h145
-rw-r--r--isisd/isis_network.h8
-rw-r--r--isisd/isis_pdu.c200
-rw-r--r--isisd/isis_pdu.h8
-rw-r--r--isisd/isis_pfpacket.c13
-rw-r--r--isisd/isis_redist.c8
-rw-r--r--isisd/isis_redist.h8
-rw-r--r--isisd/isis_route.c8
-rw-r--r--isisd/isis_route.h8
-rw-r--r--isisd/isis_routemap.c8
-rw-r--r--isisd/isis_routemap.h8
-rw-r--r--isisd/isis_spf.c734
-rw-r--r--isisd/isis_spf.h18
-rw-r--r--isisd/isis_te.c7
-rw-r--r--isisd/isis_te.h7
-rw-r--r--isisd/isis_tlv.c695
-rw-r--r--isisd/isis_tlv.h30
-rw-r--r--isisd/isis_vty.c80
-rw-r--r--isisd/isis_zebra.c11
-rw-r--r--isisd/isis_zebra.h8
-rw-r--r--isisd/isisd.c115
-rw-r--r--isisd/isisd.h10
-rw-r--r--isisd/iso_checksum.c8
-rw-r--r--isisd/iso_checksum.h6
-rw-r--r--ldpd/Makefile.am2
-rw-r--r--ldpd/accept.c15
-rw-r--r--ldpd/adjacency.c41
-rw-r--r--ldpd/control.c23
-rw-r--r--ldpd/control.h4
-rw-r--r--ldpd/interface.c14
-rw-r--r--ldpd/lde.c225
-rw-r--r--ldpd/lde.h7
-rw-r--r--ldpd/lde_lib.c60
-rw-r--r--ldpd/ldp_debug.c7
-rw-r--r--ldpd/ldp_debug.h7
-rw-r--r--ldpd/ldp_vty.h7
-rw-r--r--ldpd/ldp_vty_conf.c9
-rw-r--r--ldpd/ldp_vty_exec.c11
-rw-r--r--ldpd/ldp_zebra.c48
-rw-r--r--ldpd/ldpd.c106
-rw-r--r--ldpd/ldpd.h43
-rw-r--r--ldpd/ldpe.c142
-rw-r--r--ldpd/ldpe.h4
-rw-r--r--ldpd/log.c493
-rw-r--r--ldpd/log.h66
-rw-r--r--ldpd/logmsg.c487
-rw-r--r--ldpd/neighbor.c19
-rw-r--r--ldpd/notification.c10
-rw-r--r--ldpd/packet.c35
-rw-r--r--lib/Makefile.am8
-rw-r--r--lib/agentx.c24
-rw-r--r--lib/bfd.c7
-rw-r--r--lib/bfd.h7
-rw-r--r--lib/bitfield.h7
-rw-r--r--lib/buffer.c9
-rw-r--r--lib/buffer.h7
-rw-r--r--lib/command.c476
-rw-r--r--lib/command.h94
-rw-r--r--lib/command_graph.c478
-rw-r--r--lib/command_graph.h119
-rw-r--r--lib/command_lex.l3
-rw-r--r--lib/command_match.c52
-rw-r--r--lib/command_match.h7
-rw-r--r--lib/command_parse.y58
-rw-r--r--lib/csv.c7
-rw-r--r--lib/csv.h7
-rw-r--r--lib/distribute.c7
-rw-r--r--lib/distribute.h7
-rw-r--r--lib/event_counter.c7
-rw-r--r--lib/event_counter.h7
-rw-r--r--lib/fifo.h36
-rw-r--r--lib/filter.c7
-rw-r--r--lib/filter.h7
-rw-r--r--lib/frr_pthread.c183
-rw-r--r--lib/frr_pthread.h144
-rw-r--r--lib/frratomic.h118
-rw-r--r--lib/getopt.c48
-rw-r--r--lib/getopt.h38
-rw-r--r--lib/getopt1.c40
-rw-r--r--lib/grammar_sandbox.c25
-rw-r--r--lib/grammar_sandbox_main.c4
-rw-r--r--lib/graph.c7
-rw-r--r--lib/graph.h7
-rw-r--r--lib/hash.c7
-rw-r--r--lib/hash.h36
-rw-r--r--lib/if.c42
-rw-r--r--lib/if.h36
-rw-r--r--lib/if_rmap.c7
-rw-r--r--lib/if_rmap.h7
-rw-r--r--lib/json.c7
-rw-r--r--lib/json.h7
-rw-r--r--lib/keychain.c36
-rw-r--r--lib/keychain.h7
-rw-r--r--lib/libfrr.c6
-rw-r--r--lib/libfrr.h6
-rw-r--r--lib/libospf.h7
-rw-r--r--lib/linklist.c7
-rw-r--r--lib/linklist.h7
-rw-r--r--lib/log.c20
-rw-r--r--lib/log.h10
-rw-r--r--lib/log_int.h7
-rw-r--r--lib/memory.c150
-rw-r--r--lib/memory.h43
-rw-r--r--lib/memory_vty.c6
-rw-r--r--lib/memory_vty.h36
-rw-r--r--lib/mpls.h15
-rw-r--r--lib/network.c7
-rw-r--r--lib/network.h7
-rw-r--r--lib/nexthop.c29
-rw-r--r--lib/nexthop.h8
-rw-r--r--lib/ns.c7
-rw-r--r--lib/ns.h7
-rw-r--r--lib/pid_output.c7
-rw-r--r--lib/plist.c43
-rw-r--r--lib/plist.h7
-rw-r--r--lib/plist_int.h7
-rw-r--r--lib/pqueue.c44
-rw-r--r--lib/pqueue.h37
-rw-r--r--lib/prefix.c13
-rw-r--r--lib/prefix.h9
-rw-r--r--lib/privs.c8
-rw-r--r--lib/privs.h7
-rw-r--r--lib/ptm_lib.c7
-rw-r--r--lib/ptm_lib.h7
-rw-r--r--lib/qobj.c7
-rw-r--r--lib/route_types.txt2
-rw-r--r--lib/routemap.c64
-rw-r--r--lib/routemap.h7
-rw-r--r--lib/sha256.c433
-rw-r--r--lib/sha256.h58
-rw-r--r--lib/sigevent.c35
-rw-r--r--lib/sigevent.h7
-rw-r--r--lib/smux.c18
-rw-r--r--lib/smux.h7
-rw-r--r--lib/snmp.c7
-rw-r--r--lib/sockopt.c7
-rw-r--r--lib/sockopt.h7
-rw-r--r--lib/sockunion.c7
-rw-r--r--lib/sockunion.h7
-rw-r--r--lib/spf_backoff.c23
-rw-r--r--lib/spf_backoff.h7
-rw-r--r--lib/srcdest_table.c7
-rw-r--r--lib/srcdest_table.h7
-rw-r--r--lib/stream.c34
-rw-r--r--lib/stream.h10
-rw-r--r--lib/strlcat.c33
-rw-r--r--lib/strlcpy.c33
-rw-r--r--lib/systemd.c42
-rw-r--r--lib/systemd.h38
-rw-r--r--lib/table.c7
-rw-r--r--lib/table.h7
-rw-r--r--lib/thread.c494
-rw-r--r--lib/thread.h128
-rw-r--r--lib/vector.c7
-rw-r--r--lib/vector.h7
-rw-r--r--lib/vrf.c63
-rw-r--r--lib/vrf.h58
-rw-r--r--lib/vrf_int.h56
-rw-r--r--lib/vty.c65
-rw-r--r--lib/vty.h36
-rw-r--r--lib/wheel.c22
-rw-r--r--lib/wheel.h7
-rw-r--r--lib/workqueue.c12
-rw-r--r--lib/workqueue.h7
-rw-r--r--lib/zassert.h7
-rw-r--r--lib/zclient.c87
-rw-r--r--lib/zclient.h22
-rw-r--r--lib/zebra.h51
-rw-r--r--m4/.gitignore3
-rw-r--r--m4/ax_pthread.m4332
-rw-r--r--nhrpd/netlink_arp.c11
-rw-r--r--nhrpd/nhrp_cache.c13
-rw-r--r--nhrpd/nhrp_event.c20
-rw-r--r--nhrpd/nhrp_main.c2
-rw-r--r--nhrpd/nhrp_nhs.c27
-rw-r--r--nhrpd/nhrp_packet.c4
-rw-r--r--nhrpd/nhrp_peer.c13
-rw-r--r--nhrpd/nhrp_shortcut.c17
-rw-r--r--nhrpd/resolver.c15
-rw-r--r--nhrpd/vici.c17
-rw-r--r--ospf6d/ospf6_abr.c7
-rw-r--r--ospf6d/ospf6_abr.h7
-rw-r--r--ospf6d/ospf6_area.c28
-rw-r--r--ospf6d/ospf6_area.h7
-rw-r--r--ospf6d/ospf6_asbr.c7
-rw-r--r--ospf6d/ospf6_asbr.h7
-rw-r--r--ospf6d/ospf6_bfd.c9
-rw-r--r--ospf6d/ospf6_bfd.h7
-rw-r--r--ospf6d/ospf6_flood.c76
-rw-r--r--ospf6d/ospf6_flood.h7
-rw-r--r--ospf6d/ospf6_interface.c47
-rw-r--r--ospf6d/ospf6_interface.h7
-rw-r--r--ospf6d/ospf6_intra.c7
-rw-r--r--ospf6d/ospf6_intra.h41
-rw-r--r--ospf6d/ospf6_lsa.c14
-rw-r--r--ospf6d/ospf6_lsa.h7
-rw-r--r--ospf6d/ospf6_lsdb.c7
-rw-r--r--ospf6d/ospf6_lsdb.h7
-rw-r--r--ospf6d/ospf6_main.c9
-rw-r--r--ospf6d/ospf6_memory.c7
-rw-r--r--ospf6d/ospf6_memory.h7
-rw-r--r--ospf6d/ospf6_message.c136
-rw-r--r--ospf6d/ospf6_message.h7
-rw-r--r--ospf6d/ospf6_neighbor.c47
-rw-r--r--ospf6d/ospf6_neighbor.h7
-rw-r--r--ospf6d/ospf6_network.c7
-rw-r--r--ospf6d/ospf6_network.h7
-rw-r--r--ospf6d/ospf6_proto.c7
-rw-r--r--ospf6d/ospf6_proto.h7
-rw-r--r--ospf6d/ospf6_route.c7
-rw-r--r--ospf6d/ospf6_route.h7
-rw-r--r--ospf6d/ospf6_snmp.c7
-rw-r--r--ospf6d/ospf6_spf.c12
-rw-r--r--ospf6d/ospf6_spf.h7
-rw-r--r--ospf6d/ospf6_top.c13
-rw-r--r--ospf6d/ospf6_top.h7
-rw-r--r--ospf6d/ospf6_zebra.c7
-rw-r--r--ospf6d/ospf6_zebra.h7
-rw-r--r--ospf6d/ospf6d.c9
-rw-r--r--ospf6d/ospf6d.h7
-rw-r--r--ospfclient/ospf_apiclient.c9
-rw-r--r--ospfclient/ospf_apiclient.h9
-rw-r--r--ospfclient/ospfclient.c17
-rw-r--r--ospfd/ospf_abr.c16
-rw-r--r--ospfd/ospf_abr.h11
-rw-r--r--ospfd/ospf_api.c9
-rw-r--r--ospfd/ospf_api.h9
-rw-r--r--ospfd/ospf_apiserver.c35
-rw-r--r--ospfd/ospf_apiserver.h9
-rw-r--r--ospfd/ospf_asbr.c7
-rw-r--r--ospfd/ospf_asbr.h7
-rw-r--r--ospfd/ospf_ase.c12
-rw-r--r--ospfd/ospf_ase.h7
-rw-r--r--ospfd/ospf_bfd.c7
-rw-r--r--ospfd/ospf_bfd.h7
-rw-r--r--ospfd/ospf_dump.c7
-rw-r--r--ospfd/ospf_dump.h7
-rw-r--r--ospfd/ospf_dump_api.c4
-rw-r--r--ospfd/ospf_dump_api.h4
-rw-r--r--ospfd/ospf_flood.c9
-rw-r--r--ospfd/ospf_flood.h9
-rw-r--r--ospfd/ospf_ia.c7
-rw-r--r--ospfd/ospf_ia.h7
-rw-r--r--ospfd/ospf_interface.c9
-rw-r--r--ospfd/ospf_interface.h9
-rw-r--r--ospfd/ospf_ism.c7
-rw-r--r--ospfd/ospf_ism.h42
-rw-r--r--ospfd/ospf_lsa.c16
-rw-r--r--ospfd/ospf_lsa.h7
-rw-r--r--ospfd/ospf_lsdb.c7
-rw-r--r--ospfd/ospf_lsdb.h7
-rw-r--r--ospfd/ospf_main.c9
-rw-r--r--ospfd/ospf_memory.c7
-rw-r--r--ospfd/ospf_memory.h7
-rw-r--r--ospfd/ospf_neighbor.c9
-rw-r--r--ospfd/ospf_neighbor.h9
-rw-r--r--ospfd/ospf_network.c7
-rw-r--r--ospfd/ospf_network.h7
-rw-r--r--ospfd/ospf_nsm.c7
-rw-r--r--ospfd/ospf_nsm.h15
-rw-r--r--ospfd/ospf_opaque.c30
-rw-r--r--ospfd/ospf_opaque.h9
-rw-r--r--ospfd/ospf_packet.c35
-rw-r--r--ospfd/ospf_packet.h7
-rw-r--r--ospfd/ospf_ri.c7
-rw-r--r--ospfd/ospf_ri.h7
-rw-r--r--ospfd/ospf_route.c7
-rw-r--r--ospfd/ospf_route.h7
-rw-r--r--ospfd/ospf_routemap.c7
-rw-r--r--ospfd/ospf_snmp.c7
-rw-r--r--ospfd/ospf_spf.c41
-rw-r--r--ospfd/ospf_spf.h7
-rw-r--r--ospfd/ospf_te.c9
-rw-r--r--ospfd/ospf_te.h9
-rw-r--r--ospfd/ospf_vty.c10
-rw-r--r--ospfd/ospf_vty.h7
-rw-r--r--ospfd/ospf_zebra.c15
-rw-r--r--ospfd/ospf_zebra.h7
-rw-r--r--ospfd/ospfd.c73
-rw-r--r--ospfd/ospfd.h33
-rw-r--r--pimd/pim_assert.c46
-rw-r--r--pimd/pim_assert.h35
-rw-r--r--pimd/pim_br.c7
-rw-r--r--pimd/pim_br.h7
-rw-r--r--pimd/pim_cmd.c343
-rw-r--r--pimd/pim_cmd.h35
-rw-r--r--pimd/pim_hello.c71
-rw-r--r--pimd/pim_hello.h40
-rw-r--r--pimd/pim_iface.c101
-rw-r--r--pimd/pim_iface.h45
-rw-r--r--pimd/pim_ifchannel.c121
-rw-r--r--pimd/pim_ifchannel.h35
-rw-r--r--pimd/pim_igmp.c61
-rw-r--r--pimd/pim_igmp.h35
-rw-r--r--pimd/pim_igmp_join.h35
-rw-r--r--pimd/pim_igmpv2.c7
-rw-r--r--pimd/pim_igmpv2.h7
-rw-r--r--pimd/pim_igmpv3.c45
-rw-r--r--pimd/pim_igmpv3.h35
-rw-r--r--pimd/pim_int.c35
-rw-r--r--pimd/pim_int.h35
-rw-r--r--pimd/pim_join.c52
-rw-r--r--pimd/pim_join.h35
-rw-r--r--pimd/pim_jp_agg.c7
-rw-r--r--pimd/pim_jp_agg.h7
-rw-r--r--pimd/pim_macro.c35
-rw-r--r--pimd/pim_macro.h35
-rw-r--r--pimd/pim_main.c35
-rw-r--r--pimd/pim_memory.c7
-rw-r--r--pimd/pim_memory.h7
-rw-r--r--pimd/pim_mroute.c39
-rw-r--r--pimd/pim_mroute.h35
-rw-r--r--pimd/pim_msdp.c27
-rw-r--r--pimd/pim_msdp.h14
-rw-r--r--pimd/pim_msdp_packet.c7
-rw-r--r--pimd/pim_msdp_packet.h7
-rw-r--r--pimd/pim_msdp_socket.c16
-rw-r--r--pimd/pim_msdp_socket.h7
-rw-r--r--pimd/pim_msg.c35
-rw-r--r--pimd/pim_msg.h41
-rw-r--r--pimd/pim_neighbor.c88
-rw-r--r--pimd/pim_neighbor.h40
-rw-r--r--pimd/pim_nht.c13
-rw-r--r--pimd/pim_nht.h7
-rw-r--r--pimd/pim_oil.c35
-rw-r--r--pimd/pim_oil.h35
-rw-r--r--pimd/pim_pim.c54
-rw-r--r--pimd/pim_pim.h35
-rw-r--r--pimd/pim_register.c19
-rw-r--r--pimd/pim_register.h7
-rw-r--r--pimd/pim_routemap.c7
-rw-r--r--pimd/pim_rp.c11
-rw-r--r--pimd/pim_rp.h9
-rw-r--r--pimd/pim_rpf.c35
-rw-r--r--pimd/pim_rpf.h35
-rw-r--r--pimd/pim_signals.c35
-rw-r--r--pimd/pim_signals.h35
-rw-r--r--pimd/pim_sock.c35
-rw-r--r--pimd/pim_sock.h35
-rw-r--r--pimd/pim_ssm.c7
-rw-r--r--pimd/pim_ssm.h7
-rw-r--r--pimd/pim_ssmpingd.c39
-rw-r--r--pimd/pim_ssmpingd.h35
-rw-r--r--pimd/pim_static.c35
-rw-r--r--pimd/pim_static.h35
-rw-r--r--pimd/pim_str.c35
-rw-r--r--pimd/pim_str.h35
-rw-r--r--pimd/pim_time.c35
-rw-r--r--pimd/pim_time.h35
-rw-r--r--pimd/pim_tlv.c88
-rw-r--r--pimd/pim_tlv.h38
-rw-r--r--pimd/pim_upstream.c155
-rw-r--r--pimd/pim_upstream.h37
-rw-r--r--pimd/pim_util.c35
-rw-r--r--pimd/pim_util.h35
-rw-r--r--pimd/pim_version.c35
-rw-r--r--pimd/pim_version.h35
-rw-r--r--pimd/pim_vty.c43
-rw-r--r--pimd/pim_vty.h35
-rw-r--r--pimd/pim_zebra.c63
-rw-r--r--pimd/pim_zebra.h35
-rw-r--r--pimd/pim_zlookup.c65
-rw-r--r--pimd/pim_zlookup.h35
-rw-r--r--pimd/pimd.c55
-rw-r--r--pimd/pimd.h38
-rw-r--r--pimd/test_igmpv3_join.c35
-rw-r--r--pkgsrc/eigrpd.sh.in44
-rw-r--r--qpb/linear_allocator.h7
-rw-r--r--qpb/qpb.c7
-rw-r--r--qpb/qpb.h7
-rw-r--r--qpb/qpb_allocator.c7
-rw-r--r--qpb/qpb_allocator.h7
-rw-r--r--redhat/frr.spec.in8
-rw-r--r--ripd/rip_debug.c7
-rw-r--r--ripd/rip_debug.h7
-rw-r--r--ripd/rip_interface.c12
-rw-r--r--ripd/rip_interface.h7
-rw-r--r--ripd/rip_main.c9
-rw-r--r--ripd/rip_memory.c7
-rw-r--r--ripd/rip_memory.h7
-rw-r--r--ripd/rip_offset.c7
-rw-r--r--ripd/rip_peer.c12
-rw-r--r--ripd/rip_routemap.c7
-rw-r--r--ripd/rip_snmp.c7
-rw-r--r--ripd/rip_zebra.c7
-rw-r--r--ripd/ripd.c27
-rw-r--r--ripd/ripd.h13
-rw-r--r--ripngd/ripng_debug.c7
-rw-r--r--ripngd/ripng_debug.h7
-rw-r--r--ripngd/ripng_interface.c12
-rw-r--r--ripngd/ripng_main.c9
-rw-r--r--ripngd/ripng_memory.c7
-rw-r--r--ripngd/ripng_memory.h7
-rw-r--r--ripngd/ripng_nexthop.c7
-rw-r--r--ripngd/ripng_nexthop.h7
-rw-r--r--ripngd/ripng_offset.c7
-rw-r--r--ripngd/ripng_peer.c12
-rw-r--r--ripngd/ripng_route.c7
-rw-r--r--ripngd/ripng_route.h7
-rw-r--r--ripngd/ripng_routemap.c7
-rw-r--r--ripngd/ripng_zebra.c7
-rw-r--r--ripngd/ripngd.c26
-rw-r--r--ripngd/ripngd.h13
-rw-r--r--tests/bgpd/test_aspath.c7
-rw-r--r--tests/bgpd/test_capability.c9
-rw-r--r--tests/bgpd/test_ecommunity.c7
-rw-r--r--tests/bgpd/test_mp_attr.c9
-rw-r--r--tests/bgpd/test_mpath.c9
-rw-r--r--tests/helpers/c/main.c11
-rw-r--r--tests/helpers/c/prng.c7
-rw-r--r--tests/helpers/c/prng.h7
-rw-r--r--tests/helpers/c/tests.h7
-rw-r--r--tests/helpers/python/frrtest.py3
-rw-r--r--tests/lib/cli/common_cli.c7
-rw-r--r--tests/lib/cli/common_cli.h7
-rw-r--r--tests/lib/cli/test_cli.c7
-rw-r--r--tests/lib/cli/test_cli.refout.in8
-rw-r--r--tests/lib/cli/test_commands.c7
-rw-r--r--tests/lib/test_buffer.c7
-rw-r--r--tests/lib/test_checksum.c7
-rw-r--r--tests/lib/test_heavy.c7
-rw-r--r--tests/lib/test_heavy_thread.c11
-rw-r--r--tests/lib/test_heavy_wq.c7
-rw-r--r--tests/lib/test_memory.c7
-rw-r--r--tests/lib/test_nexthop_iter.c7
-rw-r--r--tests/lib/test_privs.c7
-rw-r--r--tests/lib/test_segv.c7
-rw-r--r--tests/lib/test_sig.c7
-rw-r--r--tests/lib/test_srcdest_table.c7
-rw-r--r--tests/lib/test_stream.c9
-rw-r--r--tests/lib/test_table.c7
-rw-r--r--tests/lib/test_timer_correctness.c11
-rw-r--r--tests/lib/test_timer_performance.c18
-rw-r--r--tests/test_lblmgr.c7
-rw-r--r--tools/.gitignore3
-rw-r--r--tools/Makefile.am4
-rw-r--r--tools/cocci.h3
-rw-r--r--tools/etc/default/frr (renamed from cumulus/etc/default/frr)1
-rw-r--r--tools/etc/frr/daemons (renamed from cumulus/etc/frr/daemons)3
-rw-r--r--tools/etc/frr/daemons.conf (renamed from cumulus/etc/frr/debian.conf)6
-rw-r--r--tools/etc/frr/frr.conf (renamed from cumulus/etc/frr/frr.conf)0
-rw-r--r--tools/etc/frr/vtysh.conf (renamed from cumulus/etc/frr/vtysh.conf)0
-rw-r--r--tools/etc/iproute2/rt_protos.d/frr.conf8
-rwxr-xr-xtools/frr24
-rwxr-xr-xtools/frr-reload.py56
-rw-r--r--tools/permutations.c11
-rw-r--r--tools/start-stop-daemon.c (renamed from cumulus/start-stop-daemon.c)1
-rw-r--r--vtysh/Makefile.am10
-rwxr-xr-xvtysh/extract.pl.in9
-rw-r--r--vtysh/vtysh.c197
-rw-r--r--vtysh/vtysh.h14
-rw-r--r--vtysh/vtysh_config.c47
-rw-r--r--vtysh/vtysh_main.c7
-rw-r--r--vtysh/vtysh_user.c7
-rw-r--r--vtysh/vtysh_user.h7
-rw-r--r--watchfrr/watchfrr.c105
-rw-r--r--watchfrr/watchfrr.h34
-rw-r--r--watchfrr/watchfrr_vty.c34
-rw-r--r--zebra/Makefile.am6
-rw-r--r--zebra/client_main.c7
-rw-r--r--zebra/connected.c7
-rw-r--r--zebra/connected.h7
-rw-r--r--zebra/debug.c17
-rw-r--r--zebra/debug.h7
-rw-r--r--zebra/if_ioctl.c7
-rw-r--r--zebra/if_ioctl_solaris.c7
-rw-r--r--zebra/if_netlink.c8
-rw-r--r--zebra/if_netlink.h7
-rw-r--r--zebra/if_null.c7
-rw-r--r--zebra/if_sysctl.c7
-rw-r--r--zebra/interface.c12
-rw-r--r--zebra/interface.h7
-rw-r--r--zebra/ioctl.c7
-rw-r--r--zebra/ioctl.h7
-rw-r--r--zebra/ioctl_null.c7
-rw-r--r--zebra/ioctl_solaris.c7
-rw-r--r--zebra/ioctl_solaris.h7
-rw-r--r--zebra/ipforward.h7
-rw-r--r--zebra/ipforward_proc.c7
-rw-r--r--zebra/ipforward_solaris.c7
-rw-r--r--zebra/ipforward_sysctl.c7
-rw-r--r--zebra/irdp.h7
-rw-r--r--zebra/irdp_interface.c14
-rw-r--r--zebra/irdp_main.c21
-rw-r--r--zebra/irdp_packet.c10
-rw-r--r--zebra/kernel_netlink.c26
-rw-r--r--zebra/kernel_netlink.h7
-rw-r--r--zebra/kernel_null.c12
-rw-r--r--zebra/kernel_socket.c11
-rw-r--r--zebra/kernel_socket.h7
-rw-r--r--zebra/label_manager.c12
-rw-r--r--zebra/label_manager.h7
-rw-r--r--zebra/main.c7
-rw-r--r--zebra/misc_null.c7
-rw-r--r--zebra/redistribute.c89
-rw-r--r--zebra/redistribute.h7
-rw-r--r--zebra/redistribute_null.c7
-rw-r--r--zebra/rib.h9
-rw-r--r--zebra/router-id.c7
-rw-r--r--zebra/router-id.h7
-rw-r--r--zebra/rt.h7
-rw-r--r--zebra/rt_netlink.c54
-rw-r--r--zebra/rt_netlink.h15
-rw-r--r--zebra/rt_socket.c7
-rw-r--r--zebra/rtadv.c26
-rw-r--r--zebra/rtadv.h7
-rw-r--r--zebra/rtadv_null.c7
-rw-r--r--zebra/rtread_getmsg.c7
-rw-r--r--zebra/rtread_netlink.c7
-rw-r--r--zebra/rtread_sysctl.c7
-rw-r--r--zebra/test_main.c7
-rw-r--r--zebra/zebra_fpm.c51
-rw-r--r--zebra/zebra_fpm_dt.c7
-rw-r--r--zebra/zebra_fpm_netlink.c7
-rw-r--r--zebra/zebra_fpm_private.h7
-rw-r--r--zebra/zebra_fpm_protobuf.c7
-rw-r--r--zebra/zebra_memory.c7
-rw-r--r--zebra/zebra_memory.h7
-rw-r--r--zebra/zebra_mpls.c1141
-rw-r--r--zebra/zebra_mpls.h155
-rw-r--r--zebra/zebra_mpls_netlink.c7
-rw-r--r--zebra/zebra_mpls_null.c213
-rw-r--r--zebra/zebra_mpls_openbsd.c7
-rw-r--r--zebra/zebra_mpls_vty.c237
-rw-r--r--zebra/zebra_mroute.c7
-rw-r--r--zebra/zebra_mroute.h7
-rw-r--r--zebra/zebra_ns.c7
-rw-r--r--zebra/zebra_ns.h7
-rw-r--r--zebra/zebra_ptm.c66
-rw-r--r--zebra/zebra_ptm.h7
-rw-r--r--zebra/zebra_ptm_null.c7
-rw-r--r--zebra/zebra_ptm_redistribute.c7
-rw-r--r--zebra/zebra_ptm_redistribute.h7
-rw-r--r--zebra/zebra_rib.c55
-rw-r--r--zebra/zebra_rnh.c9
-rw-r--r--zebra/zebra_rnh.h7
-rw-r--r--zebra/zebra_rnh_null.c7
-rw-r--r--zebra/zebra_routemap.c16
-rw-r--r--zebra/zebra_routemap.h7
-rw-r--r--zebra/zebra_snmp.c7
-rw-r--r--zebra/zebra_static.c7
-rw-r--r--zebra/zebra_static.h7
-rw-r--r--zebra/zebra_vrf.c16
-rw-r--r--zebra/zebra_vrf.h20
-rw-r--r--zebra/zebra_vty.c286
-rw-r--r--zebra/zserv.c200
-rw-r--r--zebra/zserv.h7
-rw-r--r--zebra/zserv_null.c7
767 files changed, 34033 insertions, 9071 deletions
diff --git a/.gitignore b/.gitignore
index 6f281112b0..76d396ef25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -72,4 +72,5 @@ GTAGS
GSYMS
GRTAGS
GPATH
-
+*.la
+*.lo
diff --git a/COMMUNITY.md b/COMMUNITY.md
index 704c47a95e..a441929b31 100644
--- a/COMMUNITY.md
+++ b/COMMUNITY.md
@@ -132,6 +132,12 @@ Linux Foundation
website](http://www.linuxfoundation.org/content/how-participate-linux-community-0)
to be a helpful resource.
+### Code submission - What do I submit my changes against?
+
+We've documented where we would like to have the different fixes applied at
+https://github.com/FRRouting/frr/wiki/Where-Do-I-create-a-Pull-Request-against%3F
+If you are unsure where your submission goes, look at that document or ask
+the question of a maintainer.
### Code submission - Github Pull Request (Strongly Preferred)
@@ -224,23 +230,22 @@ form of the header is as follows:
```
/*
- Title/Function of file
- Copyright (C) 2016 Author’s Name
-
- 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
+ * Title/Function of file
+ * Copyright (C) YEAR Author’s Name
+ *
+ * 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>
diff --git a/COPYING b/COPYING
index b8cf3a1ab2..d159169d10 100644
--- a/COPYING
+++ b/COPYING
@@ -1,12 +1,12 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
- Preamble
+ Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
+the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@@ -56,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
- GNU GENERAL PUBLIC LICENSE
+ GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
- NO WARRANTY
+ NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
- END OF TERMS AND CONDITIONS
+ END OF TERMS AND CONDITIONS
- Appendix: How to Apply These Terms to Your New Programs
+ How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
+ Copyright (C) <year> <name of author>
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
@@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 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.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
- Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -335,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
+library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
diff --git a/Makefile.am b/Makefile.am
index 89e7ea890e..d87b5943d8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,13 +2,13 @@
SUBDIRS = lib qpb fpm @ZEBRA@ @LIBRFP@ @RFPTEST@ \
@BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @LDPD@ \
- @ISISD@ @PIMD@ @NHRPD@ \
+ @ISISD@ @PIMD@ @NHRPD@ @EIGRPD@ \
@WATCHFRR@ @VTYSH@ @OSPFCLIENT@ @DOC@ m4 @pkgsrcdir@ \
- redhat @SOLARIS@ tests tools cumulus snapcraft
+ redhat @SOLARIS@ tests tools snapcraft
DIST_SUBDIRS = lib qpb fpm zebra bgpd ripd ripngd ospfd ospf6d ldpd \
isisd watchfrr vtysh ospfclient doc m4 pkgsrc redhat tests \
- solaris pimd nhrpd @LIBRFP@ @RFPTEST@ tools cumulus snapcraft
+ solaris pimd nhrpd eigrpd @LIBRFP@ @RFPTEST@ tools snapcraft
EXTRA_DIST = aclocal.m4 SERVICES REPORTING-BUGS \
update-autotools \
diff --git a/README b/README
index 7c6ef7034e..bbad60087b 100644
--- a/README
+++ b/README
@@ -2,7 +2,8 @@ FRRouting is free software that manages various IPv4 and IPv6 routing
protocols.
Currently FRRouting supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1,
-RIPv2, RIPng, PIM-SM/MSDP and LDP as well as very early support for IS-IS.
+RIPv2, RIPng, PIM-SM/MSDP and LDP as well as very early support for IS-IS,
+EIGRP and NHRP.
See the file REPORTING-BUGS to report bugs.
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index b6ed9a4d6d..4ea0455525 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -81,7 +81,7 @@ libbgp_a_SOURCES = \
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) bgp_attr_evpn.c \
- bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c
+ bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c
noinst_HEADERS = \
bgp_memory.h \
@@ -92,7 +92,8 @@ noinst_HEADERS = \
bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
bgp_advertise.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) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h bgp_vpn.h
+ $(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h \
+ bgp_vpn.h bgp_label.h
bgpd_SOURCES = bgp_main.c
bgpd_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@
diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index da5ab94e97..f005b20183 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -1,22 +1,22 @@
/* BGP advertisement and adjacency
- Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
+ *
+ * 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 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>
diff --git a/bgpd/bgp_advertise.h b/bgpd/bgp_advertise.h
index 6dc9bb647c..03a1ffcb99 100644
--- a/bgpd/bgp_advertise.h
+++ b/bgpd/bgp_advertise.h
@@ -1,22 +1,22 @@
/* BGP advertisement and adjacency
- Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_ADVERTISE_H
#define _QUAGGA_BGP_ADVERTISE_H
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 006631c1f0..372650a2a6 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -1,23 +1,23 @@
/* AS path management routines.
- Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
- Copyright (C) 2005 Sun Microsystems, 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. */
+ * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
+ * Copyright (C) 2005 Sun Microsystems, 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 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>
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
index b15e32fec3..abf4c6ccf9 100644
--- a/bgpd/bgp_aspath.h
+++ b/bgpd/bgp_aspath.h
@@ -1,22 +1,22 @@
/* AS path related definitions.
- Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_ASPATH_H
#define _QUAGGA_BGP_ASPATH_H
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 61dcbd1b29..9c06c74aac 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1,22 +1,22 @@
/* BGP attributes management routines.
- Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -78,7 +78,8 @@ static const struct message attr_str [] =
#if ENABLE_BGP_VNC
{ BGP_ATTR_VNC, "VNC" },
#endif
- { BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY" }
+ { BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY" },
+ { BGP_ATTR_PREFIX_SID, "PREFIX_SID" }
};
static const int attr_str_max = array_size(attr_str);
@@ -532,7 +533,10 @@ static struct hash *attrhash;
static struct attr_extra *
bgp_attr_extra_new (void)
{
- return XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra));
+ struct attr_extra *extra;
+ extra = XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra));
+ extra->label_index = BGP_INVALID_LABEL_INDEX;
+ return extra;
}
void
@@ -676,6 +680,7 @@ attrhash_key_make (void *p)
MIX(extra->mp_nexthop_global_in.s_addr);
MIX(extra->originator_id.s_addr);
MIX(extra->tag);
+ MIX(extra->label_index);
}
if (attr->aspath)
@@ -730,6 +735,7 @@ 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
+ && ae1->label_index == ae2->label_index
&& 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)
@@ -962,26 +968,6 @@ bgp_attr_default_set (struct attr *attr, u_char origin)
return attr;
}
-
-/* Make network statement's attribute. */
-struct attr *
-bgp_attr_default_intern (u_char origin)
-{
- struct attr attr;
- struct attr *new;
-
- memset (&attr, 0, sizeof (struct attr));
- bgp_attr_extra_get (&attr);
-
- bgp_attr_default_set(&attr, origin);
-
- new = bgp_attr_intern (&attr);
- bgp_attr_extra_free (&attr);
-
- aspath_unintern (&new->aspath);
- return new;
-}
-
/* Create the attributes for an aggregate */
struct attr *
bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin,
@@ -1287,6 +1273,7 @@ const u_int8_t attr_flags_values [] = {
[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,
+ [BGP_ATTR_PREFIX_SID] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
};
static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
@@ -1493,8 +1480,7 @@ bgp_attr_as4_path (struct bgp_attr_parser_args *args, struct aspath **as4_path)
}
/* Set aspath attribute flag. */
- if (as4_path)
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
+ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
return BGP_ATTR_PARSE_PROCEED;
}
@@ -2274,6 +2260,106 @@ bgp_attr_encap(
return 0;
}
+/* Prefix SID attribute
+ * draft-ietf-idr-bgp-prefix-sid-05
+ */
+static bgp_attr_parse_ret_t
+bgp_attr_prefix_sid (struct bgp_attr_parser_args *args, struct bgp_nlri *mp_update)
+{
+ struct peer *const peer = args->peer;
+ struct attr *const attr = args->attr;
+ int type;
+ int length;
+ u_int32_t label_index;
+ struct in6_addr ipv6_sid;
+ u_int32_t srgb_base;
+ u_int32_t srgb_range;
+ int srgb_count;
+
+ attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID);
+
+ type = stream_getc (peer->ibuf);
+ length = stream_getw (peer->ibuf);
+
+ if (type == BGP_PREFIX_SID_LABEL_INDEX)
+ {
+ if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH)
+ {
+ zlog_err ("Prefix SID label index length is %d instead of %d", length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
+ return bgp_attr_malformed (args,
+ BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
+ }
+
+ /* Ignore flags and reserved */
+ stream_getc (peer->ibuf);
+ stream_getw (peer->ibuf);
+
+ /* Fetch the label index and see if it is valid. */
+ label_index = stream_getl (peer->ibuf);
+ if (label_index == BGP_INVALID_LABEL_INDEX)
+ return bgp_attr_malformed (args,
+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
+
+ /* Store label index; subsequently, we'll check on address-family */
+ (bgp_attr_extra_get (attr))->label_index = label_index;
+
+ /*
+ * Ignore the Label index attribute unless received for labeled-unicast
+ * SAFI.
+ */
+ if (!mp_update->length || mp_update->safi != SAFI_LABELED_UNICAST)
+ attr->extra->label_index = BGP_INVALID_LABEL_INDEX;
+ }
+
+ /* Placeholder code for the IPv6 SID type */
+ else if (type == BGP_PREFIX_SID_IPV6)
+ {
+ if (length != BGP_PREFIX_SID_IPV6_LENGTH)
+ {
+ zlog_err ("Prefix SID IPv6 length is %d instead of %d", length, BGP_PREFIX_SID_IPV6_LENGTH);
+ return bgp_attr_malformed (args,
+ BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
+ }
+
+ /* Ignore reserved */
+ stream_getc (peer->ibuf);
+ stream_getw (peer->ibuf);
+
+ stream_get (&ipv6_sid, peer->ibuf, 16);
+ }
+
+ /* Placeholder code for the Originator SRGB type */
+ else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB)
+ {
+ /* Ignore flags */
+ stream_getw (peer->ibuf);
+
+ length -= 2;
+
+ if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH)
+ {
+ zlog_err ("Prefix SID Originator SRGB length is %d, it must be a multiple of %d ",
+ length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
+ return bgp_attr_malformed (args,
+ BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
+ }
+
+ srgb_count = length / BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH;
+
+ for (int i = 0; i < srgb_count; i++)
+ {
+ stream_get (&srgb_base, peer->ibuf, 3);
+ stream_get (&srgb_range, peer->ibuf, 3);
+ }
+ }
+
+ return BGP_ATTR_PARSE_PROCEED;
+}
+
/* BGP unknown attribute treatment. */
static bgp_attr_parse_ret_t
bgp_attr_unknown (struct bgp_attr_parser_args *args)
@@ -2572,6 +2658,9 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
case BGP_ATTR_ENCAP:
ret = bgp_attr_encap (type, peer, length, attr, flag, startp);
break;
+ case BGP_ATTR_PREFIX_SID:
+ ret = bgp_attr_prefix_sid (&attr_args, mp_update);
+ break;
default:
ret = bgp_attr_unknown (&attr_args);
break;
@@ -2717,13 +2806,15 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
}
size_t
-bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
+bgp_packet_mpattr_start (struct stream *s, struct peer *peer,
+ afi_t afi, safi_t safi,
struct bpacket_attr_vec_arr *vecarr,
struct attr *attr)
{
size_t sizep;
iana_afi_t pkt_afi;
safi_t pkt_safi;
+ afi_t nh_afi;
/* Set extended bit always to encode the attribute length as 2 bytes */
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
@@ -2737,10 +2828,19 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
stream_putw (s, pkt_afi); /* AFI */
stream_putc (s, pkt_safi); /* SAFI */
- if (afi == AFI_L2VPN)
- nh_afi = AFI_L2VPN;
- else if (nh_afi == AFI_MAX)
- nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
+
+ /* Nexthop AFI */
+ if (peer_cap_enhe(peer, afi, safi)) {
+ nh_afi = AFI_IP6;
+ } else {
+ if (afi == AFI_L2VPN)
+ nh_afi = AFI_L2VPN;
+ else if (safi == SAFI_LABELED_UNICAST)
+ nh_afi = afi;
+ else
+ nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
+ }
+
/* Nexthop */
switch (nh_afi)
{
@@ -2749,6 +2849,7 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
{
case SAFI_UNICAST:
case SAFI_MULTICAST:
+ case SAFI_LABELED_UNICAST:
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
stream_putc (s, 4);
stream_put_ipv4 (s, attr->nexthop.s_addr);
@@ -2773,15 +2874,21 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
{
case SAFI_UNICAST:
case SAFI_MULTICAST:
+ case SAFI_LABELED_UNICAST:
{
struct attr_extra *attre = attr->extra;
assert (attr->extra);
bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
- stream_putc (s, attre->mp_nexthop_len);
- stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
- if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
+
+ if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ stream_putc (s, BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL);
+ stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
stream_put (s, &attre->mp_nexthop_local, IPV6_MAX_BYTELEN);
+ } else {
+ stream_putc (s, IPV6_MAX_BYTELEN);
+ stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
+ }
}
break;
case SAFI_MPLS_VPN:
@@ -2876,6 +2983,11 @@ bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
{
bgp_packet_mpattr_route_type_5(s, p, prd, tag, attr);
}
+ else if (safi == SAFI_LABELED_UNICAST)
+ {
+ /* Prefix write with label. */
+ stream_put_labeled_prefix(s, p, tag);
+ }
else
stream_put_prefix_addpath (s, p, addpath_encode, addpath_tx_id);
}
@@ -3020,14 +3132,11 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
cp = stream_get_endp (s);
if (p && !((afi == AFI_IP && safi == SAFI_UNICAST) &&
- !peer_cap_enhe(peer)))
+ !peer_cap_enhe(peer, afi, safi)))
{
size_t mpattrlen_pos = 0;
- mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi,
- (peer_cap_enhe(peer) ? AFI_IP6 :
- AFI_MAX), /* get from NH */
- vecarr, attr);
+ mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi, vecarr, attr);
bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag,
addpath_encode, addpath_tx_id, attr);
bgp_packet_mpattr_end(s, mpattrlen_pos);
@@ -3103,7 +3212,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
send_as4_path = 1; /* we'll do this later, at the correct place */
/* Nexthop attribute. */
- if (afi == AFI_IP && safi == SAFI_UNICAST && !peer_cap_enhe(peer))
+ if (afi == AFI_IP && safi == SAFI_UNICAST && !peer_cap_enhe(peer, afi, safi))
{
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))
{
@@ -3113,7 +3222,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
stream_putc (s, 4);
stream_put_ipv4 (s, attr->nexthop.s_addr);
}
- else if (safi == SAFI_UNICAST && peer_cap_enhe(from))
+ else if (peer_cap_enhe(from, afi, safi))
{
/*
* Likely this is the case when an IPv4 prefix was received with
@@ -3349,6 +3458,30 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
}
}
+ /* Label index attribute. */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
+ {
+ u_int32_t label_index;
+
+ assert (attr->extra);
+ label_index = attr->extra->label_index;
+
+ if (label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
+ stream_putc (s, BGP_ATTR_PREFIX_SID);
+ stream_putc (s, 10);
+ stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX);
+ stream_putw (s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
+ stream_putc (s, 0); // reserved
+ stream_putw (s, 0); // flags
+ stream_putl (s, label_index);
+ }
+ }
+ }
+
if ( send_as4_path )
{
/* If the peer is NOT As4 capable, AND */
@@ -3440,6 +3573,11 @@ bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
u_char *tag, int addpath_encode,
u_int32_t addpath_tx_id, struct attr *attr)
{
+ u_char wlabel[3] = {0x80, 0x00, 0x00};
+
+ if (safi == SAFI_LABELED_UNICAST)
+ tag = wlabel;
+
return bgp_packet_mpattr_prefix (s, afi, safi, p, prd,
tag, addpath_encode, addpath_tx_id, attr);
}
@@ -3627,6 +3765,24 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr,
stream_putc_at (s, sizep, (stream_get_endp (s) - sizep) - 1);
}
+ /* Prefix SID */
+ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
+ {
+ assert (attr->extra);
+
+ if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
+ stream_putc (s, BGP_ATTR_PREFIX_SID);
+ stream_putc (s, 10);
+ stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX);
+ stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
+ stream_putc (s, 0); // reserved
+ stream_putw (s, 0); // flags
+ stream_putl (s, attr->extra->label_index);
+ }
+ }
+
/* Return total size of attribute. */
len = stream_get_endp (s) - cp - 2;
stream_putw_at (s, cp, len);
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 015039c6cd..f25df3a8b9 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -1,22 +1,22 @@
/* BGP attributes.
- Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_ATTR_H
#define _QUAGGA_BGP_ATTR_H
@@ -57,6 +57,14 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#define BGP_ATTR_NHLEN_VPNV6_GLOBAL 8+IPV6_MAX_BYTELEN
#define BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL ((8+IPV6_MAX_BYTELEN) * 2)
+/* Prefix SID types */
+#define BGP_PREFIX_SID_LABEL_INDEX 1
+#define BGP_PREFIX_SID_IPV6 2
+#define BGP_PREFIX_SID_ORIGINATOR_SRGB 3
+
+#define BGP_PREFIX_SID_LABEL_INDEX_LENGTH 7
+#define BGP_PREFIX_SID_IPV6_LENGTH 19
+#define BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH 6
struct bgp_attr_encap_subtlv {
struct bgp_attr_encap_subtlv *next; /* for chaining */
@@ -134,6 +142,9 @@ struct attr_extra
/* route tag */
route_tag_t tag;
+ /* Label index */
+ u_int32_t label_index;
+
uint16_t encap_tunneltype; /* grr */
struct bgp_attr_encap_subtlv *encap_subtlvs; /* rfc5512 */
@@ -160,7 +171,7 @@ struct attr
unsigned long refcnt;
/* Flag of attribute is set or not. */
- u_int32_t flag;
+ uint64_t flag;
/* Apart from in6_addr, the remaining static attributes */
struct in_addr nexthop;
@@ -201,7 +212,7 @@ struct transit
u_char *val;
};
-#define ATTR_FLAG_BIT(X) (1 << ((X) - 1))
+#define ATTR_FLAG_BIT(X) (1ULL << ((X) - 1))
#define BGP_CLUSTER_LIST_LENGTH(attr) \
(((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) ? \
@@ -235,7 +246,6 @@ extern void bgp_attr_unintern_sub (struct attr *);
extern void bgp_attr_unintern (struct attr **);
extern void bgp_attr_flush (struct attr *);
extern struct attr *bgp_attr_default_set (struct attr *attr, u_char);
-extern struct attr *bgp_attr_default_intern (u_char);
extern struct attr *bgp_attr_aggregate_intern (struct bgp *, u_char,
struct aspath *,
struct community *, int as_set, u_char);
@@ -287,8 +297,8 @@ bgp_attr_flush_encap(struct attr *attr);
* one for each NLRI that needs to be encoded into the UPDATE message, and
* finally the _end() function.
*/
-extern size_t bgp_packet_mpattr_start(struct stream *s, afi_t afi, safi_t safi,
- afi_t nh_afi,
+extern size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer,
+ afi_t afi, safi_t safi,
struct bpacket_attr_vec_arr *vecarr,
struct attr *attr);
extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c
index 5b24d4ec61..e565d0801b 100644
--- a/bgpd/bgp_attr_evpn.c
+++ b/bgpd/bgp_attr_evpn.c
@@ -1,22 +1,22 @@
/* Ethernet-VPN Attribute handling file
- Copyright (C) 2016 6WIND
-
-This file is part of FRRouting.
-
-FRRouting 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.
-
-FRRouting 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 FRRouting; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 2016 6WIND
+ *
+ * This file is part of FRRouting.
+ *
+ * FRRouting 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.
+ *
+ * FRRouting 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>
diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h
index 4b7d24de18..3a93f6ae62 100644
--- a/bgpd/bgp_attr_evpn.h
+++ b/bgpd/bgp_attr_evpn.h
@@ -1,22 +1,22 @@
/* E-VPN attribute handling structure file
- Copyright (C) 2016 6WIND
-
-This file is part of FRRouting.
-
-FRRouting 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.
-
-FRRouting 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 FRRouting; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 2016 6WIND
+ *
+ * This file is part of FRRouting.
+ *
+ * FRRouting 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.
+ *
+ * FRRouting 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 _QUAGGA_BGP_ATTR_EVPN_H
#define _QUAGGA_BGP_ATTR_EVPN_H
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c
index 0a06a57fe5..08cdee76f3 100644
--- a/bgpd/bgp_bfd.c
+++ b/bgpd/bgp_bfd.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
diff --git a/bgpd/bgp_bfd.h b/bgpd/bgp_bfd.h
index e872637e3e..e2c85af04a 100644
--- a/bgpd/bgp_bfd.h
+++ b/bgpd/bgp_bfd.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _QUAGGA_BGP_BFD_H
diff --git a/bgpd/bgp_btoa.c b/bgpd/bgp_btoa.c
index d3162a4ea5..be93448302 100644
--- a/bgpd/bgp_btoa.c
+++ b/bgpd/bgp_btoa.c
@@ -1,22 +1,22 @@
/* BGP dump to ascii converter
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index 3def97c73d..a61d63bb85 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -1,22 +1,22 @@
/* BGP community-list and extcommunity-list.
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -1158,16 +1158,13 @@ extcommunity_list_set (struct community_list_handler *ch,
}
}
- if (str)
- {
- if (style == EXTCOMMUNITY_LIST_STANDARD)
- ecom = ecommunity_str2com (str, 0, 1);
- else
- regex = bgp_regcomp (str);
+ if (style == EXTCOMMUNITY_LIST_STANDARD)
+ ecom = ecommunity_str2com (str, 0, 1);
+ else
+ regex = bgp_regcomp (str);
- if (! ecom && ! regex)
- return COMMUNITY_LIST_ERR_MALFORMED_VAL;
- }
+ if (! ecom && ! regex)
+ return COMMUNITY_LIST_ERR_MALFORMED_VAL;
if (ecom)
ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
@@ -1180,8 +1177,7 @@ extcommunity_list_set (struct community_list_handler *ch,
entry->config = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST, 0);
else if (regex)
entry->config = XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str);
- else
- entry->config = NULL;
+
entry->u.ecom = ecom;
entry->reg = regex;
diff --git a/bgpd/bgp_clist.h b/bgpd/bgp_clist.h
index 68e45c8f7b..114acde8ff 100644
--- a/bgpd/bgp_clist.h
+++ b/bgpd/bgp_clist.h
@@ -1,22 +1,22 @@
/* BGP Community list.
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_CLIST_H
#define _QUAGGA_BGP_CLIST_H
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index 17a3d2fdae..bd67829d77 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -1,22 +1,22 @@
/* Community attribute related functions.
- Copyright (C) 1998, 2001 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1998, 2001 Kunihiro Ishiguro
+ *
+ * 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 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>
diff --git a/bgpd/bgp_community.h b/bgpd/bgp_community.h
index 257f7767b4..cda079c130 100644
--- a/bgpd/bgp_community.h
+++ b/bgpd/bgp_community.h
@@ -1,22 +1,22 @@
/* Community attribute related functions.
- Copyright (C) 1998 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_COMMUNITY_H
#define _QUAGGA_BGP_COMMUNITY_H
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c
index 168dbd0122..dcb4519e1c 100644
--- a/bgpd/bgp_damp.c
+++ b/bgpd/bgp_damp.c
@@ -1,22 +1,22 @@
/* BGP flap dampening
- Copyright (C) 2001 IP Infusion 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. */
+ * Copyright (C) 2001 IP Infusion 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 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 <math.h>
@@ -116,8 +116,8 @@ bgp_reuse_timer (struct thread *t)
time_t t_now, t_diff;
damp->t_reuse = NULL;
- damp->t_reuse =
- thread_add_timer (bm->master, bgp_reuse_timer, NULL, DELTA_REUSE);
+ thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE,
+ &damp->t_reuse);
t_now = bgp_clock ();
@@ -447,9 +447,8 @@ bgp_damp_enable (struct bgp *bgp, afi_t afi, safi_t safi, time_t half,
bgp_damp_parameter_set (half, reuse, suppress, max);
/* Register reuse timer. */
- if (! damp->t_reuse)
- damp->t_reuse =
- thread_add_timer (bm->master, bgp_reuse_timer, NULL, DELTA_REUSE);
+ thread_add_timer(bm->master, bgp_reuse_timer, NULL, DELTA_REUSE,
+ &damp->t_reuse);
return 0;
}
diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h
index 030a621974..fe44d980b2 100644
--- a/bgpd/bgp_damp.h
+++ b/bgpd/bgp_damp.h
@@ -1,22 +1,22 @@
/* BGP flap dampening
- Copyright (C) 2001 IP Infusion 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. */
+ * Copyright (C) 2001 IP Infusion 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 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 _QUAGGA_BGP_DAMP_H
#define _QUAGGA_BGP_DAMP_H
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 232f53c778..f4722e62dc 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -1,22 +1,22 @@
/* BGP-4, BGP-4+ packet debug routine
- Copyright (C) 1996, 97, 99 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 99 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -383,7 +383,7 @@ bgp_debug_peer_updout_enabled(char *host)
/* Dump attribute. */
int
-bgp_dump_attr (struct peer *peer, struct attr *attr, char *buf, size_t size)
+bgp_dump_attr (struct attr *attr, char *buf, size_t size)
{
if (! attr)
return 0;
@@ -450,6 +450,13 @@ bgp_dump_attr (struct peer *peer, struct attr *attr, char *buf, size_t size)
snprintf (buf + strlen (buf), size - strlen (buf), ", path %s",
aspath_print (attr->aspath));
+ if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID)))
+ {
+ if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+ snprintf (buf + strlen (buf), size - strlen (buf), ", label-index %u",
+ attr->extra->label_index);
+ }
+
if (strlen (buf) > 1)
return 1;
else
diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h
index 0968568225..2912eb750d 100644
--- a/bgpd/bgp_debug.h
+++ b/bgpd/bgp_debug.h
@@ -1,22 +1,22 @@
/* BGP message debug header.
- Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_DEBUG_H
#define _QUAGGA_BGP_DEBUG_H
@@ -138,7 +138,7 @@ struct bgp_debug_filter
extern const char *bgp_type_str[];
-extern int bgp_dump_attr (struct peer *, struct attr *, char *, size_t);
+extern int bgp_dump_attr (struct attr *, char *, size_t);
extern int bgp_debug_peer_updout_enabled(char *host);
extern const char *bgp_notify_code_str(char);
extern const char *bgp_notify_subcode_str(char, char);
diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c
index 84ece48850..bf26fddf9c 100644
--- a/bgpd/bgp_dump.c
+++ b/bgpd/bgp_dump.c
@@ -1,22 +1,22 @@
/* BGP-4 dump routine
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -171,14 +171,16 @@ bgp_dump_interval_add (struct bgp_dump *bgp_dump, int interval)
secs_into_day = tm->tm_sec + 60*tm->tm_min + 60*60*tm->tm_hour;
interval = interval - secs_into_day % interval; /* always > 0 */
}
- bgp_dump->t_interval = thread_add_timer (bm->master, bgp_dump_interval_func,
- bgp_dump, interval);
+ bgp_dump->t_interval = NULL;
+ thread_add_timer(bm->master, bgp_dump_interval_func, bgp_dump, interval,
+ &bgp_dump->t_interval);
}
else
{
/* One-off dump: execute immediately, don't affect any scheduled dumps */
- bgp_dump->t_interval = thread_add_event (bm->master, bgp_dump_interval_func,
- bgp_dump, 0);
+ bgp_dump->t_interval = NULL;
+ thread_add_event(bm->master, bgp_dump_interval_func, bgp_dump, 0,
+ &bgp_dump->t_interval);
}
return 0;
@@ -624,7 +626,7 @@ bgp_dump_parse_time (const char *str)
return 0;
total += time * 60;
time = 0;
- seen_h = 1;
+ seen_m = 1;
}
else
return 0;
diff --git a/bgpd/bgp_dump.h b/bgpd/bgp_dump.h
index d1e66d91c3..a54388fef2 100644
--- a/bgpd/bgp_dump.h
+++ b/bgpd/bgp_dump.h
@@ -1,22 +1,22 @@
/* BGP dump routine.
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_DUMP_H
#define _QUAGGA_BGP_DUMP_H
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index c80966ec6d..fa1ad813f1 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -1,22 +1,22 @@
/* BGP Extended Communities Attribute
- Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
-
-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. */
+ * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
+ *
+ * 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 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>
diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h
index 356598f6b1..d6006e81d5 100644
--- a/bgpd/bgp_ecommunity.h
+++ b/bgpd/bgp_ecommunity.h
@@ -1,22 +1,22 @@
/* BGP Extended Communities Attribute.
- Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
-
-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. */
+ * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
+ *
+ * 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 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 _QUAGGA_BGP_ECOMMUNITY_H
#define _QUAGGA_BGP_ECOMMUNITY_H
diff --git a/bgpd/bgp_encap.c b/bgpd/bgp_encap.c
index 01df053952..a1a0c1710b 100644
--- a/bgpd/bgp_encap.c
+++ b/bgpd/bgp_encap.c
@@ -1,32 +1,26 @@
-
/*
* This file created by LabN Consulting, L.L.C.
*
- *
* This file is based on bgp_mplsvpn.c which is Copyright (C) 2000
* Kunihiro Ishiguro <kunihiro@zebra.org>
*
+ * 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 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
*/
-/*
-
-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.h"
diff --git a/bgpd/bgp_encap.h b/bgpd/bgp_encap.h
index 4d57fca79d..2805dd3e1d 100644
--- a/bgpd/bgp_encap.h
+++ b/bgpd/bgp_encap.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_ENCAP_H
diff --git a/bgpd/bgp_encap_tlv.c b/bgpd/bgp_encap_tlv.c
index 7acd23b9ae..eee2cb72c3 100644
--- a/bgpd/bgp_encap_tlv.c
+++ b/bgpd/bgp_encap_tlv.c
@@ -11,10 +11,9 @@
* 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.
- *
+ * 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>
diff --git a/bgpd/bgp_encap_tlv.h b/bgpd/bgp_encap_tlv.h
index d94d544d26..487762714c 100644
--- a/bgpd/bgp_encap_tlv.h
+++ b/bgpd/bgp_encap_tlv.h
@@ -11,10 +11,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_ENCAP_TLV_H
diff --git a/bgpd/bgp_encap_types.h b/bgpd/bgp_encap_types.h
index 04c0d2f235..ffeb2f61ea 100644
--- a/bgpd/bgp_encap_types.h
+++ b/bgpd/bgp_encap_types.h
@@ -11,10 +11,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_ENCAP_TYPES_H
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 612f49f1cb..c5a0ef8893 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -1,22 +1,22 @@
/* Ethernet-VPN Packet and vty Processing File
- Copyright (C) 2016 6WIND
-
-This file is part of FRRouting.
-
-FRRouting 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.
-
-FRRouting 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 FRRouting; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 2016 6WIND
+ *
+ * This file is part of FRRouting.
+ *
+ * FRRouting 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.
+ *
+ * FRRouting 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>
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index 9b24bb066a..95d4280150 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -1,22 +1,22 @@
/* E-VPN header for packet handling
- Copyright (C) 2016 6WIND
-
-This file is part of FRRouting.
-
-FRRouting 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.
-
-FRRouting 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 FRRouting; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 2016 6WIND
+ *
+ * This file is part of FRRouting.
+ *
+ * FRRouting 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.
+ *
+ * FRRouting 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 _QUAGGA_BGP_EVPN_H
#define _QUAGGA_BGP_EVPN_H
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index a51affc4f7..e91a6d9bfd 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -1,22 +1,22 @@
/* Ethernet-VPN Packet and vty Processing File
- Copyright (C) 2017 6WIND
-
-This file is part of FRRouting
-
-FRRouting 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.
-
-FRRouting 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 FRRouting; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 2017 6WIND
+ *
+ * This file is part of FRRouting
+ *
+ * FRRouting 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.
+ *
+ * FRRouting 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 "command.h"
diff --git a/bgpd/bgp_evpn_vty.h b/bgpd/bgp_evpn_vty.h
index 68b5f5cfbf..fe01e84e2b 100644
--- a/bgpd/bgp_evpn_vty.h
+++ b/bgpd/bgp_evpn_vty.h
@@ -1,22 +1,22 @@
/* EVPN VTY functions to EVPN
- Copyright (C) 2017 6WIND
-
-This file is part of FRRouting.
-
-FRRouting 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.
-
-FRRouting 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 FRRouting; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 2017 6WIND
+ *
+ * This file is part of FRRouting.
+ *
+ * FRRouting 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.
+ *
+ * FRRouting 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 _FRR_BGP_EVPN_VTY_H
#define _FRR_BGP_EVPN_VTY_H
diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c
index 0de2663dd4..31fc39fd23 100644
--- a/bgpd/bgp_filter.c
+++ b/bgpd/bgp_filter.c
@@ -1,22 +1,22 @@
/* AS path filter list.
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
diff --git a/bgpd/bgp_filter.h b/bgpd/bgp_filter.h
index 03447942d4..e3ce7a1c1d 100644
--- a/bgpd/bgp_filter.h
+++ b/bgpd/bgp_filter.h
@@ -1,22 +1,22 @@
/* AS path filter list.
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_FILTER_H
#define _QUAGGA_BGP_FILTER_H
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 424eec55c4..a25e0be22d 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1,23 +1,23 @@
/* BGP-4 Finite State Machine
- From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
- Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
-
-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. */
+ * From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
+ * Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -808,9 +808,8 @@ bgp_maxmed_onstartup_begin (struct bgp *bgp)
zlog_info ("Begin maxmed onstartup mode - timer %d seconds",
bgp->v_maxmed_onstartup);
- THREAD_TIMER_ON (bm->master, bgp->t_maxmed_onstartup,
- bgp_maxmed_onstartup_timer,
- bgp, bgp->v_maxmed_onstartup);
+ thread_add_timer(bm->master, bgp_maxmed_onstartup_timer, bgp,
+ bgp->v_maxmed_onstartup, &bgp->t_maxmed_onstartup);
if (!bgp->v_maxmed_admin)
{
@@ -877,12 +876,12 @@ bgp_update_delay_begin (struct bgp *bgp)
peer->update_delay_over = 0;
/* Start the update-delay timer */
- THREAD_TIMER_ON (bm->master, bgp->t_update_delay, bgp_update_delay_timer,
- bgp, bgp->v_update_delay);
+ thread_add_timer(bm->master, bgp_update_delay_timer, bgp,
+ bgp->v_update_delay, &bgp->t_update_delay);
if (bgp->v_establish_wait != bgp->v_update_delay)
- THREAD_TIMER_ON (bm->master, bgp->t_establish_wait, bgp_establish_wait_timer,
- bgp, bgp->v_establish_wait);
+ thread_add_timer(bm->master, bgp_establish_wait_timer, bgp,
+ bgp->v_establish_wait, &bgp->t_establish_wait);
quagga_timestamp(3, bgp->update_delay_begin_time,
sizeof(bgp->update_delay_begin_time));
@@ -1026,7 +1025,7 @@ bgp_stop (struct peer *peer)
zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
peer->host,
(peer->hostname) ? peer->hostname : "Unknown",
- (vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default",
+ vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default") : "",
peer_down_str [(int) peer->last_reset]);
}
@@ -1148,9 +1147,11 @@ bgp_stop (struct peer *peer)
/* Reset prefix count */
peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
+ peer->pcount[AFI_IP][SAFI_LABELED_UNICAST] = 0;
peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
+ peer->pcount[AFI_IP6][SAFI_LABELED_UNICAST] = 0;
#endif /* 0 */
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) &&
diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h
index 4d0b48f529..33cba868ee 100644
--- a/bgpd/bgp_fsm.h
+++ b/bgpd/bgp_fsm.h
@@ -1,80 +1,80 @@
/* BGP-4 Finite State Machine
- From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
- Copyright (C) 1998 Kunihiro Ishiguro
-
-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. */
+ * From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_FSM_H
#define _QUAGGA_BGP_FSM_H
/* Macro for BGP read, write and timer thread. */
-#define BGP_READ_ON(T,F,V) \
- do { \
- if (!(T) && (peer->status != Deleted)) \
- THREAD_READ_ON(bm->master,T,F,peer,V); \
+#define BGP_READ_ON(T,F,V) \
+ do { \
+ if ((peer->status != Deleted)) \
+ thread_add_read (bm->master,(F),peer,(V),&(T)); \
} while (0)
-#define BGP_READ_OFF(T) \
- do { \
- if (T) \
- THREAD_READ_OFF(T); \
+#define BGP_READ_OFF(T) \
+ do { \
+ if (T) \
+ THREAD_READ_OFF(T); \
} while (0)
-#define BGP_WRITE_ON(T,F,V) \
- do { \
- if (!(T) && (peer->status != Deleted)) \
- THREAD_WRITE_ON(bm->master,(T),(F),peer,(V)); \
+#define BGP_WRITE_ON(T,F,V) \
+ do { \
+ if ((peer)->status != Deleted) \
+ thread_add_write (bm->master,(F),(peer),(V),&(T)); \
} while (0)
-#define BGP_PEER_WRITE_ON(T,F,V, peer) \
- do { \
- if (!(T) && ((peer)->status != Deleted)) \
- THREAD_WRITE_ON(bm->master,(T),(F),(peer),(V)); \
+#define BGP_PEER_WRITE_ON(T,F,V, peer) \
+ do { \
+ if ((peer)->status != Deleted) \
+ thread_add_write (bm->master,(F),(peer),(V),&(T)); \
} while (0)
-#define BGP_WRITE_OFF(T) \
- do { \
- if (T) \
- THREAD_WRITE_OFF(T); \
+#define BGP_WRITE_OFF(T) \
+ do { \
+ if (T) \
+ THREAD_WRITE_OFF(T); \
} while (0)
-#define BGP_TIMER_ON(T,F,V) \
- do { \
- if (!(T) && (peer->status != Deleted)) \
- THREAD_TIMER_ON(bm->master,(T),(F),peer,(V)); \
+#define BGP_TIMER_ON(T,F,V) \
+ do { \
+ if ((peer->status != Deleted)) \
+ thread_add_timer (bm->master,(F),peer,(V),&(T)); \
} while (0)
-#define BGP_TIMER_OFF(T) \
- do { \
- if (T) \
- THREAD_TIMER_OFF(T); \
+#define BGP_TIMER_OFF(T) \
+ do { \
+ if (T) \
+ THREAD_TIMER_OFF(T); \
} while (0)
-#define BGP_EVENT_ADD(P,E) \
- do { \
- if ((P)->status != Deleted) \
- thread_add_event (bm->master, bgp_event, (P), (E)); \
+#define BGP_EVENT_ADD(P,E) \
+ do { \
+ if ((P)->status != Deleted) \
+ thread_add_event (bm->master, bgp_event, (P), (E), NULL); \
} while (0)
-#define BGP_EVENT_FLUSH(P) \
- do { \
- assert (peer); \
- thread_cancel_event (bm->master, (P)); \
+#define BGP_EVENT_FLUSH(P) \
+ do { \
+ assert (peer); \
+ thread_cancel_event (bm->master, (P)); \
} while (0)
#define BGP_MSEC_JITTER 10
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
new file mode 100644
index 0000000000..0798515ebb
--- /dev/null
+++ b/bgpd/bgp_label.c
@@ -0,0 +1,341 @@
+/* BGP carrying label information
+ * Copyright (C) 2013 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 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 "command.h"
+#include "thread.h"
+#include "prefix.h"
+#include "zclient.h"
+#include "stream.h"
+#include "network.h"
+#include "log.h"
+#include "memory.h"
+#include "nexthop.h"
+#include "mpls.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_table.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_label.h"
+#include "bgpd/bgp_packet.h"
+#include "bgpd/bgp_debug.h"
+
+extern struct zclient *zclient;
+
+int
+bgp_parse_fec_update (void)
+{
+ struct stream *s;
+ struct bgp_node *rn;
+ struct bgp *bgp;
+ struct bgp_table *table;
+ struct prefix p;
+ u_int32_t label;
+ afi_t afi;
+ safi_t safi;
+
+ s = zclient->ibuf;
+
+ memset(&p, 0, sizeof(struct prefix));
+ p.family = stream_getw(s);
+ p.prefixlen = stream_getc(s);
+ stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
+ label = stream_getl(s);
+
+ /* hack for the bgp instance & SAFI = have to send/receive it */
+ afi = family2afi(p.family);
+ safi = SAFI_LABELED_UNICAST;
+ bgp = bgp_get_default();
+ if (!bgp)
+ {
+ zlog_debug("no default bgp instance");
+ return -1;
+ }
+
+ table = bgp->rib[afi][safi];
+ if (!table)
+ {
+ zlog_debug("no %u labeled-unicast table", p.family);
+ return -1;
+ }
+ rn = bgp_node_lookup(table, &p);
+ if (!rn)
+ {
+ zlog_debug("no node for the prefix");
+ return -1;
+ }
+
+ /* treat it as implicit withdraw - the label is invalid */
+ if (label == MPLS_INVALID_LABEL)
+ bgp_unset_valid_label(rn->local_label);
+ else
+ {
+ label_ntop(label, 1, rn->local_label);
+ bgp_set_valid_label(rn->local_label);
+ }
+ SET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
+ bgp_unlock_node (rn);
+ bgp_process (bgp, rn, afi, safi);
+ return 1;
+}
+
+u_char *
+bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to,
+ afi_t afi, safi_t safi)
+{
+ struct peer *from;
+ u_char *remote_label;
+ int reflect;
+
+ if (!rn || !ri || !to)
+ return NULL;
+
+ remote_label = ri->extra ? ri->extra->tag : NULL;
+ from = ri->peer;
+ reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
+
+ if (reflect && !CHECK_FLAG(to->af_flags[afi][safi],
+ PEER_FLAG_FORCE_NEXTHOP_SELF))
+ return remote_label;
+
+ if (CHECK_FLAG(to->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED))
+ return remote_label;
+
+ return rn->local_label;
+}
+
+void
+bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
+ int reg)
+{
+ struct stream *s;
+ struct prefix *p;
+ int command;
+ u_int16_t flags = 0;
+ size_t flags_pos = 0;
+
+ /* Check socket. */
+ if (!zclient || zclient->sock < 0)
+ return;
+
+ p = &(rn->p);
+ s = zclient->obuf;
+ stream_reset (s);
+ command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER;
+ zclient_create_header (s, command, VRF_DEFAULT);
+ flags_pos = stream_get_endp (s); /* save position of 'flags' */
+ stream_putw(s, flags); /* initial flags */
+ stream_putw(s, PREFIX_FAMILY(p));
+ stream_put_prefix(s, p);
+ if (reg)
+ {
+ assert (ri);
+ if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
+ {
+ assert (ri->attr->extra);
+
+ if (ri->attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
+ stream_putl (s, ri->attr->extra->label_index);
+ }
+ }
+ SET_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
+ }
+ else
+ UNSET_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
+
+ /* Set length and flags */
+ stream_putw_at (s, 0, stream_get_endp (s));
+ stream_putw_at (s, flags_pos, flags);
+
+ zclient_send_message(zclient);
+}
+
+static int
+bgp_nlri_get_labels (struct peer *peer, u_char *pnt, u_char plen,
+ u_char label[])
+{
+ u_char *data = pnt;
+ u_char *lim = pnt + plen;
+ u_char llen = 0;
+
+ for (; data < lim; data += BGP_LABEL_BYTES)
+ {
+ memcpy(label, data, BGP_LABEL_BYTES);
+ llen += 3;
+ if (bgp_is_withdraw_label(label) || label_bos(label))
+ break;
+ }
+ if (!(bgp_is_withdraw_label(label) || label_bos(label)))
+ zlog_warn("%s: [Update:RCVD] invalid label - no bottom of stack",
+ peer->host);
+
+ return llen;
+}
+
+int
+bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
+ struct bgp_nlri *packet)
+{
+ u_char *pnt;
+ u_char *lim;
+ struct prefix p;
+ int psize = 0;
+ int prefixlen;
+ afi_t afi;
+ safi_t safi;
+ int addpath_encoded;
+ u_int32_t addpath_id;
+ u_char label[3];
+ u_char llen;
+
+ /* Check peer status. */
+ if (peer->status != Established)
+ return 0;
+
+ pnt = packet->nlri;
+ lim = pnt + packet->length;
+ afi = packet->afi;
+ safi = packet->safi;
+ addpath_id = 0;
+
+ addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
+ CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
+
+ for (; pnt < lim; pnt += psize)
+ {
+ /* Clear prefix structure. */
+ memset (&p, 0, sizeof (struct prefix));
+ llen = 0;
+
+ if (addpath_encoded)
+ {
+
+ /* When packet overflow occurs return immediately. */
+ if (pnt + BGP_ADDPATH_ID_LEN > lim)
+ return -1;
+
+ addpath_id = ntohl(*((uint32_t*) pnt));
+ pnt += BGP_ADDPATH_ID_LEN;
+ }
+
+ /* Fetch prefix length. */
+ prefixlen = *pnt++;
+ p.family = afi2family (packet->afi);
+ psize = PSIZE (prefixlen);
+
+ /* sanity check against packet data */
+ if ((pnt + psize) > lim)
+ {
+ zlog_err ("%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
+ peer->host,
+ prefixlen, (uint)(lim-pnt));
+ return -1;
+ }
+
+ /* Fill in the labels */
+ llen = bgp_nlri_get_labels(peer, pnt, psize, label);
+ // zlog_debug("rcvd label [%x/%x/%x], llen=%d\n", label[0], label[1], label[2], llen);
+ p.prefixlen = prefixlen - BSIZE(llen);
+
+ /* There needs to be at least one label */
+ if (prefixlen < 24)
+ {
+ zlog_err ("%s [Error] Update packet error"
+ " (wrong label length %d)",
+ peer->host, prefixlen);
+ bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+ return -1;
+ }
+
+ if ((afi == AFI_IP && p.prefixlen > 32)
+ || (afi == AFI_IP6 && p.prefixlen > 128))
+ return -1;
+
+ /* Fetch prefix from NLRI packet */
+ memcpy (&p.u.prefix, pnt + llen, psize - llen);
+
+ /* Check address. */
+ if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
+ {
+ if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
+ {
+ /* From RFC4271 Section 6.3:
+ *
+ * If a prefix in the NLRI field is semantically incorrect
+ * (e.g., an unexpected multicast IP address), an error SHOULD
+ * be logged locally, and the prefix SHOULD be ignored.
+ */
+ zlog_err ("%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
+ peer->host, inet_ntoa (p.u.prefix4));
+ continue;
+ }
+ }
+
+ /* Check address. */
+ if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
+ {
+ if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
+ {
+ char buf[BUFSIZ];
+
+ zlog_err ("%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring",
+ peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
+
+ continue;
+ }
+
+ if (IN6_IS_ADDR_MULTICAST (&p.u.prefix6))
+ {
+ char buf[BUFSIZ];
+
+ zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
+ peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
+
+ continue;
+ }
+ }
+
+ if (attr)
+ {
+ bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_LABELED_UNICAST,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label, 0, NULL);
+ }
+ else
+ {
+ bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_LABELED_UNICAST,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label, NULL);
+ }
+ }
+
+ /* Packet length consistency check. */
+ if (pnt != lim)
+ {
+ zlog_err ("%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
+ peer->host, lim - pnt);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h
new file mode 100644
index 0000000000..dbc675dd43
--- /dev/null
+++ b/bgpd/bgp_label.h
@@ -0,0 +1,125 @@
+/* BGP carrying Label information
+ * Copyright (C) 2013 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 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 _BGP_LABEL_H
+#define _BGP_LABEL_H
+
+#define BGP_LABEL_BYTES 3
+#define BGP_LABEL_BITS 24
+#define BGP_WITHDRAW_LABEL 0x800000
+
+struct bgp_node;
+struct bgp_info;
+struct peer;
+
+extern void bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
+ int reg);
+extern int bgp_parse_fec_update(void);
+extern u_char * bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
+ struct peer *to, afi_t afi, safi_t safi);
+
+extern int bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
+ struct bgp_nlri *packet);
+
+static inline int
+bgp_labeled_safi (safi_t safi)
+{
+ if ((safi == SAFI_LABELED_UNICAST) || (safi == SAFI_MPLS_VPN) ||
+ (safi == SAFI_EVPN))
+ return 1;
+ return 0;
+}
+
+static inline int
+bgp_is_withdraw_label (u_char *pkt)
+{
+ if ((pkt[0] == 0x80) && (pkt[1] == 0x00) && (pkt[2] == 0x00))
+ return 1;
+ return 0;
+}
+
+static inline u_char *
+bgp_encode_withdraw_label (u_char *pkt)
+{
+ *pkt++ = 0x80; *pkt++ = 0x00; *pkt++ = 0x00;
+ return pkt;
+}
+
+static inline int
+bgp_is_valid_label (u_char *t)
+{
+ if (!t)
+ return 0;
+ return (t[2] & 0x02);
+}
+
+static inline void
+bgp_set_valid_label (u_char *t)
+{
+ if (t)
+ t[2] |= 0x02;
+}
+
+static inline void
+bgp_unset_valid_label (u_char *t)
+{
+ if (t)
+ t[2] &= ~0x02;
+}
+
+static inline void
+bgp_register_for_label (struct bgp_node *rn, struct bgp_info *ri)
+{
+ bgp_reg_dereg_for_label (rn, ri, 1);
+}
+
+static inline void
+bgp_unregister_for_label (struct bgp_node *rn)
+{
+ bgp_reg_dereg_for_label (rn, NULL, 0);
+}
+
+/* Label stream to value */
+static inline u_int32_t
+label_pton (u_char t[])
+{
+ return ((((unsigned int) t[0]) << 12) | (((unsigned int) t[1]) << 4) |
+ ((unsigned int) ((t[2] & 0xF0) >> 4)));
+}
+
+/* Encode label values */
+static inline void
+label_ntop (u_int32_t l, int bos, u_char t[])
+{
+ t[0] = ((l & 0x000FF000) >> 12);
+ t[1] = ((l & 0x00000FF0) >> 4);
+ t[2] = ((l & 0x0000000F) << 4);
+ if (bos)
+ t[2] |= 0x01;
+}
+
+/* Return BOS value of label stream */
+static inline u_char
+label_bos (u_char t[])
+{
+ return (t[2] & 0x01);
+};
+
+#endif /* _BGP_LABEL_H */
diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c
index 549a2ebad8..4a969c8b90 100644
--- a/bgpd/bgp_lcommunity.c
+++ b/bgpd/bgp_lcommunity.c
@@ -14,8 +14,8 @@
* 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.
+ * 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>
diff --git a/bgpd/bgp_lcommunity.h b/bgpd/bgp_lcommunity.h
index de3697f477..e401c8d8f3 100644
--- a/bgpd/bgp_lcommunity.h
+++ b/bgpd/bgp_lcommunity.h
@@ -14,8 +14,8 @@
* 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.
+ * 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 _QUAGGA_BGP_LCOMMUNITY_H
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 1773070fe3..8714820e2a 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -1,22 +1,22 @@
/* Main routine of bgpd.
- Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -237,6 +237,8 @@ bgp_exit (int status)
stream_free (bgp_nexthop_buf);
if (bgp_ifindices_buf)
stream_free (bgp_ifindices_buf);
+ if (bgp_label_buf)
+ stream_free (bgp_label_buf);
/* reverse bgp_master_init */
if (bm->master)
@@ -325,22 +327,15 @@ bgp_vrf_disable (struct vrf *vrf)
static void
bgp_vrf_init (void)
{
- vrf_add_hook (VRF_NEW_HOOK, bgp_vrf_new);
- vrf_add_hook (VRF_ENABLE_HOOK, bgp_vrf_enable);
- vrf_add_hook (VRF_DISABLE_HOOK, bgp_vrf_disable);
- vrf_add_hook (VRF_DELETE_HOOK, bgp_vrf_delete);
-
- vrf_init ();
+ vrf_init (bgp_vrf_new,
+ bgp_vrf_enable,
+ bgp_vrf_disable,
+ bgp_vrf_delete);
}
static void
bgp_vrf_terminate (void)
{
- vrf_add_hook (VRF_NEW_HOOK, NULL);
- vrf_add_hook (VRF_ENABLE_HOOK, NULL);
- vrf_add_hook (VRF_DISABLE_HOOK, NULL);
- vrf_add_hook (VRF_DELETE_HOOK, NULL);
-
vrf_terminate ();
}
diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c
index 85e32645ee..c457f4b3e9 100644
--- a/bgpd/bgp_memory.c
+++ b/bgpd/bgp_memory.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
#ifdef HAVE_CONFIG_H
diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h
index 341fb235d0..454092cef3 100644
--- a/bgpd/bgp_memory.h
+++ b/bgpd/bgp_memory.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_BGP_MEMORY_H
diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index a95c4a008e..34690ac776 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/bgpd/bgp_mpath.h b/bgpd/bgp_mpath.h
index 9a38b5943d..316dda3ec6 100644
--- a/bgpd/bgp_mpath.h
+++ b/bgpd/bgp_mpath.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_BGP_MPATH_H
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 60a48f506b..2d13d05c00 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1,22 +1,22 @@
/* MPLS-VPN
- Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
-
-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. */
+ * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
+ *
+ * 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 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>
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 518bf6143f..d5378a9d37 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -1,22 +1,22 @@
/* MPLS-VPN
- Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
-
-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. */
+ * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
+ *
+ * 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 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 _QUAGGA_BGP_MPLSVPN_H
#define _QUAGGA_BGP_MPLSVPN_H
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 46ae882b2e..70da5e176f 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -1,22 +1,22 @@
/* BGP network related fucntions
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -297,7 +297,9 @@ bgp_accept (struct thread *thread)
zlog_err ("accept_sock is nevative value %d", accept_sock);
return -1;
}
- listener->thread = thread_add_read (bm->master, bgp_accept, listener, accept_sock);
+ listener->thread = NULL;
+ thread_add_read(bm->master, bgp_accept, listener, accept_sock,
+ &listener->thread);
/* Accept client connection. */
bgp_sock = sockunion_accept (accept_sock, &su);
@@ -704,7 +706,8 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
listener = XMALLOC (MTYPE_BGP_LISTENER, sizeof(*listener));
listener->fd = sock;
memcpy(&listener->su, sa, salen);
- listener->thread = thread_add_read (bm->master, bgp_accept, listener, sock);
+ listener->thread = NULL;
+ thread_add_read(bm->master, bgp_accept, listener, sock, &listener->thread);
listnode_add (bm->listen_sockets, listener);
return 0;
diff --git a/bgpd/bgp_network.h b/bgpd/bgp_network.h
index 1148d1978b..56938b4374 100644
--- a/bgpd/bgp_network.h
+++ b/bgpd/bgp_network.h
@@ -1,22 +1,22 @@
/* BGP network related header
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_NETWORK_H
#define _QUAGGA_BGP_NETWORK_H
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 9300345899..132b754104 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -1,22 +1,22 @@
/* BGP nexthop scan
- Copyright (C) 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 2000 Kunihiro Ishiguro
+ *
+ * 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 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>
diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h
index 652a6813ee..c5d9232e33 100644
--- a/bgpd/bgp_nexthop.h
+++ b/bgpd/bgp_nexthop.h
@@ -1,22 +1,22 @@
/* BGP nexthop scan
- Copyright (C) 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 2000 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_NEXTHOP_H
#define _QUAGGA_BGP_NEXTHOP_H
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index b0362b5537..341bb0abb5 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -404,8 +403,9 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
{
char buf[PREFIX2STR_BUFFER];
prefix2str(&p, buf, sizeof (buf));
- zlog_debug("%d: NH update for %s - metric %d (cur %d) #nhops %d (cur %d)",
- vrf_id, buf, metric, bnc->metric, nexthop_num, bnc->nexthop_num);
+ zlog_debug("%d: Rcvd NH update %s - metric %d/%d #nhops %d/%d flags 0x%x",
+ vrf_id, buf, metric, bnc->metric, nexthop_num, bnc->nexthop_num,
+ bnc->flags);
}
if (metric != bnc->metric)
@@ -678,6 +678,8 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
struct bgp *bgp = bnc->bgp;
int afi;
struct peer *peer = (struct peer *)bnc->nht_info;
+ struct bgp_table *table;
+ safi_t safi;
if (BGP_DEBUG(nht, NHT))
{
@@ -695,7 +697,10 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
continue;
rn = path->net;
+ assert (rn && bgp_node_table (rn));
afi = family2afi(rn->p.family);
+ table = bgp_node_table (rn);
+ safi = table->safi;
/* Path becomes valid/invalid depending on whether the nexthop
* reachable/unreachable.
@@ -705,15 +710,13 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
{
if (CHECK_FLAG (path->flags, BGP_INFO_VALID))
{
- bgp_aggregate_decrement (bgp, &rn->p, path,
- afi, SAFI_UNICAST);
+ bgp_aggregate_decrement (bgp, &rn->p, path, afi, safi);
bgp_info_unset_flag (rn, path, BGP_INFO_VALID);
}
else
{
bgp_info_set_flag (rn, path, BGP_INFO_VALID);
- bgp_aggregate_increment (bgp, &rn->p, path,
- afi, SAFI_UNICAST);
+ bgp_aggregate_increment (bgp, &rn->p, path, afi, safi);
}
}
@@ -727,7 +730,7 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
SET_FLAG(path->flags, BGP_INFO_IGP_CHANGED);
- bgp_process(bgp, rn, afi, SAFI_UNICAST);
+ bgp_process(bgp, rn, afi, safi);
}
if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED))
diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h
index 02a7e5a45c..3497dc8565 100644
--- a/bgpd/bgp_nht.h
+++ b/bgpd/bgp_nht.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _BGP_NHT_H
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 51079f31e0..4374729668 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -1,22 +1,22 @@
/* BGP open message handling
- Copyright (C) 1998, 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1998, 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -108,6 +108,9 @@ 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_LABELED_UNICAST:
+ json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "labeled-unicast");
+ break;
case SAFI_MPLS_VPN:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "MPLS-labeled VPN");
break;
@@ -148,6 +151,9 @@ 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_LABELED_UNICAST:
+ vty_out (vty, "SAFI Labeled-unicast");
+ break;
case SAFI_MPLS_VPN:
vty_out (vty, "SAFI MPLS-labeled VPN");
break;
@@ -588,11 +594,11 @@ bgp_capability_enhe (struct peer *peer, struct capability_header *hdr)
/* RFC 5549 specifies use of this capability only for IPv4 AFI, with
* the Nexthop AFI being IPv6. A future spec may introduce other
* possibilities, so we ignore other values with a log. Also, only
- * Unicast SAFI is currently supported (and expected).
+ * SAFI_UNICAST and SAFI_LABELED_UNICAST are currently supported (and expected).
*/
nh_afi = afi_iana2int (pkt_nh_afi);
- if (afi != AFI_IP || safi != SAFI_UNICAST || nh_afi != AFI_IP6)
+ if (afi != AFI_IP || nh_afi != AFI_IP6 || !(safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
{
zlog_warn ("%s Unexpected afi/safi/next-hop afi: %u/%u/%u "
"in Extended Next-hop capability, ignoring",
@@ -1143,10 +1149,12 @@ bgp_open_option_parse (struct peer *peer, u_char length, int *mp_capability)
{
if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
&& ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
+ && ! peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
&& ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
&& ! peer->afc_nego[AFI_IP][SAFI_ENCAP]
&& ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
&& ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
+ && ! peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
&& ! peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
&& ! peer->afc_nego[AFI_IP6][SAFI_ENCAP]
&& ! peer->afc_nego[AFI_L2VPN][SAFI_EVPN])
@@ -1280,32 +1288,34 @@ bgp_open_capability (struct stream *s, struct peer *peer)
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) &&
+ afi == AFI_IP &&
+ (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
+ {
+ /* RFC 5549 Extended Next Hop Encoding */
+ SET_FLAG (peer->cap, PEER_CAP_ENHE_ADV);
+ stream_putc (s, BGP_OPEN_OPT_CAP);
+ stream_putc (s, CAPABILITY_CODE_ENHE_LEN + 2);
+ stream_putc (s, CAPABILITY_CODE_ENHE);
+ stream_putc (s, CAPABILITY_CODE_ENHE_LEN);
+
+ SET_FLAG (peer->af_cap[AFI_IP][safi], PEER_CAP_ENHE_AF_ADV);
+ stream_putw (s, pkt_afi);
+ stream_putw (s, pkt_safi);
+ stream_putw (s, afi_int2iana(AFI_IP6));
+
+ if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_RCV))
+ SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_NEGO);
+ }
}
}
- /* 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))
- {
- /* RFC 5549 Extended Next Hop Encoding */
- SET_FLAG (peer->cap, PEER_CAP_ENHE_ADV);
- stream_putc (s, BGP_OPEN_OPT_CAP);
- stream_putc (s, CAPABILITY_CODE_ENHE_LEN + 2);
- stream_putc (s, CAPABILITY_CODE_ENHE);
- stream_putc (s, CAPABILITY_CODE_ENHE_LEN);
- /* Currently supporting for SAFI_UNICAST only */
- SET_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_ADV);
- stream_putw (s, AFI_IP);
- stream_putw (s, SAFI_UNICAST);
- stream_putw (s, AFI_IP6);
-
- 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);
- }
-
/* Route refresh. */
SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
stream_putc (s, BGP_OPEN_OPT_CAP);
diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h
index 9275b3a101..459b966dd2 100644
--- a/bgpd/bgp_open.h
+++ b/bgpd/bgp_open.h
@@ -1,22 +1,22 @@
/* BGP open message handling
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_OPEN_H
#define _QUAGGA_BGP_OPEN_H
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 853fcc8697..126a920944 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1,22 +1,22 @@
/* BGP packet management routine.
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -55,6 +55,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_updgrp.h"
+#include "bgpd/bgp_label.h"
/* Set up BGP packet marker and packet type. */
int
@@ -1128,7 +1129,10 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
else
peer->v_holdtime = send_holdtime;
- peer->v_keepalive = peer->v_holdtime / 3;
+ if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
+ peer->v_keepalive = peer->keepalive;
+ else
+ peer->v_keepalive = peer->v_holdtime / 3;
/* Open option part parse. */
if (optlen != 0)
@@ -1153,8 +1157,10 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
{
peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
+ peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] = peer->afc[AFI_IP][SAFI_LABELED_UNICAST];
peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
+ peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST] = peer->afc[AFI_IP6][SAFI_LABELED_UNICAST];
}
/* When collision is detected and this peer is closed. Retrun
@@ -1342,6 +1348,8 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet, i
case SAFI_UNICAST:
case SAFI_MULTICAST:
return bgp_nlri_parse_ip (peer, mp_withdraw?NULL:attr, packet);
+ case SAFI_LABELED_UNICAST:
+ return bgp_nlri_parse_label (peer, mp_withdraw?NULL:attr, packet);
case SAFI_MPLS_VPN:
return bgp_nlri_parse_vpn (peer, mp_withdraw?NULL:attr, packet);
case SAFI_ENCAP:
@@ -1386,6 +1394,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
/* Set initial values. */
memset (&attr, 0, sizeof (struct attr));
memset (&extra, 0, sizeof (struct attr_extra));
+ extra.label_index = BGP_INVALID_LABEL_INDEX;
memset (&nlris, 0, sizeof (nlris));
attr.extra = &extra;
memset (peer->rcvd_attr_str, 0, BUFSIZ);
@@ -1487,7 +1496,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
BGP_DEBUG (update, UPDATE_IN) ||
BGP_DEBUG (update, UPDATE_PREFIX))
{
- ret = bgp_dump_attr (peer, &attr, peer->rcvd_attr_str, BUFSIZ);
+ ret = bgp_dump_attr (&attr, peer->rcvd_attr_str, BUFSIZ);
if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
zlog_err ("%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
diff --git a/bgpd/bgp_packet.h b/bgpd/bgp_packet.h
index ea5c7a8998..f7beaf4949 100644
--- a/bgpd/bgp_packet.h
+++ b/bgpd/bgp_packet.h
@@ -1,22 +1,22 @@
/* BGP packet management header.
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_PACKET_H
#define _QUAGGA_BGP_PACKET_H
diff --git a/bgpd/bgp_regex.c b/bgpd/bgp_regex.c
index ea87633dc0..3674a9b6d3 100644
--- a/bgpd/bgp_regex.c
+++ b/bgpd/bgp_regex.c
@@ -1,22 +1,22 @@
/* AS regular expression routine
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
diff --git a/bgpd/bgp_regex.h b/bgpd/bgp_regex.h
index e5d28d1b74..68bff001c9 100644
--- a/bgpd/bgp_regex.h
+++ b/bgpd/bgp_regex.h
@@ -1,22 +1,22 @@
/* AS regular expression routine
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_REGEX_H
#define _QUAGGA_BGP_REGEX_H
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index cb4d88859e..0f719d5536 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1,23 +1,23 @@
/* 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.
-
-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. */
+ * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
+ * Copyright (C) 2016 Job Snijders <job@instituut.net>
+ *
+ * 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 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>
@@ -35,6 +35,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "thread.h"
#include "workqueue.h"
#include "queue.h"
+#include "mpls.h"
#include "memory.h"
#include "lib/json.h"
@@ -62,6 +63,7 @@ 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_label.h"
#if ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h"
@@ -296,6 +298,11 @@ bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
}
}
+static int
+bgp_label_index_differs (struct bgp_info *ri1, struct bgp_info *ri2)
+{
+ return (!(ri1->attr->extra->label_index == ri2->attr->extra->label_index));
+}
/* Set/unset bgp_info flags, adjusting any other state as needed.
* This is here primarily to keep prefix-count in check.
@@ -1187,7 +1194,8 @@ subgroup_announce_reset_nhop (u_char family, struct attr *attr)
}
int
-subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
+subgroup_announce_check (struct bgp_node *rn, struct bgp_info *ri,
+ struct update_subgroup *subgrp,
struct prefix *p, struct attr *attr)
{
struct bgp_filter *filter;
@@ -1261,6 +1269,21 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
return 0;
}
+ /* If it's labeled safi, make sure the route has a valid label. */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ u_char *tag = bgp_adv_label(rn, ri, peer, afi, safi);
+ if (!bgp_is_valid_label(tag))
+ {
+ if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s/%d is filtered - no label (%p)",
+ subgrp->update_group->id, subgrp->id,
+ inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen, tag);
+ return 0;
+ }
+ }
+
/* Do not send back route to sender. */
if (onlypeer && from == onlypeer)
{
@@ -1433,7 +1456,7 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
#define NEXTHOP_IS_V6 (\
(safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
- (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
+ (p->family == AF_INET6 || peer_cap_enhe(peer, AFI_IP6, safi))) || \
((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
@@ -1535,7 +1558,7 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
if (!reflect ||
CHECK_FLAG (peer->af_flags[afi][safi],
PEER_FLAG_FORCE_NEXTHOP_SELF))
- subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ?
+ subgroup_announce_reset_nhop ((peer_cap_enhe(peer, afi, safi) ?
AF_INET6 : p->family), attr);
}
else if (peer->sort == BGP_PEER_EBGP)
@@ -1550,14 +1573,14 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
break;
}
if (!paf)
- subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ? AF_INET6 : p->family), attr);
+ subgroup_announce_reset_nhop ((peer_cap_enhe(peer, afi, safi) ? AF_INET6 : p->family), attr);
}
/* If IPv6/MP and nexthop does not have any override and happens to
* be a link-local address, reset it so that we don't pass along the
* source's link-local IPv6 address to recipients who may not be on
* the same interface.
*/
- if (p->family == AF_INET6 || peer_cap_enhe(peer))
+ if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))
{
if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
subgroup_announce_reset_nhop (AF_INET6, attr);
@@ -1804,7 +1827,7 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp,
/* Announcement to the subgroup. If the route is filtered withdraw it. */
if (selected)
{
- if (subgroup_announce_check(selected, subgrp, p, &attr))
+ if (subgroup_announce_check(rn, selected, subgrp, p, &attr))
bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
else
bgp_adj_out_unset_subgroup(rn, subgrp, 1, selected->addpath_tx_id);
@@ -1914,7 +1937,40 @@ bgp_process_main (struct work_queue *wq, void *data)
old_select = old_and_new.old;
new_select = old_and_new.new;
- /* Nothing to do. */
+ /* Do we need to allocate or free labels?
+ * Right now, since we only deal with per-prefix labels, it is not necessary
+ * to do this upon changes to best path except of the label index changes.
+ */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ bgp_table_lock (bgp_node_table (rn));
+ if (new_select)
+ {
+ if (!old_select ||
+ bgp_label_index_differs (new_select, old_select) ||
+ new_select->sub_type != old_select->sub_type)
+ {
+ if (new_select->sub_type == BGP_ROUTE_STATIC &&
+ new_select->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID) &&
+ new_select->attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
+ bgp_unregister_for_label (rn);
+ label_ntop (MPLS_IMP_NULL_LABEL, 1, rn->local_label);
+ bgp_set_valid_label(rn->local_label);
+ }
+ else
+ bgp_register_for_label (rn, new_select);
+ }
+ }
+ else if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
+ bgp_unregister_for_label (rn);
+ }
+
+ /* If best route remains the same and this is not due to user-initiated
+ * clear, see exactly what needs to be done.
+ */
+
if (old_select && old_select == new_select &&
!CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR) &&
!CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED) &&
@@ -1926,10 +1982,26 @@ 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);
+ if (bgp_fibupd_safi(safi) &&
+ !bgp->name &&
+ !bgp_option_check (BGP_OPT_NO_FIB) &&
+ new_select->type == ZEBRA_ROUTE_BGP &&
+ new_select->sub_type == BGP_ROUTE_NORMAL)
+ bgp_zebra_announce (rn, p, old_select, bgp, afi, safi);
}
UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
bgp_zebra_clear_route_change_flags (rn);
+
+ /* If there is a change of interest to peers, reannounce the route. */
+ if (CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED) ||
+ CHECK_FLAG (rn->flags, BGP_NODE_LABEL_CHANGED))
+ {
+ group_announce_route(bgp, afi, safi, rn, new_select);
+
+ UNSET_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED);
+ UNSET_FLAG (rn->flags, BGP_NODE_LABEL_CHANGED);
+ }
+
UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
return WQ_SUCCESS;
}
@@ -1945,9 +2017,10 @@ bgp_process_main (struct work_queue *wq, void *data)
if (!bgp->t_rmap_def_originate_eval)
{
bgp_lock (bgp);
- THREAD_TIMER_ON(bm->master, bgp->t_rmap_def_originate_eval,
- update_group_refresh_default_originate_route_map,
- bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER);
+ thread_add_timer(bm->master,
+ update_group_refresh_default_originate_route_map,
+ bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
+ &bgp->t_rmap_def_originate_eval);
}
}
@@ -1978,7 +2051,7 @@ bgp_process_main (struct work_queue *wq, void *data)
group_announce_route(bgp, afi, safi, rn, new_select);
/* FIB update. */
- if ((safi == SAFI_UNICAST || safi == SAFI_MULTICAST) &&
+ if (bgp_fibupd_safi(safi) &&
(bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) &&
!bgp_option_check (BGP_OPT_NO_FIB))
{
@@ -1986,7 +2059,7 @@ bgp_process_main (struct work_queue *wq, void *data)
&& new_select->type == ZEBRA_ROUTE_BGP
&& (new_select->sub_type == BGP_ROUTE_NORMAL ||
new_select->sub_type == BGP_ROUTE_AGGREGATE))
- bgp_zebra_announce (p, new_select, bgp, afi, safi);
+ bgp_zebra_announce (rn, p, new_select, bgp, afi, safi);
else
{
/* Withdraw the route from the kernel. */
@@ -2406,6 +2479,7 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
struct bgp_info *new;
const char *reason;
char pfx_buf[BGP_PRD_PATH_STRLEN];
+ char label_buf[20];
int connected = 0;
int do_loop_check = 1;
#if ENABLE_BGP_VNC
@@ -2417,6 +2491,9 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
bgp = peer->bgp;
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
+ label_buf[0] = '\0';
+ if (bgp_labeled_safi(safi))
+ sprintf (label_buf, "label %u", label_pton(tag));
/* When peer's soft reconfiguration enabled. Record input packet in
Adj-RIBs-In. */
@@ -2516,6 +2593,8 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
/* Same attribute comes in. */
if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
&& attrhash_cmp (ri->attr, attr_new)
+ && (!bgp_labeled_safi(safi) ||
+ memcmp ((bgp_info_extra_get (ri))->tag, tag, 3) == 0)
&& (overlay_index_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_s_id,
evpn==NULL?NULL:&evpn->gw_ip)))
{
@@ -2524,9 +2603,9 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
&& CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
{
if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s rcvd %s", peer->host,
+ zlog_debug ("%s rcvd %s %s", peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
if (bgp_damp_update (ri, rn, afi, safi) != BGP_DAMP_SUPPRESSED)
{
@@ -2544,10 +2623,10 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
peer->rcvd_attr_printed = 1;
}
- zlog_debug ("%s rcvd %s...duplicate ignored",
+ zlog_debug ("%s rcvd %s %s...duplicate ignored",
peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ?
- 1 : 0, addpath_id, pfx_buf, sizeof (pfx_buf)));
+ 1 : 0, addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
}
/* graceful restart STALE flag unset. */
@@ -2568,18 +2647,18 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
{
if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s rcvd %s, flapped quicker than processing",
+ zlog_debug ("%s rcvd %s %s, flapped quicker than processing",
peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
bgp_info_restore (rn, ri);
}
/* Received Logging. */
if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s rcvd %s", peer->host,
+ zlog_debug ("%s rcvd %s %s", peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
/* graceful restart STALE flag unset. */
if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
@@ -2637,7 +2716,7 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
ri->attr = attr_new;
/* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
+ if (bgp_labeled_safi(safi))
memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
#if ENABLE_BGP_VNC
@@ -2678,8 +2757,9 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
}
}
- /* Nexthop reachability check. */
- if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
+ /* Nexthop reachability check - for unicast and labeled-unicast.. */
+ if ((afi == AFI_IP || afi == AFI_IP6) &&
+ (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
{
if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
@@ -2759,16 +2839,16 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
peer->rcvd_attr_printed = 1;
}
- zlog_debug ("%s rcvd %s", peer->host,
+ zlog_debug ("%s rcvd %s%s ", peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
}
/* Make new BGP info. */
new = info_make(type, sub_type, 0, peer, attr_new, rn);
/* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
+ if (bgp_labeled_safi(safi))
memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
/* Update Overlay Index */
@@ -2778,7 +2858,8 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
evpn==NULL?NULL:&evpn->gw_ip);
}
/* Nexthop reachability check. */
- if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
+ if ((afi == AFI_IP || afi == AFI_IP6) &&
+ (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
{
if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
@@ -2873,10 +2954,10 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
peer->rcvd_attr_printed = 1;
}
- zlog_debug ("%s rcvd UPDATE about %s -- DENIED due to: %s",
+ zlog_debug ("%s rcvd UPDATE about %s %s -- DENIED due to: %s",
peer->host,
bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)), reason);
+ addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf, reason);
}
if (ri)
@@ -3008,9 +3089,6 @@ bgp_announce_route_timer_expired (struct thread *t)
paf = THREAD_ARG (t);
peer = paf->peer;
- assert (paf->t_announce_route);
- paf->t_announce_route = NULL;
-
if (peer->status != Established)
return 0;
@@ -3050,11 +3128,9 @@ bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
* multiple peers and the announcement doesn't happen in the
* vty context.
*/
- THREAD_TIMER_MSEC_ON (bm->master, paf->t_announce_route,
- bgp_announce_route_timer_expired, paf,
- (subgrp->peer_count == 1) ?
- BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS :
- BGP_ANNOUNCE_ROUTE_DELAY_MS);
+ thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
+ (subgrp->peer_count == 1) ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS : BGP_ANNOUNCE_ROUTE_DELAY_MS,
+ &paf->t_announce_route);
}
/*
@@ -3702,9 +3778,9 @@ bgp_static_free (struct bgp_static *bgp_static)
XFREE (MTYPE_BGP_STATIC, bgp_static);
}
-static void
-bgp_static_update_main (struct bgp *bgp, struct prefix *p,
- struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+void
+bgp_static_update (struct bgp *bgp, struct prefix *p,
+ struct bgp_static *bgp_static, afi_t afi, safi_t safi)
{
struct bgp_node *rn;
struct bgp_info *ri;
@@ -3732,6 +3808,13 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
if (bgp_static->atomic)
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
+ /* Store label index, if required. */
+ if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ (bgp_attr_extra_get (&attr))->label_index = bgp_static->label_index;
+ attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID);
+ }
+
/* Apply route-map. */
if (bgp_static->rmap.name)
{
@@ -3818,9 +3901,11 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
#endif
/* Nexthop reachability check. */
- if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
+ if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK) &&
+ safi == SAFI_UNICAST)
{
- if (bgp_find_or_add_nexthop (bgp, afi, ri, NULL, 0))
+ if (bgp_find_or_add_nexthop (bgp, afi, ri, NULL, 0) &&
+ safi == SAFI_UNICAST)
bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
else
{
@@ -3904,13 +3989,6 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
}
void
-bgp_static_update (struct bgp *bgp, struct prefix *p,
- struct bgp_static *bgp_static, afi_t afi, safi_t safi)
-{
- bgp_static_update_main (bgp, p, bgp_static, afi, safi);
-}
-
-void
bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
safi_t safi)
{
@@ -4158,7 +4236,8 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
route should be installed as valid. */
static int
bgp_static_set (struct vty *vty, const char *ip_str,
- afi_t afi, safi_t safi, const char *rmap, int backdoor)
+ afi_t afi, safi_t safi, const char *rmap, int backdoor,
+ u_int32_t label_index)
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
@@ -4191,6 +4270,13 @@ bgp_static_set (struct vty *vty, const char *ip_str,
/* Configuration change. */
bgp_static = rn->info;
+ /* Label index cannot be changed. */
+ if (bgp_static->label_index != label_index)
+ {
+ vty_out (vty, "%% Label index cannot be changed%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
/* Check previous routes are installed into BGP. */
if (bgp_static->valid && bgp_static->backdoor != backdoor)
need_update = 1;
@@ -4222,6 +4308,7 @@ bgp_static_set (struct vty *vty, const char *ip_str,
bgp_static->valid = 0;
bgp_static->igpmetric = 0;
bgp_static->igpnexthop.s_addr = 0;
+ bgp_static->label_index = label_index;
if (rmap)
{
@@ -4751,7 +4838,8 @@ DEFUN (bgp_network,
{
int idx_ipv4_prefixlen = 1;
return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
- AFI_IP, bgp_node_safi (vty), NULL, 0);
+ AFI_IP, bgp_node_safi (vty), NULL, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_route_map,
@@ -4765,7 +4853,8 @@ DEFUN (bgp_network_route_map,
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);
+ AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_backdoor,
@@ -4777,7 +4866,7 @@ DEFUN (bgp_network_backdoor,
{
int idx_ipv4_prefixlen = 1;
return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP, SAFI_UNICAST,
- NULL, 1);
+ NULL, 1, BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask,
@@ -4801,7 +4890,7 @@ DEFUN (bgp_network_mask,
}
return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0);
+ AFI_IP, bgp_node_safi (vty), NULL, 0, BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_route_map,
@@ -4828,7 +4917,7 @@ DEFUN (bgp_network_mask_route_map,
}
return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0, BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_backdoor,
@@ -4853,7 +4942,8 @@ DEFUN (bgp_network_mask_backdoor,
}
return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1);
+ NULL, 1,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_natural,
@@ -4874,7 +4964,8 @@ DEFUN (bgp_network_mask_natural,
}
return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0);
+ AFI_IP, bgp_node_safi (vty), NULL, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_natural_route_map,
@@ -4898,7 +4989,8 @@ DEFUN (bgp_network_mask_natural_route_map,
}
return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (bgp_network_mask_natural_backdoor,
@@ -4920,7 +5012,39 @@ DEFUN (bgp_network_mask_natural_backdoor,
}
return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1);
+ NULL, 1, BGP_INVALID_LABEL_INDEX);
+}
+
+DEFUN (bgp_network_label_index,
+ bgp_network_label_index_cmd,
+ "network A.B.C.D/M label-index (0-4294967294)",
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n")
+{
+ u_int32_t label_index;
+
+ VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+ return bgp_static_set (vty, argv[1]->arg,
+ AFI_IP, bgp_node_safi (vty), NULL, 0, label_index);
+}
+
+DEFUN (bgp_network_label_index_route_map,
+ bgp_network_label_index_route_map_cmd,
+ "network A.B.C.D/M label-index (0-4294967294) route-map WORD",
+ "Specify a network to announce via BGP\n"
+ "IP prefix\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+{
+ u_int32_t label_index;
+
+ VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+ return bgp_static_set (vty, argv[1]->arg,
+ AFI_IP, bgp_node_safi (vty), argv[5]->arg, 0, label_index);
}
DEFUN (no_bgp_network,
@@ -4991,6 +5115,26 @@ DEFUN (no_bgp_network_mask_natural,
bgp_node_safi (vty));
}
+ALIAS (no_bgp_network,
+ no_bgp_network_label_index_cmd,
+ "no network A.B.C.D/M label-index (0-4294967294)",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n")
+
+ALIAS (no_bgp_network,
+ no_bgp_network_label_index_route_map_cmd,
+ "no network A.B.C.D/M label-index (0-4294967294) route-map WORD",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IP prefix\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+
DEFUN (ipv6_bgp_network,
ipv6_bgp_network_cmd,
"network X:X::X:X/M",
@@ -4999,7 +5143,8 @@ DEFUN (ipv6_bgp_network,
{
int idx_ipv6_prefixlen = 1;
return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty),
- NULL, 0);
+ NULL, 0,
+ BGP_INVALID_LABEL_INDEX);
}
DEFUN (ipv6_bgp_network_route_map,
@@ -5013,7 +5158,40 @@ DEFUN (ipv6_bgp_network_route_map,
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);
+ bgp_node_safi (vty), argv[idx_word]->arg, 0,
+ BGP_INVALID_LABEL_INDEX);
+}
+
+DEFUN (ipv6_bgp_network_label_index,
+ ipv6_bgp_network_label_index_cmd,
+ "network X:X::X:X/M label-index (0-4294967294)",
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n")
+{
+ u_int32_t label_index;
+
+ VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+ return bgp_static_set (vty, argv[1]->arg,
+ AFI_IP6, bgp_node_safi (vty), NULL, 0, label_index);
+}
+
+DEFUN (ipv6_bgp_network_label_index_route_map,
+ ipv6_bgp_network_label_index_route_map_cmd,
+ "network X:X::X:X/M label-index (0-4294967294) route-map WORD",
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+{
+ u_int32_t label_index;
+
+ VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+ return bgp_static_set (vty, argv[1]->arg,
+ AFI_IP6, bgp_node_safi (vty), argv[5]->arg, 0, label_index);
}
DEFUN (no_ipv6_bgp_network,
@@ -5029,6 +5207,26 @@ DEFUN (no_ipv6_bgp_network,
return bgp_static_unset (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty));
}
+ALIAS (no_ipv6_bgp_network,
+ no_ipv6_bgp_network_label_index_cmd,
+ "no network X:X::X:X/M label-index (0-4294967294)",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix <network>/<length>\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n")
+
+ALIAS (no_ipv6_bgp_network,
+ no_ipv6_bgp_network_label_index_route_map_cmd,
+ "no network X:X::X:X/M label-index (0-4294967294) route-map WORD",
+ NO_STR
+ "Specify a network to announce via BGP\n"
+ "IPv6 prefix\n"
+ "Label index to associate with the prefix\n"
+ "Label index value\n"
+ "Route-map to modify the attributes\n"
+ "Name of the route map\n")
+
/* Aggreagete address:
advertise-map Set condition to advertise attribute
@@ -5558,9 +5756,11 @@ bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
}
aggregate = rn->info;
- if (aggregate->safi & SAFI_UNICAST)
+ if (aggregate->safi == SAFI_UNICAST)
bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (aggregate->safi & SAFI_MULTICAST)
+ if (aggregate->safi == SAFI_LABELED_UNICAST)
+ bgp_aggregate_delete (bgp, &p, afi, SAFI_LABELED_UNICAST, aggregate);
+ if (aggregate->safi == SAFI_MULTICAST)
bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
/* Unlock aggregate address configuration. */
@@ -5616,9 +5816,11 @@ bgp_aggregate_set (struct vty *vty, const char *prefix_str,
rn->info = aggregate;
/* Aggregate address insert into BGP routing table. */
- if (safi & SAFI_UNICAST)
+ if (safi == SAFI_UNICAST)
bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (safi & SAFI_MULTICAST)
+ if (safi == SAFI_LABELED_UNICAST)
+ bgp_aggregate_add (bgp, &p, afi, SAFI_LABELED_UNICAST, aggregate);
+ if (safi == SAFI_MULTICAST)
bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
return CMD_SUCCESS;
@@ -5657,9 +5859,8 @@ DEFUN (aggregate_address_mask,
{
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;
+ char *prefix = argv[idx]->arg;
+ char *mask = argv[idx+1]->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;
@@ -5707,9 +5908,8 @@ DEFUN (no_aggregate_address_mask,
{
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;
+ char *prefix = argv[idx]->arg;
+ char *mask = argv[idx+1]->arg;
char prefix_str[BUFSIZ];
int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
@@ -7442,6 +7642,25 @@ 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);
+ /* Remove Label */
+ if (bgp_labeled_safi(safi) && binfo->extra)
+ {
+ uint32_t label = label_pton(binfo->extra->tag);
+ if (json_paths)
+ json_object_int_add(json_path, "remoteLabel", label);
+ else
+ vty_out(vty, " Remote label: %d%s", label, VTY_NEWLINE);
+ }
+
+ /* Label Index */
+ if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+ {
+ if (json_paths)
+ json_object_int_add(json_path, "labelIndex", attr->extra->label_index);
+ else
+ vty_out(vty, " Label Index: %d%s", attr->extra->label_index, VTY_NEWLINE);
+ }
+
/* Line 8 display Addpath IDs */
if (binfo->addpath_rx_id || binfo->addpath_tx_id)
{
@@ -7935,6 +8154,18 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":" : "",
buf2,
p->prefixlen, VTY_NEWLINE);
+
+ if (bgp_labeled_safi(safi))
+ {
+ vty_out(vty, "Local label: ");
+ if (!bgp_is_valid_label(rn->local_label))
+ vty_out(vty, "not allocated%s", VTY_NEWLINE);
+ else
+ {
+ uint32_t label = label_pton(rn->local_label);
+ vty_out(vty, "%d%s", label, VTY_NEWLINE);
+ }
+ }
}
for (ri = rn->info; ri; ri = ri->next)
@@ -8216,7 +8447,7 @@ bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom,
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 [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -8227,6 +8458,7 @@ DEFUN (show_ip_bgp_large_community_list,
"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"
@@ -8262,7 +8494,7 @@ DEFUN (show_ip_bgp_large_community_list,
}
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 [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community [AA:BB:CC] [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -8273,6 +8505,7 @@ DEFUN (show_ip_bgp_large_community,
"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)
@@ -8642,6 +8875,7 @@ bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
int i;
char *str;
int first = 0;
+ int ret = 0;
b = buffer_new (1024);
for (i = 0; i < argc; i++)
@@ -8670,9 +8904,12 @@ bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
return CMD_WARNING;
}
- return bgp_show (vty, bgp, afi, safi,
- (exact ? bgp_show_type_community_exact :
- bgp_show_type_community), com, 0);
+ ret = bgp_show (vty, bgp, afi, safi,
+ (exact ? bgp_show_type_community_exact :
+ bgp_show_type_community), com, 0);
+ community_free (com);
+
+ return ret;
}
static int
@@ -9213,7 +9450,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_c
DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
show_ip_bgp_instance_neighbor_prefix_counts_cmd,
- "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] "
+ "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] "
"neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
SHOW_STR
IP_STR
@@ -9225,6 +9462,7 @@ DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
"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"
@@ -10548,6 +10786,9 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
p->prefixlen);
}
+ if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
+ vty_out (vty, " label-index %u", bgp_static->label_index);
+
if (bgp_static->rmap.name)
vty_out (vty, " route-map %s", bgp_static->rmap.name);
else
@@ -10674,6 +10915,8 @@ bgp_route_init (void)
install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_route_map_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_table_map_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
@@ -10701,6 +10944,21 @@ bgp_route_init (void)
install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd);
install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
+ /* IPv4 labeled-unicast configuration. */
+ install_element (BGP_IPV4L_NODE, &bgp_table_map_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_mask_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_mask_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_label_index_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_network_label_index_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_table_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_natural_cmd);
+
install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
install_element (VIEW_NODE, &show_ip_bgp_cmd);
install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
@@ -10734,6 +10992,10 @@ 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, &ipv6_bgp_network_label_index_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_cmd);
+ install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_route_map_cmd);
+ install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_route_map_cmd);
install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
@@ -10741,6 +11003,12 @@ bgp_route_init (void)
install_element (BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
+ install_element (BGP_IPV6L_NODE, &bgp_table_map_cmd);
+ install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
+ install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_route_map_cmd);
+ install_element (BGP_IPV6L_NODE, &no_bgp_table_map_cmd);
+ install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_cmd);
+
install_element (BGP_NODE, &bgp_distance_cmd);
install_element (BGP_NODE, &no_bgp_distance_cmd);
install_element (BGP_NODE, &bgp_distance_source_cmd);
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index dbdcedd005..3d179e07be 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -1,22 +1,22 @@
/* BGP routing information base
- Copyright (C) 1996, 97, 98, 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98, 2000 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_ROUTE_H
#define _QUAGGA_BGP_ROUTE_H
@@ -85,7 +85,7 @@ struct bgp_info_extra
} export;
struct {
- void *timer;
+ struct thread *timer;
void *hme; /* encap monitor, if this is a VPN route */
struct prefix_rd rd; /* import: route's route-distinguisher */
u_char un_family; /* family of cached un address, 0 if unset */
@@ -150,6 +150,7 @@ struct bgp_info
#define BGP_INFO_COUNTED (1 << 10)
#define BGP_INFO_MULTIPATH (1 << 11)
#define BGP_INFO_MULTIPATH_CHG (1 << 12)
+#define BGP_INFO_RIB_ATTR_CHG (1 << 13)
/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
u_char type;
@@ -179,6 +180,10 @@ struct bgp_static
/* Backdoor configuration. */
int backdoor;
+ /* Label index configuration; applies to LU prefixes. */
+ u_int32_t label_index;
+#define BGP_INVALID_LABEL_INDEX 0xFFFFFFFF
+
/* Import check status. */
u_char valid;
@@ -273,6 +278,16 @@ bgp_bump_version (struct bgp_node *node)
node->version = bgp_table_next_version(bgp_node_table(node));
}
+static inline int
+bgp_fibupd_safi (safi_t safi)
+{
+ if (safi == SAFI_UNICAST ||
+ safi == SAFI_MULTICAST ||
+ safi == SAFI_LABELED_UNICAST)
+ return 1;
+ return 0;
+}
+
/* Prototypes. */
extern void bgp_process_queue_init (void);
extern void bgp_route_init (void);
@@ -370,7 +385,7 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp,
struct bgp_node *rn,
u_int32_t addpath_tx_id);
-extern int subgroup_announce_check(struct bgp_info *ri,
+extern int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
struct update_subgroup *subgrp,
struct prefix *p, struct attr *attr);
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 9b3a6a513a..570fcc1a34 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1,22 +1,22 @@
/* Route map function of bgpd.
- Copyright (C) 1998, 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1998, 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -3176,9 +3176,9 @@ bgp_route_map_mark_update (const char *rmap_name)
/* rmap_update_timer of 0 means don't do route updates */
if (bm->rmap_update_timer)
{
- bm->t_rmap_update =
- thread_add_timer(bm->master, bgp_route_map_update_timer, NULL,
- bm->rmap_update_timer);
+ bm->t_rmap_update = NULL;
+ thread_add_timer(bm->master, bgp_route_map_update_timer, NULL, bm->rmap_update_timer,
+ &bm->t_rmap_update);
/* Signal the groups that a route-map update event has started */
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c
index f45d683848..db69400a67 100644
--- a/bgpd/bgp_snmp.c
+++ b/bgpd/bgp_snmp.c
@@ -1,22 +1,22 @@
/* BGP4 SNMP support
- Copyright (C) 1999, 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999, 2000 Kunihiro Ishiguro
+ *
+ * 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 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>
diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c
index 06e443b25a..ff0cfdd658 100644
--- a/bgpd/bgp_table.c
+++ b/bgpd/bgp_table.c
@@ -1,22 +1,22 @@
/* BGP routing table
- Copyright (C) 1998, 2001 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1998, 2001 Kunihiro Ishiguro
+ *
+ * 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 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>
diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h
index 3c96dac617..cff270ebb9 100644
--- a/bgpd/bgp_table.h
+++ b/bgpd/bgp_table.h
@@ -1,22 +1,22 @@
/* BGP routing table
- Copyright (C) 1998, 2001 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1998, 2001 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_TABLE_H
#define _QUAGGA_BGP_TABLE_H
@@ -56,10 +56,14 @@ struct bgp_node
struct bgp_node *prn;
+ u_char local_label[3];
+
uint64_t version;
u_char flags;
#define BGP_NODE_PROCESS_SCHEDULED (1 << 0)
#define BGP_NODE_USER_CLEAR (1 << 1)
+#define BGP_NODE_LABEL_CHANGED (1 << 2)
+#define BGP_NODE_REGISTERED_FOR_LABEL (1 << 3)
};
/*
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index 9e5ec4b26d..04d262050f 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -19,10 +19,9 @@
* 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.
+ * 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>
@@ -1169,10 +1168,9 @@ update_subgroup_trigger_merge_check (struct update_subgroup *subgrp,
if (!force && !update_subgroup_ready_for_merge (subgrp))
return 0;
- subgrp->t_merge_check =
- thread_add_background (bm->master,
- update_subgroup_merge_check_thread_cb,
- subgrp, 0);
+ subgrp->t_merge_check = NULL;
+ thread_add_background(bm->master, update_subgroup_merge_check_thread_cb, subgrp, 0,
+ &subgrp->t_merge_check);
SUBGRP_INCR_STAT (subgrp, merge_checks_triggered);
diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h
index 8f3e27bc84..87b85adae4 100644
--- a/bgpd/bgp_updgrp.h
+++ b/bgpd/bgp_updgrp.h
@@ -19,10 +19,9 @@
* 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.
+ * 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 _QUAGGA_BGP_UPDGRP_H
diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c
index efb2046e12..c6a1606323 100644
--- a/bgpd/bgp_updgrp_adv.c
+++ b/bgpd/bgp_updgrp_adv.c
@@ -21,10 +21,9 @@
* 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.
+ * 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>
@@ -618,7 +617,7 @@ subgroup_announce_table (struct update_subgroup *subgrp,
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) ||
(addpath_capable && bgp_addpath_tx_path(peer, afi, safi, ri)))
{
- if (subgroup_announce_check (ri, subgrp, &rn->p, &attr))
+ if (subgroup_announce_check (rn, ri, subgrp, &rn->p, &attr))
bgp_adj_out_set_subgroup (rn, subgrp, &attr, ri);
else
bgp_adj_out_unset_subgroup (rn, subgrp, 1, ri->addpath_tx_id);
@@ -828,8 +827,8 @@ subgroup_announce_all (struct update_subgroup *subgrp)
*/
if (!subgrp->t_coalesce)
{
- THREAD_TIMER_MSEC_ON (bm->master, subgrp->t_coalesce, subgroup_coalesce_timer,
- subgrp, subgrp->v_coalesce);
+ thread_add_timer_msec(bm->master, subgroup_coalesce_timer, subgrp,
+ subgrp->v_coalesce, &subgrp->t_coalesce);
}
}
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c
index 8839de391e..7e524dd347 100644
--- a/bgpd/bgp_updgrp_packet.c
+++ b/bgpd/bgp_updgrp_packet.c
@@ -19,10 +19,9 @@
* 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.
+ * 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>
@@ -43,6 +42,7 @@
#include "workqueue.h"
#include "hash.h"
#include "queue.h"
+#include "mpls.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_debug.h"
@@ -54,6 +54,7 @@
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_mplsvpn.h"
+#include "bgpd/bgp_label.h"
/********************
* PRIVATE FUNCTIONS
@@ -425,7 +426,7 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
if (paf->afi == AFI_IP || paf->afi == AFI_IP6)
{
nhafi = BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen);
- if (peer_cap_enhe(peer))
+ if (peer_cap_enhe(peer, paf->afi, paf->safi))
nhafi = AFI_IP6;
if (paf->safi == SAFI_MPLS_VPN && /* if VPN && not global */
nhlen != BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
@@ -653,6 +654,7 @@ subgroup_update_packet (struct update_subgroup *subgrp)
int addpath_encode = 0;
u_int32_t addpath_tx_id = 0;
struct prefix_rd *prd = NULL;
+ char label_buf[20];
if (!subgrp)
return NULL;
@@ -660,7 +662,6 @@ subgroup_update_packet (struct update_subgroup *subgrp)
if (bpacket_queue_is_full (SUBGRP_INST (subgrp), SUBGRP_PKTQ (subgrp)))
return NULL;
-
peer = SUBGRP_PEER (subgrp);
afi = SUBGRP_AFI (subgrp);
safi = SUBGRP_SAFI (subgrp);
@@ -668,6 +669,7 @@ subgroup_update_packet (struct update_subgroup *subgrp)
stream_reset (s);
snlri = subgrp->scratch;
stream_reset (snlri);
+ label_buf[0] = '\0';
bpacket_attr_vec_arr_reset (&vecarr);
@@ -746,12 +748,12 @@ subgroup_update_packet (struct update_subgroup *subgrp)
{
memset (send_attr_str, 0, BUFSIZ);
send_attr_printed = 0;
- bgp_dump_attr (peer, adv->baa->attr, send_attr_str, BUFSIZ);
+ bgp_dump_attr (adv->baa->attr, send_attr_str, BUFSIZ);
}
}
if ((afi == AFI_IP && safi == SAFI_UNICAST) &&
- !peer_cap_enhe(peer))
+ !peer_cap_enhe(peer, afi, safi))
stream_put_prefix_addpath (s, &rn->p, addpath_encode, addpath_tx_id);
else
{
@@ -760,14 +762,19 @@ subgroup_update_packet (struct update_subgroup *subgrp)
if (rn->prn)
prd = (struct prefix_rd *) &rn->prn->p;
- if (binfo && binfo->extra)
- tag = binfo->extra->tag;
+
+ if (safi == SAFI_LABELED_UNICAST)
+ tag = bgp_adv_label(rn, binfo, peer, afi, safi);
+ else
+ if (binfo && binfo->extra)
+ tag = binfo->extra->tag;
+
+ if (bgp_labeled_safi(safi))
+ sprintf (label_buf, "label %u", label_pton(tag));
if (stream_empty (snlri))
- mpattrlen_pos = bgp_packet_mpattr_start (snlri, afi, safi,
- (peer_cap_enhe(peer) ? AFI_IP6 :
- AFI_MAX), /* get from NH */
- &vecarr, adv->baa->attr);
+ mpattrlen_pos = bgp_packet_mpattr_start (snlri, peer, afi, safi,
+ &vecarr, adv->baa->attr);
bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd,
tag, addpath_encode, addpath_tx_id, adv->baa->attr);
@@ -783,14 +790,26 @@ subgroup_update_packet (struct update_subgroup *subgrp)
{
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE w/ attr: %s",
subgrp->update_group->id, subgrp->id, send_attr_str);
+ if (!stream_empty (snlri))
+ {
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
+
+ pkt_afi = afi_int2iana (afi);
+ pkt_safi = safi_int2iana (safi);
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send MP_REACH for afi/safi %d/%d",
+ subgrp->update_group->id, subgrp->id, pkt_afi, pkt_safi);
+ }
+
send_attr_printed = 1;
}
- zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s",
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s %s",
subgrp->update_group->id, subgrp->id,
bgp_debug_rdpfxpath2str (prd, &rn->p, addpath_encode,
addpath_tx_id,
- pfx_buf, sizeof (pfx_buf)));
+ pfx_buf, sizeof (pfx_buf)),
+ label_buf);
}
/* Synchnorize attribute. */
@@ -824,7 +843,7 @@ subgroup_update_packet (struct update_subgroup *subgrp)
packet = stream_dup (s);
bgp_packet_set_size (packet);
if (bgp_debug_update(NULL, NULL, subgrp->update_group, 0))
- zlog_debug ("u%" PRIu64 ":s%" PRIu64 " UPDATE len %zd numpfx %d",
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE len %zd numpfx %d",
subgrp->update_group->id, subgrp->id,
(stream_get_endp(packet) - stream_get_getp(packet)), num_pfx);
pkt = bpacket_queue_add (SUBGRP_PKTQ (subgrp), packet, &vecarr);
@@ -907,7 +926,7 @@ subgroup_withdraw_packet (struct update_subgroup *subgrp)
first_time = 0;
if (afi == AFI_IP && safi == SAFI_UNICAST &&
- !peer_cap_enhe(peer))
+ !peer_cap_enhe(peer, afi, safi))
stream_put_prefix_addpath (s, &rn->p, addpath_encode, addpath_tx_id);
else
{
@@ -917,11 +936,20 @@ subgroup_withdraw_packet (struct update_subgroup *subgrp)
/* If first time, format the MP_UNREACH header */
if (first_time)
{
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
+
+ pkt_afi = afi_int2iana (afi);
+ pkt_safi = safi_int2iana (safi);
+
attrlen_pos = stream_get_endp (s);
/* total attr length = 0 for now. reevaluate later */
stream_putw (s, 0);
mp_start = stream_get_endp (s);
mplen_pos = bgp_packet_mpunreach_start (s, afi, safi);
+ if (bgp_debug_update(NULL, NULL, subgrp->update_group, 0))
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send MP_UNREACH for afi/safi %d/%d",
+ subgrp->update_group->id, subgrp->id, pkt_afi, pkt_safi);
}
bgp_packet_mpunreach_prefix (s, &rn->p, afi, safi, prd, NULL,
@@ -950,7 +978,7 @@ subgroup_withdraw_packet (struct update_subgroup *subgrp)
if (!stream_empty (s))
{
if (afi == AFI_IP && safi == SAFI_UNICAST &&
- !peer_cap_enhe(peer))
+ !peer_cap_enhe(peer, afi, safi))
{
unfeasible_len
= stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
@@ -968,7 +996,7 @@ subgroup_withdraw_packet (struct update_subgroup *subgrp)
}
bgp_packet_set_size (s);
if (bgp_debug_update(NULL, NULL, subgrp->update_group, 0))
- zlog_debug ("u%" PRIu64 ":s%" PRIu64 " UPDATE (withdraw) len %zd numpfx %d",
+ zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE (withdraw) len %zd numpfx %d",
subgrp->update_group->id, subgrp->id,
(stream_get_endp(s) - stream_get_getp(s)), num_pfx);
pkt = bpacket_queue_add (SUBGRP_PKTQ (subgrp), stream_dup (s), NULL);
@@ -1018,7 +1046,7 @@ subgroup_default_update_packet (struct update_subgroup *subgrp,
char tx_id_buf[30];
attrstr[0] = '\0';
- bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
+ bgp_dump_attr (attr, attrstr, BUFSIZ);
bgp_info_addpath_tx_str (addpath_encode, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, tx_id_buf);
zlog_debug ("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s %s",
(SUBGRP_UPDGRP (subgrp))->id, subgrp->id,
@@ -1047,7 +1075,7 @@ subgroup_default_update_packet (struct update_subgroup *subgrp,
/* NLRI set. */
if (p.family == AF_INET && safi == SAFI_UNICAST &&
- !peer_cap_enhe(peer))
+ !peer_cap_enhe(peer, afi, safi))
stream_put_prefix_addpath (s, &p, addpath_encode, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
/* Set size. */
@@ -1108,7 +1136,7 @@ subgroup_default_withdraw_packet (struct update_subgroup *subgrp)
/* Withdrawn Routes. */
if (p.family == AF_INET && safi == SAFI_UNICAST &&
- !peer_cap_enhe(peer))
+ !peer_cap_enhe(peer, afi, safi))
{
stream_put_prefix_addpath (s, &p, addpath_encode,
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
diff --git a/bgpd/bgp_vnc_types.h b/bgpd/bgp_vnc_types.h
index 8bc9cb6407..e97a47e1a3 100644
--- a/bgpd/bgp_vnc_types.h
+++ b/bgpd/bgp_vnc_types.h
@@ -11,10 +11,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_VNC_TYPES_H
diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c
index 5b1b1b85b2..e99161d406 100644
--- a/bgpd/bgp_vpn.c
+++ b/bgpd/bgp_vpn.c
@@ -1,22 +1,22 @@
/* VPN Related functions
- Copyright (C) 2017 6WIND
-
-This file is part of FRRouting
-
-FRRouting 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.
-
-FRRouting 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 FRRouting; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 2017 6WIND
+ *
+ * This file is part of FRRouting
+ *
+ * FRRouting 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.
+ *
+ * FRRouting 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 "command.h"
diff --git a/bgpd/bgp_vpn.h b/bgpd/bgp_vpn.h
index dd53503bf3..fcccd45c7e 100644
--- a/bgpd/bgp_vpn.h
+++ b/bgpd/bgp_vpn.h
@@ -1,22 +1,22 @@
/* VPN common functions to MP-BGP
- Copyright (C) 2017 6WIND
-
-This file is part of FRRouting.
-
-FRRouting 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.
-
-FRRouting 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 FRRouting; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * Copyright (C) 2017 6WIND
+ *
+ * This file is part of FRRouting.
+ *
+ * FRRouting 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.
+ *
+ * FRRouting 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 _FRR_BGP_VPN_H
#define _FRR_BGP_VPN_H
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 0c6648d562..5059104e92 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -1,22 +1,22 @@
/* BGP VTY interface.
- Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -61,6 +61,64 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
static struct peer_group *
listen_range_exists (struct bgp *bgp, struct prefix *range, int exact);
+static enum node_type
+bgp_node_type (afi_t afi, safi_t safi)
+{
+ switch (afi)
+ {
+ case AFI_IP:
+ switch (safi)
+ {
+ case SAFI_UNICAST:
+ return BGP_IPV4_NODE;
+ break;
+ case SAFI_MULTICAST:
+ return BGP_IPV4M_NODE;
+ break;
+ case SAFI_LABELED_UNICAST:
+ return BGP_IPV4L_NODE;
+ break;
+ case SAFI_MPLS_VPN:
+ return BGP_VPNV4_NODE;
+ break;
+ case SAFI_ENCAP:
+ return BGP_ENCAP_NODE;
+ break;
+ }
+ break;
+ case AFI_IP6:
+ switch (safi)
+ {
+ case SAFI_UNICAST:
+ return BGP_IPV6_NODE;
+ break;
+ case SAFI_MULTICAST:
+ return BGP_IPV6M_NODE;
+ break;
+ case SAFI_LABELED_UNICAST:
+ return BGP_IPV6L_NODE;
+ break;
+ case SAFI_MPLS_VPN:
+ return BGP_VPNV6_NODE;
+ break;
+ case SAFI_ENCAP:
+ return BGP_ENCAPV6_NODE;
+ break;
+ }
+ break;
+ case AFI_L2VPN:
+ return BGP_EVPN_NODE;
+ break;
+ case AFI_MAX:
+ // We should never be here but to clarify the switch statement..
+ return BGP_IPV4_NODE;
+ break;
+ }
+
+ // Impossible to happen
+ return BGP_IPV4_NODE;
+}
+
/* Utility function to get address family from current node. */
afi_t
bgp_node_afi (struct vty *vty)
@@ -70,6 +128,7 @@ bgp_node_afi (struct vty *vty)
{
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
+ case BGP_IPV6L_NODE:
case BGP_VPNV6_NODE:
case BGP_ENCAPV6_NODE:
afi = AFI_IP6;
@@ -107,6 +166,10 @@ bgp_node_safi (struct vty *vty)
case BGP_EVPN_NODE:
safi = SAFI_EVPN;
break;
+ case BGP_IPV4L_NODE:
+ case BGP_IPV6L_NODE:
+ safi = SAFI_LABELED_UNICAST;
+ break;
default:
safi = SAFI_UNICAST;
break;
@@ -160,7 +223,7 @@ argv_find_and_parse_afi(struct cmd_token **argv, int argc, int *index, afi_t *af
return ret;
}
-/* supports <unicast|multicast|vpn|encap> */
+/* supports <unicast|multicast|vpn|encap|labeled-unicast> */
safi_t
bgp_vty_safi_from_arg(const char *safi_str)
{
@@ -173,6 +236,8 @@ bgp_vty_safi_from_arg(const char *safi_str)
safi = SAFI_ENCAP;
else if (strncmp (safi_str, "v", 1) == 0)
safi = SAFI_MPLS_VPN;
+ else if (strncmp (safi_str, "l", 1) == 0)
+ safi = SAFI_LABELED_UNICAST;
return safi;
}
@@ -192,6 +257,12 @@ argv_find_and_parse_safi (struct cmd_token **argv, int argc, int *index, safi_t
if (safi)
*safi = SAFI_MULTICAST;
}
+ else if (argv_find (argv, argc, "labeled-unicast", index))
+ {
+ ret = 1;
+ if (safi)
+ *safi = SAFI_LABELED_UNICAST;
+ }
else if (argv_find (argv, argc, "vpn", index))
{
ret = 1;
@@ -223,12 +294,12 @@ argv_find_and_parse_safi (struct cmd_token **argv, int argc, int *index, safi_t
* that is being parsed.
*
* The show commands are generally of the form:
- * "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] ..."
+ * "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] ..."
*
* Since we use argv_find if the show command in particular doesn't have:
* [ip]
* [<view|vrf> WORD]
- * [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]]
+ * [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]]
* The command parsing should still be ok.
*
* vty -> The vty for the command so we can output some useful data in
@@ -1495,6 +1566,12 @@ DEFUN (bgp_maxpaths,
return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, argv[idx_number]->arg, 0, 1);
}
+ALIAS_HIDDEN (bgp_maxpaths,
+ bgp_maxpaths_hidden_cmd,
+ "maximum-paths (1-255)",
+ "Forward packets over multiple paths\n"
+ "Number of paths\n")
+
DEFUN (bgp_maxpaths_ibgp,
bgp_maxpaths_ibgp_cmd,
"maximum-paths ibgp (1-255)",
@@ -1506,6 +1583,13 @@ DEFUN (bgp_maxpaths_ibgp,
return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, argv[idx_number]->arg, 0, 1);
}
+ALIAS_HIDDEN (bgp_maxpaths_ibgp,
+ bgp_maxpaths_ibgp_hidden_cmd,
+ "maximum-paths ibgp (1-255)",
+ "Forward packets over multiple paths\n"
+ "iBGP-multipath\n"
+ "Number of paths\n")
+
DEFUN (bgp_maxpaths_ibgp_cluster,
bgp_maxpaths_ibgp_cluster_cmd,
"maximum-paths ibgp (1-255) equal-cluster-length",
@@ -1519,6 +1603,14 @@ DEFUN (bgp_maxpaths_ibgp_cluster,
BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN, 1);
}
+ALIAS_HIDDEN (bgp_maxpaths_ibgp_cluster,
+ bgp_maxpaths_ibgp_cluster_hidden_cmd,
+ "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")
+
DEFUN (no_bgp_maxpaths,
no_bgp_maxpaths_cmd,
"no maximum-paths [(1-255)]",
@@ -1529,6 +1621,13 @@ DEFUN (no_bgp_maxpaths,
return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, NULL, 0, 0);
}
+ALIAS_HIDDEN (no_bgp_maxpaths,
+ no_bgp_maxpaths_hidden_cmd,
+ "no maximum-paths [(1-255)]",
+ 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 [(1-255) [equal-cluster-length]]",
@@ -1541,6 +1640,15 @@ DEFUN (no_bgp_maxpaths_ibgp,
return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, NULL, 0, 0);
}
+ALIAS_HIDDEN (no_bgp_maxpaths_ibgp,
+ no_bgp_maxpaths_ibgp_hidden_cmd,
+ "no maximum-paths ibgp [(1-255) [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)
@@ -2704,7 +2812,12 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
}
peer = peer_lookup_by_conf_if (bgp, conf_if);
- if (!peer)
+ if (peer)
+ {
+ if (as_str)
+ ret = peer_remote_as (bgp, &su, conf_if, &as, as_type, afi, safi);
+ }
+ else
{
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
&& afi == AFI_IP && safi == SAFI_UNICAST)
@@ -2728,8 +2841,9 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
if (peer->ifp)
bgp_zebra_initiate_radv (bgp, peer);
}
- else if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
- (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)))
+
+ if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
+ (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)))
{
if (v6only)
SET_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY);
@@ -3228,6 +3342,13 @@ DEFUN (neighbor_activate,
return CMD_SUCCESS;
}
+ALIAS_HIDDEN (neighbor_activate,
+ neighbor_activate_hidden_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Enable the Address Family for this Neighbor\n")
+
DEFUN (no_neighbor_activate,
no_neighbor_activate_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
@@ -3252,6 +3373,14 @@ DEFUN (no_neighbor_activate,
return CMD_SUCCESS;
}
+ALIAS_HIDDEN (no_neighbor_activate,
+ no_neighbor_activate_hidden_cmd,
+ "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")
+
DEFUN (neighbor_set_peer_group,
neighbor_set_peer_group_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD",
@@ -3318,6 +3447,14 @@ DEFUN (neighbor_set_peer_group,
return bgp_vty_return (vty, ret);
}
+ALIAS_HIDDEN (neighbor_set_peer_group,
+ neighbor_set_peer_group_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_set_peer_group,
no_neighbor_set_peer_group_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD",
@@ -3350,6 +3487,15 @@ DEFUN (no_neighbor_set_peer_group,
return bgp_vty_return (vty, ret);
}
+ALIAS_HIDDEN (no_neighbor_set_peer_group,
+ no_neighbor_set_peer_group_hidden_cmd,
+ "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")
+
static int
peer_flag_modify_vty (struct vty *vty, const char *ip_str,
u_int16_t flag, int set)
@@ -3614,6 +3760,18 @@ DEFUN (neighbor_capability_orf_prefix,
bgp_node_safi (vty), flag);
}
+ALIAS_HIDDEN (neighbor_capability_orf_prefix,
+ neighbor_capability_orf_prefix_hidden_cmd,
+ "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"
+ "Advertise ORF capability to the peer\n"
+ "Advertise prefixlist ORF capability to this neighbor\n"
+ "Capability to SEND and RECEIVE the ORF to/from this neighbor\n"
+ "Capability to RECEIVE the ORF from this neighbor\n"
+ "Capability to SEND the ORF to this neighbor\n")
+
DEFUN (no_neighbor_capability_orf_prefix,
no_neighbor_capability_orf_prefix_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> capability orf prefix-list <both|send|receive>",
@@ -3644,6 +3802,19 @@ DEFUN (no_neighbor_capability_orf_prefix,
bgp_node_safi (vty), flag);
}
+ALIAS_HIDDEN (no_neighbor_capability_orf_prefix,
+ no_neighbor_capability_orf_prefix_hidden_cmd,
+ "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
+ "Advertise capability to the peer\n"
+ "Advertise ORF capability to the peer\n"
+ "Advertise prefixlist ORF capability to this neighbor\n"
+ "Capability to SEND and RECEIVE the ORF to/from this neighbor\n"
+ "Capability to RECEIVE the ORF from this neighbor\n"
+ "Capability to SEND the ORF to this neighbor\n")
+
/* neighbor next-hop-self. */
DEFUN (neighbor_nexthop_self,
neighbor_nexthop_self_cmd,
@@ -3657,6 +3828,13 @@ DEFUN (neighbor_nexthop_self,
bgp_node_safi (vty), PEER_FLAG_NEXTHOP_SELF);
}
+ALIAS_HIDDEN (neighbor_nexthop_self,
+ neighbor_nexthop_self_hidden_cmd,
+ "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")
+
/* neighbor next-hop-self. */
DEFUN (neighbor_nexthop_self_force,
neighbor_nexthop_self_force_cmd,
@@ -3672,6 +3850,14 @@ DEFUN (neighbor_nexthop_self_force,
PEER_FLAG_FORCE_NEXTHOP_SELF);
}
+ALIAS_HIDDEN (neighbor_nexthop_self_force,
+ neighbor_nexthop_self_force_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_nexthop_self,
no_neighbor_nexthop_self_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self",
@@ -3686,6 +3872,14 @@ DEFUN (no_neighbor_nexthop_self,
PEER_FLAG_NEXTHOP_SELF);
}
+ALIAS_HIDDEN (no_neighbor_nexthop_self,
+ no_neighbor_nexthop_self_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_nexthop_self_force,
no_neighbor_nexthop_self_force_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self force",
@@ -3701,6 +3895,15 @@ DEFUN (no_neighbor_nexthop_self_force,
PEER_FLAG_FORCE_NEXTHOP_SELF);
}
+ALIAS_HIDDEN (no_neighbor_nexthop_self_force,
+ no_neighbor_nexthop_self_force_hidden_cmd,
+ "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")
+
/* neighbor as-override */
DEFUN (neighbor_as_override,
neighbor_as_override_cmd,
@@ -3715,6 +3918,13 @@ DEFUN (neighbor_as_override,
PEER_FLAG_AS_OVERRIDE);
}
+ALIAS_HIDDEN (neighbor_as_override,
+ neighbor_as_override_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_as_override,
no_neighbor_as_override_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> as-override",
@@ -3729,6 +3939,14 @@ DEFUN (no_neighbor_as_override,
PEER_FLAG_AS_OVERRIDE);
}
+ALIAS_HIDDEN (no_neighbor_as_override,
+ no_neighbor_as_override_hidden_cmd,
+ "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")
+
/* neighbor remove-private-AS. */
DEFUN (neighbor_remove_private_as,
neighbor_remove_private_as_cmd,
@@ -3743,6 +3961,13 @@ DEFUN (neighbor_remove_private_as,
PEER_FLAG_REMOVE_PRIVATE_AS);
}
+ALIAS_HIDDEN (neighbor_remove_private_as,
+ neighbor_remove_private_as_hidden_cmd,
+ "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")
+
DEFUN (neighbor_remove_private_as_all,
neighbor_remove_private_as_all_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS all",
@@ -3757,6 +3982,14 @@ DEFUN (neighbor_remove_private_as_all,
PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
}
+ALIAS_HIDDEN (neighbor_remove_private_as_all,
+ neighbor_remove_private_as_all_hidden_cmd,
+ "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")
+
DEFUN (neighbor_remove_private_as_replace_as,
neighbor_remove_private_as_replace_as_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS replace-AS",
@@ -3771,6 +4004,14 @@ DEFUN (neighbor_remove_private_as_replace_as,
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
}
+ALIAS_HIDDEN (neighbor_remove_private_as_replace_as,
+ neighbor_remove_private_as_replace_as_hidden_cmd,
+ "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")
+
DEFUN (neighbor_remove_private_as_all_replace_as,
neighbor_remove_private_as_all_replace_as_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS all replace-AS",
@@ -3786,6 +4027,15 @@ DEFUN (neighbor_remove_private_as_all_replace_as,
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE);
}
+ALIAS_HIDDEN (neighbor_remove_private_as_all_replace_as,
+ neighbor_remove_private_as_all_replace_as_hidden_cmd,
+ "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\n"
+ "Replace private ASNs with our ASN in outbound updates\n")
+
DEFUN (no_neighbor_remove_private_as,
no_neighbor_remove_private_as_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS",
@@ -3800,6 +4050,14 @@ DEFUN (no_neighbor_remove_private_as,
PEER_FLAG_REMOVE_PRIVATE_AS);
}
+ALIAS_HIDDEN (no_neighbor_remove_private_as,
+ no_neighbor_remove_private_as_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_remove_private_as_all,
no_neighbor_remove_private_as_all_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS all",
@@ -3815,6 +4073,15 @@ DEFUN (no_neighbor_remove_private_as_all,
PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
}
+ALIAS_HIDDEN (no_neighbor_remove_private_as_all,
+ no_neighbor_remove_private_as_all_hidden_cmd,
+ "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\n")
+
DEFUN (no_neighbor_remove_private_as_replace_as,
no_neighbor_remove_private_as_replace_as_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS replace-AS",
@@ -3830,6 +4097,15 @@ DEFUN (no_neighbor_remove_private_as_replace_as,
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
}
+ALIAS_HIDDEN (no_neighbor_remove_private_as_replace_as,
+ no_neighbor_remove_private_as_replace_as_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_remove_private_as_all_replace_as,
no_neighbor_remove_private_as_all_replace_as_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> remove-private-AS all replace-AS",
@@ -3846,6 +4122,16 @@ DEFUN (no_neighbor_remove_private_as_all_replace_as,
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE);
}
+ALIAS_HIDDEN (no_neighbor_remove_private_as_all_replace_as,
+ no_neighbor_remove_private_as_all_replace_as_hidden_cmd,
+ "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\n"
+ "Replace private ASNs with our ASN in outbound updates\n")
+
/* neighbor send-community. */
DEFUN (neighbor_send_community,
@@ -3861,6 +4147,13 @@ DEFUN (neighbor_send_community,
PEER_FLAG_SEND_COMMUNITY);
}
+ALIAS_HIDDEN (neighbor_send_community,
+ neighbor_send_community_hidden_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> send-community",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Send Community attribute to this neighbor\n")
+
DEFUN (no_neighbor_send_community,
no_neighbor_send_community_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> send-community",
@@ -3875,6 +4168,14 @@ DEFUN (no_neighbor_send_community,
PEER_FLAG_SEND_COMMUNITY);
}
+ALIAS_HIDDEN (no_neighbor_send_community,
+ no_neighbor_send_community_hidden_cmd,
+ "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")
+
/* neighbor send-community extended. */
DEFUN (neighbor_send_community_type,
neighbor_send_community_type_cmd,
@@ -3914,6 +4215,18 @@ DEFUN (neighbor_send_community_type,
return peer_af_flag_set_vty (vty, peer, bgp_node_afi (vty), bgp_node_safi (vty), flag);
}
+ALIAS_HIDDEN (neighbor_send_community_type,
+ neighbor_send_community_type_hidden_cmd,
+ "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 Large Community attributes\n")
+
DEFUN (no_neighbor_send_community_type,
no_neighbor_send_community_type_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> send-community <both|all|extended|standard|large>",
@@ -3954,6 +4267,19 @@ DEFUN (no_neighbor_send_community_type,
PEER_FLAG_SEND_LARGE_COMMUNITY));
}
+ALIAS_HIDDEN (no_neighbor_send_community_type,
+ no_neighbor_send_community_type_hidden_cmd,
+ "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 Large Community attributes\n")
+
/* neighbor soft-reconfig. */
DEFUN (neighbor_soft_reconfiguration,
neighbor_soft_reconfiguration_cmd,
@@ -3969,6 +4295,14 @@ DEFUN (neighbor_soft_reconfiguration,
PEER_FLAG_SOFT_RECONFIG);
}
+ALIAS_HIDDEN (neighbor_soft_reconfiguration,
+ neighbor_soft_reconfiguration_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_soft_reconfiguration,
no_neighbor_soft_reconfiguration_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> soft-reconfiguration inbound",
@@ -3984,6 +4318,15 @@ DEFUN (no_neighbor_soft_reconfiguration,
PEER_FLAG_SOFT_RECONFIG);
}
+ALIAS_HIDDEN (no_neighbor_soft_reconfiguration,
+ no_neighbor_soft_reconfiguration_hidden_cmd,
+ "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")
+
DEFUN (neighbor_route_reflector_client,
neighbor_route_reflector_client_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> route-reflector-client",
@@ -4004,6 +4347,13 @@ DEFUN (neighbor_route_reflector_client,
PEER_FLAG_REFLECTOR_CLIENT);
}
+ALIAS_HIDDEN (neighbor_route_reflector_client,
+ neighbor_route_reflector_client_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_route_reflector_client,
no_neighbor_route_reflector_client_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> route-reflector-client",
@@ -4018,6 +4368,14 @@ DEFUN (no_neighbor_route_reflector_client,
PEER_FLAG_REFLECTOR_CLIENT);
}
+ALIAS_HIDDEN (no_neighbor_route_reflector_client,
+ no_neighbor_route_reflector_client_hidden_cmd,
+ "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")
+
/* neighbor route-server-client. */
DEFUN (neighbor_route_server_client,
neighbor_route_server_client_cmd,
@@ -4037,6 +4395,13 @@ DEFUN (neighbor_route_server_client,
PEER_FLAG_RSERVER_CLIENT);
}
+ALIAS_HIDDEN (neighbor_route_server_client,
+ neighbor_route_server_client_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_route_server_client,
no_neighbor_route_server_client_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> route-server-client",
@@ -4051,6 +4416,14 @@ DEFUN (no_neighbor_route_server_client,
PEER_FLAG_RSERVER_CLIENT);
}
+ALIAS_HIDDEN (no_neighbor_route_server_client,
+ no_neighbor_route_server_client_hidden_cmd,
+ "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")
+
DEFUN (neighbor_nexthop_local_unchanged,
neighbor_nexthop_local_unchanged_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> nexthop-local unchanged",
@@ -4130,6 +4503,33 @@ DEFUN (neighbor_attr_unchanged,
return peer_af_flag_set_vty (vty, peer, bgp_node_afi (vty), bgp_node_safi (vty), flags);
}
+ALIAS_HIDDEN (neighbor_attr_unchanged,
+ neighbor_attr_unchanged_hidden_cmd,
+ "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"
+ "Med attribute\n"
+ "Nexthop attribute\n"
+ "Nexthop attribute\n"
+ "As-path 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")
+
DEFUN (no_neighbor_attr_unchanged,
no_neighbor_attr_unchanged_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> attribute-unchanged\
@@ -4181,6 +4581,34 @@ DEFUN (no_neighbor_attr_unchanged,
return peer_af_flag_unset_vty (vty, peer, bgp_node_afi (vty), bgp_node_safi (vty), flags);
}
+ALIAS_HIDDEN (no_neighbor_attr_unchanged,
+ no_neighbor_attr_unchanged_hidden_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"
+ "Med attribute\n"
+ "Nexthop attribute\n"
+ "Nexthop attribute\n"
+ "As-path 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")
+
/* EBGP multihop configuration. */
static int
@@ -4434,6 +4862,13 @@ DEFUN (neighbor_default_originate,
bgp_node_safi (vty), NULL, 1);
}
+ALIAS_HIDDEN (neighbor_default_originate,
+ neighbor_default_originate_hidden_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> default-originate",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Originate default route to this neighbor\n")
+
DEFUN (neighbor_default_originate_rmap,
neighbor_default_originate_rmap_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> default-originate route-map WORD",
@@ -4449,6 +4884,15 @@ DEFUN (neighbor_default_originate_rmap,
bgp_node_safi (vty), argv[idx_word]->arg, 1);
}
+ALIAS_HIDDEN (neighbor_default_originate_rmap,
+ neighbor_default_originate_rmap_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_default_originate,
no_neighbor_default_originate_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> default-originate [route-map WORD]",
@@ -4464,6 +4908,16 @@ DEFUN (no_neighbor_default_originate,
bgp_node_safi (vty), NULL, 0);
}
+ALIAS_HIDDEN (no_neighbor_default_originate,
+ no_neighbor_default_originate_hidden_cmd,
+ "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"
+ "Route-map to specify criteria to originate default\n"
+ "route-map name\n")
+
/* Set neighbor's BGP port. */
static int
@@ -4573,6 +5027,14 @@ DEFUN (neighbor_weight,
argv[idx_number]->arg);
}
+ALIAS_HIDDEN (neighbor_weight,
+ neighbor_weight_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_weight,
no_neighbor_weight_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> weight [(0-65535)]",
@@ -4586,6 +5048,15 @@ DEFUN (no_neighbor_weight,
return peer_weight_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty), bgp_node_safi (vty));
}
+ALIAS_HIDDEN (no_neighbor_weight,
+ no_neighbor_weight_hidden_cmd,
+ "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"
+ "default weight\n")
+
/* Override capability negotiation. */
DEFUN (neighbor_override_capability,
@@ -4971,6 +5442,18 @@ DEFUN (neighbor_distribute_list,
bgp_node_safi (vty), argv[idx_acl]->arg, argv[idx_in_out]->arg);
}
+ALIAS_HIDDEN (neighbor_distribute_list,
+ neighbor_distribute_list_hidden_cmd,
+ "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"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n"
+ "Filter incoming updates\n"
+ "Filter outgoing updates\n")
+
DEFUN (no_neighbor_distribute_list,
no_neighbor_distribute_list_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list <(1-199)|(1300-2699)|WORD> <in|out>",
@@ -4990,6 +5473,19 @@ DEFUN (no_neighbor_distribute_list,
bgp_node_safi (vty), argv[idx_in_out]->arg);
}
+ALIAS_HIDDEN (no_neighbor_distribute_list,
+ no_neighbor_distribute_list_hidden_cmd,
+ "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
+ "Filter updates to/from this neighbor\n"
+ "IP access-list number\n"
+ "IP access-list number (expanded range)\n"
+ "IP Access-list name\n"
+ "Filter incoming updates\n"
+ "Filter outgoing updates\n")
+
/* Set prefix list to the peer. */
static int
peer_prefix_list_set_vty (struct vty *vty, const char *ip_str, afi_t afi,
@@ -5055,6 +5551,16 @@ DEFUN (neighbor_prefix_list,
bgp_node_safi (vty), argv[idx_word]->arg, argv[idx_in_out]->arg);
}
+ALIAS_HIDDEN (neighbor_prefix_list,
+ neighbor_prefix_list_hidden_cmd,
+ "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"
+ "Name of a prefix list\n"
+ "Filter incoming updates\n"
+ "Filter outgoing updates\n")
+
DEFUN (no_neighbor_prefix_list,
no_neighbor_prefix_list_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>",
@@ -5072,6 +5578,17 @@ DEFUN (no_neighbor_prefix_list,
bgp_node_safi (vty), argv[idx_in_out]->arg);
}
+ALIAS_HIDDEN (no_neighbor_prefix_list,
+ no_neighbor_prefix_list_hidden_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Filter updates to/from this neighbor\n"
+ "Name of a prefix list\n"
+ "Filter incoming updates\n"
+ "Filter outgoing updates\n")
+
static int
peer_aslist_set_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
@@ -5137,6 +5654,16 @@ DEFUN (neighbor_filter_list,
bgp_node_safi (vty), argv[idx_word]->arg, argv[idx_in_out]->arg);
}
+ALIAS_HIDDEN (neighbor_filter_list,
+ neighbor_filter_list_hidden_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> filter-list WORD <in|out>",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Establish BGP filters\n"
+ "AS path access-list name\n"
+ "Filter incoming routes\n"
+ "Filter outgoing routes\n")
+
DEFUN (no_neighbor_filter_list,
no_neighbor_filter_list_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> filter-list WORD <in|out>",
@@ -5154,6 +5681,17 @@ DEFUN (no_neighbor_filter_list,
bgp_node_safi (vty), argv[idx_in_out]->arg);
}
+ALIAS_HIDDEN (no_neighbor_filter_list,
+ no_neighbor_filter_list_hidden_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> filter-list WORD <in|out>",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Establish BGP filters\n"
+ "AS path access-list name\n"
+ "Filter incoming routes\n"
+ "Filter outgoing routes\n")
+
/* Set route-map to the peer. */
static int
peer_route_map_set_vty (struct vty *vty, const char *ip_str,
@@ -5219,6 +5757,16 @@ DEFUN (neighbor_route_map,
bgp_node_safi (vty), argv[idx_word]->arg, argv[idx_in_out]->arg);
}
+ALIAS_HIDDEN (neighbor_route_map,
+ neighbor_route_map_hidden_cmd,
+ "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"
+ "Name of route map\n"
+ "Apply map to incoming routes\n"
+ "Apply map to outbound routes\n")
+
DEFUN (no_neighbor_route_map,
no_neighbor_route_map_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>",
@@ -5236,6 +5784,17 @@ DEFUN (no_neighbor_route_map,
bgp_node_safi (vty), argv[idx_in_out]->arg);
}
+ALIAS_HIDDEN (no_neighbor_route_map,
+ no_neighbor_route_map_hidden_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Apply route map to neighbor\n"
+ "Name of route map\n"
+ "Apply map to incoming routes\n"
+ "Apply map to outbound routes\n")
+
/* Set unsuppress-map to the peer. */
static int
peer_unsuppress_map_set_vty (struct vty *vty, const char *ip_str, afi_t afi,
@@ -5284,6 +5843,14 @@ DEFUN (neighbor_unsuppress_map,
bgp_node_safi (vty), argv[idx_word]->arg);
}
+ALIAS_HIDDEN (neighbor_unsuppress_map,
+ neighbor_unsuppress_map_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_unsuppress_map,
no_neighbor_unsuppress_map_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> unsuppress-map WORD",
@@ -5298,6 +5865,15 @@ DEFUN (no_neighbor_unsuppress_map,
bgp_node_safi (vty));
}
+ALIAS_HIDDEN (no_neighbor_unsuppress_map,
+ no_neighbor_unsuppress_map_hidden_cmd,
+ "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")
+
static int
peer_maximum_prefix_set_vty (struct vty *vty, const char *ip_str, afi_t afi,
safi_t safi, const char *num_str,
@@ -5364,6 +5940,14 @@ DEFUN (neighbor_maximum_prefix,
NULL);
}
+ALIAS_HIDDEN (neighbor_maximum_prefix,
+ neighbor_maximum_prefix_hidden_cmd,
+ "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")
+
DEFUN (neighbor_maximum_prefix_threshold,
neighbor_maximum_prefix_threshold_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100)",
@@ -5381,6 +5965,15 @@ DEFUN (neighbor_maximum_prefix_threshold,
NULL);
}
+ALIAS_HIDDEN (neighbor_maximum_prefix_threshold,
+ neighbor_maximum_prefix_threshold_hidden_cmd,
+ "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")
+
DEFUN (neighbor_maximum_prefix_warning,
neighbor_maximum_prefix_warning_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) warning-only",
@@ -5397,6 +5990,15 @@ DEFUN (neighbor_maximum_prefix_warning,
NULL);
}
+ALIAS_HIDDEN (neighbor_maximum_prefix_warning,
+ neighbor_maximum_prefix_warning_hidden_cmd,
+ "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")
+
DEFUN (neighbor_maximum_prefix_threshold_warning,
neighbor_maximum_prefix_threshold_warning_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) warning-only",
@@ -5414,6 +6016,16 @@ DEFUN (neighbor_maximum_prefix_threshold_warning,
bgp_node_safi (vty), argv[idx_number]->arg, argv[idx_number_2]->arg, 1, NULL);
}
+ALIAS_HIDDEN (neighbor_maximum_prefix_threshold_warning,
+ neighbor_maximum_prefix_threshold_warning_hidden_cmd,
+ "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"
+ "maximum no. of prefix limit\n"
+ "Threshold value (%) at which to generate a warning msg\n"
+ "Only give warning message when limit is exceeded\n")
+
DEFUN (neighbor_maximum_prefix_restart,
neighbor_maximum_prefix_restart_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) restart (1-65535)",
@@ -5431,6 +6043,16 @@ DEFUN (neighbor_maximum_prefix_restart,
bgp_node_safi (vty), argv[idx_number]->arg, NULL, 0, argv[idx_number_2]->arg);
}
+ALIAS_HIDDEN (neighbor_maximum_prefix_restart,
+ neighbor_maximum_prefix_restart_hidden_cmd,
+ "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"
+ "maximum no. of prefix limit\n"
+ "Restart bgp connection after limit is exceeded\n"
+ "Restart interval in minutes")
+
DEFUN (neighbor_maximum_prefix_threshold_restart,
neighbor_maximum_prefix_threshold_restart_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100) restart (1-65535)",
@@ -5450,6 +6072,17 @@ DEFUN (neighbor_maximum_prefix_threshold_restart,
bgp_node_safi (vty), argv[idx_number]->arg, argv[idx_number_2]->arg, 0, argv[idx_number_3]->arg);
}
+ALIAS_HIDDEN (neighbor_maximum_prefix_threshold_restart,
+ neighbor_maximum_prefix_threshold_restart_hidden_cmd,
+ "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 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")
+
DEFUN (no_neighbor_maximum_prefix,
no_neighbor_maximum_prefix_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix [(1-4294967295) [(1-100)] [restart (1-65535)] [warning-only]]",
@@ -5468,6 +6101,19 @@ DEFUN (no_neighbor_maximum_prefix,
bgp_node_safi (vty));
}
+ALIAS_HIDDEN (no_neighbor_maximum_prefix,
+ no_neighbor_maximum_prefix_hidden_cmd,
+ "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 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")
+
/* "neighbor allowas-in" */
DEFUN (neighbor_allowas_in,
@@ -5506,6 +6152,15 @@ DEFUN (neighbor_allowas_in,
return bgp_vty_return (vty, ret);
}
+ALIAS_HIDDEN (neighbor_allowas_in,
+ neighbor_allowas_in_hidden_cmd,
+ "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"
+ "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 <A.B.C.D|X:X::X:X|WORD> allowas-in [<(1-10)|origin>]",
@@ -5529,6 +6184,16 @@ DEFUN (no_neighbor_allowas_in,
return bgp_vty_return (vty, ret);
}
+ALIAS_HIDDEN (no_neighbor_allowas_in,
+ no_neighbor_allowas_in_hidden_cmd,
+ "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"
+ "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 <A.B.C.D|X:X::X:X|WORD> ttl-security hops (1-254)",
@@ -5601,6 +6266,13 @@ DEFUN (neighbor_addpath_tx_all_paths,
PEER_FLAG_ADDPATH_TX_ALL_PATHS);
}
+ALIAS_HIDDEN (neighbor_addpath_tx_all_paths,
+ neighbor_addpath_tx_all_paths_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_addpath_tx_all_paths,
no_neighbor_addpath_tx_all_paths_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-all-paths",
@@ -5615,6 +6287,14 @@ DEFUN (no_neighbor_addpath_tx_all_paths,
PEER_FLAG_ADDPATH_TX_ALL_PATHS);
}
+ALIAS_HIDDEN (no_neighbor_addpath_tx_all_paths,
+ no_neighbor_addpath_tx_all_paths_hidden_cmd,
+ "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")
+
DEFUN (neighbor_addpath_tx_bestpath_per_as,
neighbor_addpath_tx_bestpath_per_as_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-bestpath-per-AS",
@@ -5634,6 +6314,13 @@ DEFUN (neighbor_addpath_tx_bestpath_per_as,
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS);
}
+ALIAS_HIDDEN (neighbor_addpath_tx_bestpath_per_as,
+ neighbor_addpath_tx_bestpath_per_as_hidden_cmd,
+ "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")
+
DEFUN (no_neighbor_addpath_tx_bestpath_per_as,
no_neighbor_addpath_tx_bestpath_per_as_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-bestpath-per-AS",
@@ -5648,32 +6335,26 @@ DEFUN (no_neighbor_addpath_tx_bestpath_per_as,
PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS);
}
+ALIAS_HIDDEN (no_neighbor_addpath_tx_bestpath_per_as,
+ no_neighbor_addpath_tx_bestpath_per_as_hidden_cmd,
+ "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")
+
DEFUN_NOSH (address_family_ipv4_safi,
address_family_ipv4_safi_cmd,
- "address-family ipv4 [<unicast|multicast|vpn|encap>]",
+ "address-family ipv4 [<unicast|multicast|vpn|encap|labeled-unicast>]",
"Enter Address Family command mode\n"
"Address Family\n"
BGP_SAFI_HELP_STR)
{
- int idx_safi = 2;
- if (argc == (idx_safi + 1))
+
+ if (argc == 3)
{
- 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;
- }
+ safi_t safi = bgp_vty_safi_from_arg(argv[2]->arg);
+ vty->node = bgp_node_type(AFI_IP, safi);
}
else
vty->node = BGP_IPV4_NODE;
@@ -5683,30 +6364,15 @@ DEFUN_NOSH (address_family_ipv4_safi,
DEFUN_NOSH (address_family_ipv6_safi,
address_family_ipv6_safi_cmd,
- "address-family ipv6 [<unicast|multicast|vpn|encap>]",
+ "address-family ipv6 [<unicast|multicast|vpn|encap|labeled-unicast>]",
"Enter Address Family command mode\n"
"Address Family\n"
BGP_SAFI_HELP_STR)
{
- int idx_safi = 2;
- if (argc == (idx_safi + 1))
+ if (argc == 3)
{
- 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;
- }
+ safi_t safi = bgp_vty_safi_from_arg(argv[2]->arg);
+ vty->node = bgp_node_type(AFI_IP6, safi);
}
else
vty->node = BGP_IPV6_NODE;
@@ -5779,9 +6445,11 @@ DEFUN_NOSH (exit_address_family,
{
if (vty->node == BGP_IPV4_NODE
|| vty->node == BGP_IPV4M_NODE
+ || vty->node == BGP_IPV4L_NODE
|| vty->node == BGP_VPNV4_NODE
|| vty->node == BGP_IPV6_NODE
|| vty->node == BGP_IPV6M_NODE
+ || vty->node == BGP_IPV6L_NODE
|| vty->node == BGP_VPNV6_NODE
|| vty->node == BGP_ENCAP_NODE
|| vty->node == BGP_ENCAPV6_NODE
@@ -6707,6 +7375,7 @@ bgp_show_summary_afi_safi (struct vty *vty, struct bgp *bgp, int afi, int safi,
int afi_wildcard = (afi == AFI_MAX);
int safi_wildcard = (safi == SAFI_MAX);
int is_wildcard = (afi_wildcard || safi_wildcard);
+ bool json_output = false;
if (use_json && is_wildcard)
vty_out (vty, "{%s", VTY_NEWLINE);
@@ -6720,6 +7389,7 @@ bgp_show_summary_afi_safi (struct vty *vty, struct bgp *bgp, int afi, int safi,
{
if (bgp_show_summary_afi_safi_peer_exists (bgp, afi, safi))
{
+ json_output = true;
if (is_wildcard)
{
/*
@@ -6760,7 +7430,8 @@ bgp_show_summary_afi_safi (struct vty *vty, struct bgp *bgp, int afi, int safi,
if (use_json && is_wildcard)
vty_out (vty, "}%s", VTY_NEWLINE);
-
+ else if (use_json && !json_output)
+ vty_out (vty, "{}%s", VTY_NEWLINE);
}
static void
@@ -6886,6 +7557,8 @@ afi_safi_print (afi_t afi, safi_t safi)
return "IPv4 Unicast";
else if (afi == AFI_IP && safi == SAFI_MULTICAST)
return "IPv4 Multicast";
+ else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
+ return "IPv4 labeled-unicast";
else if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
return "IPv4 VPN";
else if (afi == AFI_IP && safi == SAFI_ENCAP)
@@ -6894,6 +7567,8 @@ afi_safi_print (afi_t afi, safi_t safi)
return "IPv6 Unicast";
else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
return "IPv6 Multicast";
+ else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
+ return "IPv6 labeled-unicast";
else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN)
return "IPv6 VPN";
else if (afi == AFI_IP6 && safi == SAFI_ENCAP)
@@ -6917,6 +7592,8 @@ afi_safi_json (afi_t afi, safi_t safi)
return "ipv4Unicast";
else if (afi == AFI_IP && safi == SAFI_MULTICAST)
return "ipv4Multicast";
+ else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
+ return "ipv4LabeledUnicast";
else if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
return "ipv4Vpn";
else if (afi == AFI_IP && safi == SAFI_ENCAP)
@@ -6925,6 +7602,8 @@ afi_safi_json (afi_t afi, safi_t safi)
return "ipv6Unicast";
else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
return "ipv6Multicast";
+ else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
+ return "ipv6LabeledUnicast";
else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN)
return "ipv6Vpn";
else if (afi == AFI_IP6 && safi == SAFI_ENCAP)
@@ -7433,6 +8112,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
u_int16_t i;
u_char *msg;
json_object *json_neigh = NULL;
+ time_t epoch_tbuf;
bgp = p->bgp;
@@ -7622,8 +8302,11 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
uptime = bgp_clock();
uptime -= p->uptime;
tm = gmtime(&uptime);
+ epoch_tbuf = time(NULL) - uptime;
json_object_int_add(json_neigh, "bgpTimerUp", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000));
+ json_object_string_add(json_neigh, "bgpTimerUpString", peer_uptime (p->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL));
+ json_object_int_add(json_neigh, "bgpTimerUpEstablishedEpoch", epoch_tbuf);
}
else if (p->status == Active)
@@ -8554,6 +9237,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
json_object_int_add(json_neigh, "mraiInterval", p->v_routeadv);
json_object_int_add(json_neigh, "mraiTimerExpireInMsecs", thread_timer_remain_second (p->t_routeadv) * 1000);
}
+ if (p->password)
+ json_object_int_add(json_neigh, "authenticationEnabled", 1);
if (p->t_read)
json_object_string_add(json_neigh, "readThread", "on");
@@ -8581,6 +9266,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
vty_out (vty, "MRAI (interval %u) timer expires in %ld seconds%s",
p->v_routeadv, thread_timer_remain_second (p->t_routeadv),
VTY_NEWLINE);
+ if (p->password)
+ vty_out (vty, "Peer Authentication Enabled%s", VTY_NEWLINE);
vty_out (vty, "Read thread: %s Write thread: %s%s",
p->t_read ? "on" : "off",
@@ -9499,6 +10186,12 @@ DEFUN (bgp_redistribute_ipv4,
return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4,
+ bgp_redistribute_ipv4_hidden_cmd,
+ "redistribute " FRR_IP_REDIST_STR_BGPD,
+ "Redistribute information from another routing protocol\n"
+ FRR_IP_REDIST_HELP_STR_BGPD)
+
DEFUN (bgp_redistribute_ipv4_rmap,
bgp_redistribute_ipv4_rmap_cmd,
"redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD",
@@ -9525,6 +10218,14 @@ DEFUN (bgp_redistribute_ipv4_rmap,
return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4_rmap,
+ bgp_redistribute_ipv4_rmap_hidden_cmd,
+ "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD",
+ "Redistribute information from another routing protocol\n"
+ FRR_IP_REDIST_HELP_STR_BGPD
+ "Route map reference\n"
+ "Pointer to route-map entries\n")
+
DEFUN (bgp_redistribute_ipv4_metric,
bgp_redistribute_ipv4_metric_cmd,
"redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295)",
@@ -9553,6 +10254,14 @@ DEFUN (bgp_redistribute_ipv4_metric,
return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4_metric,
+ bgp_redistribute_ipv4_metric_hidden_cmd,
+ "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")
+
DEFUN (bgp_redistribute_ipv4_rmap_metric,
bgp_redistribute_ipv4_rmap_metric_cmd,
"redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD metric (0-4294967295)",
@@ -9585,6 +10294,16 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4_rmap_metric,
+ bgp_redistribute_ipv4_rmap_metric_hidden_cmd,
+ "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"
+ "Pointer to route-map entries\n"
+ "Metric for redistributed routes\n"
+ "Default metric\n")
+
DEFUN (bgp_redistribute_ipv4_metric_rmap,
bgp_redistribute_ipv4_metric_rmap_cmd,
"redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295) route-map WORD",
@@ -9617,6 +10336,16 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
return bgp_redistribute_set (bgp, AFI_IP, type, 0);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4_metric_rmap,
+ bgp_redistribute_ipv4_metric_rmap_hidden_cmd,
+ "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"
+ "Default metric\n"
+ "Route map reference\n"
+ "Pointer to route-map entries\n")
+
DEFUN (bgp_redistribute_ipv4_ospf,
bgp_redistribute_ipv4_ospf_cmd,
"redistribute <ospf|table> (1-65535)",
@@ -9642,6 +10371,14 @@ DEFUN (bgp_redistribute_ipv4_ospf,
return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4_ospf,
+ bgp_redistribute_ipv4_ospf_hidden_cmd,
+ "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")
+
DEFUN (bgp_redistribute_ipv4_ospf_rmap,
bgp_redistribute_ipv4_ospf_rmap_cmd,
"redistribute <ospf|table> (1-65535) route-map WORD",
@@ -9671,6 +10408,16 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap,
return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4_ospf_rmap,
+ bgp_redistribute_ipv4_ospf_rmap_hidden_cmd,
+ "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"
+ "Instance ID/Table ID\n"
+ "Route map reference\n"
+ "Pointer to route-map entries\n")
+
DEFUN (bgp_redistribute_ipv4_ospf_metric,
bgp_redistribute_ipv4_ospf_metric_cmd,
"redistribute <ospf|table> (1-65535) metric (0-4294967295)",
@@ -9703,6 +10450,16 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric,
return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4_ospf_metric,
+ bgp_redistribute_ipv4_ospf_metric_hidden_cmd,
+ "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"
+ "Instance ID/Table ID\n"
+ "Metric for redistributed routes\n"
+ "Default metric\n")
+
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)",
@@ -9739,6 +10496,18 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4_ospf_rmap_metric,
+ bgp_redistribute_ipv4_ospf_rmap_metric_hidden_cmd,
+ "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"
+ "Instance ID/Table ID\n"
+ "Route map reference\n"
+ "Pointer to route-map entries\n"
+ "Metric for redistributed routes\n"
+ "Default metric\n")
+
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",
@@ -9775,6 +10544,18 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
return bgp_redistribute_set (bgp, AFI_IP, protocol, instance);
}
+ALIAS_HIDDEN (bgp_redistribute_ipv4_ospf_metric_rmap,
+ bgp_redistribute_ipv4_ospf_metric_rmap_hidden_cmd,
+ "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"
+ "Instance ID/Table ID\n"
+ "Metric for redistributed routes\n"
+ "Default metric\n"
+ "Route map reference\n"
+ "Pointer to route-map entries\n")
+
DEFUN (no_bgp_redistribute_ipv4_ospf,
no_bgp_redistribute_ipv4_ospf_cmd,
"no redistribute <ospf|table> (1-65535) [metric (0-4294967295)] [route-map WORD]",
@@ -9803,6 +10584,19 @@ DEFUN (no_bgp_redistribute_ipv4_ospf,
return bgp_redistribute_unset (bgp, AFI_IP, protocol, instance);
}
+ALIAS_HIDDEN (no_bgp_redistribute_ipv4_ospf,
+ no_bgp_redistribute_ipv4_ospf_hidden_cmd,
+ "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"
+ "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 " [metric (0-4294967295)] [route-map WORD]",
@@ -9827,6 +10621,17 @@ DEFUN (no_bgp_redistribute_ipv4,
return bgp_redistribute_unset (bgp, AFI_IP, type, 0);
}
+ALIAS_HIDDEN (no_bgp_redistribute_ipv4,
+ no_bgp_redistribute_ipv4_hidden_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,
@@ -10056,6 +10861,13 @@ static struct cmd_node bgp_ipv4_multicast_node =
1,
};
+static struct cmd_node bgp_ipv4_labeled_unicast_node =
+{
+ BGP_IPV4L_NODE,
+ "%s(config-router-af)# ",
+ 1,
+};
+
static struct cmd_node bgp_ipv6_unicast_node =
{
BGP_IPV6_NODE,
@@ -10070,6 +10882,13 @@ static struct cmd_node bgp_ipv6_multicast_node =
1,
};
+static struct cmd_node bgp_ipv6_labeled_unicast_node =
+{
+ BGP_IPV6L_NODE,
+ "%s(config-router-af)# ",
+ 1,
+};
+
static struct cmd_node bgp_vpnv4_node =
{
BGP_VPNV4_NODE,
@@ -10107,15 +10926,70 @@ static struct cmd_node bgp_evpn_node =
static void community_list_vty (void);
+static void
+bgp_ac_neighbor (vector comps, struct cmd_token *token)
+{
+ struct bgp *bgp;
+ struct peer *peer;
+ struct peer_group *group;
+ struct listnode *lnbgp, *lnpeer;
+
+ for (ALL_LIST_ELEMENTS_RO (bm->bgp, lnbgp, bgp))
+ {
+ for (ALL_LIST_ELEMENTS_RO (bgp->peer, lnpeer, peer))
+ {
+ /* only provide suggestions on the appropriate input token type,
+ * they'll otherwise show up multiple times */
+ enum cmd_token_type match_type;
+ char *name = peer->host;
+
+ if (peer->conf_if)
+ {
+ match_type = VARIABLE_TKN;
+ name = peer->conf_if;
+ }
+ else if (strchr(peer->host, ':'))
+ match_type = IPV6_TKN;
+ else
+ match_type = IPV4_TKN;
+
+ if (token->type != match_type)
+ continue;
+
+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION, name));
+ }
+
+ if (token->type == VARIABLE_TKN)
+ for (ALL_LIST_ELEMENTS_RO (bgp->group, lnpeer, group))
+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION, group->name));
+ }
+}
+
+static const struct cmd_variable_handler bgp_var_neighbor[] = {
+ {
+ .varname = "neighbor",
+ .completions = bgp_ac_neighbor
+ }, {
+ .varname = "neighbors",
+ .completions = bgp_ac_neighbor
+ }, {
+ .completions = NULL
+ }
+};
+
void
bgp_vty_init (void)
{
+ cmd_variable_handler_register(bgp_var_neighbor);
+
/* Install bgp top node. */
install_node (&bgp_node, bgp_config_write);
install_node (&bgp_ipv4_unicast_node, NULL);
install_node (&bgp_ipv4_multicast_node, NULL);
+ install_node (&bgp_ipv4_labeled_unicast_node, NULL);
install_node (&bgp_ipv6_unicast_node, NULL);
install_node (&bgp_ipv6_multicast_node, NULL);
+ install_node (&bgp_ipv6_labeled_unicast_node, NULL);
install_node (&bgp_vpnv4_node, NULL);
install_node (&bgp_vpnv6_node, NULL);
install_node (&bgp_encap_node, NULL);
@@ -10126,8 +11000,10 @@ bgp_vty_init (void)
install_default (BGP_NODE);
install_default (BGP_IPV4_NODE);
install_default (BGP_IPV4M_NODE);
+ install_default (BGP_IPV4L_NODE);
install_default (BGP_IPV6_NODE);
install_default (BGP_IPV6M_NODE);
+ install_default (BGP_IPV6L_NODE);
install_default (BGP_VPNV4_NODE);
install_default (BGP_VPNV6_NODE);
install_default (BGP_ENCAP_NODE);
@@ -10196,22 +11072,34 @@ bgp_vty_init (void)
install_element (BGP_NODE, &no_bgp_coalesce_time_cmd);
/* "maximum-paths" commands. */
- install_element (BGP_NODE, &bgp_maxpaths_cmd);
- install_element (BGP_NODE, &no_bgp_maxpaths_cmd);
+ install_element (BGP_NODE, &bgp_maxpaths_hidden_cmd);
+ install_element (BGP_NODE, &no_bgp_maxpaths_hidden_cmd);
install_element (BGP_IPV4_NODE, &bgp_maxpaths_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_cmd);
install_element (BGP_IPV6_NODE, &bgp_maxpaths_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_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, &bgp_maxpaths_ibgp_hidden_cmd);
+ install_element (BGP_NODE, &bgp_maxpaths_ibgp_cluster_hidden_cmd);
+ install_element (BGP_NODE, &no_bgp_maxpaths_ibgp_hidden_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, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_maxpaths_ibgp_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, &bgp_maxpaths_ibgp_cluster_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_maxpaths_ibgp_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_maxpaths_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_maxpaths_cmd);
+ install_element (BGP_IPV6L_NODE, &bgp_maxpaths_cmd);
+ install_element (BGP_IPV6L_NODE, &no_bgp_maxpaths_cmd);
+
+ install_element (BGP_IPV4L_NODE, &bgp_maxpaths_ibgp_cmd);
+ install_element (BGP_IPV4L_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
+ install_element (BGP_IPV4L_NODE, &no_bgp_maxpaths_ibgp_cmd);
+ install_element (BGP_IPV6L_NODE, &bgp_maxpaths_ibgp_cmd);
+ install_element (BGP_IPV6L_NODE, &bgp_maxpaths_ibgp_cluster_cmd);
+ install_element (BGP_IPV6L_NODE, &no_bgp_maxpaths_ibgp_cmd);
+
/* "timers bgp" commands. */
install_element (BGP_NODE, &bgp_timers_cmd);
install_element (BGP_NODE, &no_bgp_timers_cmd);
@@ -10337,11 +11225,13 @@ bgp_vty_init (void)
install_element (BGP_NODE, &no_neighbor_password_cmd);
/* "neighbor activate" commands. */
- install_element (BGP_NODE, &neighbor_activate_cmd);
+ install_element (BGP_NODE, &neighbor_activate_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_activate_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_activate_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_activate_cmd);
install_element (BGP_IPV6_NODE, &neighbor_activate_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_activate_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_activate_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_activate_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_activate_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_activate_cmd);
@@ -10349,55 +11239,60 @@ bgp_vty_init (void)
install_element (BGP_EVPN_NODE, &neighbor_activate_cmd);
/* "no neighbor activate" commands. */
- install_element (BGP_NODE, &no_neighbor_activate_cmd);
+ install_element (BGP_NODE, &no_neighbor_activate_hidden_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_activate_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_activate_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_activate_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_activate_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_activate_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_activate_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_activate_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_activate_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_activate_cmd);
install_element (BGP_ENCAPV6_NODE, &no_neighbor_activate_cmd);
install_element (BGP_EVPN_NODE, &no_neighbor_activate_cmd);
- /* "neighbor peer-group" set commands.
- * Long term we should only accept this command under BGP_NODE and not all of
- * the afi/safi sub-contexts. For now though we need to accept it for backwards
- * compatibility. This changed when we stopped requiring that peers be assigned
- * to their peer-group under each address-family sub-context.
- */
+ /* "neighbor peer-group" set commands. */
install_element (BGP_NODE, &neighbor_set_peer_group_cmd);
- install_element (BGP_IPV4_NODE, &neighbor_set_peer_group_cmd);
- install_element (BGP_IPV4M_NODE, &neighbor_set_peer_group_cmd);
- install_element (BGP_IPV6_NODE, &neighbor_set_peer_group_cmd);
- install_element (BGP_IPV6M_NODE, &neighbor_set_peer_group_cmd);
- install_element (BGP_VPNV4_NODE, &neighbor_set_peer_group_cmd);
- install_element (BGP_VPNV6_NODE, &neighbor_set_peer_group_cmd);
- install_element (BGP_ENCAP_NODE, &neighbor_set_peer_group_cmd);
- install_element (BGP_ENCAPV6_NODE, &neighbor_set_peer_group_cmd);
+ install_element (BGP_IPV4_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV4M_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV6_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV6M_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_VPNV4_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_VPNV6_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_ENCAP_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_ENCAPV6_NODE, &neighbor_set_peer_group_hidden_cmd);
/* "no neighbor peer-group unset" commands. */
install_element (BGP_NODE, &no_neighbor_set_peer_group_cmd);
- install_element (BGP_IPV4_NODE, &no_neighbor_set_peer_group_cmd);
- install_element (BGP_IPV4M_NODE, &no_neighbor_set_peer_group_cmd);
- install_element (BGP_IPV6_NODE, &no_neighbor_set_peer_group_cmd);
- install_element (BGP_IPV6M_NODE, &no_neighbor_set_peer_group_cmd);
- install_element (BGP_VPNV4_NODE, &no_neighbor_set_peer_group_cmd);
- 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);
+ install_element (BGP_IPV4_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV4M_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV6_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV6M_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_VPNV4_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_VPNV6_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_ENCAP_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element (BGP_ENCAPV6_NODE, &no_neighbor_set_peer_group_hidden_cmd);
/* "neighbor softreconfiguration inbound" commands.*/
- install_element (BGP_NODE, &neighbor_soft_reconfiguration_cmd);
- install_element (BGP_NODE, &no_neighbor_soft_reconfiguration_cmd);
+ install_element (BGP_NODE, &neighbor_soft_reconfiguration_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_soft_reconfiguration_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_soft_reconfiguration_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_soft_reconfiguration_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV6_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_soft_reconfiguration_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_soft_reconfiguration_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_soft_reconfiguration_cmd);
@@ -10408,16 +11303,20 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_soft_reconfiguration_cmd);
/* "neighbor attribute-unchanged" commands. */
- install_element (BGP_NODE, &neighbor_attr_unchanged_cmd);
- install_element (BGP_NODE, &no_neighbor_attr_unchanged_cmd);
+ install_element (BGP_NODE, &neighbor_attr_unchanged_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_attr_unchanged_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_attr_unchanged_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_attr_unchanged_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_IPV6_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_attr_unchanged_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_attr_unchanged_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_attr_unchanged_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_attr_unchanged_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_attr_unchanged_cmd);
@@ -10437,16 +11336,20 @@ bgp_vty_init (void)
install_element (BGP_IPV6_NODE, &no_neighbor_nexthop_local_unchanged_cmd);
/* "neighbor next-hop-self" commands. */
- install_element (BGP_NODE, &neighbor_nexthop_self_cmd);
- install_element (BGP_NODE, &no_neighbor_nexthop_self_cmd);
+ install_element (BGP_NODE, &neighbor_nexthop_self_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_nexthop_self_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_nexthop_self_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_nexthop_self_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_IPV6_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_nexthop_self_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_nexthop_self_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_nexthop_self_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_nexthop_self_cmd);
@@ -10457,46 +11360,54 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_nexthop_self_cmd);
/* "neighbor next-hop-self force" commands. */
- install_element (BGP_NODE, &neighbor_nexthop_self_force_cmd);
- install_element (BGP_NODE, &no_neighbor_nexthop_self_force_cmd);
+ install_element (BGP_NODE, &neighbor_nexthop_self_force_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_nexthop_self_force_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_nexthop_self_force_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_nexthop_self_force_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV6_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_nexthop_self_force_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_nexthop_self_force_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_nexthop_self_force_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_nexthop_self_force_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_nexthop_self_force_cmd);
/* "neighbor as-override" commands. */
- install_element (BGP_NODE, &neighbor_as_override_cmd);
- install_element (BGP_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_NODE, &neighbor_as_override_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_as_override_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_as_override_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_as_override_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_IPV6_NODE, &neighbor_as_override_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_as_override_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_as_override_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_as_override_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_as_override_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_as_override_cmd);
/* "neighbor remove-private-AS" commands. */
- install_element (BGP_NODE, &neighbor_remove_private_as_cmd);
- install_element (BGP_NODE, &no_neighbor_remove_private_as_cmd);
- install_element (BGP_NODE, &neighbor_remove_private_as_all_cmd);
- install_element (BGP_NODE, &no_neighbor_remove_private_as_all_cmd);
- install_element (BGP_NODE, &neighbor_remove_private_as_replace_as_cmd);
- install_element (BGP_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
- install_element (BGP_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
- install_element (BGP_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_NODE, &neighbor_remove_private_as_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_remove_private_as_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_remove_private_as_all_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_remove_private_as_all_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_remove_private_as_replace_as_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_remove_private_as_replace_as_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_remove_private_as_all_replace_as_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_remove_private_as_all_replace_as_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_remove_private_as_cmd);
install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_all_cmd);
@@ -10513,6 +11424,14 @@ bgp_vty_init (void)
install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_cmd);
install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_all_cmd);
@@ -10529,6 +11448,14 @@ bgp_vty_init (void)
install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_all_cmd);
@@ -10551,10 +11478,10 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_remove_private_as_cmd);
/* "neighbor send-community" commands.*/
- install_element (BGP_NODE, &neighbor_send_community_cmd);
- install_element (BGP_NODE, &neighbor_send_community_type_cmd);
- install_element (BGP_NODE, &no_neighbor_send_community_cmd);
- install_element (BGP_NODE, &no_neighbor_send_community_type_cmd);
+ install_element (BGP_NODE, &neighbor_send_community_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_send_community_type_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_send_community_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_send_community_type_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_send_community_cmd);
install_element (BGP_IPV4_NODE, &neighbor_send_community_type_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_send_community_cmd);
@@ -10563,6 +11490,10 @@ bgp_vty_init (void)
install_element (BGP_IPV4M_NODE, &neighbor_send_community_type_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_send_community_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_send_community_type_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_send_community_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_send_community_type_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_send_community_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_send_community_type_cmd);
install_element (BGP_IPV6_NODE, &neighbor_send_community_cmd);
install_element (BGP_IPV6_NODE, &neighbor_send_community_type_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_send_community_cmd);
@@ -10571,6 +11502,10 @@ bgp_vty_init (void)
install_element (BGP_IPV6M_NODE, &neighbor_send_community_type_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_send_community_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_send_community_type_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_send_community_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_send_community_type_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_send_community_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_send_community_type_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_send_community_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_send_community_type_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_send_community_cmd);
@@ -10589,16 +11524,20 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_send_community_type_cmd);
/* "neighbor route-reflector" commands.*/
- install_element (BGP_NODE, &neighbor_route_reflector_client_cmd);
- install_element (BGP_NODE, &no_neighbor_route_reflector_client_cmd);
+ install_element (BGP_NODE, &neighbor_route_reflector_client_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_route_reflector_client_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_route_reflector_client_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_route_reflector_client_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_IPV6_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_route_reflector_client_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_route_reflector_client_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_route_reflector_client_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_route_reflector_client_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_route_reflector_client_cmd);
@@ -10609,16 +11548,20 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_route_reflector_client_cmd);
/* "neighbor route-server" commands.*/
- install_element (BGP_NODE, &neighbor_route_server_client_cmd);
- install_element (BGP_NODE, &no_neighbor_route_server_client_cmd);
+ install_element (BGP_NODE, &neighbor_route_server_client_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_route_server_client_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_route_server_client_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_route_server_client_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_IPV6_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_route_server_client_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_route_server_client_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_route_server_client_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_route_server_client_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_route_server_client_cmd);
@@ -10629,32 +11572,40 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_route_server_client_cmd);
/* "neighbor addpath-tx-all-paths" commands.*/
- install_element (BGP_NODE, &neighbor_addpath_tx_all_paths_cmd);
- install_element (BGP_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
+ install_element (BGP_NODE, &neighbor_addpath_tx_all_paths_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_addpath_tx_all_paths_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_addpath_tx_all_paths_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV6_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_addpath_tx_all_paths_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_addpath_tx_all_paths_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_addpath_tx_all_paths_cmd);
/* "neighbor addpath-tx-bestpath-per-AS" commands.*/
- install_element (BGP_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
- install_element (BGP_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
+ install_element (BGP_NODE, &neighbor_addpath_tx_bestpath_per_as_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_addpath_tx_bestpath_per_as_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV6_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_addpath_tx_bestpath_per_as_cmd);
@@ -10676,16 +11627,20 @@ bgp_vty_init (void)
install_element (BGP_NODE, &no_neighbor_capability_enhe_cmd);
/* "neighbor capability orf prefix-list" commands.*/
- install_element (BGP_NODE, &neighbor_capability_orf_prefix_cmd);
- install_element (BGP_NODE, &no_neighbor_capability_orf_prefix_cmd);
+ install_element (BGP_NODE, &neighbor_capability_orf_prefix_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_capability_orf_prefix_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_capability_orf_prefix_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_capability_orf_prefix_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV6_NODE, &neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_capability_orf_prefix_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_capability_orf_prefix_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_capability_orf_prefix_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_capability_orf_prefix_cmd);
/* "neighbor capability dynamic" commands.*/
install_element (BGP_NODE, &neighbor_capability_dynamic_cmd);
@@ -10713,38 +11668,48 @@ bgp_vty_init (void)
install_element (BGP_NODE, &no_neighbor_update_source_cmd);
/* "neighbor default-originate" commands. */
- 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, &neighbor_default_originate_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_default_originate_rmap_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_default_originate_hidden_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_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_IPV4L_NODE, &neighbor_default_originate_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_default_originate_rmap_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_default_originate_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_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_IPV6L_NODE, &neighbor_default_originate_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_default_originate_rmap_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_default_originate_cmd);
/* "neighbor port" commands. */
install_element (BGP_NODE, &neighbor_port_cmd);
install_element (BGP_NODE, &no_neighbor_port_cmd);
/* "neighbor weight" commands. */
- install_element (BGP_NODE, &neighbor_weight_cmd);
- install_element (BGP_NODE, &no_neighbor_weight_cmd);
+ install_element (BGP_NODE, &neighbor_weight_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_weight_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_weight_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_weight_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV6_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_weight_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_weight_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_weight_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_weight_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_weight_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_weight_cmd);
@@ -10779,16 +11744,20 @@ bgp_vty_init (void)
install_element (BGP_NODE, &no_neighbor_interface_cmd);
/* "neighbor distribute" commands. */
- install_element (BGP_NODE, &neighbor_distribute_list_cmd);
- install_element (BGP_NODE, &no_neighbor_distribute_list_cmd);
+ install_element (BGP_NODE, &neighbor_distribute_list_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_distribute_list_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_distribute_list_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_distribute_list_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_IPV6_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_distribute_list_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_distribute_list_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_distribute_list_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_distribute_list_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_distribute_list_cmd);
@@ -10799,16 +11768,20 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_distribute_list_cmd);
/* "neighbor prefix-list" commands. */
- install_element (BGP_NODE, &neighbor_prefix_list_cmd);
- install_element (BGP_NODE, &no_neighbor_prefix_list_cmd);
+ install_element (BGP_NODE, &neighbor_prefix_list_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_prefix_list_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_prefix_list_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_prefix_list_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_IPV6_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_prefix_list_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_prefix_list_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_prefix_list_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_prefix_list_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_prefix_list_cmd);
@@ -10819,16 +11792,20 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_prefix_list_cmd);
/* "neighbor filter-list" commands. */
- install_element (BGP_NODE, &neighbor_filter_list_cmd);
- install_element (BGP_NODE, &no_neighbor_filter_list_cmd);
+ install_element (BGP_NODE, &neighbor_filter_list_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_filter_list_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_filter_list_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_filter_list_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_filter_list_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_filter_list_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_IPV6_NODE, &neighbor_filter_list_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_filter_list_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_filter_list_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_filter_list_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_filter_list_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_filter_list_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_filter_list_cmd);
@@ -10839,16 +11816,20 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_filter_list_cmd);
/* "neighbor route-map" commands. */
- install_element (BGP_NODE, &neighbor_route_map_cmd);
- install_element (BGP_NODE, &no_neighbor_route_map_cmd);
+ install_element (BGP_NODE, &neighbor_route_map_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_route_map_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_route_map_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_route_map_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_route_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_IPV6_NODE, &neighbor_route_map_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_route_map_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_route_map_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_route_map_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_route_map_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_route_map_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_route_map_cmd);
@@ -10859,16 +11840,20 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_route_map_cmd);
/* "neighbor unsuppress-map" commands. */
- install_element (BGP_NODE, &neighbor_unsuppress_map_cmd);
- install_element (BGP_NODE, &no_neighbor_unsuppress_map_cmd);
+ install_element (BGP_NODE, &neighbor_unsuppress_map_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_unsuppress_map_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_unsuppress_map_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_unsuppress_map_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_IPV6_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_unsuppress_map_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_unsuppress_map_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_unsuppress_map_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_unsuppress_map_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd);
@@ -10879,13 +11864,13 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_unsuppress_map_cmd);
/* "neighbor maximum-prefix" commands. */
- install_element (BGP_NODE, &neighbor_maximum_prefix_cmd);
- install_element (BGP_NODE, &neighbor_maximum_prefix_threshold_cmd);
- install_element (BGP_NODE, &neighbor_maximum_prefix_warning_cmd);
- install_element (BGP_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
- 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, &neighbor_maximum_prefix_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_maximum_prefix_threshold_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_maximum_prefix_warning_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_maximum_prefix_threshold_warning_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_maximum_prefix_restart_hidden_cmd);
+ install_element (BGP_NODE, &neighbor_maximum_prefix_threshold_restart_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_maximum_prefix_hidden_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);
@@ -10900,6 +11885,13 @@ 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_IPV4L_NODE, &neighbor_maximum_prefix_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_threshold_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_warning_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_restart_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_maximum_prefix_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);
@@ -10914,6 +11906,13 @@ 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_IPV6L_NODE, &neighbor_maximum_prefix_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_threshold_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_warning_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_restart_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_maximum_prefix_threshold_restart_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_maximum_prefix_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);
@@ -10946,16 +11945,20 @@ bgp_vty_init (void)
install_element (BGP_ENCAPV6_NODE, &no_neighbor_maximum_prefix_cmd);
/* "neighbor allowas-in" */
- install_element (BGP_NODE, &neighbor_allowas_in_cmd);
- install_element (BGP_NODE, &no_neighbor_allowas_in_cmd);
+ install_element (BGP_NODE, &neighbor_allowas_in_hidden_cmd);
+ install_element (BGP_NODE, &no_neighbor_allowas_in_hidden_cmd);
install_element (BGP_IPV4_NODE, &neighbor_allowas_in_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_allowas_in_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_allowas_in_cmd);
+ install_element (BGP_IPV4L_NODE, &neighbor_allowas_in_cmd);
+ install_element (BGP_IPV4L_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_IPV6_NODE, &neighbor_allowas_in_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_allowas_in_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_allowas_in_cmd);
+ install_element (BGP_IPV6L_NODE, &neighbor_allowas_in_cmd);
+ install_element (BGP_IPV6L_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_allowas_in_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_allowas_in_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_allowas_in_cmd);
@@ -10981,8 +11984,10 @@ bgp_vty_init (void)
/* "exit-address-family" command. */
install_element (BGP_IPV4_NODE, &exit_address_family_cmd);
install_element (BGP_IPV4M_NODE, &exit_address_family_cmd);
+ install_element (BGP_IPV4L_NODE, &exit_address_family_cmd);
install_element (BGP_IPV6_NODE, &exit_address_family_cmd);
install_element (BGP_IPV6M_NODE, &exit_address_family_cmd);
+ install_element (BGP_IPV6L_NODE, &exit_address_family_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);
@@ -11032,18 +12037,18 @@ bgp_vty_init (void)
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, &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, &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, &bgp_redistribute_ipv4_ospf_metric_cmd);
- install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_rmap_metric_cmd);
- install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_metric_rmap_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_hidden_cmd);
+ install_element (BGP_NODE, &no_bgp_redistribute_ipv4_hidden_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_rmap_hidden_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_metric_hidden_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_rmap_metric_hidden_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_metric_rmap_hidden_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_hidden_cmd);
+ install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_hidden_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_rmap_hidden_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_metric_hidden_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_rmap_metric_hidden_cmd);
+ install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_metric_rmap_hidden_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);
diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h
index 33d24d530e..eae1f2d018 100644
--- a/bgpd/bgp_vty.h
+++ b/bgpd/bgp_vty.h
@@ -1,22 +1,22 @@
/* BGP VTY interface.
- Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_VTY_H
#define _QUAGGA_BGP_VTY_H
@@ -28,11 +28,13 @@ struct bgp;
#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|labeled-unicast>"
#define BGP_SAFI_HELP_STR \
"Address Family modifier\n" \
"Address Family modifier\n" \
"Address Family modifier\n" \
+ "Address Family modifier\n" \
+ "Address Family modifier\n" \
"Address Family modifier\n"
#define BGP_AFI_SAFI_CMD_STR BGP_AFI_CMD_STR" "BGP_SAFI_CMD_STR
#define BGP_AFI_SAFI_HELP_STR BGP_AFI_HELP_STR BGP_SAFI_HELP_STR
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 72bd081a7e..37d532f56b 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1,22 +1,22 @@
/* zebra client
- Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA. */
#include "lib/json.h"
#include "lib/bfd.h"
#include "filter.h"
+#include "mpls.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
@@ -46,6 +47,7 @@ Boston, MA 02111-1307, USA. */
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_bfd.h"
+#include "bgpd/bgp_label.h"
#if ENABLE_BGP_VNC
# include "bgpd/rfapi/rfapi_backend.h"
# include "bgpd/rfapi/vnc_export_bgp.h"
@@ -57,6 +59,7 @@ struct zclient *zclient = NULL;
/* Growable buffer for nexthops sent to zebra */
struct stream *bgp_nexthop_buf = NULL;
struct stream *bgp_ifindices_buf = NULL;
+struct stream *bgp_label_buf = NULL;
/* These array buffers are used in making a copy of the attributes for
route-map apply. Arrays are being used here to minimize mallocs and
@@ -178,6 +181,14 @@ bgp_update_interface_nbrs (struct bgp *bgp, struct interface *ifp,
}
}
+static int
+bgp_read_fec_update (int command, struct zclient *zclient,
+ zebra_size_t length)
+{
+ bgp_parse_fec_update();
+ return 0;
+}
+
static void
bgp_start_interface_nbrs (struct bgp *bgp, struct interface *ifp)
{
@@ -1204,8 +1215,8 @@ bgp_table_map_apply (struct route_map *map, struct prefix *p,
}
void
-bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
- afi_t afi, safi_t safi)
+bgp_zebra_announce (struct bgp_node *rn, struct prefix *p, struct bgp_info *info,
+ struct bgp *bgp, afi_t afi, safi_t safi)
{
u_int32_t flags;
u_char distance;
@@ -1216,6 +1227,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
struct bgp_info local_info;
struct bgp_info *info_cp = &local_info;
route_tag_t tag;
+ u_int32_t label;
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
@@ -1271,7 +1283,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
(sizeof (struct in_addr *) * nhcount))
{
- newsize = (sizeof (struct in_addr *) * nhcount);
+ newsize = sizeof (struct in_addr *) * nhcount;
newsize = stream_resize (bgp_nexthop_buf, newsize);
if (newsize == oldsize)
{
@@ -1282,6 +1294,25 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
stream_reset (bgp_nexthop_buf);
nexthop = NULL;
+ /* For labeled unicast, each nexthop has a label too. Resize label
+ * buffer, if required.
+ */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ if ((oldsize = stream_get_size (bgp_label_buf)) <
+ (sizeof (unsigned int) * nhcount))
+ {
+ newsize = (sizeof (unsigned int) * nhcount);
+ newsize = stream_resize (bgp_label_buf, newsize);
+ if (newsize == oldsize)
+ {
+ zlog_err ("can't resize label buffer");
+ return;
+ }
+ }
+ stream_reset (bgp_label_buf);
+ }
+
/* Metric is currently based on the best-path only. */
metric = info->attr->med;
@@ -1311,6 +1342,11 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
{
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
valid_nh_count++;
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ label = label_pton(info->extra->tag);
+ stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
+ }
}
for (mpinfo = bgp_info_mpath_first (info); mpinfo;
@@ -1336,6 +1372,11 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
continue;
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ label = label_pton(mpinfo->extra->tag);
+ stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
+ }
valid_nh_count++;
}
@@ -1344,8 +1385,10 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
- api.safi = safi;
+ api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
+ if (safi == SAFI_LABELED_UNICAST)
+ SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
/* Note that this currently only applies to Null0 routes for aggregates.
* ZEBRA_FLAG_BLACKHOLE signals zapi_ipv4_route to encode a special
@@ -1358,6 +1401,16 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
api.nexthop_num = valid_nh_count;
api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ api.label_num = valid_nh_count;
+ api.label = (unsigned int *)STREAM_DATA (bgp_label_buf);
+ }
+ else
+ {
+ api.label_num = 0;
+ api.label = NULL;
+ }
api.ifindex_num = 0;
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = metric;
@@ -1379,14 +1432,22 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
+ char label_buf[20];
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI
" count %d", (valid_nh_count ? "add":"delete"),
bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag, api.nexthop_num);
for (i = 0; i < api.nexthop_num; i++)
- zlog_debug(" IPv4 [nexthop %d] %s", i+1,
- inet_ntop(AF_INET, api.nexthop[i], buf[1], sizeof(buf[1])));
+ {
+ label_buf[0] = '\0';
+ if (safi == SAFI_LABELED_UNICAST)
+ sprintf(label_buf, "label %u", api.label[i]);
+ zlog_debug(" nhop [%d]: %s %s",
+ i+1,
+ inet_ntop(AF_INET, api.nexthop[i], buf[1], sizeof(buf[1])),
+ label_buf);
+ }
}
zapi_ipv4_route (valid_nh_count ? ZEBRA_IPV4_ROUTE_ADD: ZEBRA_IPV4_ROUTE_DELETE,
@@ -1431,6 +1492,25 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
}
stream_reset (bgp_ifindices_buf);
+ /* For labeled unicast, each nexthop has a label too. Resize label
+ * buffer, if required.
+ */
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ if ((oldsize = stream_get_size (bgp_label_buf)) <
+ (sizeof (unsigned int) * nhcount))
+ {
+ newsize = (sizeof (unsigned int) * nhcount);
+ newsize = stream_resize (bgp_label_buf, newsize);
+ if (newsize == oldsize)
+ {
+ zlog_err ("can't resize label buffer");
+ return;
+ }
+ }
+ stream_reset (bgp_label_buf);
+ }
+
ifindex = 0;
nexthop = NULL;
@@ -1470,12 +1550,18 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (!ifindex)
{
if (info->peer->conf_if || info->peer->ifname)
- ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname);
+ ifindex = ifname2ifindex_vrf (info->peer->conf_if ? info->peer->conf_if :
+ info->peer->ifname, bgp->vrf_id);
else if (info->peer->nexthop.ifp)
ifindex = info->peer->nexthop.ifp->ifindex;
}
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ label = label_pton(info->extra->tag);
+ stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
+ }
valid_nh_count++;
}
@@ -1518,6 +1604,11 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ label = label_pton(mpinfo->extra->tag);
+ stream_put (bgp_label_buf, &label, sizeof (u_int32_t));
+ }
valid_nh_count++;
}
@@ -1527,8 +1618,10 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
- api.safi = safi;
+ api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
+ if (safi == SAFI_LABELED_UNICAST)
+ SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
/* Note that this currently only applies to Null0 routes for aggregates.
* ZEBRA_FLAG_BLACKHOLE signals zapi_ipv6_route to encode a special
@@ -1544,6 +1637,16 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
api.ifindex_num = valid_nh_count;
api.ifindex = (ifindex_t *)STREAM_DATA (bgp_ifindices_buf);
+ if (safi == SAFI_LABELED_UNICAST)
+ {
+ api.label_num = valid_nh_count;
+ api.label = (unsigned int *)STREAM_DATA (bgp_label_buf);
+ }
+ else
+ {
+ api.label_num = 0;
+ api.label = NULL;
+ }
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = metric;
api.tag = 0;
@@ -1566,13 +1669,22 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
+ char label_buf[20];
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI,
valid_nh_count ? "add" : "delete", bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
for (i = 0; i < api.nexthop_num; i++)
- zlog_debug(" IPv6 [nexthop %d] %s", i+1,
- inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])));
+ {
+ label_buf[0] = '\0';
+ if (safi == SAFI_LABELED_UNICAST)
+ sprintf(label_buf, "label %u", api.label[i]);
+ zlog_debug(" nhop [%d]: %s if %s %s",
+ i+1,
+ inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])),
+ ifindex2ifname (api.ifindex[i], bgp->vrf_id),
+ label_buf);
+ }
}
if (valid_nh_count)
@@ -1588,13 +1700,22 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
+ char label_buf[20];
zlog_debug("Tx IPv6 route %s VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI,
valid_nh_count ? "add" : "delete", bgp->vrf_id,
inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
for (i = 0; i < api.nexthop_num; i++)
- zlog_debug(" IPv6 [nexthop %d] %s", i+1,
- inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])));
+ {
+ label_buf[0] = '\0';
+ if (safi == SAFI_LABELED_UNICAST)
+ sprintf(label_buf, "label %u", api.label[i]);
+ zlog_debug(" nhop [%d]: %s if %s %s",
+ i+1,
+ inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])),
+ ifindex2ifname (api.ifindex[i], bgp->vrf_id),
+ label_buf);
+ }
}
zapi_ipv6_route (valid_nh_count ?
@@ -1626,7 +1747,7 @@ bgp_zebra_announce_table (struct bgp *bgp, afi_t afi, safi_t safi)
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
&& ri->type == ZEBRA_ROUTE_BGP
&& ri->sub_type == BGP_ROUTE_NORMAL)
- bgp_zebra_announce (&rn->p, ri, bgp, afi, safi);
+ bgp_zebra_announce (rn, &rn->p, ri, bgp, afi, safi);
}
void
@@ -1673,10 +1794,14 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
- api.safi = safi;
+ api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
+ if (safi == SAFI_LABELED_UNICAST)
+ SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
api.nexthop_num = 0;
api.nexthop = NULL;
+ api.label_num = 0;
+ api.label = NULL;
api.ifindex_num = 0;
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = info->attr->med;
@@ -1712,11 +1837,14 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
- api.safi = safi;
+ api.safi = (safi == SAFI_LABELED_UNICAST) ? SAFI_UNICAST : safi;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
+ if (safi == SAFI_LABELED_UNICAST)
+ SET_FLAG (api.message, ZAPI_MESSAGE_LABEL);
api.nexthop_num = 0;
api.nexthop = NULL;
api.ifindex_num = 0;
+ api.label_num = 0;
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = info->attr->med;
api.tag = 0;
@@ -2141,9 +2269,11 @@ bgp_zebra_init (struct thread_master *master)
zclient->redistribute_route_ipv6_del = zebra_read_ipv6;
zclient->nexthop_update = bgp_read_nexthop_update;
zclient->import_check_update = bgp_read_import_check_update;
+ zclient->fec_update = bgp_read_fec_update;
bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
+ bgp_label_buf = stream_new(BGP_LABEL_BUF_SIZE);
}
void
diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h
index d22a00e8fb..6a36fb84f7 100644
--- a/bgpd/bgp_zebra.h
+++ b/bgpd/bgp_zebra.h
@@ -1,31 +1,33 @@
/* zebra connection and redistribute fucntions.
- Copyright (C) 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGP_ZEBRA_H
#define _QUAGGA_BGP_ZEBRA_H
#define BGP_NEXTHOP_BUF_SIZE (8 * sizeof (struct in_addr *))
#define BGP_IFINDICES_BUF_SIZE (8 * sizeof (unsigned int))
+#define BGP_LABEL_BUF_SIZE (8 * sizeof (unsigned int))
extern struct stream *bgp_nexthop_buf;
extern struct stream *bgp_ifindices_buf;
+extern struct stream *bgp_label_buf;
extern void bgp_zebra_init (struct thread_master *master);
extern void bgp_zebra_destroy (void);
@@ -34,8 +36,8 @@ extern int bgp_config_write_maxpaths (struct vty *, struct bgp *, afi_t,
safi_t, int *);
extern int bgp_config_write_redistribute (struct vty *, struct bgp *, afi_t, safi_t,
int *);
-extern void bgp_zebra_announce (struct prefix *, struct bgp_info *, struct bgp *,
- afi_t, safi_t);
+extern void bgp_zebra_announce (struct bgp_node *, struct prefix *,
+ struct bgp_info *, struct bgp *, afi_t, safi_t);
extern void bgp_zebra_announce_table (struct bgp *, afi_t, safi_t);
extern void bgp_zebra_withdraw (struct prefix *, struct bgp_info *, safi_t);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 7343d3714f..655431b015 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1,22 +1,22 @@
/* BGP-4, BGP-4+ daemon program
- Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -94,7 +94,6 @@ struct community_list_handler *bgp_clist;
unsigned int multipath_num = MULTIPATH_NUM;
-static void bgp_if_init (struct bgp *bgp);
static void bgp_if_finish (struct bgp *bgp);
extern struct zclient *zclient;
@@ -1636,6 +1635,8 @@ peer_as_change (struct peer *peer, as_t as, int as_specified)
PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
PEER_FLAG_REFLECTOR_CLIENT);
+ UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_LABELED_UNICAST],
+ PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN],
PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_ENCAP],
@@ -1644,6 +1645,8 @@ peer_as_change (struct peer *peer, as_t as, int as_specified)
PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],
PEER_FLAG_REFLECTOR_CLIENT);
+ UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_LABELED_UNICAST],
+ PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MPLS_VPN],
PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_ENCAP],
@@ -2966,8 +2969,8 @@ bgp_create (as_t *as, const char *name, enum bgp_instance_type inst_type)
else
{
/* TODO - The startup timer needs to be run for the whole of BGP */
- THREAD_TIMER_ON (bm->master, bgp->t_startup, bgp_startup_timer_expire,
- bgp, bgp->restart_time);
+ thread_add_timer(bm->master, bgp_startup_timer_expire, bgp,
+ bgp->restart_time, &bgp->t_startup);
}
bgp->wpkt_quanta = BGP_WRITE_PACKET_MAX;
@@ -3111,10 +3114,7 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name,
vrf = bgp_vrf_lookup_by_instance_type (bgp);
if (vrf)
- {
- bgp_vrf_link (bgp, vrf);
- bgp_if_init (bgp);
- }
+ bgp_vrf_link (bgp, vrf);
}
/* Register with Zebra, if needed */
@@ -3611,10 +3611,12 @@ peer_active (struct peer *peer)
return 0;
if (peer->afc[AFI_IP][SAFI_UNICAST]
|| peer->afc[AFI_IP][SAFI_MULTICAST]
+ || peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP][SAFI_ENCAP]
|| peer->afc[AFI_IP6][SAFI_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MULTICAST]
+ || peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP6][SAFI_ENCAP])
return 1;
@@ -3627,10 +3629,12 @@ peer_active_nego (struct peer *peer)
{
if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
|| peer->afc_nego[AFI_IP][SAFI_MULTICAST]
+ || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
|| peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
|| peer->afc_nego[AFI_IP][SAFI_ENCAP]
|| peer->afc_nego[AFI_IP6][SAFI_UNICAST]
|| peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
+ || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
|| peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
|| peer->afc_nego[AFI_IP6][SAFI_ENCAP])
return 1;
@@ -5024,8 +5028,28 @@ int
peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
{
struct peer_group *group;
+ struct peer *tmp_peer;
struct listnode *node, *nnode;
+ /* If this is a peer-group we must first clear the flags for all of the
+ * peer-group members
+ */
+ if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ {
+ group = peer->group;
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, tmp_peer))
+ {
+ if (CHECK_FLAG (tmp_peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN) ||
+ CHECK_FLAG (tmp_peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
+ {
+ tmp_peer->allowas_in[afi][safi] = 0;
+ peer_af_flag_unset (tmp_peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
+ peer_af_flag_unset (tmp_peer, afi, safi, PEER_FLAG_ALLOWAS_IN_ORIGIN);
+ peer_on_policy_change (tmp_peer, afi, safi, 0);
+ }
+ }
+ }
+
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN) ||
CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
{
@@ -5035,21 +5059,6 @@ peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
peer_on_policy_change (peer, afi, safi, 0);
}
- if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
- return 0;
-
- group = peer->group;
- for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
- {
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN) ||
- CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
- {
- peer->allowas_in[afi][safi] = 0;
- peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
- peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN_ORIGIN);
- peer_on_policy_change (peer, afi, safi, 0);
- }
- }
return 0;
}
@@ -6341,7 +6350,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
char *
peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object *json)
{
- time_t uptime1;
+ time_t uptime1, epoch_tbuf;
struct tm *tm;
/* Check buffer length. */
@@ -6395,8 +6404,10 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object
if (use_json)
{
+ epoch_tbuf = time(NULL) - uptime1;
json_object_string_add(json, "peerUptime", buf);
json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000);
+ json_object_int_add(json, "peerUptimeEstablishedEpoch", epoch_tbuf);
}
return buf;
@@ -7260,6 +7271,8 @@ bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
{
if (safi == SAFI_UNICAST)
vty_out (vty, "ipv4 unicast");
+ else if (safi == SAFI_LABELED_UNICAST)
+ vty_out (vty, "ipv4 labeled-unicast");
else if (safi == SAFI_MULTICAST)
vty_out (vty, "ipv4 multicast");
else if (safi == SAFI_MPLS_VPN)
@@ -7271,6 +7284,8 @@ bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
{
if (safi == SAFI_UNICAST)
vty_out (vty, "ipv6 unicast");
+ else if (safi == SAFI_LABELED_UNICAST)
+ vty_out (vty, "ipv6 labeled-unicast");
else if (safi == SAFI_MULTICAST)
vty_out (vty, "ipv6 multicast");
else if (safi == SAFI_MPLS_VPN)
@@ -7577,6 +7592,9 @@ bgp_config_write (struct vty *vty)
/* IPv4 multicast configuration. */
write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MULTICAST);
+ /* IPv4 labeled-unicast configuration. */
+ write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_LABELED_UNICAST);
+
/* IPv4 VPN configuration. */
write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);
@@ -7589,6 +7607,9 @@ bgp_config_write (struct vty *vty)
/* IPv6 multicast configuration. */
write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
+ /* IPv6 labeled-unicast configuration. */
+ write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_LABELED_UNICAST);
+
/* IPv6 VPN configuration. */
write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MPLS_VPN);
@@ -7632,19 +7653,6 @@ bgp_master_init (struct thread_master *master)
}
/*
- * Initialize interface list for instance, if needed. Invoked upon
- * instance create.
- */
-static void
-bgp_if_init (struct bgp *bgp)
-{
- if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
- return;
-
- vrf_iflist_create (bgp->vrf_id);
-}
-
-/*
* Free up connected routes and interfaces for a BGP instance. Invoked upon
* instance delete (non-default only) or BGP exit.
*/
diff --git a/bgpd/bgpd.conf.sample b/bgpd/bgpd.conf.sample
index b6a8b6f100..60a74a71ef 100644
--- a/bgpd/bgpd.conf.sample
+++ b/bgpd/bgpd.conf.sample
@@ -14,9 +14,12 @@ router bgp 7675
! bgp router-id 10.0.0.1
! network 10.0.0.0/8
! neighbor 10.0.0.2 remote-as 7675
-! neighbor 10.0.0.2 route-map set-nexthop out
! neighbor 10.0.0.2 ebgp-multihop
-! neighbor 10.0.0.2 next-hop-self
+!
+! address-family ipv4 unicast
+! neighbor 10.0.0.2 route-map set-nexthop out
+! neighbor 10.0.0.2 next-hop-self
+! exit-address-family
!
! access-list all permit any
!
diff --git a/bgpd/bgpd.conf.vnc.sample b/bgpd/bgpd.conf.vnc.sample
index 863abde3a6..a8a2dc5fa0 100644
--- a/bgpd/bgpd.conf.vnc.sample
+++ b/bgpd/bgpd.conf.vnc.sample
@@ -19,13 +19,15 @@ router bgp 64512
neighbor 192.1.1.2 description H192.1.1.2
neighbor 192.1.1.2 update-source 192.1.1.1
neighbor 192.1.1.2 advertisement-interval 1
- no neighbor 192.1.1.2 activate
neighbor 192.1.1.3 remote-as 64512
neighbor 192.1.1.3 description H192.1.1.3
neighbor 192.1.1.3 update-source 192.1.1.1
neighbor 192.1.1.3 advertisement-interval 1
- no neighbor 192.1.1.3 activate
+
+ address-family ipv4 unicast
+ no neighbor 192.1.1.2 activate
+ no neighbor 192.1.1.3 activate
address-family vpnv4
neighbor 192.1.1.2 activate
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index a72974bc1d..84dcb7e1d9 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -1,22 +1,22 @@
/* BGP message definition header.
- Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
+ *
+ * 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 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 _QUAGGA_BGPD_H
#define _QUAGGA_BGPD_H
@@ -76,6 +76,8 @@ enum bgp_af_index
BGP_AF_IPV4_ENCAP,
BGP_AF_IPV6_ENCAP,
BGP_AF_L2VPN_EVPN,
+ BGP_AF_IPV4_LBL_UNICAST,
+ BGP_AF_IPV6_LBL_UNICAST,
BGP_AF_MAX
};
@@ -971,6 +973,7 @@ struct bgp_nlri
#define BGP_ATTR_AS_PATHLIMIT 21
#define BGP_ATTR_ENCAP 23
#define BGP_ATTR_LARGE_COMMUNITIES 32
+#define BGP_ATTR_PREFIX_SID 40
#if ENABLE_BGP_VNC
#define BGP_ATTR_VNC 255
#endif
@@ -1394,6 +1397,9 @@ afindex (afi_t afi, safi_t safi)
case SAFI_MULTICAST:
return BGP_AF_IPV4_MULTICAST;
break;
+ case SAFI_LABELED_UNICAST:
+ return BGP_AF_IPV4_LBL_UNICAST;
+ break;
case SAFI_MPLS_VPN:
return BGP_AF_IPV4_VPN;
break;
@@ -1414,7 +1420,10 @@ afindex (afi_t afi, safi_t safi)
case SAFI_MULTICAST:
return BGP_AF_IPV6_MULTICAST;
break;
- case SAFI_MPLS_VPN:
+ case SAFI_LABELED_UNICAST:
+ return BGP_AF_IPV6_LBL_UNICAST;
+ break;
+ case SAFI_MPLS_VPN:
return BGP_AF_IPV6_VPN;
break;
case SAFI_ENCAP:
@@ -1456,6 +1465,7 @@ peer_afi_active_nego (const struct peer *peer, afi_t afi)
{
if (peer->afc_nego[afi][SAFI_UNICAST]
|| peer->afc_nego[afi][SAFI_MULTICAST]
+ || peer->afc_nego[afi][SAFI_LABELED_UNICAST]
|| peer->afc_nego[afi][SAFI_MPLS_VPN]
|| peer->afc_nego[afi][SAFI_ENCAP])
return 1;
@@ -1470,10 +1480,12 @@ peer_group_af_configured (struct peer_group *group)
if (peer->afc[AFI_IP][SAFI_UNICAST]
|| peer->afc[AFI_IP][SAFI_MULTICAST]
+ || peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP][SAFI_ENCAP]
|| peer->afc[AFI_IP6][SAFI_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MULTICAST]
+ || peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP6][SAFI_ENCAP])
return 1;
@@ -1502,16 +1514,10 @@ peer_dynamic_neighbor (struct peer *peer)
return (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR)) ? 1 : 0;
}
-/*
- * Currently supporting RFC 5549 for AFI_IP/SAFI_UNICAST only.
- *
- * Note: When other RFC-5549 applicable SAFIs to be supported, that should
- * come as an argument to this routine.
- */
static inline int
-peer_cap_enhe (struct peer *peer)
+peer_cap_enhe (struct peer *peer, afi_t afi, safi_t safi)
{
- return (CHECK_FLAG(peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_NEGO));
+ return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_NEGO));
}
/* Lookup VRF for BGP instance based on its type. */
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c
index 4f46565900..722948c737 100644
--- a/bgpd/rfapi/bgp_rfapi_cfg.c
+++ b/bgpd/rfapi/bgp_rfapi_cfg.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 "lib/zebra.h"
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.h b/bgpd/rfapi/bgp_rfapi_cfg.h
index 8f93d69f6b..44abbe2223 100644
--- a/bgpd/rfapi/bgp_rfapi_cfg.h
+++ b/bgpd/rfapi/bgp_rfapi_cfg.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_RFAPI_CFG_H
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index 99d26cf13c..69fae2ae40 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
@@ -1198,6 +1197,7 @@ add_vnc_route (
bgp, prd, table, p, new);
}
bgp_unlock_node (prn);
+ encode_label (label_val, bn->local_label);
}
bgp_unlock_node (bn);
diff --git a/bgpd/rfapi/rfapi.h b/bgpd/rfapi/rfapi.h
index 420c6e0d71..11d41c9d1d 100644
--- a/bgpd/rfapi/rfapi.h
+++ b/bgpd/rfapi/rfapi.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_RFAPI_H
diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c
index 68292c26b1..fac28cd74c 100644
--- a/bgpd/rfapi/rfapi_ap.c
+++ b/bgpd/rfapi/rfapi_ap.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 <errno.h>
diff --git a/bgpd/rfapi/rfapi_ap.h b/bgpd/rfapi/rfapi_ap.h
index 8a59f05274..c875a52e50 100644
--- a/bgpd/rfapi/rfapi_ap.h
+++ b/bgpd/rfapi/rfapi_ap.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_RFAPI_AP_H
#define _QUAGGA_BGP_RFAPI_AP_H
diff --git a/bgpd/rfapi/rfapi_backend.h b/bgpd/rfapi/rfapi_backend.h
index 9e5b0dc5cb..a2537bd918 100644
--- a/bgpd/rfapi/rfapi_backend.h
+++ b/bgpd/rfapi/rfapi_backend.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_RFAPI_BACKEND_H
diff --git a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c
index 8106186d97..d05b271288 100644
--- a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c
+++ b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
diff --git a/bgpd/rfapi/rfapi_descriptor_rfp_utils.h b/bgpd/rfapi/rfapi_descriptor_rfp_utils.h
index 9067cdf54b..04fbfbcec8 100644
--- a/bgpd/rfapi/rfapi_descriptor_rfp_utils.h
+++ b/bgpd/rfapi/rfapi_descriptor_rfp_utils.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
diff --git a/bgpd/rfapi/rfapi_encap_tlv.c b/bgpd/rfapi/rfapi_encap_tlv.c
index 171ea8f24d..04f8b249f7 100644
--- a/bgpd/rfapi/rfapi_encap_tlv.c
+++ b/bgpd/rfapi/rfapi_encap_tlv.c
@@ -11,10 +11,9 @@
* 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.
- *
+ * 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 "lib/zebra.h"
diff --git a/bgpd/rfapi/rfapi_encap_tlv.h b/bgpd/rfapi/rfapi_encap_tlv.h
index 9678655a69..19e16a41a5 100644
--- a/bgpd/rfapi/rfapi_encap_tlv.h
+++ b/bgpd/rfapi/rfapi_encap_tlv.h
@@ -11,10 +11,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_RFAPI_ENCAP_TLV_H
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index 4a05018d23..741ad7d705 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
@@ -3033,9 +3032,9 @@ rfapiBiStartWithdrawTimer (
if (lifetime > UINT32_MAX / 1001)
{
/* sub-optimal case, but will probably never happen */
- bi->extra->vnc.import.timer = thread_add_timer (bm->master,
- timer_service_func,
- wcb, lifetime);
+ bi->extra->vnc.import.timer = NULL;
+ thread_add_timer(bm->master, timer_service_func, wcb, lifetime,
+ &bi->extra->vnc.import.timer);
}
else
{
@@ -3051,10 +3050,9 @@ rfapiBiStartWithdrawTimer (
lifetime_msec = (lifetime * 1000) + jitter;
- bi->extra->vnc.import.timer = thread_add_background (bm->master,
- timer_service_func,
- wcb,
- lifetime_msec);
+ bi->extra->vnc.import.timer = NULL;
+ thread_add_background(bm->master, timer_service_func, wcb, lifetime_msec,
+ &bi->extra->vnc.import.timer);
}
/* re-sort route list (BGP_INFO_REMOVED routes are last) */
diff --git a/bgpd/rfapi/rfapi_import.h b/bgpd/rfapi/rfapi_import.h
index 3ba76539dd..1888d5f25d 100644
--- a/bgpd/rfapi/rfapi_import.h
+++ b/bgpd/rfapi/rfapi_import.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c
index a9e6e4f934..275e448967 100644
--- a/bgpd/rfapi/rfapi_monitor.c
+++ b/bgpd/rfapi/rfapi_monitor.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
@@ -852,8 +851,9 @@ rfapiMonitorTimerRestart (struct rfapi_monitor_vpn *m)
rfapi_ntop (m->p.family, m->p.u.val, buf, BUFSIZ),
m->rfd->response_lifetime);
}
- m->timer = thread_add_timer (bm->master, rfapiMonitorTimerExpire, m,
- m->rfd->response_lifetime);
+ m->timer = NULL;
+ thread_add_timer(bm->master, rfapiMonitorTimerExpire, m, m->rfd->response_lifetime,
+ &m->timer);
}
/*
@@ -1183,8 +1183,9 @@ rfapiMonitorEthTimerRestart (struct rfapi_monitor_eth *m)
rfapiEthAddr2Str (&m->macaddr, buf, BUFSIZ),
m->rfd->response_lifetime);
}
- m->timer = thread_add_timer (bm->master, rfapiMonitorEthTimerExpire, m,
- m->rfd->response_lifetime);
+ m->timer = NULL;
+ thread_add_timer(bm->master, rfapiMonitorEthTimerExpire, m, m->rfd->response_lifetime,
+ &m->timer);
}
static int
diff --git a/bgpd/rfapi/rfapi_monitor.h b/bgpd/rfapi/rfapi_monitor.h
index be04b0f09d..667d61ec1d 100644
--- a/bgpd/rfapi/rfapi_monitor.h
+++ b/bgpd/rfapi/rfapi_monitor.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 QUAGGA_HGP_RFAPI_MONITOR_H
@@ -40,7 +39,7 @@ struct rfapi_monitor_vpn
#define RFAPI_MON_FLAG_NEEDCALLBACK 0x00000001 /* deferred callback */
//int dcount; /* debugging counter */
- void *timer;
+ struct thread *timer;
};
struct rfapi_monitor_encap
@@ -58,7 +57,7 @@ struct rfapi_monitor_eth
struct rfapi_descriptor *rfd; /* which NVE requested the route */
struct ethaddr macaddr;
uint32_t logical_net_id;
- void *timer;
+ struct thread *timer;
};
/*
diff --git a/bgpd/rfapi/rfapi_nve_addr.c b/bgpd/rfapi/rfapi_nve_addr.c
index e00ff30312..f80455bbed 100644
--- a/bgpd/rfapi/rfapi_nve_addr.c
+++ b/bgpd/rfapi/rfapi_nve_addr.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
diff --git a/bgpd/rfapi/rfapi_nve_addr.h b/bgpd/rfapi/rfapi_nve_addr.h
index 2b2d2b50d4..f2159d1063 100644
--- a/bgpd/rfapi/rfapi_nve_addr.h
+++ b/bgpd/rfapi/rfapi_nve_addr.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_RFAPI_NVE_ADDR_H
diff --git a/bgpd/rfapi/rfapi_private.h b/bgpd/rfapi/rfapi_private.h
index a5e3970549..5a6936fcce 100644
--- a/bgpd/rfapi/rfapi_private.h
+++ b/bgpd/rfapi/rfapi_private.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c
index 8fb2fe44ed..04c69d58ac 100644
--- a/bgpd/rfapi/rfapi_rib.c
+++ b/bgpd/rfapi/rfapi_rib.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
@@ -400,8 +399,9 @@ rfapiRibStartTimer (
prefix2str (&rn->p, buf_prefix, BUFSIZ);
vnc_zlog_debug_verbose ("%s: rfd %p pfx %s life %u", __func__, rfd, buf_prefix,
ri->lifetime);
- ri->timer = thread_add_timer (bm->master, rfapiRibExpireTimer,
- tcb, ri->lifetime);
+ ri->timer = NULL;
+ thread_add_timer(bm->master, rfapiRibExpireTimer, tcb, ri->lifetime,
+ &ri->timer);
assert (ri->timer);
}
diff --git a/bgpd/rfapi/rfapi_rib.h b/bgpd/rfapi/rfapi_rib.h
index 74331a28d0..40e4c0c2f2 100644
--- a/bgpd/rfapi/rfapi_rib.h
+++ b/bgpd/rfapi/rfapi_rib.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
@@ -78,7 +77,7 @@ struct rfapi_info
struct bgp_tea_options *tea_options;
struct rfapi_un_option *un_options;
struct rfapi_vn_option *vn_options;
- void *timer;
+ struct thread *timer;
};
/*
diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c
index 3de79dac04..7c5d6ce3fa 100644
--- a/bgpd/rfapi/rfapi_vty.c
+++ b/bgpd/rfapi/rfapi_vty.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
diff --git a/bgpd/rfapi/rfapi_vty.h b/bgpd/rfapi/rfapi_vty.h
index c1aeda953c..46b77b55ed 100644
--- a/bgpd/rfapi/rfapi_vty.h
+++ b/bgpd/rfapi/rfapi_vty.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 RFAPI_VTY_H
diff --git a/bgpd/rfapi/vnc_debug.c b/bgpd/rfapi/vnc_debug.c
index b5ff5bbc88..cc27277a72 100644
--- a/bgpd/rfapi/vnc_debug.c
+++ b/bgpd/rfapi/vnc_debug.c
@@ -12,10 +12,9 @@
* 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.
- *
+ * 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 "lib/zebra.h"
diff --git a/bgpd/rfapi/vnc_debug.h b/bgpd/rfapi/vnc_debug.h
index d16bceed93..c1d81f5c15 100644
--- a/bgpd/rfapi/vnc_debug.h
+++ b/bgpd/rfapi/vnc_debug.h
@@ -12,10 +12,9 @@
* 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.
- *
+ * 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 _QUAGGA_BGP_VNC_DEBUG_H
diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c
index 9b2dc25823..bca95e47c0 100644
--- a/bgpd/rfapi/vnc_export_bgp.c
+++ b/bgpd/rfapi/vnc_export_bgp.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
@@ -1856,9 +1855,9 @@ vnc_direct_bgp_rh_del_route (
if (!eti->timer && eti->lifetime <= INT32_MAX)
{
- eti->timer = thread_add_timer (bm->master,
- vncExportWithdrawTimer,
- eti, eti->lifetime);
+ eti->timer = NULL;
+ thread_add_timer(bm->master, vncExportWithdrawTimer, eti, eti->lifetime,
+ &eti->timer);
vnc_zlog_debug_verbose ("%s: set expiration timer for %u seconds",
__func__, eti->lifetime);
}
diff --git a/bgpd/rfapi/vnc_export_bgp.h b/bgpd/rfapi/vnc_export_bgp.h
index ae113fdcb2..7dbbb40e0a 100644
--- a/bgpd/rfapi/vnc_export_bgp.h
+++ b/bgpd/rfapi/vnc_export_bgp.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_RFAPI_VNC_EXPORT_BGP_H_
diff --git a/bgpd/rfapi/vnc_export_bgp_p.h b/bgpd/rfapi/vnc_export_bgp_p.h
index fceab02e05..31830a3c13 100644
--- a/bgpd/rfapi/vnc_export_bgp_p.h
+++ b/bgpd/rfapi/vnc_export_bgp_p.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_RFAPI_VNC_EXPORT_BGP_P_H_
diff --git a/bgpd/rfapi/vnc_export_table.c b/bgpd/rfapi/vnc_export_table.c
index 7c8035cf81..5c7a64d3bb 100644
--- a/bgpd/rfapi/vnc_export_table.c
+++ b/bgpd/rfapi/vnc_export_table.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
diff --git a/bgpd/rfapi/vnc_export_table.h b/bgpd/rfapi/vnc_export_table.h
index 77829ca382..234520670d 100644
--- a/bgpd/rfapi/vnc_export_table.h
+++ b/bgpd/rfapi/vnc_export_table.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_VNC_VNC_EXPORT_TABLE_H_
diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c
index 10246758f3..cb9c474d92 100644
--- a/bgpd/rfapi/vnc_import_bgp.c
+++ b/bgpd/rfapi/vnc_import_bgp.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
diff --git a/bgpd/rfapi/vnc_import_bgp.h b/bgpd/rfapi/vnc_import_bgp.h
index db739e3320..9a7261067a 100644
--- a/bgpd/rfapi/vnc_import_bgp.h
+++ b/bgpd/rfapi/vnc_import_bgp.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_
diff --git a/bgpd/rfapi/vnc_import_bgp_p.h b/bgpd/rfapi/vnc_import_bgp_p.h
index 85800c1cab..19bcd19253 100644
--- a/bgpd/rfapi/vnc_import_bgp_p.h
+++ b/bgpd/rfapi/vnc_import_bgp_p.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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 _QUAGGA_RFAPI_VNC_IMPORT_BGP_P_H_
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index 84b299ce1d..6a8b4a83fa 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
diff --git a/bgpd/rfapi/vnc_zebra.h b/bgpd/rfapi/vnc_zebra.h
index ad24844423..68e567ec35 100644
--- a/bgpd/rfapi/vnc_zebra.h
+++ b/bgpd/rfapi/vnc_zebra.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/*
diff --git a/bgpd/rfp-example/librfp/rfp.h b/bgpd/rfp-example/librfp/rfp.h
index 91dbf5e71f..a8df87f82d 100644
--- a/bgpd/rfp-example/librfp/rfp.h
+++ b/bgpd/rfp-example/librfp/rfp.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/* Sample header file */
diff --git a/bgpd/rfp-example/librfp/rfp_example.c b/bgpd/rfp-example/librfp/rfp_example.c
index d4100c096f..dad81c6ddb 100644
--- a/bgpd/rfp-example/librfp/rfp_example.c
+++ b/bgpd/rfp-example/librfp/rfp_example.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/* stub rfp */
diff --git a/bgpd/rfp-example/librfp/rfp_internal.h b/bgpd/rfp-example/librfp/rfp_internal.h
index 64452d2397..b8cfeb0490 100644
--- a/bgpd/rfp-example/librfp/rfp_internal.h
+++ b/bgpd/rfp-example/librfp/rfp_internal.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/* Sample header file */
diff --git a/bgpd/rfp-example/rfptest/rfptest.c b/bgpd/rfp-example/rfptest/rfptest.c
index 39b798e516..2141933d14 100644
--- a/bgpd/rfp-example/rfptest/rfptest.c
+++ b/bgpd/rfp-example/rfptest/rfptest.c
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
diff --git a/bgpd/rfp-example/rfptest/rfptest.h b/bgpd/rfp-example/rfptest/rfptest.h
index 00effb8673..2ebd7d12b7 100644
--- a/bgpd/rfp-example/rfptest/rfptest.h
+++ b/bgpd/rfp-example/rfptest/rfptest.h
@@ -13,10 +13,9 @@
* 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.
- *
+ * 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
*/
/* Sample header file */
diff --git a/configure.ac b/configure.ac
index d9bed28c95..fa10baf8fa 100755
--- a/configure.ac
+++ b/configure.ac
@@ -7,7 +7,7 @@
##
AC_PREREQ(2.60)
-AC_INIT(frr, 3.0, [https://github.com/frrouting/frr/issues])
+AC_INIT(frr, 3.1-dev, [https://github.com/frrouting/frr/issues])
PACKAGE_URL="https://frrouting.org/"
PACKAGE_FULLNAME="FRRouting"
AC_SUBST(PACKAGE_FULLNAME)
@@ -73,6 +73,10 @@ LIBS="$LIBS -ltcmalloc_minimal"
esac],[tcmalloc_enabled=false])
+dnl Thanks autoconf, but we don't want a default -g -O2. We have our own
+dnl flag determination logic.
+CFLAGS="${CFLAGS:-}"
+
dnl --------------------
dnl Check CC and friends
dnl --------------------
@@ -85,6 +89,7 @@ AM_PROG_CC_C_O
dnl remove autoconf default "-g -O2"
CFLAGS="$orig_cflags"
AC_PROG_CC_C99
+dnl NB: see C11 below
AC_PROG_EGREP
PKG_PROG_PKG_CONFIG
@@ -96,7 +101,7 @@ AC_CHECK_PROG([SED],[sed],[sed],[/bin/false])
dnl try and enable CFLAGS that are useful for Quagga
dnl - specifically, options to control warnings
-AC_USE_SYSTEM_EXTENSIONS()
+AC_USE_SYSTEM_EXTENSIONS
AC_DEFUN([AC_C_FLAG], [{
AC_LANG_PUSH(C)
ac_c_flag_save="$CFLAGS"
@@ -122,6 +127,13 @@ dnl ICC won't bail on unknown options without -diag-error 10006
dnl need to do this first so we get useful results for the other options
AC_C_FLAG([-diag-error 10006])
+dnl AC_PROG_CC_C99 may change CC to include -std=gnu99 or something
+ac_cc="$CC"
+CC="${CC% -std=gnu99}"
+CC="${CC% -std=c99}"
+
+AC_C_FLAG([-std=gnu11], [CC="$ac_cc"], [CC="$CC -std=gnu11"])
+
dnl if the user specified any CFLAGS, we don't add "-g -Os/-O2" here
if test "z$orig_cflags" = "z"; then
AC_C_FLAG([-g])
@@ -177,6 +189,18 @@ AC_LINK_IFELSE(
])
AC_LANG_POP(C)
+dnl ----------
+dnl Essentials
+dnl ----------
+
+AX_PTHREAD([
+ CC="$PTHREAD_CC"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+], [
+ AC_MSG_FAILURE([This Quagga version needs pthreads])
+])
+
dnl --------------
dnl Check programs
dnl --------------
@@ -204,6 +228,9 @@ AC_ARG_WITH(pkg-extra-version,
AC_ARG_WITH(pkg-git-version,
AS_HELP_STRING([--with-pkg-git-version], [add git information to MOTD and build version string]),
[ test "x$withval" != "xno" && with_pkg_git_version="yes" ])
+AC_ARG_WITH(vtysh_pager,
+ AS_HELP_STRING([--with-vtysh-pager=PAGER], [control what pager is compiled in as default]),
+ VTYSH_PAGER=$withval, VTYSH_PAGER="more")
AC_ARG_ENABLE(vtysh,
AS_HELP_STRING([--disable-vtysh], [do not build integrated vty shell for Quagga]))
AC_ARG_ENABLE(doc,
@@ -224,6 +251,8 @@ AC_ARG_ENABLE(ldpd,
AS_HELP_STRING([--enable-ldpd], [build ldpd]))
AC_ARG_ENABLE(nhrpd,
AS_HELP_STRING([--disable-nhrpd], [do not build nhrpd]))
+AC_ARG_ENABLE(eigrpd,
+ AS_HELP_STRING([--disable-eigrpd], [do not build eigrpd]))
AC_ARG_ENABLE(watchfrr,
AS_HELP_STRING([--disable-watchfrr], [do not build watchfrr]))
AC_ARG_ENABLE(isisd,
@@ -289,6 +318,8 @@ AC_ARG_ENABLE(werror,
AS_HELP_STRING([--enable-werror], [enable -Werror (recommended for developers only)]))
AC_ARG_ENABLE(cumulus,
AS_HELP_STRING([--enable-cumulus], [enable Cumulus Switch Special Extensions]))
+AC_ARG_ENABLE(datacenter,
+ AS_HELP_STRING([--enable-datacenter], [enable Compilation for Data Center Extensions]))
AC_ARG_ENABLE(rr-semantics,
AS_HELP_STRING([--disable-rr-semantics], [disable the v6 Route Replace semantics]))
AC_ARG_ENABLE([protobuf],
@@ -343,11 +374,11 @@ dnl ----------
AC_MSG_CHECKING(whether this OS has MPLS stack)
case "$host" in
*-linux*)
- MPLS_METHOD="zebra_mpls_netlink.o"
+ MPLS_METHOD="zebra_mpls_netlink.o zebra_mpls.o"
AC_MSG_RESULT(Linux MPLS)
;;
*-openbsd*)
- MPLS_METHOD="zebra_mpls_openbsd.o"
+ MPLS_METHOD="zebra_mpls_openbsd.o zebra_mpls.o"
AC_MSG_RESULT(OpenBSD MPLS)
;;
*)
@@ -357,12 +388,17 @@ case "$host" in
esac
AC_SUBST(MPLS_METHOD)
-if test "${enable_cumulus}" = "yes" ; then
- AC_DEFINE(HAVE_CUMULUS,,Compile Special Cumulus Code in)
+if test "${enable_datacenter}" = "yes" ; then
+ AC_DEFINE(HAVE_DATACENTER,,Compile extensions for a DataCenter)
DFLT_NAME="datacenter"
else
DFLT_NAME="traditional"
fi
+
+if test "${enable_cumulus}" = "yes" ; then
+ AC_DEFINE(HAVE_CUMULUS,,Compile Special Cumulus Code in)
+fi
+
AC_SUBST(DFLT_NAME)
AC_DEFINE_UNQUOTED(DFLT_NAME,["$DFLT_NAME"], Name of the configuration default set)
@@ -499,6 +535,8 @@ esac
AC_DEFINE_UNQUOTED(MULTIPATH_NUM, $MPATH_NUM, Maximum number of paths for a route)
+AC_DEFINE_UNQUOTED(VTYSH_PAGER, "$VTYSH_PAGER", [What pager to use])
+
dnl -----------------------------------
dnl Add extra version string to package
dnl name, string and version fields.
@@ -539,6 +577,72 @@ AC_CHECK_HEADERS([stropts.h sys/ksym.h \
linux/version.h asm/types.h \
sys/cdefs.h])
+ac_stdatomic_ok=false
+AC_DEFINE(FRR_AUTOCONF_ATOMIC, 1, [did autoconf checks for atomic funcs])
+AC_CHECK_HEADER([stdatomic.h],[
+
+ AC_MSG_CHECKING([whether _Atomic qualifier works])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+#include <stdatomic.h>
+int main(int argc, char **argv) {
+ _Atomic int i = 0;
+ return i;
+}
+]])], [
+ AC_DEFINE(HAVE_STDATOMIC_H, 1, [found stdatomic.h])
+ AC_MSG_RESULT([yes])
+ ac_stdatomic_ok=true
+ ], [
+ AC_MSG_RESULT([no])
+ ])
+])
+
+AS_IF([$ac_stdatomic_ok], [true], [
+ AC_MSG_CHECKING([for __atomic_* builtins])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+int main(int argc, char **argv) {
+ volatile int i = 1;
+ __atomic_store_n (&i, 0, __ATOMIC_RELEASE);
+ return __atomic_load_n (&i, __ATOMIC_ACQUIRE);
+}
+]])], [
+ AC_DEFINE(HAVE___ATOMIC, 1, [found __atomic builtins])
+ AC_MSG_RESULT([yes])
+ ], [
+ AC_MSG_RESULT([no])
+
+ dnl FreeBSD 9 has a broken stdatomic.h where _Atomic doesn't work
+ AC_MSG_CHECKING([for __sync_* builtins])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+int main(int argc, char **argv) {
+ volatile int i = 1;
+ __sync_fetch_and_sub (&i, 1);
+ return __sync_val_compare_and_swap (&i, 0, 1);
+}
+]])], [
+ AC_DEFINE(HAVE___SYNC, 1, [found __sync builtins])
+ AC_MSG_RESULT([yes])
+
+ AC_MSG_CHECKING([for __sync_swap builtin])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+int main(int argc, char **argv) {
+ volatile int i = 1;
+ return __sync_swap (&i, 2);
+}
+]])], [
+ AC_DEFINE(HAVE___SYNC_SWAP, 1, [found __sync_swap builtin])
+ AC_MSG_RESULT([yes])
+ ], [
+ AC_MSG_RESULT([no])
+ ])
+
+ ], [
+ AC_MSG_RESULT([no])
+ AC_MSG_FAILURE([stdatomic.h unavailable and $CC has neither __atomic nor __sync builtins])
+ ])
+ ])
+])
+
dnl Utility macro to avoid retyping includes all the time
m4_define([FRR_INCLUDES],
[#ifdef SUNOS_5
@@ -1210,6 +1314,13 @@ else
fi
AM_CONDITIONAL(NHRPD, test "x$NHRPD" = "xnhrpd")
+if test "${enable_eigrpd}" = "no";then
+ EIGRPD=""
+else
+ EIGRPD="eigrpd"
+fi
+AM_CONDITIONAL(EIGRPD, test "x$EIGRPD" = "xeigrpd")
+
if test "${enable_watchfrr}" = "no";then
WATCHFRR=""
else
@@ -1291,6 +1402,7 @@ AC_SUBST(OSPFD)
AC_SUBST(OSPF6D)
AC_SUBST(LDPD)
AC_SUBST(NHRPD)
+AC_SUBST(EIGRPD)
AC_SUBST(WATCHFRR)
AC_SUBST(ISISD)
AC_SUBST(PIMD)
@@ -1403,6 +1515,8 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
])
+AM_CONDITIONAL(SNMP, test "x$SNMP_METHOD" = "xagentx")
+
dnl ---------------------------
dnl sockaddr and netinet checks
dnl ---------------------------
@@ -1503,6 +1617,12 @@ AC_TRY_COMPILE([#include <netinet/in.h>], [
])
dnl --------------------------------------
+dnl checking for be32dec existence or not
+dnl --------------------------------------
+AC_CHECK_DECLS([be32enc, be32dec], [], [],
+ [#include <sys/endian.h>])
+
+dnl --------------------------------------
dnl checking for clock_time monotonic struct and call
dnl --------------------------------------
AC_CHECK_DECL(CLOCK_MONOTONIC,
@@ -1731,10 +1851,10 @@ 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
+ eigrpd/Makefile
nhrpd/Makefile
redhat/Makefile
tools/Makefile
- cumulus/Makefile
pkgsrc/Makefile
fpm/Makefile
redhat/frr.spec
@@ -1750,6 +1870,7 @@ AC_CONFIG_FILES([Makefile lib/Makefile qpb/Makefile zebra/Makefile ripd/Makefile
doc/ospfd.8
doc/ldpd.8
doc/ripd.8
+ doc/eigrpd.8
doc/ripngd.8
doc/pimd.8
doc/nhrpd.8
@@ -1758,7 +1879,8 @@ AC_CONFIG_FILES([Makefile lib/Makefile qpb/Makefile zebra/Makefile ripd/Makefile
doc/zebra.8
doc/frr.1
pkgsrc/bgpd.sh pkgsrc/ospf6d.sh pkgsrc/ospfd.sh
- pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh])
+ pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh
+ pkgsrc/eigrpd.sh])
if test "${enable_bgp_vnc}" != "no"; then
if test "${with_rfp_path}" = "bgpd/rfp-example" ; then
diff --git a/cumulus/.gitignore b/cumulus/.gitignore
deleted file mode 100644
index 2a198f5d45..0000000000
--- a/cumulus/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.o
-ssd
diff --git a/cumulus/Makefile.am b/cumulus/Makefile.am
deleted file mode 100644
index 027862314c..0000000000
--- a/cumulus/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-
-sbin_PROGRAMS = ssd
-EXTRA_DIST = etc/frr/debian.conf etc/frr/daemons etc/default/frr
-
-ssd_SOURCES = start-stop-daemon.c
diff --git a/debian/README.Debian b/debian/README.Debian
index 4cf35d7e32..1b04803366 100644
--- a/debian/README.Debian
+++ b/debian/README.Debian
@@ -83,7 +83,7 @@ into the kernel.
=====================================================================
If this message occurs the receive buffer should be increased by adding the
-following to /etc/sysctl.conf and "--nl-bufsize" to /etc/frr/debian.conf.
+following to /etc/sysctl.conf and "--nl-bufsize" to /etc/frr/daemons.conf.
> net.core.rmem_default = 262144
> net.core.rmem_max = 262144
See message #4525 from 2005-05-09 in the quagga-users mailing list.
diff --git a/debian/README.Maintainer b/debian/README.Maintainer
index aa8ac0cf35..84b68e1949 100644
--- a/debian/README.Maintainer
+++ b/debian/README.Maintainer
@@ -11,7 +11,7 @@ Files that keep their names
/usr/bin/vtysh
Files that got an -pj suffix
- /etc/default/zebra -> /etc/frr/debian.conf
+ /etc/default/zebra -> /etc/frr/daemons.conf
/etc/init.d/zebra -> /etc/init.d/frr
/etc/zebra/ -> /etc/frr/
/usr/share/doc/zebra/ -> /usr/share/doc/frr/
diff --git a/debian/changelog b/debian/changelog
index fe4ee6b334..4ea86929fc 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+frr (3.1-dev) Released; urgency=medium
+
+ * New Enabled: PIM draft Unnumbered
+
+ -- frr <frog@lists.frrouting.org> Wed, 5 Apr 2017 22:29:42 -0500
+
frr (3.0) Released; urgency=medium
* New Enabled: BGP Shutdown Message
diff --git a/debian/control b/debian/control
index 4ecbefc6d6..3982aa41be 100644
--- a/debian/control
+++ b/debian/control
@@ -12,7 +12,7 @@ Package: frr
Architecture: any
Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute, ${misc:Depends}, libc-ares2
Pre-Depends: adduser
-Conflicts: zebra, zebra-pj
+Conflicts: zebra, zebra-pj, quagga
Replaces: zebra, zebra-pj
Suggests: snmpd
Description: BGP/OSPF/RIP routing daemon
diff --git a/debian/frr.dirs b/debian/frr.dirs
index 58290080d0..56699b2daa 100644
--- a/debian/frr.dirs
+++ b/debian/frr.dirs
@@ -1,5 +1,6 @@
etc/logrotate.d/
etc/frr/
+etc/iproute2/rt_protos.d/
usr/share/doc/frr/
usr/share/doc/frr/examples/
usr/share/lintian/overrides/
diff --git a/debian/frr.install b/debian/frr.install
index 45b3b973be..49aeb395bb 100644
--- a/debian/frr.install
+++ b/debian/frr.install
@@ -17,6 +17,6 @@ usr/share/man/man8/zebra.8
usr/share/man/man8/isisd.8
usr/share/man/man8/watchfrr.8
usr/share/snmp/mibs/
-cumulus/etc/* etc/
+tools/etc/* etc/
tools/*.service lib/systemd/system
debian/frr.conf usr/lib/tmpfiles.d
diff --git a/defaults.h b/defaults.h
index 57e35f3ce6..d9fd44e14c 100644
--- a/defaults.h
+++ b/defaults.h
@@ -14,8 +14,8 @@
* 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.
+ * 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 _FRR_DEFAULTS_H
@@ -23,7 +23,7 @@
#include "config.h"
-#ifdef HAVE_CUMULUS
+#ifdef HAVE_DATACENTER
#define DFLT_BGP_IMPORT_CHECK 1
#define DFLT_BGP_TIMERS_CONNECT 10
@@ -36,7 +36,7 @@
#define DFLT_OSPF_LOG_ADJACENCY_CHANGES 1
#define DFLT_OSPF6_LOG_ADJACENCY_CHANGES 1
-#else /* !HAVE_CUMULUS */
+#else /* !HAVE_DATACENTER */
#define DFLT_BGP_IMPORT_CHECK 0
#define DFLT_BGP_TIMERS_CONNECT 120
@@ -49,6 +49,6 @@
#define DFLT_OSPF_LOG_ADJACENCY_CHANGES 0
#define DFLT_OSPF6_LOG_ADJACENCY_CHANGES 0
-#endif /* !HAVE_CUMULUS */
+#endif /* !HAVE_DATACENTER */
#endif /* _FRR_DEFAULTS_H */
diff --git a/doc/Building_FRR_on_Ubuntu1204.md b/doc/Building_FRR_on_Ubuntu1204.md
index 521f0a0c2b..033e05bcdb 100644
--- a/doc/Building_FRR_on_Ubuntu1204.md
+++ b/doc/Building_FRR_on_Ubuntu1204.md
@@ -136,7 +136,7 @@ other settings)
sudo install -m 755 tools/frr /etc/init.d/frr
sudo install -m 644 cumulus/etc/frr/daemons /etc/frr/daemons
- sudo install -m 644 cumulus/etc/frr/debian.conf /etc/frr/debian.conf
+ sudo install -m 644 cumulus/etc/frr/daemons.conf /etc/frr/daemons.conf
sudo install -m 644 -o frr -g frr cumulus/etc/frr/vtysh.conf /etc/frr/vtysh.conf
### Enable daemons
diff --git a/doc/Building_FRR_on_Ubuntu1404.md b/doc/Building_FRR_on_Ubuntu1404.md
index 2c5f132ad7..11daecf195 100644
--- a/doc/Building_FRR_on_Ubuntu1404.md
+++ b/doc/Building_FRR_on_Ubuntu1404.md
@@ -96,7 +96,7 @@ other settings)
sudo install -m 755 tools/frr /etc/init.d/frr
sudo install -m 644 cumulus/etc/frr/daemons /etc/frr/daemons
- sudo install -m 644 cumulus/etc/frr/debian.conf /etc/frr/debian.conf
+ sudo install -m 644 cumulus/etc/frr/daemons.conf /etc/frr/daemons.conf
sudo install -m 644 -o frr -g frr cumulus/etc/frr/vtysh.conf /etc/frr/vtysh.conf
diff --git a/doc/Building_FRR_on_Ubuntu1604.md b/doc/Building_FRR_on_Ubuntu1604.md
index 655c810550..9aa3206fee 100644
--- a/doc/Building_FRR_on_Ubuntu1604.md
+++ b/doc/Building_FRR_on_Ubuntu1604.md
@@ -119,8 +119,8 @@ Add the following lines to `/etc/modules-load.d/modules.conf`:
sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
sudo install -m 644 cumulus/etc/default/frr /etc/default/frr
sudo install -m 644 cumulus/etc/frr/daemons /etc/frr/daemons
- sudo install -m 644 cumulus/etc/frr/debian.conf /etc/frr/debian.conf
- sudo install -m 644 cumulus/etc/frr/frr.conf /etc/frr/frr.conf
+ sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
+ sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf
sudo install -m 644 -o frr -g frr cumulus/etc/frr/vtysh.conf /etc/frr/vtysh.conf
### Enable daemons
diff --git a/doc/Makefile.am b/doc/Makefile.am
index d82a307304..318179e255 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -61,6 +61,7 @@ frr_TEXINFOS = appendix.texi basic.texi bgpd.texi isisd.texi filter.texi \
vnc.texi \
install.texi ipv6.texi kernel.texi main.texi \
nhrpd.texi \
+ eigrpd.texi \
ospf6d.texi ospfd.texi \
overview.texi protocol.texi ripd.texi ripngd.texi routemap.texi \
snmp.texi vtysh.texi routeserver.texi defines.texi $(figures_png) \
@@ -129,6 +130,10 @@ if ZEBRA
man_MANS += zebra.8
endif
+if EIGRPD
+man_MANS += eigrpd.8
+endif
+
EXTRA_DIST = BGP-TypeCode draft-zebra-00.ms draft-zebra-00.txt \
\
bgpd.8.in \
@@ -145,6 +150,7 @@ EXTRA_DIST = BGP-TypeCode draft-zebra-00.ms draft-zebra-00.txt \
watchfrr.8.in \
zebra.8.in \
frr.1.in \
+ eigrpd.8.in \
\
mpls/ChangeLog.opaque.txt mpls/cli_summary.txt \
mpls/opaque_lsa.txt mpls/ospfd.conf \
diff --git a/doc/bgpd.texi b/doc/bgpd.texi
index 08cd4149a4..8e0da12949 100644
--- a/doc/bgpd.texi
+++ b/doc/bgpd.texi
@@ -526,7 +526,9 @@ This command adds the announcement network.
@example
@group
router bgp 1
- network 10.0.0.0/8
+ address-family ipv4 unicast
+ network 10.0.0.0/8
+ exit-address-family
@end group
@end example
This configuration example says that network 10.0.0.0/8 will be
@@ -1160,7 +1162,9 @@ communities attribute to the updates.
@example
router bgp 7675
neighbor 192.168.0.1 remote-as 100
- neighbor 192.168.0.1 route-map RMAP in
+ address-family ipv4 unicast
+ neighbor 192.168.0.1 route-map RMAP in
+ exit-address-family
!
ip community-list 70 permit 7675:70
ip community-list 70 deny
@@ -1191,7 +1195,9 @@ value 80.
router bgp 100
network 10.0.0.0/8
neighbor 192.168.0.2 remote-as 7675
- neighbor 192.168.0.2 route-map RMAP out
+ address-family ipv4 unicast
+ neighbor 192.168.0.2 route-map RMAP out
+ exit-address-family
!
ip prefix-list PLIST permit 10.0.0.0/8
!
@@ -1209,7 +1215,9 @@ limit the BGP routes announcement into the internal network.
@example
router bgp 7675
neighbor 192.168.0.1 remote-as 100
- neighbor 192.168.0.1 route-map RMAP in
+ address-family ipv4 unicast
+ neighbor 192.168.0.1 route-map RMAP in
+ exit-address-family
!
ip community-list 1 permit 0:80 0:90
!
@@ -1224,7 +1232,9 @@ filtering all of routes, we need to define permit any at last.
@example
router bgp 7675
neighbor 192.168.0.1 remote-as 100
- neighbor 192.168.0.1 route-map RMAP in
+ address-family ipv4 unicast
+ neighbor 192.168.0.1 route-map RMAP in
+ exit-address-family
!
ip community-list standard FILTER deny 1:1
ip community-list standard FILTER permit
@@ -1252,7 +1262,9 @@ community-list is used. @code{deny} community-list is ignored.
@example
router bgp 7675
neighbor 192.168.0.1 remote-as 100
- neighbor 192.168.0.1 route-map RMAP in
+ address-family ipv4 unicast
+ neighbor 192.168.0.1 route-map RMAP in
+ exit-address-family
!
ip community-list standard DEL permit 100:1 100:2
!
@@ -1606,11 +1618,15 @@ to specify @command{neighbor A.B.C.D send-community} command.
!
router bgp 1
neighbor 10.0.0.1 remote-as 1
- no neighbor 10.0.0.1 send-community
+ address-family ipv4 unicast
+ no neighbor 10.0.0.1 send-community
+ exit-address-family
!
router bgp 1
neighbor 10.0.0.1 remote-as 1
- neighbor 10.0.0.1 send-community
+ address-family ipv4 unicast
+ neighbor 10.0.0.1 send-community
+ exit-address-family
!
@end example
@@ -1680,11 +1696,15 @@ bgp multiple-instance
!
router bgp 1 view 1
neighbor 10.0.0.1 remote-as 2
- neighbor 10.0.0.1 distribute-list 1 in
+ address-family ipv4 unicast
+ neighbor 10.0.0.1 distribute-list 1 in
+ exit-address-family
!
router bgp 1 view 2
neighbor 10.0.0.1 remote-as 2
- neighbor 10.0.0.1 distribute-list 2 in
+ address-family ipv4 unicast
+ neighbor 10.0.0.1 distribute-list 2 in
+ exit-address-family
@end group
@end example
@@ -1792,13 +1812,16 @@ Example of a session to an upstream, advertising only one prefix to it.
@example
router bgp 64512
bgp router-id 10.236.87.1
- network 10.236.87.0/24
neighbor upstream peer-group
neighbor upstream remote-as 64515
neighbor upstream capability dynamic
- neighbor upstream prefix-list pl-allowed-adv out
neighbor 10.1.1.1 peer-group upstream
neighbor 10.1.1.1 description ACME ISP
+
+ address-family ipv4 unicast
+ network 10.236.87.0/24
+ neighbor upstream prefix-list pl-allowed-adv out
+ exit-address-family
!
ip prefix-list pl-allowed-adv seq 5 permit 82.195.133.0/25
ip prefix-list pl-allowed-adv seq 10 deny any
@@ -1816,18 +1839,9 @@ flaws.
@example
router bgp 64512
bgp router-id 10.236.87.1
- network 10.123.456.0/24
- network 10.123.456.128/25 route-map rm-no-export
neighbor upstream capability dynamic
- neighbor upstream route-map rm-upstream-out out
neighbor cust capability dynamic
- neighbor cust route-map rm-cust-in in
- neighbor cust route-map rm-cust-out out
- neighbor cust send-community both
neighbor peer capability dynamic
- neighbor peer route-map rm-peer-in in
- neighbor peer route-map rm-peer-out out
- neighbor peer send-community both
neighbor 10.1.1.1 remote-as 64515
neighbor 10.1.1.1 peer-group upstream
neighbor 10.2.1.1 remote-as 64516
@@ -1835,19 +1849,31 @@ router bgp 64512
neighbor 10.3.1.1 remote-as 64517
neighbor 10.3.1.1 peer-group cust-default
neighbor 10.3.1.1 description customer1
- neighbor 10.3.1.1 prefix-list pl-cust1-network in
neighbor 10.4.1.1 remote-as 64518
neighbor 10.4.1.1 peer-group cust
- neighbor 10.4.1.1 prefix-list pl-cust2-network in
neighbor 10.4.1.1 description customer2
neighbor 10.5.1.1 remote-as 64519
neighbor 10.5.1.1 peer-group peer
- neighbor 10.5.1.1 prefix-list pl-peer1-network in
neighbor 10.5.1.1 description peer AS 1
neighbor 10.6.1.1 remote-as 64520
neighbor 10.6.1.1 peer-group peer
- neighbor 10.6.1.1 prefix-list pl-peer2-network in
neighbor 10.6.1.1 description peer AS 2
+
+ address-family ipv4 unicast
+ network 10.123.456.0/24
+ network 10.123.456.128/25 route-map rm-no-export
+ neighbor upstream route-map rm-upstream-out out
+ neighbor cust route-map rm-cust-in in
+ neighbor cust route-map rm-cust-out out
+ neighbor cust send-community both
+ neighbor peer route-map rm-peer-in in
+ neighbor peer route-map rm-peer-out out
+ neighbor peer send-community both
+ neighbor 10.3.1.1 prefix-list pl-cust1-network in
+ neighbor 10.4.1.1 prefix-list pl-cust2-network in
+ neighbor 10.5.1.1 prefix-list pl-peer1-network in
+ neighbor 10.6.1.1 prefix-list pl-peer2-network in
+ exit-address-family
!
ip prefix-list pl-default permit 0.0.0.0/0
!
diff --git a/doc/cli.md b/doc/cli.md
index 559f75a740..ffd34dd302 100644
--- a/doc/cli.md
+++ b/doc/cli.md
@@ -7,10 +7,12 @@ Definition Grammar
This is a reference for the syntax used when defining new CLI commands. An
example definition is:
+```
DEFUN (command_name,
command_name_cmd,
--> "example <command|line [interface]> DEFINITION...",
<..doc strings..>)
+```
The arrowed part is the definition string.
@@ -27,34 +29,36 @@ Characters allowed in each token type:
Tokens
------
-* WORD -- A token that begins with +, -, or a lowercase letter. It is
- an unchanging part of the command and will only match itself.
- Example: "show ip bgp", every token is a WORD.
-* IPV4 -- 'A.B.C.D', matches an IPv4 address.
-* IPV6 -- 'X:X::X:X', matches an IPv6 address.
-* IPV4_PREFIX -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR notation.
-* IPV6_PREFIX -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR notation.
-* VARIABLE -- Begins with a capital letter. Matches any input.
-* RANGE -- Numeric range delimited by parentheses, e.g. (-100 - 100) or
- (10-20). Will only match numbers in the range.
+* `WORD` -- A token that begins with +, -, or a lowercase letter. It is
+ an unchanging part of the command and will only match itself.
+ Example: "show ip bgp", every token is a WORD.
+* `IPV4` -- 'A.B.C.D', matches an IPv4 address.
+* `IPV6` -- 'X:X::X:X', matches an IPv6 address.
+* `IPV4_PREFIX` -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR notation.
+* `IPV6_PREFIX` -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR notation.
+* `VARIABLE` -- Begins with a capital letter. Matches any input.
+* `RANGE` -- Numeric range delimited by parentheses, e.g. (-100 - 100) or
+ (10-20). Will only match numbers in the range.
Rules
-----
-* <angle|brackets> -- Contain sequences of tokens separated by pipes and
+* `<angle|brackets>` -- Contain sequences of tokens separated by pipes and
provide mutual exclusion. Sequences may contain
- <mutual|exclusion> but not as the first token.
- Disallowed: "example <<a|b> c|d>"
- Allowed: "example <a c|b c|d>
-* [square brackets] -- Contains sequences of tokens that are optional (can be
- omitted).
-* {curly|braces} -- similar to angle brackets, but instead of mutual
+ `<mutual|exclusion>` but not as the first token.
+ Disallowed: `"example <<a|b> c|d>"`
+ Allowed: `"example <a c|b c|d>"`
+* `[square brackets]` -- Contains sequences of tokens that are optional (can be
+ omitted). `[<a|b>]` can be shortened to `[a|b]`.
+* `{curly|braces}` -- similar to angle brackets, but instead of mutual
exclusion, curly braces indicate that one or more of the
pipe-separated sequences may be provided in any order.
-* VARIADICS... -- Any token which accepts input (so anything except WORD)
+* `VARIADICS...` -- Any token which accepts input (so anything except WORD)
and that occurs as the last token of a line may be
followed by an ellipsis, which indicates that input
matching the token may be repeated an unlimited number
of times.
+* `$name` -- Specify a variable name for the preceding token. See
+ "Variable Names" below.
Some general notes:
@@ -69,6 +73,40 @@ Some general notes:
configuration items should be defined in separate commands. Clarity is
preferred over LOC (within reason).
+Variable Names
+--------------
+The parser tries to fill the "varname" field on each token. This can happen
+either manually or automatically. Manual specifications work by appending
+`"$name"` after the input specifier:
+
+```
+foo bar$cmd WORD$name A.B.C.D$ip
+```
+
+Note that you can also assign variable names to fixed input tokens, this can
+be useful if multiple commands share code. You can also use "$name" after a
+multiple-choice option:
+
+```
+foo bar <A.B.C.D|X:X::X:X>$addr [optionA|optionB]$mode
+```
+
+The variable name is in this case assigned to the last token in each of the
+branches.
+
+Automatic assignment of variable names works by applying the following rules:
+
+- manual names always have priority
+- a "[no]" at the beginning receives "no" as varname on the "no" token
+- VARIABLE tokens whose text is not "WORD" or "NAME" receive a cleaned lowercase
+ version of the token text as varname, e.g. "ROUTE-MAP" becomes "route_map".
+- other variable tokens (i.e. everything except "fixed") receive the text of
+ the preceding fixed token as varname, if one can be found. E.g.:
+ "ip route A.B.C.D/M INTERFACE" assigns "route" to the "A.B.C.D/M" token.
+
+These rules should make it possible to avoid manual varname assignment in 90%
+of the cases.
+
Doc Strings
-----------
Each token in a command definition should be documented with a brief doc
@@ -77,11 +115,13 @@ command tree. These strings are provided as the last parameter to DEFUN macros,
concatenated together and separated by an escaped newline ('\n'). These are
best explained by example.
+```
DEFUN (config_terminal,
config_terminal_cmd,
"configure terminal",
"Configuration from vty interface\n"
"Configuration terminal\n")
+```
The last parameter is split into two lines for readability. Two newline
delimited doc strings are present, one for each token in the command. The
@@ -110,11 +150,13 @@ constructs.
In the examples below, each arrowed token needs a doc string.
+```
"show ip bgp"
^ ^ ^
"command <foo|bar> [example]"
^ ^ ^ ^
+```
Data Structures
---------------
@@ -216,22 +258,32 @@ it is generally _incorrect_ to assume consistent indices in this array. As a
simple example:
Command definition:
+```
command [foo] <bar|baz>
+```
User enters:
+```
command foo bar
+```
Array:
+```
[0] -> command
[1] -> foo
[2] -> bar
+```
User enters:
+```
command baz
+```
Array:
+```
[0] -> command
[1] -> baz
+```
@@ -242,24 +294,32 @@ tokens when the CLI matcher does not need them to make an unambiguous match.
This is best explained by example.
Command definitions:
+```
command dog cow
command dog crow
+```
User input:
+```
c d c -> ambiguous command
c d co -> match "command dog cow"
+```
In the new implementation, this functionality has improved. Where previously
the parser would stop at the first ambiguous token, it will now look ahead and
attempt to disambiguate based on tokens later on in the input string.
Command definitions:
+```
show ip bgp A.B.C.D
show ipv6 bgp X:X::X:X
+```
User enters:
+```
s i b 4.3.2.1 -> match "show ip bgp A.B.C.D"
s i b ::e0 -> match "show ipv6 bgp X:X::X:X"
+```
Previously both of these commands would be ambiguous since 'i' does not
explicitly select either 'ip' or 'ipv6'. However, since the user later provides
@@ -268,17 +328,23 @@ parser is able to look ahead and select the appropriate command. This has some
implications for parsing the argv*[] that is passed to the command handler.
Now consider a command definition such as:
+```
command <foo|VAR>
+```
'foo' only matches the string 'foo', but 'VAR' matches any input, including
'foo'. Who wins? In situations like this the matcher will always choose the
'better' match, so 'foo' will win.
Consider also:
+```
show <ip|ipv6> foo
+```
User input:
+```
show ip foo
+```
'ip' partially matches 'ipv6' but exactly matches 'ip', so 'ip' will win.
@@ -286,6 +352,7 @@ User input:
struct cmd_token
----------------
+```
/* Command token struct. */
struct cmd_token
{
@@ -297,7 +364,9 @@ struct cmd_token
char *desc; // token description
long long min, max; // for ranges
char *arg; // user input that matches this token
+ char *varname; // variable name
};
+```
This struct is used in the CLI graph to match input against. It is also used to
pass user input to command handler functions, as it is frequently useful for
@@ -316,7 +385,9 @@ has the full text of the corresponding token in the definition string and using
it makes for much more readable code. An example is helpful.
Command definition:
+```
command <(1-10)|foo|BAR>
+```
In this example, the user may enter any one of:
* an integer between 1 and 10
@@ -325,9 +396,11 @@ In this example, the user may enter any one of:
If the user enters "command f", then:
+```
argv[1]->type == WORD_TKN
argv[1]->arg == "f"
argv[1]->text == "foo"
+```
Range tokens have some special treatment; a token with ->type == RANGE_TKN will
have the ->min and ->max fields set to the bounding values of the range.
@@ -342,6 +415,7 @@ all matching input permutations. It also dumps a text representation of the
graph, which is more useful for debugging than anything else. It looks like
this:
+```
$ ./permutations "show [ip] bgp [<view|vrf> WORD]"
show ip bgp view WORD
@@ -350,6 +424,7 @@ show ip bgp
show bgp view WORD
show bgp vrf WORD
show bgp
+```
This functionality is also built into VTY/VTYSH; the 'list permutations'
command will list all possible matching input permutations in the current CLI
diff --git a/doc/eigrpd.8.in b/doc/eigrpd.8.in
new file mode 100644
index 0000000000..ecac972bc2
--- /dev/null
+++ b/doc/eigrpd.8.in
@@ -0,0 +1,122 @@
+.TH EIGRPD 8 "6 May 2017" "@PACKAGE_FULLNAME@ EIGRP daemon" "Version @PACKAGE_VERSION@"
+.SH NAME
+eigrpd \- a EIGRP routing engine for use with @PACKAGE_FULLNAME@.
+.SH SYNOPSIS
+.B eigrpd
+[
+.B \-dhrv
+] [
+.B \-f
+.I config-file
+] [
+.B \-i
+.I pid-file
+] [
+.B \-P
+.I port-number
+] [
+.B \-A
+.I vty-address
+] [
+.B \-u
+.I user
+] [
+.B \-g
+.I group
+] [
+.B \-M
+.I module:options
+]
+.SH DESCRIPTION
+.B eigrpd
+is a routing component that works with the
+.B @PACKAGE_FULLNAME@
+routing engine.
+.SH OPTIONS
+Options available for the
+.B eigrpd
+command:
+.SH OPTIONS
+.TP
+\fB\-d\fR, \fB\-\-daemon\fR
+Runs in daemon mode, forking and exiting from tty.
+.TP
+\fB\-f\fR, \fB\-\-config-file \fR\fIconfig-file\fR
+Specifies the config file to use for startup. If not specified this
+option will default to \fB\fI@CFG_SYSCONF@/eigrpd.conf\fR.
+.TP
+\fB\-g\fR, \fB\-\-group \fR\fIgroup\fR
+Specify the group to run as. Default is \fI@enable_group@\fR.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+A brief message.
+.TP
+\fB\-i\fR, \fB\-\-pid_file \fR\fIpid-file\fR
+When eigrpd starts its process identifier is written to
+\fB\fIpid-file\fR. The init system uses the recorded PID to stop or
+restart eigrpd. The default is \fB\fI@CFG_STATE@/eigrpd.pid\fR.
+.TP
+\fB\-P\fR, \fB\-\-vty_port \fR\fIport-number\fR
+Specify the port that the eigrpd VTY will listen on. This defaults to
+2602, as specified in \fB\fI/etc/services\fR.
+.TP
+\fB\-A\fR, \fB\-\-vty_addr \fR\fIvty-address\fR
+Specify the address that the eigrpd VTY will listen on. Default is all
+interfaces.
+.TP
+\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
+Specify the user to run as. Default is \fI@enable_user@\fR.
+.TP
+\fB\-r\fR, \fB\-\-retain\fR
+When the program terminates, retain routes added by \fBeigrpd\fR.
+.TP
+\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
+Load a module at startup. May be specified more than once.
+The \fBsnmp\fR module may be available for
+\fBeigrpd\fR, if the package was built with SNMP support.
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+Print the version and exit.
+.SH FILES
+.TP
+.BI @CFG_SBIN@/eigrpd
+The default location of the
+.B eigrpd
+binary.
+.TP
+.BI @CFG_SYSCONF@/eigrpd.conf
+The default location of the
+.B eigrpd
+config file.
+.TP
+.BI $(PWD)/eigrpd.log
+If the
+.B eigrpd
+process is config'd to output logs to a file, then you will find this
+file in the directory where you started \fBeigrpd\fR.
+.SH WARNING
+This man page is intended to be a quick reference for command line
+options. The definitive document is the Info file \fB@PACKAGE_NAME@\fR.
+.SH DIAGNOSTICS
+The eigrpd process may log to standard output, to a VTY, to a log
+file, or through syslog to the system logs. \fBeigrpd\fR supports many
+debugging options, see the Info file, or the source for details.
+.SH "SEE ALSO"
+.BR bgpd (8),
+.BR ripd (8),
+.BR ripngd (8),
+.BR ospfd (8),
+.BR ospf6d (8),
+.BR isisd (8),
+.BR zebra (8),
+.BR vtysh (1)
+.SH BUGS
+.B eigrpd
+eats bugs for breakfast. If you have food for the maintainers try
+.BI @PACKAGE_BUGREPORT@
+.SH AUTHORS
+See
+.BI http://www.zebra.org
+and
+.BI @PACKAGE_URL@
+or the Info file for an accurate list of authors.
diff --git a/doc/eigrpd.texi b/doc/eigrpd.texi
new file mode 100644
index 0000000000..a3a82bbefb
--- /dev/null
+++ b/doc/eigrpd.texi
@@ -0,0 +1,216 @@
+@c -*-texinfo-*-
+@c This is part of the Frr Manual.
+@c @value{COPYRIGHT_STR}
+@c See file frr.texi for copying conditions.
+@node EIGRP
+@chapter EIGRP
+
+EIGRP -- Routing Information Protocol is widely deployed interior gateway
+routing protocol. EIGRP was developed in the 1990's. EIGRP is a
+@dfn{distance-vector} protocol and is based on the @dfn{dual} algorithms.
+As a distance-vector protocol, the EIGRP router send updates to its
+neighbors as networks change, thus allowing the convergence to a
+known topology.
+
+@command{eigrpd} supports EIGRP as described in RFC7868
+
+@menu
+* Starting and Stopping eigrpd::
+* EIGRP Configuration::
+* How to Announce EIGRP routes::
+* Show EIGRP Information::
+* EIGRP Debug Commands::
+@end menu
+
+@node Starting and Stopping eigrpd
+@section Starting and Stopping eigrpd
+
+The default configuration file name of @command{eigrpd}'s is
+@file{eigrpd.conf}. When invocation @command{eigrpd} searches directory
+@value{INSTALL_PREFIX_ETC}. If @file{eigrpd.conf} is not there next
+search current directory. If an integrated config is specified
+configuration is written into frr.conf
+
+The EIGRP protocol requires interface information
+maintained by @command{zebra} daemon. So running @command{zebra}
+is mandatory to run @command{eigrpd}. Thus minimum sequence for running
+EIGRP is like below:
+
+@example
+@group
+# zebra -d
+# eigrpd -d
+@end group
+@end example
+
+Please note that @command{zebra} must be invoked before @command{eigrpd}.
+
+To stop @command{eigrpd}. Please use @command{kill `cat
+/var/run/eigrpd.pid`}. Certain signals have special meanings to @command{eigrpd}.
+
+@table @samp
+@item SIGHUP
+@item SIGUSR1
+Rotate @command{eigrpd} Rotate the logfile.
+@item SIGINT
+@itemx SIGTERM
+@command{eigrpd} sweeps all installed EIGRP routes then terminates properly.
+@end table
+
+@command{eigrpd} invocation options. Common options that can be specified
+(@pxref{Common Invocation Options}).
+
+@table @samp
+@item -r
+@itemx --retain
+When the program terminates, retain routes added by @command{eigrpd}.
+@end table
+
+@node EIGRP Configuration
+@section EIGRP Configuration
+
+@deffn Command {router eigrp (1-65535)} {}
+The @code{router eigrp} command is necessary to enable EIGRP. To disable
+EIGRP, use the @code{no router eigrp (1-65535)} command. EIGRP must be enabled before carrying out any of the EIGRP commands.
+@end deffn
+
+@deffn Command {no router eigrp (1-65535)} {}
+Disable EIGRP.
+@end deffn
+
+@deffn {EIGRP Command} {network @var{network}} {}
+@deffnx {EIGRP Command} {no network @var{network}} {}
+Set the EIGRP enable interface by @var{network}. The interfaces which
+have addresses matching with @var{network} are enabled.
+
+This group of commands either enables or disables EIGRP interfaces between
+certain numbers of a specified network address. For example, if the
+network for 10.0.0.0/24 is EIGRP enabled, this would result in all the
+addresses from 10.0.0.0 to 10.0.0.255 being enabled for EIGRP. The @code{no
+network} command will disable EIGRP for the specified network.
+@end deffn
+
+Below is very simple EIGRP configuration. Interface @code{eth0} and
+interface which address match to @code{10.0.0.0/8} are EIGRP enabled.
+
+@example
+@group
+!
+router eigrp 1
+ network 10.0.0.0/8
+!
+@end group
+@end example
+
+Passive interface
+
+@deffn {EIGRP command} {passive-interface (@var{IFNAME}|default)} {}
+@deffnx {EIGRP command} {no passive-interface @var{IFNAME}} {}
+This command sets the specified interface to passive mode. On passive mode
+interface, all receiving packets are ignored and eigrpd does
+not send either multicast or unicast EIGRP packets except to EIGRP neighbors
+specified with @code{neighbor} command. The interface may be specified
+as @var{default} to make eigrpd default to passive on all interfaces.
+
+The default is to be passive on all interfaces.
+@end deffn
+
+@node How to Announce EIGRP route
+@section How to Announce EIGRP route
+
+@deffn {EIGRP command} {redistribute kernel} {}
+@deffnx {EIGRP command} {redistribute kernel metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)} {}
+@deffnx {EIGRP command} {no redistribute kernel} {}
+@code{redistribute kernel} redistributes routing information from
+kernel route entries into the EIGRP tables. @code{no redistribute kernel}
+disables the routes.
+@end deffn
+
+@deffn {EIGRP command} {redistribute static} {}
+@deffnx {EIGRP command} {redistribute static metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)} {}
+@deffnx {EIGRP command} {no redistribute static} {}
+@code{redistribute static} redistributes routing information from
+static route entries into the EIGRP tables. @code{no redistribute static}
+disables the routes.
+@end deffn
+
+@deffn {EIGRP command} {redistribute connected} {}
+@deffnx {EIGRP command} {redistribute connected metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)} {}
+@deffnx {EIGRP command} {no redistribute connected} {}
+Redistribute connected routes into the EIGRP tables. @code{no
+redistribute connected} disables the connected routes in the EIGRP tables.
+This command redistribute connected of the interface which EIGRP disabled.
+The connected route on EIGRP enabled interface is announced by default.
+@end deffn
+
+@deffn {EIGRP command} {redistribute ospf} {}
+@deffnx {EIGRP command} {redistribute ospf metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)} {}
+@deffnx {EIGRP command} {no redistribute ospf} {}
+@code{redistribute ospf} redistributes routing information from
+ospf route entries into the EIGRP tables. @code{no redistribute ospf}
+disables the routes.
+@end deffn
+
+@deffn {EIGRP command} {redistribute bgp} {}
+@deffnx {EIGRP command} {redistribute bgp metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)} {}
+@deffnx {EIGRP command} {no redistribute bgp} {}
+@code{redistribute bgp} redistributes routing information from
+bgp route entries into the EIGRP tables. @code{no redistribute bgp}
+disables the routes.
+@end deffn
+
+@node Show EIGRP Information
+@section Show EIGRP Information
+
+To display EIGRP routes.
+
+@deffn Command {show ip eigrp topology} {}
+Show EIGRP routes.
+@end deffn
+
+The command displays all EIGRP routes.
+
+@c Exmaple here.
+
+@deffn Command {show ip eigrp topology} {}
+The command displays current EIGRP status
+@end deffn
+
+@example
+@group
+eigrpd> @b{show ip eigrp topology}
+# show ip eigrp topo
+
+EIGRP Topology Table for AS(4)/ID(0.0.0.0)
+
+Codes: P - Passive, A - Active, U - Update, Q - Query, R - Reply
+ r - reply Status, s - sia Status
+
+P 10.0.2.0/24, 1 successors, FD is 256256, serno: 0
+ via Connected, enp0s3
+@end group
+@end example
+
+@node EIGRP Debug Commands
+@section EIGRP Debug Commands
+
+Debug for EIGRP protocol.
+
+@deffn Command {debug eigrp packets} {}
+Debug eigrp packets
+@end deffn
+
+@code{debug eigrp} will show EIGRP packets that are sent and recevied.
+
+@deffn Command {debug eigrp transmit} {}
+Debug eigrp transmit events
+@end deffn
+
+@code{debug eigrp transmit} will display detailed information about the EIGRP transmit events.
+
+@deffn Command {show debugging eigrp} {}
+Display @command{eigrpd}'s debugging option.
+@end deffn
+
+@code{show debugging eigrp} will show all information currently set for eigrpd
+debug.
diff --git a/doc/install.texi b/doc/install.texi
index d989928b8f..9a98f46733 100644
--- a/doc/install.texi
+++ b/doc/install.texi
@@ -63,6 +63,9 @@ Do not build bgpd.
@item --disable-bgp-announce
Make @command{bgpd} which does not make bgp announcements at all. This
feature is good for using @command{bgpd} as a BGP announcement listener.
+@item --enable-datacenter
+Enable system defaults to work as if in a Data Center. See defaults.h
+for what is changed by this configure option.
@item --enable-snmp
Enable SNMP support. By default, SNMP support is disabled.
@item --disable-ospfapi
diff --git a/doc/nhrpd.texi b/doc/nhrpd.texi
index 1820044aea..069b46495c 100644
--- a/doc/nhrpd.texi
+++ b/doc/nhrpd.texi
@@ -64,8 +64,10 @@ command defines the GRE subnet):
@example
@group
router bgp 65555
+ address-family ipv4 unicast
network 172.16.0.0/16
redistribute nhrp
+ exit-address-family
@end group
@end example
diff --git a/doc/vnc.texi b/doc/vnc.texi
index f375d3a7df..b148994210 100644
--- a/doc/vnc.texi
+++ b/doc/vnc.texi
@@ -1115,18 +1115,21 @@ The configuration for @code{VNC-GW 1} is shown below.
router bgp 64512
bgp router-id 192.168.1.101
bgp cluster-id 1.2.3.4
- redistribute vnc-direct
neighbor 192.168.1.102 remote-as 64512
- no neighbor 192.168.1.102 activate
neighbor 192.168.1.103 remote-as 64512
- no neighbor 192.168.1.103 activate
neighbor 192.168.1.104 remote-as 64512
- no neighbor 192.168.1.104 activate
neighbor 172.16.1.2 remote-as 64512
- neighbor 172.16.1.2 route-reflector-client
neighbor 172.16.2.2 remote-as 64512
- neighbor 172.16.2.2 route-reflector-client
-!
+ !
+ address-family ipv4 unicast
+ redistribute vnc-direct
+ no neighbor 192.168.1.102 activate
+ no neighbor 192.168.1.103 activate
+ no neighbor 192.168.1.104 activate
+ neighbor 172.16.1.2 route-reflector-client
+ neighbor 172.16.2.2 route-reflector-client
+ exit-address-family
+ !
address-family vpnv4 unicast
neighbor 192.168.1.102 activate
neighbor 192.168.1.103 activate
@@ -1148,16 +1151,21 @@ Configuration for @code{NVA 2}:
router bgp 64512
bgp router-id 192.168.1.104
neighbor 192.168.1.101 remote-as 64512
- no neighbor 192.168.1.101 activate
neighbor 192.168.1.102 remote-as 64512
- no neighbor 192.168.1.102 activate
neighbor 192.168.1.103 remote-as 64512
- no neighbor 192.168.1.103 activate
+ !
+ address-family ipv4 unicast
+ no neighbor 192.168.1.101 activate
+ no neighbor 192.168.1.102 activate
+ no neighbor 192.168.1.103 activate
+ exit-address-family
+ !
address-family vpnv4 unicast
neighbor 192.168.1.101 activate
neighbor 192.168.1.102 activate
neighbor 192.168.1.103 activate
exit-address-family
+ !
vnc defaults
response-lifetime 3600
exit-vnc
@@ -1231,12 +1239,15 @@ router bgp 64512
neighbor 192.168.1.101 remote-as 64512
neighbor 192.168.1.101 port 7179
neighbor 192.168.1.101 description iBGP-client-192-168-1-101
- neighbor 192.168.1.101 route-reflector-client
neighbor 192.168.1.102 remote-as 64512
neighbor 192.168.1.102 port 7179
neighbor 192.168.1.102 description iBGP-client-192-168-1-102
- neighbor 192.168.1.102 route-reflector-client
+
+ address-family ipv4 unicast
+ neighbor 192.168.1.101 route-reflector-client
+ neighbor 192.168.1.102 route-reflector-client
+ exit-address-family
address-family vpnv4
neighbor 192.168.1.101 activate
diff --git a/eigrpd/.gitignore b/eigrpd/.gitignore
new file mode 100644
index 0000000000..cd46e50c6c
--- /dev/null
+++ b/eigrpd/.gitignore
@@ -0,0 +1,18 @@
+Makefile
+Makefile.in
+*.o
+*.a
+eigrpd
+eigrpd.conf
+tags
+TAGS
+.deps
+.nfs*
+*.lo
+*.la
+*.libs
+.arch-inventory
+.arch-ids
+*~
+*.loT
+
diff --git a/eigrpd/EIGRP-MIB.txt b/eigrpd/EIGRP-MIB.txt
new file mode 100644
index 0000000000..f6ea298cfd
--- /dev/null
+++ b/eigrpd/EIGRP-MIB.txt
@@ -0,0 +1,1321 @@
+CISCO-EIGRP-MIB DEFINITIONS ::= BEGIN
+
+ IMPORTS
+ MODULE-IDENTITY,
+ OBJECT-TYPE,
+ NOTIFICATION-TYPE,
+ Unsigned32,
+ Gauge32,
+ Counter32,
+ Counter64
+ FROM SNMPv2-SMI
+ TruthValue,
+ TEXTUAL-CONVENTION
+ FROM SNMPv2-TC
+ SnmpAdminString
+ FROM SNMP-FRAMEWORK-MIB
+ MODULE-COMPLIANCE,
+ OBJECT-GROUP,
+ NOTIFICATION-GROUP
+ FROM SNMPv2-CONF
+ ciscoMgmt
+ FROM CISCO-SMI
+ InterfaceIndexOrZero,
+ ifIndex
+ FROM IF-MIB
+ InetAddressType,
+ InetAddress,
+ InetAddressPrefixLength
+ FROM INET-ADDRESS-MIB;
+
+ciscoEigrpMIB MODULE-IDENTITY
+ LAST-UPDATED "200411160000Z"
+ ORGANIZATION "Cisco Systems, Inc."
+ CONTACT-INFO "Cisco Systems
+ Customer Service
+
+ Postal: 170 W Tasman Drive
+ San Jose, CA 95134
+ USA
+
+ Tel: +1 800 553-NETS
+
+ E-mail: cs-eigrp@cisco.com"
+ DESCRIPTION
+ "Enhanced Interior Gateway Protocol (EIGRP) is a Cisco
+ proprietary distance vector routing protocol. It is based on
+ the Diffusing Update Algorithm (DUAL), which is a method of
+ finding loop-free paths through a network. Directly
+ connected routers running EIGRP form neighbor adjacencies in
+ order to propagate best-path and alternate-path routing
+ information for configured and learned routes.
+
+ The tables defined within the MIB are closely aligned with how
+ the router command-line interface for EIGRP displays
+ information on EIGRP configurations, i.e., the topology table
+ contains objects associated with the EIGRP topology commands,
+ and the peer table contains objects associated withe EIGRP
+ neighbor commands, etc.
+
+ There are five main tables within this mib:
+
+ EIGRP VPN table
+ Contains information regarding which virtual private
+ networks (VPN) are configured with EIGRP.
+
+ EIGRP traffic statistics table
+ Contains counter & statistcs regarding specific types of
+ EIGRP packets sent and related collective information
+ per VPN and per autonomous system (AS).
+
+ EIGRP topology table
+ Contains information regarding EIGRP routes received in
+ updates and originated locally. EIGRP sends and
+ receives routing updates from adjacent routers running
+ EIGRP with which it formed a peer relationship.
+
+ EIGRP peer (neighbor) table
+ Contains information about neighbor EIGRP routers with
+ which peer adjacencies have been established. EIGRP
+ uses a Hello protocol to form neighbor relationships
+ with directly connected routers also running EIGRP.
+
+ EIGRP interfaces table
+ Contains information and statistics on each of the
+ interfaces on the router over which EIGRP has been
+ configured to run."
+
+
+ REVISION "200411160000Z"
+ DESCRIPTION
+ "Initial version of the MIB module."
+ ::= { ciscoMgmt 449 }
+
+--
+-- Textual Conventions
+--
+
+ EigrpUpTimeString ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "8a"
+ STATUS current
+ DESCRIPTION
+ "Specifies a timer value in days, hours, minutes,
+ and seconds in ASCII format.
+
+ If the up time is less than 24 hours, the number
+ of days will not be reflected and the string will
+ be formatted like this: 'hh:mm:ss', reflecting
+ hours, minutes, and seconds.
+
+ If the up time is greater than 24 hours, EIGRP is
+ less precise and the minutes and seconds are not
+ reflected. Instead only the days and hours are shown
+ and the string will be formatted like this: 'xxxdxxh'."
+ SYNTAX OCTET STRING (SIZE (0..8))
+
+ EigrpVersionString ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "1d.1d/1d.1d"
+ STATUS current
+ DESCRIPTION
+ "Specifies an ASCII string representing the IOS major
+ and minor version followed by the EIGRP major and minor
+ version."
+ SYNTAX OCTET STRING (SIZE (0..9))
+
+--
+-- Objects
+--
+
+ cEigrpMIBNotifications OBJECT IDENTIFIER ::= { ciscoEigrpMIB 0 }
+ cEigrpMIBObjects OBJECT IDENTIFIER ::= { ciscoEigrpMIB 1 }
+ cEigrpMIBConformance OBJECT IDENTIFIER ::= { ciscoEigrpMIB 2 }
+ cEigrpVpnInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 1 }
+ cEigrpAsInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 2 }
+ cEigrpTopologyInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 3 }
+ cEigrpPeerInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 4 }
+ cEigrpInterfaceInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 5 }
+
+ -- EIGRP VPN Base Table definition
+
+ cEigrpVpnTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF CEigrpVpnEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "This table contains information on those VPN's configured
+ to run EIGRP. The VPN creation on a router is independent
+ of the routing protocol to be used over it. A VPN is
+ given a name and has a dedicated routing table associated
+ with it. This routing table is identified internally
+ by a unique integer value."
+ ::= { cEigrpVpnInfo 1 }
+
+ cEigrpVpnEntry OBJECT-TYPE
+ SYNTAX CEigrpVpnEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Information relating to a single VPN which is configured
+ to run EIGRP."
+ INDEX { cEigrpVpnId }
+ ::= { cEigrpVpnTable 1 }
+
+ CEigrpVpnEntry ::=
+ SEQUENCE {
+ cEigrpVpnId Unsigned32,
+ cEigrpVpnName SnmpAdminString
+ }
+
+ cEigrpVpnId OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The unique VPN identifier. This is a unique integer
+ relative to all other VPN's defined on the router. It
+ also identifies internally the routing table instance."
+ ::= { cEigrpVpnEntry 1 }
+
+ cEigrpVpnName OBJECT-TYPE
+ SYNTAX SnmpAdminString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The name given to the VPN."
+ ::= { cEigrpVpnEntry 2 }
+
+ -- EIGRP Traffic Stats table definition
+
+ cEigrpTraffStatsTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF CEigrpTraffStatsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Table of EIGRP traffic statistics and information
+ associated with all EIGRP autonomous systems."
+ ::= { cEigrpAsInfo 1 }
+
+ cEigrpTraffStatsEntry OBJECT-TYPE
+ SYNTAX CEigrpTraffStatsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The set of statistics and information for a single EIGRP
+ Autonomous System."
+ INDEX { cEigrpVpnId, cEigrpAsNumber }
+ ::= { cEigrpTraffStatsTable 1 }
+
+ CEigrpTraffStatsEntry ::=
+ SEQUENCE {
+ cEigrpAsNumber Unsigned32,
+ cEigrpNbrCount Unsigned32,
+ cEigrpHellosSent Counter32,
+ cEigrpHellosRcvd Counter32,
+ cEigrpUpdatesSent Counter32,
+ cEigrpUpdatesRcvd Counter32,
+ cEigrpQueriesSent Counter32,
+ cEigrpQueriesRcvd Counter32,
+ cEigrpRepliesSent Counter32,
+ cEigrpRepliesRcvd Counter32,
+ cEigrpAcksSent Counter32,
+ cEigrpAcksRcvd Counter32,
+ cEigrpInputQHighMark Unsigned32,
+ cEigrpInputQDrops Counter32,
+ cEigrpSiaQueriesSent Counter32,
+ cEigrpSiaQueriesRcvd Counter32,
+ cEigrpAsRouterIdType InetAddressType,
+ cEigrpAsRouterId InetAddress,
+ cEigrpTopoRoutes Counter32,
+ cEigrpHeadSerial Counter64,
+ cEigrpNextSerial Counter64,
+ cEigrpXmitPendReplies Unsigned32,
+ cEigrpXmitDummies Unsigned32
+ }
+
+ cEigrpAsNumber OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The Autonomous System number which is unique integer
+ per VPN."
+ ::= { cEigrpTraffStatsEntry 1 }
+
+ cEigrpNbrCount OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of live EIGRP neighbors formed on all
+ interfaces whose IP addresses fall under networks configured
+ in the EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 2 }
+
+ cEigrpHellosSent OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number Hello packets that have been sent to all
+ EIGRP neighbors formed on all interfaces whose IP addresses
+ fall under networks configured for the EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 3 }
+
+ cEigrpHellosRcvd OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number Hello packets that have been received
+ from all EIGRP neighbors formed on all interfaces whose IP
+ addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 4 }
+
+ cEigrpUpdatesSent OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number routing update packets that have been
+ sent to all EIGRP neighbors formed on all interfaces whose
+ IP addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 5 }
+
+ cEigrpUpdatesRcvd OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number routing update packets that have been
+ received from all EIGRP neighbors formed on all interfaces
+ whose IP addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 6 }
+
+ cEigrpQueriesSent OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number alternate route query packets that have
+ been sent to all EIGRP neighbors formed on all interfaces
+ whose IP addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 7 }
+
+ cEigrpQueriesRcvd OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number alternate route query packets that
+ have been received from all EIGRP neighbors formed on
+ all interfaces whose IP addresses fall under networks
+ configured for the EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 8 }
+
+ cEigrpRepliesSent OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number query reply packets that have been sent
+ to all EIGRP neighbors formed on all interfaces whose IP
+ addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 9 }
+
+ cEigrpRepliesRcvd OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number query reply packets that have been
+ received from all EIGRP neighbors formed on all interfaces
+ whose IP addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 10 }
+
+ cEigrpAcksSent OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number packet acknowledgements that have been
+ sent to all EIGRP neighbors formed on all interfaces whose
+ IP addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 11 }
+
+ cEigrpAcksRcvd OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number packet acknowledgements that have been
+ received from all EIGRP neighbors formed on all interfaces
+ whose IP addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 12 }
+
+ cEigrpInputQHighMark OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The highest number of EIGRP packets in the input queue
+ waiting to be processed internally addressed to this
+ AS."
+ ::= { cEigrpTraffStatsEntry 13 }
+
+ cEigrpInputQDrops OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of EIGRP packets dropped from the input
+ queue due to it being full within the AS."
+ ::= { cEigrpTraffStatsEntry 14 }
+
+ cEigrpSiaQueriesSent OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of Stuck-In-Active (SIA) query packets
+ sent to all EIGRP neighbors formed on all interfaces whose
+ IP addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 15 }
+
+ cEigrpSiaQueriesRcvd OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of Stuck-In-Active (SIA) query packets
+ received from all EIGRP neighbors formed on all interfaces
+ whose IP addresses fall under networks configured for the
+ EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 16 }
+
+ cEigrpAsRouterIdType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The format of the router-id configured or automatically
+ selected for the EIGRP AS."
+ ::= { cEigrpTraffStatsEntry 17 }
+
+ cEigrpAsRouterId OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The router-id configured or automatically selected for the
+ EIGRP AS. Each EIGRP routing process has a unique
+ router-id selected from each autonomous system configured.
+ The format is governed by object cEigrpAsRouterIdType."
+ ::= { cEigrpTraffStatsEntry 18 }
+
+ cEigrpTopoRoutes OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of EIGRP derived routes currently existing
+ in the topology table for the AS."
+ ::= { cEigrpTraffStatsEntry 19 }
+
+ cEigrpHeadSerial OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Routes in a topology table for an AS are assigned serial
+ numbers and are sequenced internally as they are inserted
+ and deleted. The serial number of the first route in
+ that internal sequence is called the head serial number.
+ Each AS has its own topology table, and its own serial
+ number space, each of which begins with the value 1.
+ A serial number of zero implies that there are no routes
+ in the topology."
+ ::= { cEigrpTraffStatsEntry 20 }
+
+ cEigrpNextSerial OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The serial number that would be assigned to the next new
+ or changed route in the topology table for the AS."
+ ::= { cEigrpTraffStatsEntry 21 }
+
+ cEigrpXmitPendReplies OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "When alternate route query packets are sent to adjacent
+ EIGRP peers in an AS, replies are expected. This object
+ is the total number of outstanding replies expected to
+ queries that have been sent to peers in the current AS.
+ It remains at zero most of the time until an EIGRP route
+ becomes active."
+ ::= { cEigrpTraffStatsEntry 22 }
+
+ cEigrpXmitDummies OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "A dummy is a temporary internal entity used as a place
+ holder in the topology table for an AS. They are not
+ transmitted in routing updates. This is the total
+ number currently in existence associated with the AS."
+ ::= { cEigrpTraffStatsEntry 23 }
+
+ -- EIGRP topology table definition
+
+ cEigrpTopoTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF CEigrpTopoEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The table of EIGRP routes and their associated
+ attributes for an Autonomous System (AS) configured
+ in a VPN is called a topology table. All route entries in
+ the topology table will be indexed by IP network type,
+ IP network number and network mask (prefix) size."
+ ::= { cEigrpTopologyInfo 1 }
+
+ cEigrpTopoEntry OBJECT-TYPE
+ SYNTAX CEigrpTopoEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The entry for a single EIGRP topology table in the given
+ AS."
+ INDEX { cEigrpVpnId, cEigrpAsNumber, cEigrpDestNetType,
+ cEigrpDestNet, cEigrpDestNetPrefixLen }
+ ::= { cEigrpTopoTable 1 }
+
+ CEigrpTopoEntry ::=
+ SEQUENCE {
+ cEigrpDestNetType InetAddressType,
+ cEigrpDestNet InetAddress,
+ cEigrpDestNetPrefixLen InetAddressPrefixLength,
+ cEigrpActive TruthValue,
+ cEigrpStuckInActive TruthValue,
+ cEigrpDestSuccessors Unsigned32,
+ cEigrpFdistance Unsigned32,
+ cEigrpRouteOriginType SnmpAdminString,
+ cEigrpRouteOriginAddrType InetAddressType,
+ cEigrpRouteOriginAddr InetAddress,
+ cEigrpNextHopAddressType InetAddressType,
+ cEigrpNextHopAddress InetAddress,
+ cEigrpNextHopInterface SnmpAdminString,
+ cEigrpDistance Unsigned32,
+ cEigrpReportDistance Unsigned32
+ }
+
+ cEigrpDestNetType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The format of the destination IP network number for
+ a single route in the topology table in the AS specified
+ in cEigrpDestNet."
+ ::= { cEigrpTopoEntry 1 }
+
+ cEigrpDestNet OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The destination IP network number for a single route in
+ the topology table in the AS. The format is governed
+ by object cEigrpDestNetType."
+ ::= { cEigrpTopoEntry 2 }
+
+ cEigrpDestNetPrefixLen OBJECT-TYPE
+ SYNTAX InetAddressPrefixLength
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The prefix length associated with the destination IP
+ network address for a single route in the topology
+ table in the AS. The format is governed by the object
+ cEigrpDestNetType."
+ ::= { cEigrpTopoEntry 4 }
+
+ cEigrpActive OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "A value of true(1) indicates the route to the
+ destination network has failed and an active (query)
+ search for an alternative path is in progress. A value
+ of false(2) indicates the route is stable (passive)."
+ ::= { cEigrpTopoEntry 5 }
+
+ cEigrpStuckInActive OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "A value of true(1) indicates that that this route which is
+ in active state (cEigrpActive = true(1)) has not received
+ any replies to queries for alternate paths, and a second
+ EIGRP route query, called a stuck-in-active query, has
+ now been sent."
+ ::= { cEigrpTopoEntry 6 }
+
+ cEigrpDestSuccessors OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "A successor is the next routing hop for a path to the
+ destination IP network number for a single route in the
+ topology table in the AS. There can be several
+ potential successors if there are multiple paths to the
+ destination. This is the total number of successors for
+ a topology entry."
+ ::= { cEigrpTopoEntry 7 }
+
+ cEigrpFdistance OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The feasibility (best) distance is the minimum distance
+ from this router to the destination IP network in
+ this topology entry. The feasibility distance is
+ used in determining the best successor for a path to the
+ destination network."
+ ::= { cEigrpTopoEntry 8 }
+
+ cEigrpRouteOriginType OBJECT-TYPE
+ SYNTAX SnmpAdminString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "This is a text string describing the internal origin
+ of the EIGRP route represented by the topology entry."
+ ::= { cEigrpTopoEntry 9 }
+
+ cEigrpRouteOriginAddrType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The format of the IP address defined as the origin of
+ this topology route entry."
+ ::= { cEigrpTopoEntry 10 }
+
+ cEigrpRouteOriginAddr OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "If the origin of the topology route entry is external
+ to this router, then this object is the IP address
+ of the router from which it originated. The format
+ is governed by object cEigrpRouteOriginAddrType."
+ ::= { cEigrpTopoEntry 11 }
+
+ cEigrpNextHopAddressType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The format of the next hop IP address for the route
+ represented by the topology entry."
+ ::= { cEigrpTopoEntry 12 }
+
+ cEigrpNextHopAddress OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "This is the next hop IP address for the route represented
+ by the topology entry. The next hop is where
+ network traffic will be routed to in order to reach
+ the destination network for this topology entry. The
+ format is governed by cEigrpNextHopAddressType."
+ ::= { cEigrpTopoEntry 13 }
+
+ cEigrpNextHopInterface OBJECT-TYPE
+ SYNTAX SnmpAdminString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The interface through which the next hop IP address
+ is reached to send network traffic to the destination
+ network represented by the topology entry."
+ ::= { cEigrpTopoEntry 14 }
+
+ cEigrpDistance OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The computed distance to the destination network entry
+ from this router."
+ ::= { cEigrpTopoEntry 15 }
+
+ cEigrpReportDistance OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The computed distance to the destination network in the
+ topology entry reported to this router by the originator
+ of this route."
+ ::= { cEigrpTopoEntry 16 }
+
+ -- EIGRP Peer table per VPN and AS (expansion table)
+
+ cEigrpPeerTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF CEigrpPeerEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The table of established EIGRP peers (neighbors) in the
+ selected autonomous system. Peers are indexed by their
+ unique internal handle id, as well as the AS number and
+ VPN id. The peer entry is removed from the table if
+ the peer is declared down."
+ ::= { cEigrpPeerInfo 1 }
+
+ cEigrpPeerEntry OBJECT-TYPE
+ SYNTAX CEigrpPeerEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Statistics and operational parameters for a single peer
+ in the AS."
+ INDEX { cEigrpVpnId, cEigrpAsNumber, cEigrpHandle }
+ ::= { cEigrpPeerTable 1 }
+
+ CEigrpPeerEntry ::=
+ SEQUENCE {
+ cEigrpHandle Unsigned32,
+ cEigrpPeerAddrType InetAddressType,
+ cEigrpPeerAddr InetAddress,
+ cEigrpPeerIfIndex InterfaceIndexOrZero,
+ cEigrpHoldTime Unsigned32,
+ cEigrpUpTime EigrpUpTimeString,
+ cEigrpSrtt Unsigned32,
+ cEigrpRto Unsigned32,
+ cEigrpPktsEnqueued Unsigned32,
+ cEigrpLastSeq Unsigned32,
+ cEigrpVersion EigrpVersionString,
+ cEigrpRetrans Counter32,
+ cEigrpRetries Unsigned32
+ }
+
+ cEigrpHandle OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The unique internal identifier for the peer in the AS.
+ This is a unique value among peer entries in a selected
+ table."
+ ::= { cEigrpPeerEntry 1 }
+
+ cEigrpPeerAddrType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The format of the remote source IP address used by the
+ peer to establish the EIGRP adjacency with this router."
+ ::= { cEigrpPeerEntry 2 }
+
+ cEigrpPeerAddr OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The source IP address used by the peer to establish the
+ EIGRP adjacency with this router. The format is
+ governed by object cEigrpPeerAddrType."
+ ::= { cEigrpPeerEntry 3 }
+
+ cEigrpPeerIfIndex OBJECT-TYPE
+ SYNTAX InterfaceIndexOrZero
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The ifIndex of the interface on this router through
+ which this peer can be reached."
+ ::= { cEigrpPeerEntry 4 }
+
+ cEigrpHoldTime OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "seconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The count-down timer indicating how much time must
+ pass without receiving a hello packet from this
+ EIGRP peer before this router declares the peer down.
+ A peer declared as down is removed from the table and
+ is no longer visible."
+ ::= { cEigrpPeerEntry 5 }
+
+ cEigrpUpTime OBJECT-TYPE
+ SYNTAX EigrpUpTimeString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The elapsed time since the EIGRP adjacency was first
+ established with the peer."
+ ::= { cEigrpPeerEntry 6 }
+
+ cEigrpSrtt OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The computed smooth round trip time for packets to and
+ from the peer."
+ ::= { cEigrpPeerEntry 7 }
+
+ cEigrpRto OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The computed retransmission timeout for the peer.
+ This value is computed over time as packets are sent to
+ the peer and acknowledgements are received from it,
+ and is the amount of time to wait before resending
+ a packet from the retransmission queue to the peer
+ when an expected acknowledgement has not been received."
+ ::= { cEigrpPeerEntry 8 }
+
+ cEigrpPktsEnqueued OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of any EIGRP packets currently enqueued
+ waiting to be sent to this peer."
+ ::= { cEigrpPeerEntry 9 }
+
+ cEigrpLastSeq OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "All transmitted EIGRP packets have a sequence number
+ assigned. This is the sequence number of the last EIGRP
+ packet sent to this peer."
+ ::= { cEigrpPeerEntry 10 }
+
+ cEigrpVersion OBJECT-TYPE
+ SYNTAX EigrpVersionString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The EIGRP version information reported by the remote
+ peer."
+ ::= { cEigrpPeerEntry 11 }
+
+ cEigrpRetrans OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The cumulative number of retransmissions to this peer
+ during the period that the peer adjacency has remained
+ up."
+ ::= { cEigrpPeerEntry 12 }
+
+ cEigrpRetries OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of times the current unacknowledged packet
+ has been retried, i.e. resent to this peer to be
+ acknowledged."
+ ::= { cEigrpPeerEntry 13 }
+
+ -- EIGRP Interfaces table per VPN and AS
+
+ cEigrpInterfaceTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF CEigrpInterfaceEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The table of interfaces over which EIGRP is running, and
+ their associated statistics. This table is independent
+ of whether any peer adjacencies have been formed over
+ the interfaces or not. Interfaces running EIGRP are
+ determined by whether their assigned IP addresses fall
+ within configured EIGRP network statements."
+ ::= { cEigrpInterfaceInfo 1 }
+
+ cEigrpInterfaceEntry OBJECT-TYPE
+ SYNTAX CEigrpInterfaceEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Information for a single interface running EIGRP in the
+ AS and VPN."
+ INDEX { cEigrpVpnId, cEigrpAsNumber, ifIndex }
+ ::= { cEigrpInterfaceTable 1 }
+
+ CEigrpInterfaceEntry ::=
+ SEQUENCE {
+ cEigrpPeerCount Gauge32,
+ cEigrpXmitReliableQ Gauge32,
+ cEigrpXmitUnreliableQ Gauge32,
+ cEigrpMeanSrtt Unsigned32,
+ cEigrpPacingReliable Unsigned32,
+ cEigrpPacingUnreliable Unsigned32,
+ cEigrpMFlowTimer Unsigned32,
+ cEigrpPendingRoutes Gauge32,
+ cEigrpHelloInterval Unsigned32,
+ cEigrpXmitNextSerial Counter64,
+ cEigrpUMcasts Counter32,
+ cEigrpRMcasts Counter32,
+ cEigrpUUcasts Counter32,
+ cEigrpRUcasts Counter32,
+ cEigrpMcastExcepts Counter32,
+ cEigrpCRpkts Counter32,
+ cEigrpAcksSuppressed Counter32,
+ cEigrpRetransSent Counter32,
+ cEigrpOOSrcvd Counter32,
+ cEigrpAuthMode INTEGER,
+ cEigrpAuthKeyChain SnmpAdminString
+ }
+
+ cEigrpPeerCount OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of EIGRP adjacencies currently formed with
+ peers reached through this interface."
+ ::= { cEigrpInterfaceEntry 3 }
+
+ cEigrpXmitReliableQ OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of EIGRP packets currently waiting in the
+ reliable transport (acknowledgement-required)
+ transmission queue to be sent to a peer."
+ ::= { cEigrpInterfaceEntry 4 }
+
+ cEigrpXmitUnreliableQ OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number EIGRP of packets currently waiting in
+ the unreliable transport (no acknowledgement required)
+ transmission queue."
+ ::= { cEigrpInterfaceEntry 5 }
+
+ cEigrpMeanSrtt OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The average of all the computed smooth round trip time
+ values for a packet to and from all peers established on
+ this interface."
+ ::= { cEigrpInterfaceEntry 6 }
+
+ cEigrpPacingReliable OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The configured time interval between EIGRP packet
+ transmissions on the interface when the reliable transport
+ method is used."
+ ::= { cEigrpInterfaceEntry 7 }
+
+ cEigrpPacingUnreliable OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The configured time interval between EIGRP packet
+ transmissions on the interface when the unreliable
+ transport method is used."
+ ::= { cEigrpInterfaceEntry 8 }
+
+ cEigrpMFlowTimer OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "milliseconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The configured multicast flow control timer value for
+ this interface."
+ ::= { cEigrpInterfaceEntry 9 }
+
+ cEigrpPendingRoutes OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of queued EIGRP routing updates awaiting
+ transmission on this interface."
+ ::= { cEigrpInterfaceEntry 10 }
+
+ cEigrpHelloInterval OBJECT-TYPE
+ SYNTAX Unsigned32
+ UNITS "seconds"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The configured time interval between Hello packet
+ transmissions for this interface."
+ ::= { cEigrpInterfaceEntry 11 }
+
+ cEigrpXmitNextSerial OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The serial number of the next EIGRP packet that is to
+ be queued for transmission on this interface."
+ ::= { cEigrpInterfaceEntry 12 }
+
+ cEigrpUMcasts OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of unreliable (no acknowledgement
+ required) EIGRP multicast packets sent on this
+ interface."
+ ::= { cEigrpInterfaceEntry 13 }
+
+ cEigrpRMcasts OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of reliable (acknowledgement required)
+ EIGRP multicast packets sent on this interface."
+ ::= { cEigrpInterfaceEntry 14 }
+
+ cEigrpUUcasts OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of unreliable (no acknowledgement
+ required) EIGRP unicast packets sent on this
+ interface."
+ ::= { cEigrpInterfaceEntry 15 }
+
+ cEigrpRUcasts OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of reliable (acknowledgement required)
+ unicast packets sent on this interface."
+ ::= { cEigrpInterfaceEntry 16 }
+
+ cEigrpMcastExcepts OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of EIGRP multicast exception
+ transmissions that have occurred on this interface."
+ ::= { cEigrpInterfaceEntry 17 }
+
+ cEigrpCRpkts OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number EIGRP Conditional-Receive packets sent on
+ this interface."
+ ::= { cEigrpInterfaceEntry 18 }
+
+ cEigrpAcksSuppressed OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of individual EIGRP acknowledgement
+ packets that have been suppressed and combined in
+ an already enqueued outbound reliable packet on this
+ interface."
+ ::= { cEigrpInterfaceEntry 19 }
+
+ cEigrpRetransSent OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number EIGRP packet retransmissions sent on
+ the interface."
+ ::= { cEigrpInterfaceEntry 20 }
+
+ cEigrpOOSrcvd OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The total number of out-of-sequence EIGRP packets
+ received."
+ ::= { cEigrpInterfaceEntry 21 }
+
+ cEigrpAuthMode OBJECT-TYPE
+ SYNTAX INTEGER {
+ none(1),
+ md5(2)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The EIGRP authentication mode of the interface.
+ none : no authentication enabled on the interface
+ md5 : MD5 authentication enabled on the interface"
+ ::= { cEigrpInterfaceEntry 22 }
+
+ cEigrpAuthKeyChain OBJECT-TYPE
+ SYNTAX SnmpAdminString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The name of the authentication key-chain configured
+ on this interface. The key-chain is a reference to
+ which set of secret keys are to be accessed in order
+ to determine which secret key string to use. The key
+ chain name is not the secret key string password and
+ can also be used in other routing protocols, such
+ as RIP and ISIS."
+ ::= { cEigrpInterfaceEntry 23 }
+
+ -- Notifications
+
+ cEigrpAuthFailureEvent NOTIFICATION-TYPE
+ OBJECTS { cEigrpPeerAddrType, cEigrpPeerAddr }
+ STATUS current
+ DESCRIPTION
+ "This notification is sent when EIGRP MD5 authentication
+ is enabled on any interface and peer adjacencies are
+ formed, and any adjacencies go down as a result of an
+ authentication failure."
+ ::= { cEigrpMIBNotifications 1 }
+
+ cEigrpRouteStuckInActive NOTIFICATION-TYPE
+ OBJECTS { cEigrpPeerAddrType, cEigrpPeerAddr,
+ cEigrpStuckInActive }
+ STATUS current
+ DESCRIPTION
+ "This notification is sent when a route in the topology
+ table is stuck in an active state. During the query
+ phase for a new route to a destination network, a route
+ is described as being in the active state if when an
+ alternate path is actively being sought, no replies are
+ received to normal queries or stuck-in-active queries."
+ ::= { cEigrpMIBNotifications 2 }
+
+ -- Conformance
+
+ cEigrpMIBCompliances
+ OBJECT IDENTIFIER ::= { cEigrpMIBConformance 1 }
+
+ cEigrpMIBGroups
+ OBJECT IDENTIFIER ::= { cEigrpMIBConformance 2 }
+
+ -- Compliance
+
+ cEigrpMIBCompliance MODULE-COMPLIANCE
+ STATUS current
+ DESCRIPTION
+ "The compliance statement for entities which implement
+ the Cisco EIGRP Management MIB."
+ MODULE
+ MANDATORY-GROUPS {
+ cEigrpVpnDataGroup,
+ cEigrpTrafficStatsGroup,
+ cEigrpInterfaceDataGroup,
+ cEigrpPeerDataGroup,
+ cEigrpTopoDataGroup,
+ cEigrpNotificationsGroup
+ }
+
+ OBJECT cEigrpAsRouterIdType
+ SYNTAX INTEGER { ipv4(1) }
+ DESCRIPTION
+ "An implementation is only required to support
+ IPv4 address type."
+
+ OBJECT cEigrpRouteOriginAddrType
+ SYNTAX INTEGER { ipv4(1) }
+ DESCRIPTION
+ "An implementation is only required to support
+ IPv4 address type."
+
+ OBJECT cEigrpNextHopAddressType
+ SYNTAX INTEGER { ipv4(1) }
+ DESCRIPTION
+ "An implementation is only required to support
+ IPv4 address type."
+
+ OBJECT cEigrpPeerAddrType
+ SYNTAX INTEGER { ipv4(1) }
+ DESCRIPTION
+ "An implementation is only required to support
+ IPv4 address type."
+ ::= { cEigrpMIBCompliances 1 }
+
+ -- Units of Conformance
+
+ cEigrpVpnDataGroup OBJECT-GROUP
+ OBJECTS {
+ cEigrpVpnName
+ }
+ STATUS current
+ DESCRIPTION
+ "The collection of VPN names which have been configured
+ with one or more EIGRP autonmous systems."
+ ::= { cEigrpMIBGroups 1 }
+
+ cEigrpTrafficStatsGroup OBJECT-GROUP
+ OBJECTS {
+ cEigrpHellosSent,
+ cEigrpHellosRcvd,
+ cEigrpUpdatesSent,
+ cEigrpUpdatesRcvd,
+ cEigrpQueriesSent,
+ cEigrpQueriesRcvd,
+ cEigrpRepliesSent,
+ cEigrpRepliesRcvd,
+ cEigrpAcksSent,
+ cEigrpAcksRcvd,
+ cEigrpInputQHighMark,
+ cEigrpInputQDrops,
+ cEigrpSiaQueriesSent,
+ cEigrpSiaQueriesRcvd
+ }
+ STATUS current
+ DESCRIPTION
+ "A collection of objects providing management information
+ regarding collective EIGRP packet statistics for all EIGRP
+ autonomous systems configured."
+ ::= { cEigrpMIBGroups 2 }
+
+ cEigrpInterfaceDataGroup OBJECT-GROUP
+ OBJECTS {
+ cEigrpPeerCount,
+ cEigrpXmitReliableQ,
+ cEigrpXmitUnreliableQ,
+ cEigrpMeanSrtt,
+ cEigrpPacingReliable,
+ cEigrpPacingUnreliable,
+ cEigrpMFlowTimer,
+ cEigrpPendingRoutes,
+ cEigrpHelloInterval,
+ cEigrpXmitNextSerial,
+ cEigrpUMcasts,
+ cEigrpRMcasts,
+ cEigrpUUcasts,
+ cEigrpRUcasts,
+ cEigrpMcastExcepts,
+ cEigrpCRpkts,
+ cEigrpAcksSuppressed,
+ cEigrpRetransSent,
+ cEigrpOOSrcvd,
+ cEigrpAuthMode,
+ cEigrpAuthKeyChain
+ }
+ STATUS current
+ DESCRIPTION
+ "A collection of objects providing management information
+ for interfaces over which EIGRP is configured and
+ running."
+ ::= { cEigrpMIBGroups 3 }
+
+ cEigrpPeerDataGroup OBJECT-GROUP
+ OBJECTS {
+ cEigrpNbrCount,
+ cEigrpPeerAddrType,
+ cEigrpPeerAddr,
+ cEigrpPeerIfIndex,
+ cEigrpHoldTime,
+ cEigrpUpTime,
+ cEigrpSrtt,
+ cEigrpRto,
+ cEigrpPktsEnqueued,
+ cEigrpLastSeq,
+ cEigrpVersion,
+ cEigrpRetrans,
+ cEigrpRetries
+ }
+ STATUS current
+ DESCRIPTION
+ "A collection of objects providing management information
+ for EIGRP peer adjacencies formed in the EIGRP
+ autonoumous systems."
+ ::= { cEigrpMIBGroups 4 }
+
+ cEigrpTopoDataGroup OBJECT-GROUP
+ OBJECTS {
+ cEigrpAsRouterId,
+ cEigrpAsRouterIdType,
+ cEigrpTopoRoutes,
+ cEigrpHeadSerial,
+ cEigrpNextSerial,
+ cEigrpXmitPendReplies,
+ cEigrpXmitDummies,
+ cEigrpActive,
+ cEigrpStuckInActive,
+ cEigrpDestSuccessors,
+ cEigrpFdistance,
+ cEigrpRouteOriginType,
+ cEigrpRouteOriginAddrType,
+ cEigrpRouteOriginAddr,
+ cEigrpNextHopAddressType,
+ cEigrpNextHopAddress,
+ cEigrpNextHopInterface,
+ cEigrpDistance,
+ cEigrpReportDistance
+ }
+ STATUS current
+ DESCRIPTION
+ "A collection of objects providing management information
+ for EIGRP topology routes derived within autonomous
+ systems and received in updates from EIGRP neighbors."
+ ::= { cEigrpMIBGroups 5 }
+
+ cEigrpNotificationsGroup NOTIFICATION-GROUP
+ NOTIFICATIONS {
+ cEigrpAuthFailureEvent,
+ cEigrpRouteStuckInActive
+ }
+ STATUS current
+ DESCRIPTION
+ "Group of notifications on EIGRP routers."
+ ::= { cEigrpMIBGroups 6 }
+END \ No newline at end of file
diff --git a/eigrpd/Makefile.am b/eigrpd/Makefile.am
new file mode 100644
index 0000000000..9ee792e552
--- /dev/null
+++ b/eigrpd/Makefile.am
@@ -0,0 +1,46 @@
+## Process this file with automake to produce Makefile.in.
+
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
+DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
+INSTALL_SDATA=@INSTALL@ -m 600
+
+AM_CFLAGS = $(WERROR)
+
+noinst_LIBRARIES = libeigrp.a
+sbin_PROGRAMS = eigrpd
+
+libeigrp_a_SOURCES = \
+ eigrpd.c eigrp_zebra.c \
+ eigrp_interface.c eigrp_neighbor.c \
+ eigrp_dump.c eigrp_vty.c \
+ eigrp_network.c eigrp_packet.c \
+ eigrp_topology.c eigrp_fsm.c \
+ eigrp_hello.c eigrp_update.c \
+ eigrp_query.c eigrp_reply.c \
+ eigrp_snmp.c eigrp_siaquery.c \
+ eigrp_siareply.c eigrp_filter.c \
+ eigrp_memory.c
+
+
+eigrpdheaderdir = $(pkgincludedir)/eigrpd
+
+eigrpdheader_HEADERS = \
+ eigrp_topology.h eigrp_dump.h eigrpd.h
+
+noinst_HEADERS = \
+ eigrp_const.h eigrp_structs.h \
+ eigrp_macros.h eigrp_interface.h \
+ eigrp_neighbor.h eigrp_network.h \
+ eigrp_packet.h eigrp_memory.h \
+ eigrp_zebra.h eigrp_vty.h \
+ eigrp_snmp.h eigrp_filter.h \
+ eigrp_fsm.h
+
+eigrpd_SOURCES = eigrp_main.c $(libeigrp_a_SOURCES)
+
+eigrpd_LDADD = ../lib/libfrr.la @LIBCAP@
+
+EXTRA_DIST = EIGRP-MIB.txt
+
+examplesdir = $(exampledir)
+dist_examples_DATA = eigrpd.conf.sample
diff --git a/eigrpd/eigrp_const.h b/eigrpd/eigrp_const.h
new file mode 100644
index 0000000000..6673b3a334
--- /dev/null
+++ b/eigrpd/eigrp_const.h
@@ -0,0 +1,432 @@
+/*
+ * EIGRP Definition of Constants.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 _ZEBRA_EIGRP_CONST_H_
+#define _ZEBRA_EIGRP_CONST_H_
+
+#define FALSE 0
+
+#define EIGRP_NEIGHBOR_DOWN 0
+#define EIGRP_NEIGHBOR_PENDING 1
+#define EIGRP_NEIGHBOR_UP 2
+#define EIGRP_NEIGHBOR_STATE_MAX 3
+
+/*Packet requiring ack will be retransmitted again after this time*/
+#define EIGRP_PACKET_RETRANS_TIME 2 /* in seconds */
+#define EIGRP_PACKET_RETRANS_MAX 16 /* number of retrans attempts */
+#define PLAINTEXT_LENGTH 81
+
+/*Metric variance multiplier*/
+#define EIGRP_VARIANCE_DEFAULT 1
+#define EIGRP_MAX_PATHS_DEFAULT 4
+
+
+/* Return values of functions involved in packet verification */
+#define MSG_OK 0
+#define MSG_NG 1
+
+#define EIGRP_HEADER_VERSION 2
+
+/* Default protocol, port number. */
+#ifndef IPPROTO_EIGRPIGP
+#define IPPROTO_EIGRPIGP 88
+#endif /* IPPROTO_EIGRPIGP */
+
+#define EIGRP_AUTH_MD5_TLV_SIZE 40
+#define EIGRP_AUTH_SHA256_TLV_SIZE 56
+
+/*Cisco routers use only first 44 bytes of basic hello for their MD5 calculations*/
+#define EIGRP_MD5_BASIC_COMPUTE 44
+#define EIGRP_MD5_UPDATE_INIT_COMPUTE 40
+
+
+
+#define EIGRP_AUTH_BASIC_HELLO_FLAG 0x01
+#define EIGRP_AUTH_TID_HELLO_FLAG 0x02
+#define EIGRP_AUTH_UPDATE_INIT_FLAG 0x04
+#define EIGRP_AUTH_UPDATE_FLAG 0x08
+#define EIGRP_AUTH_EXTRA_SALT_FLAG 0x10
+
+#define EIGRP_NEXT_SEQUENCE_TLV_SIZE 8
+
+/* IP TTL for EIGRP protocol. */
+#define EIGRP_IP_TTL 1
+
+/* VTY port number. */
+#define EIGRP_VTY_PORT 2609
+
+/* Default configuration file name for eigrp. */
+#define EIGRP_DEFAULT_CONFIG "eigrpd.conf"
+
+#define EIGRP_HELLO_INTERVAL_DEFAULT 5
+#define EIGRP_HOLD_INTERVAL_DEFAULT 15
+#define EIGRP_BANDWIDTH_DEFAULT 100000
+#define EIGRP_DELAY_DEFAULT 10
+#define EIGRP_RELIABILITY_DEFAULT 255
+#define EIGRP_LOAD_DEFAULT 1
+
+#define EIGRP_MULTICAST_ADDRESS 0xe000000A /*224.0.0.10*/
+
+#define EIGRP_MAX_METRIC 0xffffffffU /*4294967295*/
+
+#define DEFAULT_ROUTE ZEBRA_ROUTE_MAX
+#define DEFAULT_ROUTE_TYPE(T) ((T) == DEFAULT_ROUTE)
+
+#define INTERFACE_DOWN_BY_ZEBRA 1
+#define INTERFACE_DOWN_BY_VTY 2
+#define INTERFACE_DOWN_BY_FINAL 3
+
+#define EIGRP_HELLO_NORMAL 0x00
+#define EIGRP_HELLO_GRACEFUL_SHUTDOWN 0x01
+#define EIGRP_HELLO_ADD_SEQUENCE 0x02
+#define EIGRP_HELLO_GRACEFUL_SHUTDOWN_NBR 0x04
+
+ /* EIGRP Network Type. */
+ #define EIGRP_IFTYPE_NONE 0
+ #define EIGRP_IFTYPE_POINTOPOINT 1
+ #define EIGRP_IFTYPE_BROADCAST 2
+ #define EIGRP_IFTYPE_NBMA 3
+ #define EIGRP_IFTYPE_POINTOMULTIPOINT 4
+ #define EIGRP_IFTYPE_LOOPBACK 5
+ #define EIGRP_IFTYPE_MAX 6
+
+#define EIGRP_IF_ACTIVE 0
+#define EIGRP_IF_PASSIVE 1
+
+/* EIGRP TT destination type */
+#define EIGRP_TOPOLOGY_TYPE_CONNECTED 0 // Connected network
+#define EIGRP_TOPOLOGY_TYPE_REMOTE 1 // Remote internal network
+#define EIGRP_TOPOLOGY_TYPE_REMOTE_EXTERNAL 2 // Remote external network
+
+/*EIGRP TT entry flags*/
+#define EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG (1 << 0)
+#define EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG (1 << 1)
+#define EIGRP_NEIGHBOR_ENTRY_INTABLE_FLAG (1 << 2)
+#define EIGRP_NEIGHBOR_ENTRY_EXTERNAL_FLAG (1 << 3)
+
+/*EIGRP FSM state count, event count*/
+#define EIGRP_FSM_STATE_MAX 5
+#define EIGRP_FSM_EVENT_MAX 16
+
+/*EEGRP FSM states*/
+enum eigrp_fsm_states {
+ EIGRP_FSM_STATE_PASSIVE,
+ EIGRP_FSM_STATE_ACTIVE_0,
+ EIGRP_FSM_STATE_ACTIVE_1,
+ EIGRP_FSM_STATE_ACTIVE_2,
+ EIGRP_FSM_STATE_ACTIVE_3,
+};
+
+/*EIGRP FSM events return values*/
+#define EIGRP_FSM_NEED_UPDATE 1
+#define EIGRP_FSM_NEED_QUERY 2
+
+/*EIGRP FSM events*/
+#define EIGRP_FSM_EVENT_NQ_FCN 0 /*input event other than query from succ, FC not satisfied*/
+#define EIGRP_FSM_EVENT_LR 1 /*last reply, FD is reset*/
+#define EIGRP_FSM_EVENT_Q_FCN 2 /*query from succ, FC not satisfied*/
+#define EIGRP_FSM_EVENT_LR_FCS 3 /*last reply, FC satisfied with current value of FDij*/
+#define EIGRP_FSM_EVENT_DINC 4 /*distance increase while in active state*/
+#define EIGRP_FSM_EVENT_QACT 5 /*query from succ while in active state*/
+#define EIGRP_FSM_EVENT_LR_FCN 6 /*last reply, FC not satisfied with current value of FDij*/
+#define EIGRP_FSM_KEEP_STATE 7 /*state not changed, usually by receiving not last reply */
+
+/**
+ * External routes originate from some other protocol - these are them
+ */
+#define NULL_PROTID 0 /*!< unknown protocol */
+#define IGRP_PROTID 1 /*!< IGRP.. whos your daddy! */
+#define EIGRP_PROTID 2 /*!< EIGRP - Just flat out the best */
+#define STATIC_PROTID 3 /*!< Staticly configured source */
+#define RIP_PROTID 4 /*!< Routing Information Protocol */
+#define HELLO_PROTID 5 /*!< Hello? RFC-891 you there? */
+#define OSPF_PROTID 6 /*!< OSPF - Open Shortest Path First */
+#define ISIS_PROTID 7 /*!< Intermediate System To Intermediate System */
+#define EGP_PROTID 8 /*!< Exterior Gateway Protocol */
+#define BGP_PROTID 9 /*!< Border Gateway Protocol */
+#define IDRP_PROTID 10 /*!< InterDomain Routing Protocol */
+#define CONN_PROTID 11 /*!< Connected source */
+
+/*
+ * metric k-value defaults
+ */
+#define EIGRP_K1_DEFAULT 1 //!< unweighed inverse bandwidth
+#define EIGRP_K2_DEFAULT 0 //!< no loading term
+#define EIGRP_K3_DEFAULT 1 //!< unweighted delay
+#define EIGRP_K4_DEFAULT 0 //!< no reliability term
+#define EIGRP_K5_DEFAULT 0 //!< no reliability term
+#define EIGRP_K6_DEFAULT 0 //!< do not add in extended metrics
+
+
+/*
+ * EIGRP Fixed header
+ */
+#define EIGRP_HEADER_LEN 20U
+#define EIGRP_PACKET_MAX_LEN 65535U /* includes IP Header size. */
+
+
+#define EIGRP_TLV_HDR_LENGTH 4
+
+/**
+ * EIGRP Packet Opcodes
+ */
+#define EIGRP_OPC_UPDATE 1 /*!< packet containing routing information */
+#define EIGRP_OPC_REQUEST 2 /*!< sent to request one or more routes */
+#define EIGRP_OPC_QUERY 3 /*!< sent when a routing is in active start */
+#define EIGRP_OPC_REPLY 4 /*!< sent in response to a query */
+#define EIGRP_OPC_HELLO 5 /*!< sent to maintain a peering session */
+#define EIGRP_OPC_IPXSAP 6 /*!< IPX SAP information */
+#define EIGRP_OPC_PROBE 7 /*!< for test purposes */
+#define EIGRP_OPC_ACK 8 /*!< acknowledge */
+#define EIGRP_OPC_SIAQUERY 10 /*!< QUERY - with relaxed restrictions */
+#define EIGRP_OPC_SIAREPLY 11 /*!< REPLY - may contain old routing information */
+
+/**
+ * EIGRP TLV Range definitions
+ * PDM TLV Range
+ * General 0x0000
+ * IPv4 0x0100 ** TLVs for one and all
+ * ATALK 0x0200 ** legacy
+ * IPX 0x0300 ** discontinued
+ * IPv6 0x0400 ** legacy
+ * Multiprotocol 0x0600 ** wide metrics
+ * MultiTopology 0x00f0 ** deprecated
+ */
+#define EIGRP_TLV_RANGEMASK 0xfff0 /*!< should be 0xff00 - opps */
+#define EIGRP_TLV_GENERAL 0x0000
+
+/**
+ * 1.2 TLV Definitions ** legacy
+ * These are considered legacyu and are only used for backward compability with
+ * older Cisco Routers. They should not be your first choice for packet codings
+ */
+#define EIGRP_TLV_IPv4 0x0100 /*!< Classic IPv4 TLV encoding */
+#define EIGRP_TLV_ATALK 0x0200 /*!< Classic Appletalk TLV encoding*/
+#define EIGRP_TLV_IPX 0x0300 /*!< Classic IPX TLV encoding */
+#define EIGRP_TLV_IPv6 0x0400 /*!< Classic IPv6 TLV encoding */
+
+/**
+ * 2.0 Multi-Protocol TLV Definitions
+ * These are the current packet formats and should be used for packets
+ */
+#define EIGRP_TLV_MP 0x0600 /*!< Non-PDM specific encoding */
+
+/**
+ * TLV type definitions. Generic (protocol-independent) TLV types are
+ * defined here. Protocol-specific ones are defined elsewhere.
+ */
+#define EIGRP_TLV_PARAMETER (EIGRP_TLV_GENERAL | 0x0001) /*!< eigrp parameters */
+#define EIGRP_TLV_PARAMETER_LEN (12U)
+#define EIGRP_TLV_AUTH (EIGRP_TLV_GENERAL | 0x0002) /*!< authentication */
+#define EIGRP_TLV_SEQ (EIGRP_TLV_GENERAL | 0x0003) /*!< sequenced packet */
+#define EIGRP_TLV_SEQ_BASE_LEN (5U)
+#define EIGRP_TLV_SW_VERSION (EIGRP_TLV_GENERAL | 0x0004) /*!< software version */
+#define EIGRP_TLV_SW_VERSION_LEN (8U)
+#define EIGRP_TLV_NEXT_MCAST_SEQ (EIGRP_TLV_GENERAL | 0x0005) /*!< sequence number */
+#define EIGRP_TLV_PEER_TERMINATION (EIGRP_TLV_GENERAL | 0x0007) /*!< peer termination */
+#define EIGRP_TLV_PEER_TERMINATION_LEN (9U)
+#define EIGRP_TLV_PEER_TIDLIST (EIGRP_TLV_GENERAL | 0x0008) /*!< peer sub-topology list */
+
+/* Older cisco routers send TIDLIST value wrong, adding for backwards compatabily */
+#define EIGRP_TLV_PEER_MTRLIST (EIGRP_TLV_GENERAL | 0x00f5)
+
+/**
+ * Route Based TLVs
+ */
+#define EIGRP_TLV_REQUEST 0x0001
+#define EIGRP_TLV_INTERNAL 0x0002
+#define EIGRP_TLV_EXTERNAL 0x0003
+#define EIGRP_TLV_COMMUNITY 0x0004
+#define EIGRP_TLV_TYPEMASK 0x000f
+
+#define EIGRP_TLV_IPv4_REQ (EIGRP_TLV_IPv4 | EIGRP_TLV_REQUEST)
+#define EIGRP_TLV_IPv4_INT (EIGRP_TLV_IPv4 | EIGRP_TLV_INTERNAL)
+#define EIGRP_TLV_IPv4_EXT (EIGRP_TLV_IPv4 | EIGRP_TLV_EXTERNAL)
+#define EIGRP_TLV_IPv4_COM (EIGRP_TLV_IPv4 | EIGRP_TLV_COMMUNITY)
+
+/* max number of TLV IPv4 prefixes in packet */
+#define EIGRP_TLV_MAX_IPv4 25
+
+/**
+ *
+ * extdata flag field definitions
+ */
+#define EIGRP_OPAQUE_EXT 0x01 /*!< Route is external */
+#define EIGRP_OPAQUE_CD 0x02 /*!< Candidate default route */
+
+/**
+ * Address-Family types are taken from:
+ * http://www.iana.org/assignments/address-family-numbers
+ * to provide a standards based exchange of AFI information between
+ * EIGRP routers.
+ */
+#define EIGRP_AF_IPv4 1 /*!< IPv4 (IP version 4) */
+#define EIGRP_AF_IPv6 2 /*!< IPv6 (IP version 6) */
+#define EIGRP_AF_IPX 11 /*!< IPX */
+#define EIGRP_AF_ATALK 12 /*!< Appletalk */
+#define EIGRP_SF_COMMON 16384 /*!< Cisco Service Family */
+#define EIGRP_SF_IPv4 16385 /*!< Cisco IPv4 Service Family */
+#define EIGRP_SF_IPv6 16386 /*!< Cisco IPv6 Service Family */
+
+/**
+ * Authentication types supported by EIGRP
+ */
+#define EIGRP_AUTH_TYPE_NONE 0
+#define EIGRP_AUTH_TYPE_TEXT 1
+#define EIGRP_AUTH_TYPE_MD5 2
+#define EIGRP_AUTH_TYPE_MD5_LEN 16
+#define EIGRP_AUTH_TYPE_SHA256 3
+#define EIGRP_AUTH_TYPE_SHA256_LEN 32
+
+/**
+ * opaque flag field definitions
+ */
+#define EIGRP_OPAQUE_SRCWD 0x01 /*!< Route Source Withdraw */
+#define EIGRP_OPAQUE_ACTIVE 0x04 /*!< Route is currently in active state */
+#define EIGRP_OPAQUE_REPL 0x08 /*!< Route is replicated from different tableid */
+
+/**
+ * pak flag bit field definitions - 0 (none)-7 source priority
+ */
+#define EIGRP_PRIV_DEFAULT 0x00 /* 0 (none)-7 source priority */
+#define EIGRP_PRIV_LOW 0x01
+#define EIGRP_PRIV_MEDIUM 0x04
+#define EIGRP_PRIV_HIGH 0x07
+
+/*
+ * Init bit definition. First unicast transmitted Update has this
+ * bit set in the flags field of the fixed header. It tells the neighbor
+ * to down-load his topology table.
+ */
+#define EIGRP_INIT_FLAG 0x01
+
+/*
+ * CR bit (Conditionally Received) definition in flags field on header. Any
+ * packets with the CR-bit set can be accepted by an EIGRP speaker if and
+ * only if a previous Hello was received with the SEQUENCE_TYPE TLV present.
+ *
+ * This allows multicasts to be transmitted in order and reliably at the
+ * same time as unicasts are transmitted.
+ */
+#define EIGRP_CR_FLAG 0x02
+
+/*
+ * RS bit. The Restart flag is set in the hello and the init
+ * update packets during the nsf signaling period. A nsf-aware
+ * router looks at the RS flag to detect if a peer is restarting
+ * and maintain the adjacency. A restarting router looks at
+ * this flag to determine if the peer is helping out with the restart.
+ */
+#define EIGRP_RS_FLAG 0x04
+
+/*
+ * EOT bit. The End-of-Table flag marks the end of the start-up updates
+ * sent to a new peer. A nsf restarting router looks at this flag to
+ * determine if it has finished receiving the start-up updates from all
+ * peers. A nsf-aware router waits for this flag before cleaning up
+ * the stale routes from the restarting peer.
+ */
+#define EIGRP_EOT_FLAG 0x08
+
+/**
+ * EIGRP Virtual Router ID
+ *
+ * Define values to deal with EIGRP virtual router ids. Virtual
+ * router IDs are stored in the upper short of the EIGRP fixed packet
+ * header. The lower short of the packet header continues to be used
+ * as asystem number.
+ *
+ * Virtual Router IDs are PDM-independent. All PDMs will use
+ * VRID_BASE to indicate the 'base' or 'legacy' EIGRP instance.
+ * All PDMs need to initialize their vrid to VRID_BASE for compatibility
+ * with legacy routers.
+ * Once IPv6 supports 'MTR Multicast', it will use the same VRID as
+ * IPv4. No current plans to support VRIDs on IPX. :)
+ * Initial usage of VRID is to signal usage of Multicast topology for
+ * MTR.
+ *
+ * VRID_MCAST is a well known constant, other VRIDs will be determined
+ * programmatic...
+ *
+ * With the addition of SAF the VRID space has been divided into two
+ * segments 0x0000-0x7fff is for EIGRP and vNets, 0x8000-0xffff is
+ * for saf and its associated vNets.
+ */
+#define EIGRP_VRID_MASK 0x8001
+#define EIGRP_VRID_AF_BASE 0x0000
+#define EIGRP_VRID_MCAST_BASE 0x0001
+#define EIGRP_VRID_SF_BASE 0x8000
+
+/* Extended Attributes for a destination */
+#define EIGRP_ATTR_HDRLEN (2)
+#define EIGRP_ATTR_MAXDATA (512)
+
+#define EIGRP_ATTR_NOOP 0 /*!< No-Op used as offset padding */
+#define EIGRP_ATTR_SCALED 1 /*!< Scaled metric values */
+#define EIGRP_ATTR_TAG 2 /*!< Tag assigned by Admin for dest */
+#define EIGRP_ATTR_COMM 3 /*!< Community attribute for dest */
+#define EIGRP_ATTR_JITTER 4 /*!< Variation in path delay */
+#define EIGRP_ATTR_QENERGY 5 /*!< Non-Active energy usage along path */
+#define EIGRP_ATTR_ENERGY 6 /*!< Active energy usage along path */
+
+/*
+ * Begin EIGRP-BGP interoperability communities
+ */
+#define EIGRP_EXTCOMM_SOO_ASFMT 0x0003 /* Site-of-Origin, BGP AS format */
+#define EIGRP_EXTCOMM_SOO_ADRFMT 0x0103 /* Site-of-Origin, BGP/EIGRP addr format */
+
+/*
+ * EIGRP Specific communities
+ */
+#define EIGRP_EXTCOMM_EIGRP 0x8800 /* EIGRP route information appended*/
+#define EIGRP_EXTCOMM_DAD 0x8801 /* EIGRP AS + Delay */
+#define EIGRP_EXTCOMM_VRHB 0x8802 /* EIGRP Vector: Reliability + Hop + BW */
+#define EIGRP_EXTCOMM_SRLM 0x8803 /* EIGRP System: Reserve +Load + MTU */
+#define EIGRP_EXTCOMM_SAR 0x8804 /* EIGRP System: Remote AS + Remote ID */
+#define EIGRP_EXTCOMM_RPM 0x8805 /* EIGRP Remote: Protocol + Metric */
+#define EIGRP_EXTCOMM_VRR 0x8806 /* EIGRP Vecmet: Rsvd + (internal) Routerid */
+
+
+/*
+ * EIGRP Filter constants
+ */
+#define EIGRP_FILTER_IN 0
+#define EIGRP_FILTER_OUT 1
+#define EIGRP_FILTER_MAX 2
+
+/*
+ * EIGRP Filter constants
+ */
+#define EIGRP_HSROLE_DEFAULT EIGRP_HSROLE_SPOKE
+#define EIGRP_HSROLE_HUB 0x01
+#define EIGRP_HSROLE_SPOKE 0x02
+
+#endif /* _ZEBRA_EIGRP_CONST_H_ */
diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c
new file mode 100644
index 0000000000..c2fbe29cfc
--- /dev/null
+++ b/eigrpd/eigrp_dump.c
@@ -0,0 +1,651 @@
+/*
+ * EIGRP Dump Functions and Debugging.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 "prefix.h"
+#include "command.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "table.h"
+#include "keychain.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_topology.h"
+
+/* Enable debug option variables -- valid only session. */
+unsigned long term_debug_eigrp = 0;
+unsigned long term_debug_eigrp_nei = 0;
+unsigned long term_debug_eigrp_packet[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+unsigned long term_debug_eigrp_zebra = 6;
+unsigned long term_debug_eigrp_transmit = 0;
+
+/* Configuration debug option variables. */
+unsigned long conf_debug_eigrp = 0;
+unsigned long conf_debug_eigrp_nei = 0;
+unsigned long conf_debug_eigrp_packet[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+unsigned long conf_debug_eigrp_zebra = 0;
+unsigned long conf_debug_eigrp_transmit = 0;
+
+
+static int
+config_write_debug (struct vty *vty)
+{
+ int write = 0;
+ int i;
+
+ const char *type_str[] = {"update", "request", "query", "reply",
+ "hello", "", "probe", "ack", "",
+ "SIA query", "SIA reply", "stub", "all"};
+ const char *detail_str[] = {"", " send", " recv", "", " detail",
+ " send detail", " recv detail", " detail"};
+
+
+ /* debug eigrp event. */
+
+ /* debug eigrp packet */
+ for (i = 0; i < 10; i++)
+ {
+ if (conf_debug_eigrp_packet[i] == 0 && term_debug_eigrp_packet[i] == 0 )
+ continue;
+
+ vty_out (vty, "debug eigrp packet %s%s%s",
+ type_str[i], detail_str[conf_debug_eigrp_packet[i]],
+ VTY_NEWLINE);
+ write = 1;
+ }
+
+ return write;
+}
+
+static int
+eigrp_neighbor_packet_queue_sum (struct eigrp_interface *ei)
+{
+ struct eigrp_neighbor *nbr;
+ struct listnode *node, *nnode;
+ int sum;
+ sum = 0;
+
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node, nnode, nbr))
+ {
+ sum += nbr->retrans_queue->count;
+ }
+
+ return sum;
+}
+
+/*
+ * Expects header to be in host order
+ */
+void
+eigrp_ip_header_dump (struct ip *iph)
+{
+ /* IP Header dump. */
+ zlog_debug ("ip_v %u", iph->ip_v);
+ zlog_debug ("ip_hl %u", iph->ip_hl);
+ zlog_debug ("ip_tos %u", iph->ip_tos);
+ zlog_debug ("ip_len %u", iph->ip_len);
+ zlog_debug ("ip_id %u", (u_int32_t) iph->ip_id);
+ zlog_debug ("ip_off %u", (u_int32_t) iph->ip_off);
+ zlog_debug ("ip_ttl %u", iph->ip_ttl);
+ zlog_debug ("ip_p %u", iph->ip_p);
+ zlog_debug ("ip_sum 0x%x", (u_int32_t) iph->ip_sum);
+ zlog_debug ("ip_src %s", inet_ntoa (iph->ip_src));
+ zlog_debug ("ip_dst %s", inet_ntoa (iph->ip_dst));
+}
+
+/*
+ * Expects header to be in host order
+ */
+void
+eigrp_header_dump (struct eigrp_header *eigrph)
+{
+ /* EIGRP Header dump. */
+ zlog_debug ("eigrp_version %u", eigrph->version);
+ zlog_debug ("eigrp_opcode %u", eigrph->opcode);
+ zlog_debug ("eigrp_checksum 0x%x", ntohs(eigrph->checksum));
+ zlog_debug ("eigrp_flags 0x%x", ntohl(eigrph->flags));
+ zlog_debug ("eigrp_sequence %u", ntohl(eigrph->sequence));
+ zlog_debug ("eigrp_ack %u", ntohl(eigrph->ack));
+ zlog_debug ("eigrp_vrid %u", ntohs(eigrph->vrid));
+ zlog_debug ("eigrp_AS %u", ntohs(eigrph->ASNumber));
+}
+
+const char *
+eigrp_if_name_string (struct eigrp_interface *ei)
+{
+ static char buf[EIGRP_IF_STRING_MAXLEN] = "";
+
+ if (!ei)
+ return "inactive";
+
+ snprintf (buf, EIGRP_IF_STRING_MAXLEN,
+ "%s", ei->ifp->name);
+ return buf;
+}
+
+const char *
+eigrp_topology_ip_string (struct eigrp_prefix_entry *tn)
+{
+ static char buf[EIGRP_IF_STRING_MAXLEN] = "";
+ u_int32_t ifaddr;
+
+ ifaddr = ntohl (tn->destination_ipv4->prefix.s_addr);
+ snprintf (buf, EIGRP_IF_STRING_MAXLEN,
+ "%u.%u.%u.%u",
+ (ifaddr >> 24) & 0xff, (ifaddr >> 16) & 0xff,
+ (ifaddr >> 8) & 0xff, ifaddr & 0xff);
+ return buf;
+}
+
+
+const char *
+eigrp_if_ip_string (struct eigrp_interface *ei)
+{
+ static char buf[EIGRP_IF_STRING_MAXLEN] = "";
+ u_int32_t ifaddr;
+
+ if (!ei)
+ return "inactive";
+
+ ifaddr = ntohl (ei->address->u.prefix4.s_addr);
+ snprintf (buf, EIGRP_IF_STRING_MAXLEN,
+ "%u.%u.%u.%u",
+ (ifaddr >> 24) & 0xff, (ifaddr >> 16) & 0xff,
+ (ifaddr >> 8) & 0xff, ifaddr & 0xff);
+
+ return buf;
+}
+
+const char *
+eigrp_neigh_ip_string (struct eigrp_neighbor *nbr)
+{
+ static char buf[EIGRP_IF_STRING_MAXLEN] = "";
+ u_int32_t ifaddr;
+
+ ifaddr = ntohl (nbr->src.s_addr);
+ snprintf (buf, EIGRP_IF_STRING_MAXLEN,
+ "%u.%u.%u.%u",
+ (ifaddr >> 24) & 0xff, (ifaddr >> 16) & 0xff,
+ (ifaddr >> 8) & 0xff, ifaddr & 0xff);
+
+ return buf;
+}
+
+void
+show_ip_eigrp_interface_header (struct vty *vty, struct eigrp *eigrp)
+{
+
+ vty_out (vty, "%s%s%d%s%s%s %-10s %-10s %-10s %-6s %-12s %-7s %-14s %-12s %-8s %-8s %-8s%s %-39s %-12s %-7s %-14s %-12s %-8s%s",
+ VTY_NEWLINE,
+ "EIGRP interfaces for AS(",eigrp->AS,")",VTY_NEWLINE,VTY_NEWLINE,
+ "Interface", "Bandwidth", "Delay", "Peers", "Xmit Queue", "Mean",
+ "Pacing Time", "Multicast", "Pending", "Hello", "Holdtime",
+ VTY_NEWLINE,"","Un/Reliable","SRTT","Un/Reliable","Flow Timer","Routes",
+ VTY_NEWLINE);
+}
+
+void
+show_ip_eigrp_interface_sub (struct vty *vty, struct eigrp *eigrp,
+ struct eigrp_interface *ei)
+{
+ vty_out (vty, "%-11s ", eigrp_if_name_string (ei));
+ vty_out (vty, "%-11u", IF_DEF_PARAMS (ei->ifp)->bandwidth);
+ vty_out (vty, "%-11u", IF_DEF_PARAMS (ei->ifp)->delay);
+ vty_out (vty, "%-7u", ei->nbrs->count);
+ vty_out (vty, "%u %c %-10u",0,'/', eigrp_neighbor_packet_queue_sum (ei));
+ vty_out (vty, "%-7u %-14u %-12u %-8u", 0, 0, 0, 0);
+ vty_out (vty, "%-8u %-8u %s",
+ IF_DEF_PARAMS (ei->ifp)->v_hello,
+ IF_DEF_PARAMS (ei->ifp)->v_wait,VTY_NEWLINE);
+}
+
+void
+show_ip_eigrp_interface_detail (struct vty *vty, struct eigrp *eigrp,
+ struct eigrp_interface *ei)
+{
+ vty_out (vty, "%-2s %s %d %-3s %s","","Hello interval is ", 0, " sec", VTY_NEWLINE);
+ vty_out (vty, "%-2s %s %s %s","", "Next xmit serial","<none>", VTY_NEWLINE);
+ vty_out (vty, "%-2s %s %d %s %d %s %d %s %d %s",
+ "", "Un/reliable mcasts: ", 0, "/", 0, "Un/reliable ucasts: ",
+ 0, "/", 0, VTY_NEWLINE);
+ vty_out (vty, "%-2s %s %d %s %d %s %d %s",
+ "", "Mcast exceptions: ", 0, " CR packets: ",
+ 0, " ACKs supressed: ", 0, VTY_NEWLINE);
+ vty_out (vty, "%-2s %s %d %s %d %s",
+ "", "Retransmissions sent: ", 0, "Out-of-sequence rcvd: ",
+ 0 ,VTY_NEWLINE);
+ vty_out (vty, "%-2s %s %s %s %s",
+ "", "Authentication mode is ", "not","set", VTY_NEWLINE);
+ vty_out (vty, "%-2s %s %s", "", "Use multicast", VTY_NEWLINE);
+}
+
+void
+show_ip_eigrp_neighbor_header (struct vty *vty, struct eigrp *eigrp)
+{
+ vty_out (vty, "%s%s%d%s%s%s%-3s %-17s %-20s %-6s %-8s %-6s %-5s %-5s %-5s%s %-41s %-6s %-8s %-6s %-4s %-6s %-5s %s",
+ VTY_NEWLINE,
+ "EIGRP neighbors for AS(",eigrp->AS,")",VTY_NEWLINE,VTY_NEWLINE,
+ "H", "Address", "Interface", "Hold", "Uptime",
+ "SRTT", "RTO", "Q", "Seq", VTY_NEWLINE
+ ,"","(sec)","","(ms)","","Cnt","Num", VTY_NEWLINE);
+}
+
+void
+show_ip_eigrp_neighbor_sub (struct vty *vty, struct eigrp_neighbor *nbr,
+ int detail)
+{
+
+ vty_out (vty, "%-3u %-17s %-21s", 0,
+ eigrp_neigh_ip_string (nbr), eigrp_if_name_string (nbr->ei));
+ vty_out (vty,"%-7lu", thread_timer_remain_second (nbr->t_holddown));
+ vty_out (vty,"%-8u %-6u %-5u", 0, 0, EIGRP_PACKET_RETRANS_TIME);
+ vty_out (vty,"%-7lu", nbr->retrans_queue->count);
+ vty_out (vty,"%u%s", nbr->recv_sequence_number, VTY_NEWLINE);
+
+
+ if (detail)
+ {
+ vty_out(vty," Version %u.%u/%u.%u",
+ nbr->os_rel_major, nbr->os_rel_minor,
+ nbr->tlv_rel_major, nbr->tlv_rel_minor);
+ vty_out(vty,", Retrans: %lu, Retries: %lu",
+ nbr->retrans_queue->count, 0UL);
+ vty_out(vty,", %s%s", eigrp_nbr_state_str(nbr), VTY_NEWLINE);
+ }
+}
+
+/*
+ * Print standard header for show EIGRP topology output
+ */
+void
+show_ip_eigrp_topology_header (struct vty *vty, struct eigrp *eigrp)
+{
+ struct in_addr router_id;
+ router_id.s_addr = eigrp->router_id;
+
+ vty_out (vty, "%sEIGRP Topology Table for AS(%d)/ID(%s)%s%s",
+ VTY_NEWLINE, eigrp->AS, inet_ntoa(router_id), VTY_NEWLINE, VTY_NEWLINE);
+ vty_out (vty, "Codes: P - Passive, A - Active, U - Update, Q - Query, "
+ "R - Reply%s r - reply Status, s - sia Status%s%s",
+ VTY_NEWLINE, VTY_NEWLINE,VTY_NEWLINE);
+}
+
+void
+show_ip_eigrp_prefix_entry (struct vty *vty, struct eigrp_prefix_entry *tn)
+{
+ struct list *successors = eigrp_topology_get_successor(tn);
+
+ vty_out (vty, "%-3c",(tn->state > 0) ? 'A' : 'P');
+
+ vty_out (vty, "%s/%u, ",
+ inet_ntoa (tn->destination_ipv4->prefix), tn->destination_ipv4->prefixlen);
+ vty_out (vty, "%u successors, ", successors->count);
+ vty_out (vty, "FD is %u, serno: %" PRIu64 " %s", tn->fdistance, tn->serno, VTY_NEWLINE);
+
+ list_delete(successors);
+}
+
+void
+show_ip_eigrp_neighbor_entry (struct vty *vty, struct eigrp *eigrp,
+ struct eigrp_neighbor_entry *te, int *first)
+{
+ if (te->reported_distance == EIGRP_MAX_METRIC)
+ return;
+
+ if (*first)
+ {
+ show_ip_eigrp_prefix_entry (vty, te->prefix);
+ *first = 0;
+ }
+
+ if (te->adv_router == eigrp->neighbor_self)
+ vty_out (vty, "%-7s%s, %s%s", " ", "via Connected",
+ eigrp_if_name_string (te->ei), VTY_NEWLINE);
+ else
+ {
+ vty_out (vty, "%-7s%s%s (%u/%u), %s%s",
+ " ", "via ", inet_ntoa (te->adv_router->src),
+ te->distance, te->reported_distance,
+ eigrp_if_name_string (te->ei), VTY_NEWLINE);
+ }
+}
+
+
+DEFUN (show_debugging_eigrp,
+ show_debugging_eigrp_cmd,
+ "show debugging eigrp",
+ SHOW_STR
+ DEBUG_STR
+ EIGRP_STR)
+{
+ int i;
+
+ vty_out (vty, "EIGRP debugging status:%s", VTY_NEWLINE);
+
+ /* Show debug status for events. */
+ if (IS_DEBUG_EIGRP(event,EVENT))
+ vty_out (vty, " EIGRP event debugging is on%s", VTY_NEWLINE);
+
+ /* Show debug status for EIGRP Packets. */
+ for (i = 0; i < 11 ; i++)
+ {
+ if (i == 8)
+ continue;
+
+ if (IS_DEBUG_EIGRP_PACKET (i, SEND) && IS_DEBUG_EIGRP_PACKET (i, RECV))
+ {
+ vty_out (vty, " EIGRP packet %s%s debugging is on%s",
+ LOOKUP (eigrp_packet_type_str, i + 1),
+ IS_DEBUG_EIGRP_PACKET (i, PACKET_DETAIL) ? " detail" : "",
+ VTY_NEWLINE);
+ }
+ else
+ {
+ if (IS_DEBUG_EIGRP_PACKET (i, SEND))
+ vty_out (vty, " EIGRP packet %s send%s debugging is on%s",
+ LOOKUP (eigrp_packet_type_str, i + 1),
+ IS_DEBUG_EIGRP_PACKET (i, PACKET_DETAIL) ? " detail" : "",
+ VTY_NEWLINE);
+ if (IS_DEBUG_EIGRP_PACKET (i, RECV))
+ vty_out (vty, " EIGRP packet %s receive%s debugging is on%s",
+ LOOKUP (eigrp_packet_type_str, i + 1),
+ IS_DEBUG_EIGRP_PACKET (i, PACKET_DETAIL) ? " detail" : "",
+ VTY_NEWLINE);
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+
+/*
+ [no] debug eigrp packet (hello|dd|ls-request|ls-update|ls-ack|all)
+ [send|recv [detail]]
+*/
+
+DEFUN (debug_eigrp_transmit,
+ debug_eigrp_transmit_cmd,
+ "debug eigrp transmit <send|recv|all> [detail]",
+ DEBUG_STR
+ EIGRP_STR
+ "EIGRP transmission events\n"
+ "packet sent\n"
+ "packet received\n"
+ "all packets\n"
+ "Detailed Information\n")
+{
+ int flag = 0;
+ int idx = 2;
+
+ /* send or recv. */
+ if (argv_find (argv, argc, "send", &idx))
+ flag = EIGRP_DEBUG_SEND;
+ else if (argv_find (argv, argc, "recv", &idx))
+ flag = EIGRP_DEBUG_RECV;
+ else if (argv_find (argv, argc, "all", &idx) == 0)
+ flag = EIGRP_DEBUG_SEND_RECV;
+
+ /* detail option */
+ if (argv_find (argv, argc, "detail", &idx) == 0)
+ flag = EIGRP_DEBUG_PACKET_DETAIL;
+
+ if (vty->node == CONFIG_NODE)
+ DEBUG_TRANSMIT_ON (0, flag);
+ else
+ TERM_DEBUG_TRANSMIT_ON (0, flag);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_eigrp_transmit,
+ no_debug_eigrp_transmit_cmd,
+ "no debug eigrp transmit <send|recv|all> [detail]",
+ NO_STR
+ UNDEBUG_STR
+ EIGRP_STR
+ "EIGRP transmission events\n"
+ "packet sent\n"
+ "packet received\n"
+ "all packets\n"
+ "Detailed Information\n")
+{
+ int flag = 0;
+ int idx = 3;
+
+ /* send or recv. */
+ if (argv_find (argv, argc, "send", &idx) == 0)
+ flag = EIGRP_DEBUG_SEND;
+ else if (argv_find (argv, argc, "recv", &idx) == 0)
+ flag = EIGRP_DEBUG_RECV;
+ else if (argv_find (argv, argc, "all", &idx) == 0)
+ flag = EIGRP_DEBUG_SEND_RECV;
+
+ /* detail option */
+ if (argv_find (argv, argc, "detail", &idx) == 0)
+ flag = EIGRP_DEBUG_PACKET_DETAIL;
+
+ if (vty->node == CONFIG_NODE)
+ DEBUG_TRANSMIT_OFF (0, flag);
+ else
+ TERM_DEBUG_TRANSMIT_OFF (0, flag);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (debug_eigrp_packets,
+ debug_eigrp_packets_all_cmd,
+ "debug eigrp packets <siaquery|siareply|ack|hello|probe|query|reply|request|retry|stub|terse|update|all> [send|receive] [detail]",
+ DEBUG_STR
+ EIGRP_STR
+ "EIGRP packets\n"
+ "EIGRP SIA-Query packets\n"
+ "EIGRP SIA-Reply packets\n"
+ "EIGRP ack packets\n"
+ "EIGRP hello packets\n"
+ "EIGRP probe packets\n"
+ "EIGRP query packets\n"
+ "EIGRP reply packets\n"
+ "EIGRP request packets\n"
+ "EIGRP retransmissions\n"
+ "EIGRP stub packets\n"
+ "Display all EIGRP packets except Hellos\n"
+ "EIGRP update packets\n"
+ "Display all EIGRP packets\n"
+ "Send Packets\n"
+ "Receive Packets\n"
+ "Detail Information\n")
+{
+ int type = 0;
+ int flag = 0;
+ int i;
+ int idx = 0;
+
+ /* Check packet type. */
+ if (argv_find (argv, argc, "hello", &idx) == 0)
+ type = EIGRP_DEBUG_HELLO;
+ if (argv_find (argv, argc, "update", &idx) == 0)
+ type = EIGRP_DEBUG_UPDATE;
+ if (argv_find (argv, argc, "query", &idx) == 0)
+ type = EIGRP_DEBUG_QUERY;
+ if (argv_find (argv, argc, "ack", &idx) == 0)
+ type = EIGRP_DEBUG_ACK;
+ if (argv_find (argv, argc, "probe", &idx) == 0)
+ type = EIGRP_DEBUG_PROBE;
+ if (argv_find (argv, argc, "stub", &idx) == 0)
+ type = EIGRP_DEBUG_STUB;
+ if (argv_find (argv, argc, "reply", &idx) == 0)
+ type = EIGRP_DEBUG_REPLY;
+ if (argv_find (argv, argc, "request", &idx) == 0)
+ type = EIGRP_DEBUG_REQUEST;
+ if (argv_find (argv, argc, "siaquery", &idx) == 0)
+ type = EIGRP_DEBUG_SIAQUERY;
+ if (argv_find (argv, argc, "siareply", &idx) == 0)
+ type = EIGRP_DEBUG_SIAREPLY;
+ if (argv_find (argv, argc, "all", &idx) == 0)
+ type = EIGRP_DEBUG_PACKETS_ALL;
+
+
+ /* All packet types, both send and recv. */
+ flag = EIGRP_DEBUG_SEND_RECV;
+
+ /* send or recv. */
+ if (argv_find (argv, argc, "s", &idx) == 0)
+ flag = EIGRP_DEBUG_SEND;
+ else if (argv_find (argv, argc, "r", &idx) == 0)
+ flag = EIGRP_DEBUG_RECV;
+
+ /* detail. */
+ if (argv_find (argv, argc, "detail", &idx) == 0)
+ flag |= EIGRP_DEBUG_PACKET_DETAIL;
+
+ for (i = 0; i < 11; i++)
+ if (type & (0x01 << i))
+ {
+ if (vty->node == CONFIG_NODE)
+ DEBUG_PACKET_ON (i, flag);
+ else
+ TERM_DEBUG_PACKET_ON (i, flag);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_eigrp_packets,
+ no_debug_eigrp_packets_all_cmd,
+ "no debug eigrp packets <siaquery|siareply|ack|hello|probe|query|reply|request|retry|stub|terse|update|all> [send|receive] [detail]",
+ NO_STR
+ UNDEBUG_STR
+ EIGRP_STR
+ "EIGRP packets\n"
+ "EIGRP SIA-Query packets\n"
+ "EIGRP SIA-Reply packets\n"
+ "EIGRP ack packets\n"
+ "EIGRP hello packets\n"
+ "EIGRP probe packets\n"
+ "EIGRP query packets\n"
+ "EIGRP reply packets\n"
+ "EIGRP request packets\n"
+ "EIGRP retransmissions\n"
+ "EIGRP stub packets\n"
+ "Display all EIGRP packets except Hellos\n"
+ "EIGRP update packets\n"
+ "Display all EIGRP packets\n"
+ "Send Packets\n"
+ "Receive Packets\n"
+ "Detailed Information\n")
+{
+ int type = 0;
+ int flag = 0;
+ int i;
+ int idx = 0;
+
+ /* Check packet type. */
+ if (argv_find (argv, argc, "hello", &idx) == 0)
+ type = EIGRP_DEBUG_HELLO;
+ if (argv_find (argv, argc, "update", &idx) == 0)
+ type = EIGRP_DEBUG_UPDATE;
+ if (argv_find (argv, argc, "query", &idx) == 0)
+ type = EIGRP_DEBUG_QUERY;
+ if (argv_find (argv, argc, "ack", &idx) == 0)
+ type = EIGRP_DEBUG_ACK;
+ if (argv_find (argv, argc, "probe", &idx) == 0)
+ type = EIGRP_DEBUG_PROBE;
+ if (argv_find (argv, argc, "stub", &idx) == 0)
+ type = EIGRP_DEBUG_STUB;
+ if (argv_find (argv, argc, "reply", &idx) == 0)
+ type = EIGRP_DEBUG_REPLY;
+ if (argv_find (argv, argc, "request", &idx) == 0)
+ type = EIGRP_DEBUG_REQUEST;
+ if (argv_find (argv, argc, "siaquery", &idx) == 0)
+ type = EIGRP_DEBUG_SIAQUERY;
+ if (argv_find (argv, argc, "siareply", &idx) == 0)
+ type = EIGRP_DEBUG_SIAREPLY;
+
+ /* Default, both send and recv. */
+ flag = EIGRP_DEBUG_SEND_RECV;
+
+ /* send or recv. */
+ if (argv_find (argv, argc, "send", &idx) == 0)
+ flag = EIGRP_DEBUG_SEND;
+ else if (argv_find (argv, argc, "reply", &idx) == 0)
+ flag = EIGRP_DEBUG_RECV;
+
+ /* detail. */
+ if (argv_find (argv, argc, "detail", &idx) == 0)
+ flag |= EIGRP_DEBUG_PACKET_DETAIL;
+
+ for (i = 0; i < 11; i++)
+ if (type & (0x01 << i))
+ {
+ if (vty->node == CONFIG_NODE)
+ DEBUG_PACKET_OFF (i, flag);
+ else
+ TERM_DEBUG_PACKET_OFF (i, flag);
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* Debug node. */
+static struct cmd_node eigrp_debug_node =
+{
+ DEBUG_NODE,
+ "",
+ 1 /* VTYSH */
+};
+
+/* Initialize debug commands. */
+void
+eigrp_debug_init ()
+{
+ install_node (&eigrp_debug_node, config_write_debug);
+
+ install_element (ENABLE_NODE, &show_debugging_eigrp_cmd);
+ install_element (ENABLE_NODE, &debug_eigrp_packets_all_cmd);
+ install_element (ENABLE_NODE, &no_debug_eigrp_packets_all_cmd);
+ install_element (ENABLE_NODE, &debug_eigrp_transmit_cmd);
+ install_element (ENABLE_NODE, &no_debug_eigrp_transmit_cmd);
+
+ install_element (CONFIG_NODE, &show_debugging_eigrp_cmd);
+ install_element (CONFIG_NODE, &debug_eigrp_packets_all_cmd);
+ install_element (CONFIG_NODE, &no_debug_eigrp_packets_all_cmd);
+ install_element (CONFIG_NODE, &no_debug_eigrp_transmit_cmd);
+}
+
+
diff --git a/eigrpd/eigrp_dump.h b/eigrpd/eigrp_dump.h
new file mode 100644
index 0000000000..e18efd453a
--- /dev/null
+++ b/eigrpd/eigrp_dump.h
@@ -0,0 +1,164 @@
+/*
+ * EIGRP Dump Functions and Debbuging.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 _ZEBRA_EIGRPD_DUMP_H_
+#define _ZEBRA_EIGRPD_DUMP_H_
+
+#define EIGRP_TIME_DUMP_SIZE 16
+
+/* general debug flags */
+extern unsigned long term_debug_eigrp;
+#define EIGRP_DEBUG_EVENT 0x01
+#define EIGRP_DEBUG_DETAIL 0x02
+#define EIGRP_DEBUG_TIMERS 0x04
+
+/* neighbor debug flags */
+extern unsigned long term_debug_eigrp_nei;
+#define EIGRP_DEBUG_NEI 0x01
+
+/* packet debug flags */
+extern unsigned long term_debug_eigrp_packet[];
+#define EIGRP_DEBUG_UPDATE 0x01
+#define EIGRP_DEBUG_REQUEST 0x02
+#define EIGRP_DEBUG_QUERY 0x04
+#define EIGRP_DEBUG_REPLY 0x08
+#define EIGRP_DEBUG_HELLO 0x10
+#define EIGRP_DEBUG_PROBE 0x40
+#define EIGRP_DEBUG_ACK 0x80
+#define EIGRP_DEBUG_SIAQUERY 0x200
+#define EIGRP_DEBUG_SIAREPLY 0x400
+#define EIGRP_DEBUG_STUB 0x800
+#define EIGRP_DEBUG_PACKETS_ALL 0xfff
+
+extern unsigned long term_debug_eigrp_transmit;
+#define EIGRP_DEBUG_SEND 0x01
+#define EIGRP_DEBUG_RECV 0x02
+#define EIGRP_DEBUG_SEND_RECV 0x03
+#define EIGRP_DEBUG_PACKET_DETAIL 0x04
+
+/* zebra debug flags */
+extern unsigned long term_debug_eigrp_zebra;
+#define EIGRP_DEBUG_ZEBRA_INTERFACE 0x01
+#define EIGRP_DEBUG_ZEBRA_REDISTRIBUTE 0x02
+#define EIGRP_DEBUG_ZEBRA 0x03
+
+/* Macro for setting debug option. */
+#define CONF_DEBUG_NEI_ON(a, b) conf_debug_eigrp_nei[a] |= (b)
+#define CONF_DEBUG_NEI_OFF(a, b) conf_debug_eigrp_nei[a] &= ~(b)
+#define TERM_DEBUG_NEI_ON(a, b) term_debug_eigrp_nei[a] |= (b)
+#define TERM_DEBUG_NEI_OFF(a, b) term_debug_eigrp_nei[a] &= ~(b)
+#define DEBUG_NEI_ON(a, b) \
+ do { \
+ CONF_DEBUG_NEI_ON(a, b); \
+ TERM_DEBUG_NEI_ON(a, b); \
+ } while (0)
+#define DEBUG_NEI_OFF(a, b) \
+ do { \
+ CONF_DEBUG_NEI_OFF(a, b); \
+ TERM_DEBUG_NEI_OFF(a, b); \
+ } while (0)
+
+#define CONF_DEBUG_PACKET_ON(a, b) conf_debug_eigrp_packet[a] |= (b)
+#define CONF_DEBUG_PACKET_OFF(a, b) conf_debug_eigrp_packet[a] &= ~(b)
+#define TERM_DEBUG_PACKET_ON(a, b) term_debug_eigrp_packet[a] |= (b)
+#define TERM_DEBUG_PACKET_OFF(a, b) term_debug_eigrp_packet[a] &= ~(b)
+#define DEBUG_PACKET_ON(a, b) \
+ do { \
+ CONF_DEBUG_PACKET_ON(a, b); \
+ TERM_DEBUG_PACKET_ON(a, b); \
+ } while (0)
+#define DEBUG_PACKET_OFF(a, b) \
+ do { \
+ CONF_DEBUG_PACKET_OFF(a, b); \
+ TERM_DEBUG_PACKET_OFF(a, b); \
+ } while (0)
+
+#define CONF_DEBUG_TRANSMIT_ON(a, b) conf_debug_eigrp_transmit |= (b)
+#define CONF_DEBUG_TRANSMIT_OFF(a, b) conf_debug_eigrp_transmit &= ~(b)
+#define TERM_DEBUG_TRANSMIT_ON(a, b) term_debug_eigrp_transmit |= (b)
+#define TERM_DEBUG_TRANSMIT_OFF(a, b) term_debug_eigrp_transmit &= ~(b)
+#define DEBUG_TRANSMIT_ON(a, b) \
+ do { \
+ CONF_DEBUG_TRANSMIT_ON(a, b); \
+ TERM_DEBUG_TRANSMIT_ON(a, b); \
+ } while (0)
+#define DEBUG_TRANSMIT_OFF(a, b) \
+ do { \
+ CONF_DEBUG_TRANSMIT_OFF(a, b); \
+ TERM_DEBUG_TRANSMIT_OFF(a, b); \
+ } while (0)
+
+#define CONF_DEBUG_ON(a, b) conf_debug_eigrp_ ## a |= (EIGRP_DEBUG_ ## b)
+#define CONF_DEBUG_OFF(a, b) conf_debug_eigrp_ ## a &= ~(EIGRP_DEBUG_ ## b)
+#define TERM_DEBUG_ON(a, b) term_debug_eigrp_ ## a |= (EIGRP_DEBUG_ ## b)
+#define TERM_DEBUG_OFF(a, b) term_debug_eigrp_ ## a &= ~(EIGRP_DEBUG_ ## b)
+#define DEBUG_ON(a, b) \
+ do { \
+ CONF_DEBUG_ON(a, b); \
+ TERM_DEBUG_ON(a, b); \
+ } while (0)
+#define DEBUG_OFF(a, b) \
+ do { \
+ CONF_DEBUG_OFF(a, b); \
+ TERM_DEBUG_OFF(a, b); \
+ } while (0)
+
+/* Macro for checking debug option. */
+#define IS_DEBUG_EIGRP_PACKET(a, b) \
+ (term_debug_eigrp_packet[a] & EIGRP_DEBUG_ ## b)
+#define IS_DEBUG_EIGRP_TRANSMIT(a, b) \
+ (term_debug_eigrp_transmit & EIGRP_DEBUG_ ## b)
+#define IS_DEBUG_EIGRP_NEI(a, b) \
+ (term_debug_eigrp_nei & EIGRP_DEBUG_ ## b)
+#define IS_DEBUG_EIGRP(a, b) \
+ (term_debug_eigrp & EIGRP_DEBUG_ ## b)
+#define IS_DEBUG_EIGRP_EVENT IS_DEBUG_EIGRP(event, EVENT)
+
+
+/* Prototypes. */
+extern const char *eigrp_if_name_string (struct eigrp_interface *);
+extern const char *eigrp_if_ip_string (struct eigrp_interface *);
+extern const char *eigrp_neigh_ip_string (struct eigrp_neighbor *);
+extern const char *eigrp_topology_ip_string (struct eigrp_prefix_entry *);
+
+extern void eigrp_ip_header_dump(struct ip *);
+extern void eigrp_header_dump(struct eigrp_header *);
+
+extern void show_ip_eigrp_interface_header (struct vty *, struct eigrp *);
+extern void show_ip_eigrp_neighbor_header (struct vty *, struct eigrp *);
+extern void show_ip_eigrp_topology_header (struct vty *, struct eigrp *);
+extern void show_ip_eigrp_interface_detail (struct vty *, struct eigrp *,
+ struct eigrp_interface *);
+extern void show_ip_eigrp_interface_sub (struct vty *, struct eigrp *,
+ struct eigrp_interface *);
+extern void show_ip_eigrp_neighbor_sub (struct vty *, struct eigrp_neighbor *, int);
+extern void show_ip_eigrp_prefix_entry (struct vty *, struct eigrp_prefix_entry *);
+extern void show_ip_eigrp_neighbor_entry (struct vty *, struct eigrp *, struct eigrp_neighbor_entry *, int *);
+
+extern void eigrp_debug_init (void);
+
+#endif /* _ZEBRA_EIGRPD_DUMP_H_ */
diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c
new file mode 100644
index 0000000000..df59332176
--- /dev/null
+++ b/eigrpd/eigrp_filter.c
@@ -0,0 +1,382 @@
+/*
+ * EIGRP Filter Functions.
+ * Copyright (C) 2013-2015
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ *
+ * 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 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 "if.h"
+#include "command.h"
+#include "prefix.h"
+#include "table.h"
+#include "thread.h"
+#include "memory.h"
+#include "log.h"
+#include "stream.h"
+#include "filter.h"
+#include "sockunion.h"
+#include "sockopt.h"
+#include "routemap.h"
+#include "if_rmap.h"
+#include "plist.h"
+#include "distribute.h"
+#include "md5.h"
+#include "keychain.h"
+#include "privs.h"
+#include "vrf.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_const.h"
+#include "eigrpd/eigrp_filter.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_memory.h"
+
+/*
+ * Distribute-list update functions.
+ */
+void
+eigrp_distribute_update (struct distribute *dist)
+{
+ struct interface *ifp;
+ struct eigrp_interface *ei = NULL;
+ struct access_list *alist;
+ struct prefix_list *plist;
+ //struct route_map *routemap;
+ struct eigrp *e;
+
+ /* if no interface address is present, set list to eigrp process struct */
+ e = eigrp_lookup();
+
+ /* Check if distribute-list was set for process or interface */
+ if (! dist->ifname)
+ {
+ /* access list IN for whole process */
+ if (dist->list[DISTRIBUTE_V4_IN])
+ {
+ alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_IN]);
+ if (alist)
+ e->list[EIGRP_FILTER_IN] = alist;
+ else
+ e->list[EIGRP_FILTER_IN] = NULL;
+ }
+ else
+ {
+ e->list[EIGRP_FILTER_IN] = NULL;
+ }
+
+ /* access list OUT for whole process */
+ if (dist->list[DISTRIBUTE_V4_OUT])
+ {
+ alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_OUT]);
+ if (alist)
+ e->list[EIGRP_FILTER_OUT] = alist;
+ else
+ e->list[EIGRP_FILTER_OUT] = NULL;
+ }
+ else
+ {
+ e->list[EIGRP_FILTER_OUT] = NULL;
+ }
+
+ /* PREFIX_LIST IN for process */
+ if (dist->prefix[DISTRIBUTE_V4_IN])
+ {
+ plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]);
+ if (plist)
+ {
+ e->prefix[EIGRP_FILTER_IN] = plist;
+ }
+ else
+ e->prefix[EIGRP_FILTER_IN] = NULL;
+ } else
+ e->prefix[EIGRP_FILTER_IN] = NULL;
+
+ /* PREFIX_LIST OUT for process */
+ if (dist->prefix[DISTRIBUTE_V4_OUT])
+ {
+ plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]);
+ if (plist)
+ {
+ e->prefix[EIGRP_FILTER_OUT] = plist;
+
+ }
+ else
+ e->prefix[EIGRP_FILTER_OUT] = NULL;
+ }
+ else
+ e->prefix[EIGRP_FILTER_OUT] = NULL;
+
+ //This is commented out, because the distribute.[ch] code
+ //changes looked poorly written from first glance
+ //commit was 133bdf2d
+ //TODO: DBS
+#if 0
+ /* route-map IN for whole process */
+ if (dist->route[DISTRIBUTE_V4_IN])
+ {
+ routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_IN]);
+ if (routemap)
+ e->routemap[EIGRP_FILTER_IN] = routemap;
+ else
+ e->routemap[EIGRP_FILTER_IN] = NULL;
+ }
+ else
+ {
+ e->routemap[EIGRP_FILTER_IN] = NULL;
+ }
+
+ /* route-map OUT for whole process */
+ if (dist->route[DISTRIBUTE_V4_OUT])
+ {
+ routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_OUT]);
+ if (routemap)
+ e->routemap[EIGRP_FILTER_OUT] = routemap;
+ else
+ e->routemap[EIGRP_FILTER_OUT] = NULL;
+ }
+ else
+ {
+ e->routemap[EIGRP_FILTER_OUT] = NULL;
+ }
+#endif
+ //TODO: check Graceful restart after 10sec
+
+ /* check if there is already GR scheduled */
+ if(e->t_distribute != NULL)
+ {
+ /* if is, cancel schedule */
+ thread_cancel(e->t_distribute);
+ }
+ /* schedule Graceful restart for whole process in 10sec */
+ e->t_distribute = NULL;
+ thread_add_timer(master, eigrp_distribute_timer_process, e, (10),
+ &e->t_distribute);
+
+ return;
+ }
+
+ ifp = if_lookup_by_name (dist->ifname, VRF_DEFAULT);
+ if (ifp == NULL)
+ return;
+
+ /*struct eigrp_if_info * info = ifp->info;
+ ei = info->eigrp_interface;*/
+ struct listnode *node, *nnode;
+ struct eigrp_interface *ei2;
+ /* Find proper interface */
+ for (ALL_LIST_ELEMENTS (e->eiflist, node, nnode, ei2))
+ {
+ if(strcmp(ei2->ifp->name,ifp->name) == 0){
+ ei = ei2;
+ break;
+ }
+ }
+
+ /* Access-list for interface in */
+ if (dist->list[DISTRIBUTE_V4_IN])
+ {
+ alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_IN]);
+ if (alist){
+ ei->list[EIGRP_FILTER_IN] = alist;
+ }
+ else
+ ei->list[EIGRP_FILTER_IN] = NULL;
+ }
+ else
+ {
+ ei->list[EIGRP_FILTER_IN] = NULL;
+ }
+
+ /* Access-list for interface in */
+ if (dist->list[DISTRIBUTE_V4_OUT])
+ {
+ alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_OUT]);
+ if (alist)
+ ei->list[EIGRP_FILTER_OUT] = alist;
+ else
+ ei->list[EIGRP_FILTER_OUT] = NULL;
+
+ }
+ else
+ ei->list[EIGRP_FILTER_OUT] = NULL;
+
+ /* Prefix-list for interface in */
+ if (dist->prefix[DISTRIBUTE_V4_IN])
+ {
+ plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]);
+ if (plist)
+ ei->prefix[EIGRP_FILTER_IN] = plist;
+ else
+ ei->prefix[EIGRP_FILTER_IN] = NULL;
+ }
+ else
+ ei->prefix[EIGRP_FILTER_IN] = NULL;
+
+ /* Prefix-list for interface out */
+ if (dist->prefix[DISTRIBUTE_V4_OUT])
+ {
+ plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]);
+ if (plist)
+ ei->prefix[EIGRP_FILTER_OUT] = plist;
+ else
+ ei->prefix[EIGRP_FILTER_OUT] = NULL;
+ }
+ else
+ ei->prefix[EIGRP_FILTER_OUT] = NULL;
+
+#if 0
+ /* route-map IN for whole process */
+ if (dist->route[DISTRIBUTE_V4_IN])
+ {
+ zlog_info("<DEBUG ACL ALL in");
+ routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_IN]);
+ if (routemap)
+ ei->routemap[EIGRP_FILTER_IN] = routemap;
+ else
+ ei->routemap[EIGRP_FILTER_IN] = NULL;
+ }
+ else
+ {
+ ei->routemap[EIGRP_FILTER_IN] = NULL;
+ }
+
+ /* route-map OUT for whole process */
+ if (dist->route[DISTRIBUTE_V4_OUT])
+ {
+ routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_OUT]);
+ if (routemap)
+ ei->routemap[EIGRP_FILTER_OUT] = routemap;
+ else
+ ei->routemap[EIGRP_FILTER_OUT] = NULL;
+ }
+ else
+ {
+ ei->routemap[EIGRP_FILTER_OUT] = NULL;
+ }
+#endif
+ //TODO: check Graceful restart after 10sec
+
+ /* check if there is already GR scheduled */
+ if(ei->t_distribute != NULL)
+ {
+ /* if is, cancel schedule */
+ thread_cancel(ei->t_distribute);
+ }
+ /* schedule Graceful restart for interface in 10sec */
+ e->t_distribute = NULL;
+ thread_add_timer(master, eigrp_distribute_timer_interface, ei, 10,
+ &e->t_distribute);
+}
+
+/*
+ * Function called by prefix-list and access-list update
+ */
+void
+eigrp_distribute_update_interface (struct interface *ifp)
+{
+ struct distribute *dist;
+
+ dist = distribute_lookup (ifp->name);
+ if (dist)
+ eigrp_distribute_update (dist);
+}
+
+/* Update all interface's distribute list.
+ * Function used in hook for prefix-list
+ */
+void
+eigrp_distribute_update_all (struct prefix_list *notused)
+{
+ struct interface *ifp;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS (vrf_iflist(VRF_DEFAULT), node, nnode, ifp))
+ eigrp_distribute_update_interface (ifp);
+}
+
+/*
+ * Function used in hook for acces-list
+ */
+void
+eigrp_distribute_update_all_wrapper(struct access_list *notused)
+{
+ eigrp_distribute_update_all(NULL);
+}
+
+/*
+ * @fn eigrp_distribute_timer_process
+ *
+ * @param[in] thread current execution thread timer is associated with
+ *
+ * @return int always returns 0
+ *
+ * @par
+ * Called when 10sec waiting time expire and
+ * executes Graceful restart for whole process
+ */
+int
+eigrp_distribute_timer_process (struct thread *thread)
+{
+ struct eigrp *eigrp;
+
+ eigrp = THREAD_ARG(thread);
+ eigrp->t_distribute = NULL;
+
+ /* execute GR for whole process */
+ eigrp_update_send_process_GR(eigrp, EIGRP_GR_FILTER, NULL);
+
+ return 0;
+}
+
+/*
+ * @fn eigrp_distribute_timer_interface
+ *
+ * @param[in] thread current execution thread timer is associated with
+ *
+ * @return int always returns 0
+ *
+ * @par
+ * Called when 10sec waiting time expire and
+ * executes Graceful restart for interface
+ */
+int
+eigrp_distribute_timer_interface (struct thread *thread)
+{
+ struct eigrp_interface *ei;
+
+ ei = THREAD_ARG(thread);
+ ei->t_distribute = NULL;
+
+ /* execute GR for interface */
+ eigrp_update_send_interface_GR(ei, EIGRP_GR_FILTER, NULL);
+
+ return 0;
+}
diff --git a/eigrpd/eigrp_filter.h b/eigrpd/eigrp_filter.h
new file mode 100644
index 0000000000..117cf3c49f
--- /dev/null
+++ b/eigrpd/eigrp_filter.h
@@ -0,0 +1,43 @@
+/*
+ * EIGRP Filter Functions.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ *
+ * 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 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 EIGRPD_EIGRP_FILTER_H_
+#define EIGRPD_EIGRP_FILTER_H_
+
+extern void eigrp_distribute_update (struct distribute *);
+extern void eigrp_distribute_update_interface (struct interface *);
+extern void eigrp_distribute_update_all (struct prefix_list *);
+extern void eigrp_distribute_update_all_wrapper(struct access_list *);
+extern int eigrp_distribute_timer_process (struct thread *);
+extern int eigrp_distribute_timer_interface (struct thread *);
+
+#endif /* EIGRPD_EIGRP_FILTER_H_ */
diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c
new file mode 100644
index 0000000000..ad4eb70181
--- /dev/null
+++ b/eigrpd/eigrp_fsm.c
@@ -0,0 +1,586 @@
+/*
+ * EIGRPd Finite State Machine (DUAL).
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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
+ *
+ * This file contains functions for executing logic of finite state machine
+ *
+ * +------------ +
+ * | (7) |
+ * | v
+ * +=====================================+
+ * | |
+ * | Passive |
+ * | |
+ * +=====================================+
+ * ^ | ^ ^ ^ |
+ * (3)| | (1)| | (1)| |
+ * | (0)| | (3)| | (2)|
+ * | | | | | +---------------+
+ * | | | | | \
+ * +--------+ | | | +-----------------+ \
+ * / / / | \ \
+ * / / / +----+ \ \
+ * | | | | | |
+ * | v | | | v
+ * +===========+ (6) +===========+ +===========+ (6) +===========+
+ * | |------->| | (5) | |-------->| |
+ * | | (4) | |------>| | (4) | |
+ * | ACTIVE 0 |<-------| ACTIVE 1 | | ACTIVE 2 |<--------| ACTIVE 3 |
+ * +--| | +--| | +--| | +--| |
+ * | +===========+ | +===========+ | +===========+ | +===========+
+ * | ^ |(5) | ^ | ^ ^ | ^
+ * | | +---------|------|------------|----+ | | |
+ * +-------+ +------+ +---------+ +---------+
+ * (7) (7) (7) (7)
+ *
+ * 0- input event other than query from successor, FC not satisfied
+ * 1- last reply, FD is reset
+ * 2- query from successor, FC not satisfied
+ * 3- last reply, FC satisfied with current value of FDij
+ * 4- distance increase while in active state
+ * 5- query from successor while in active state
+ * 6- last reply, FC not satisfied with current value of FDij
+ * 7- state not changed, usually by receiving not last reply
+ */
+
+#include <thread.h>
+#include <zebra.h>
+
+#include "prefix.h"
+#include "table.h"
+#include "memory.h"
+#include "log.h"
+#include "linklist.h"
+#include "vty.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+
+/*
+ * Prototypes
+ */
+int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *);
+int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *);
+int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *);
+int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *);
+int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *);
+int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *);
+int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *);
+int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *);
+
+//---------------------------------------------------------------------
+
+/*
+ * NSM - field of fields of struct containing one function each.
+ * Which function is used depends on actual state of FSM and occurred
+ * event(arrow in diagram). Usage:
+ * NSM[actual/starting state][occurred event].func
+ * Functions are should be executed within separate thread.
+ */
+struct {
+ int
+ (*func)(struct eigrp_fsm_action_message *);
+} NSM[EIGRP_FSM_STATE_MAX][EIGRP_FSM_EVENT_MAX] = { {
+ //PASSIVE STATE
+ { eigrp_fsm_event_nq_fcn }, /* Event 0 */
+ { eigrp_fsm_event_keep_state }, /* Event 1 */
+ { eigrp_fsm_event_q_fcn }, /* Event 2 */
+ { eigrp_fsm_event_keep_state }, /* Event 3 */
+ { eigrp_fsm_event_keep_state }, /* Event 4 */
+ { eigrp_fsm_event_keep_state }, /* Event 5 */
+ { eigrp_fsm_event_keep_state }, /* Event 6 */
+ { eigrp_fsm_event_keep_state }, /* Event 7 */
+ }, {
+ //Active 0 state
+ { eigrp_fsm_event_keep_state }, /* Event 0 */
+ { eigrp_fsm_event_keep_state }, /* Event 1 */
+ { eigrp_fsm_event_keep_state }, /* Event 2 */
+ { eigrp_fsm_event_lr_fcs }, /* Event 3 */
+ { eigrp_fsm_event_keep_state }, /* Event 4 */
+ { eigrp_fsm_event_qact }, /* Event 5 */
+ { eigrp_fsm_event_lr_fcn }, /* Event 6 */
+ { eigrp_fsm_event_keep_state }, /* Event 7 */
+ }, {
+ //Active 1 state
+ { eigrp_fsm_event_keep_state }, /* Event 0 */
+ { eigrp_fsm_event_lr }, /* Event 1 */
+ { eigrp_fsm_event_keep_state }, /* Event 2 */
+ { eigrp_fsm_event_keep_state }, /* Event 3 */
+ { eigrp_fsm_event_dinc }, /* Event 4 */
+ { eigrp_fsm_event_qact }, /* Event 5 */
+ { eigrp_fsm_event_keep_state }, /* Event 6 */
+ { eigrp_fsm_event_keep_state }, /* Event 7 */
+ }, {
+ //Active 2 state
+ { eigrp_fsm_event_keep_state }, /* Event 0 */
+ { eigrp_fsm_event_keep_state }, /* Event 1 */
+ { eigrp_fsm_event_keep_state }, /* Event 2 */
+ { eigrp_fsm_event_lr_fcs }, /* Event 3 */
+ { eigrp_fsm_event_keep_state }, /* Event 4 */
+ { eigrp_fsm_event_keep_state }, /* Event 5 */
+ { eigrp_fsm_event_lr_fcn }, /* Event 6 */
+ { eigrp_fsm_event_keep_state }, /* Event 7 */
+ }, {
+ //Active 3 state
+ { eigrp_fsm_event_keep_state }, /* Event 0 */
+ { eigrp_fsm_event_lr }, /* Event 1 */
+ { eigrp_fsm_event_keep_state }, /* Event 2 */
+ { eigrp_fsm_event_keep_state }, /* Event 3 */
+ { eigrp_fsm_event_dinc }, /* Event 4 */
+ { eigrp_fsm_event_keep_state }, /* Event 5 */
+ { eigrp_fsm_event_keep_state }, /* Event 6 */
+ { eigrp_fsm_event_keep_state }, /* Event 7 */
+}, };
+
+/*
+ * Main function in which are make decisions which event occurred.
+ * msg - argument of type struct eigrp_fsm_action_message contain
+ * details about what happen
+ *
+ * Return number of occurred event (arrow in diagram).
+ *
+ */
+int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
+{
+ // Loading base information from message
+ //struct eigrp *eigrp = msg->eigrp;
+ struct eigrp_prefix_entry *prefix = msg->prefix;
+ struct eigrp_neighbor_entry *entry = msg->entry;
+ u_char actual_state = prefix->state;
+
+ if (entry == NULL)
+ {
+ entry = eigrp_neighbor_entry_new();
+ entry->adv_router = msg->adv_router;
+ entry->ei = msg->adv_router->ei;
+ entry->prefix = prefix;
+ msg->entry = entry;
+ }
+
+ // Dividing by actual state of prefix's FSM
+ switch (actual_state)
+ {
+ case EIGRP_FSM_STATE_PASSIVE:
+ {
+ //Calculate resultant metrics and insert to correct position in entries list
+ eigrp_topology_update_distance(msg);
+
+ struct eigrp_neighbor_entry * head =
+ (struct eigrp_neighbor_entry *) entry->prefix->entries->head->data;
+ //zlog_info ("flag: %d rdist: %u dist: %u pfdist: %u pdist: %u", head->flags, head->reported_distance, head->distance, prefix->fdistance, prefix->distance);
+ if (head->reported_distance < prefix->fdistance)
+ {
+ return EIGRP_FSM_KEEP_STATE;
+ }
+ /*
+ * if best entry doesn't satisfy feasibility condition it means move to active state
+ * dependently if it was query from successor
+ */
+ else
+ {
+ if (msg->packet_type == EIGRP_OPC_QUERY)
+ {
+ return EIGRP_FSM_EVENT_Q_FCN;
+ }
+ else
+ {
+ return EIGRP_FSM_EVENT_NQ_FCN;
+ }
+ }
+
+ break;
+ }
+ case EIGRP_FSM_STATE_ACTIVE_0:
+ {
+ eigrp_topology_update_distance(msg);
+
+ if (msg->packet_type == EIGRP_OPC_REPLY) {
+ listnode_delete(prefix->rij, entry->adv_router);
+ if (prefix->rij->count)
+ {
+ return EIGRP_FSM_KEEP_STATE;
+ }
+ else
+ {
+ zlog_info("All reply received\n");
+ if (((struct eigrp_neighbor_entry *) prefix->entries->head->data)->reported_distance
+ < prefix->fdistance)
+ {
+ return EIGRP_FSM_EVENT_LR_FCS;
+ }
+
+ return EIGRP_FSM_EVENT_LR_FCN;
+ }
+ }
+ else if (msg->packet_type == EIGRP_OPC_QUERY
+ && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG))
+ {
+ return EIGRP_FSM_EVENT_QACT;
+ }
+
+ return EIGRP_FSM_KEEP_STATE;
+
+ break;
+ }
+ case EIGRP_FSM_STATE_ACTIVE_1:
+ {
+ int change = eigrp_topology_update_distance(msg);
+
+ if (msg->packet_type == EIGRP_OPC_QUERY
+ && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG))
+ {
+ return EIGRP_FSM_EVENT_QACT;
+ }
+ else if (msg->packet_type == EIGRP_OPC_REPLY)
+ {
+ listnode_delete(prefix->rij, entry->adv_router);
+
+ if (change == 1
+ && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG))
+ {
+ return EIGRP_FSM_EVENT_DINC;
+ }
+ else if (prefix->rij->count)
+ {
+ return EIGRP_FSM_KEEP_STATE;
+ }
+ else
+ {
+ zlog_info("All reply received\n");
+ return EIGRP_FSM_EVENT_LR;
+ }
+ }
+ else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1
+ && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG))
+ {
+ return EIGRP_FSM_EVENT_DINC;
+ }
+ return EIGRP_FSM_KEEP_STATE;
+
+ break;
+ }
+ case EIGRP_FSM_STATE_ACTIVE_2:
+ {
+ eigrp_topology_update_distance(msg);
+
+ if (msg->packet_type == EIGRP_OPC_REPLY)
+ {
+ listnode_delete(prefix->rij, entry->adv_router);
+ if (prefix->rij->count)
+ {
+ return EIGRP_FSM_KEEP_STATE;
+ }
+ else
+ {
+ zlog_info("All reply received\n");
+ if (((struct eigrp_neighbor_entry *) prefix->entries->head->data)->reported_distance
+ < prefix->fdistance)
+ {
+ return EIGRP_FSM_EVENT_LR_FCS;
+ }
+
+ return EIGRP_FSM_EVENT_LR_FCN;
+ }
+ }
+ return EIGRP_FSM_KEEP_STATE;
+
+ break;
+ }
+ case EIGRP_FSM_STATE_ACTIVE_3:
+ {
+ int change = eigrp_topology_update_distance(msg);
+
+ if (msg->packet_type == EIGRP_OPC_REPLY)
+ {
+ listnode_delete(prefix->rij, entry->adv_router);
+
+ if (change == 1
+ && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG))
+ {
+ return EIGRP_FSM_EVENT_DINC;
+ }
+ else if (prefix->rij->count)
+ {
+ return EIGRP_FSM_KEEP_STATE;
+ }
+ else
+ {
+ zlog_info("All reply received\n");
+ return EIGRP_FSM_EVENT_LR;
+ }
+ }
+ else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1
+ && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG))
+ {
+ return EIGRP_FSM_EVENT_DINC;
+ }
+ return EIGRP_FSM_KEEP_STATE;
+
+ break;
+ }
+ }
+
+ return EIGRP_FSM_KEEP_STATE;
+}
+
+/*
+ * Function made to execute in separate thread.
+ * Load argument from thread and execute proper NSM function
+ */
+int eigrp_fsm_event(struct eigrp_fsm_action_message *msg, int event)
+{
+ zlog_info("EIGRP AS: %d State: %d Event: %d Network: %s\n", msg->eigrp->AS,
+ msg->prefix->state, event, eigrp_topology_ip_string(msg->prefix));
+ (*(NSM[msg->prefix->state][event].func))(msg);
+
+ return 1;
+}
+
+/*
+ * Function of event 0.
+ *
+ */
+int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg)
+{
+ struct eigrp *eigrp = msg->eigrp;
+ struct eigrp_prefix_entry *prefix = msg->prefix;
+ struct list *successors = eigrp_topology_get_successor(prefix);
+
+ assert(successors); // If this is NULL we have shit the bed, fun huh?
+
+ prefix->state = EIGRP_FSM_STATE_ACTIVE_1;
+ prefix->rdistance = prefix->distance = prefix->fdistance =
+ ((struct eigrp_neighbor_entry *) successors->head->data)->distance;
+ prefix->reported_metric =
+ ((struct eigrp_neighbor_entry *) successors->head->data)->total_metric;
+
+ if (eigrp_nbr_count_get())
+ {
+ prefix->req_action |= EIGRP_FSM_NEED_QUERY;
+ listnode_add(eigrp->topology_changes_internalIPV4,prefix);
+ }
+ else
+ {
+ eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left
+ }
+
+ list_delete(successors);
+
+ return 1;
+}
+
+int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
+{
+ struct eigrp *eigrp = msg->eigrp;
+ struct eigrp_prefix_entry *prefix = msg->prefix;
+ struct list *successors = eigrp_topology_get_successor(prefix);
+
+ assert(successors); // If this is NULL somebody poked us in the eye.
+
+ prefix->state = EIGRP_FSM_STATE_ACTIVE_3;
+ prefix->rdistance = prefix->distance = prefix->fdistance =
+ ((struct eigrp_neighbor_entry *) successors->head->data)->distance;
+ prefix->reported_metric =
+ ((struct eigrp_neighbor_entry *) successors->head->data)->total_metric;
+ if (eigrp_nbr_count_get())
+ {
+ prefix->req_action |= EIGRP_FSM_NEED_QUERY;
+ listnode_add(eigrp->topology_changes_internalIPV4,prefix);
+ }
+ else
+ {
+ eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left
+ }
+
+ list_delete(successors);
+
+ return 1;
+}
+
+int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg)
+{
+ struct eigrp_prefix_entry *prefix = msg->prefix;
+
+ if (prefix->state == EIGRP_FSM_STATE_PASSIVE)
+ {
+ if (!eigrp_metrics_is_same(&prefix->reported_metric,
+ &((struct eigrp_neighbor_entry *) prefix->entries->head->data)->total_metric))
+ {
+ prefix->rdistance =
+ prefix->fdistance =
+ prefix->distance =
+ ((struct eigrp_neighbor_entry *) prefix->entries->head->data)->distance;
+ prefix->reported_metric =
+ ((struct eigrp_neighbor_entry *) prefix->entries->head->data)->total_metric;
+ if (msg->packet_type == EIGRP_OPC_QUERY)
+ eigrp_send_reply(msg->adv_router, prefix);
+ prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
+ listnode_add((eigrp_lookup())->topology_changes_internalIPV4,prefix);
+ }
+ eigrp_topology_update_node_flags(prefix);
+ eigrp_update_routing_table(prefix);
+ }
+
+ if (msg->packet_type == EIGRP_OPC_QUERY)
+ eigrp_send_reply(msg->adv_router, prefix);
+
+ return 1;
+}
+
+int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg)
+{
+ struct eigrp *eigrp = msg->eigrp;
+ struct eigrp_prefix_entry *prefix = msg->prefix;
+ prefix->fdistance =
+ prefix->distance =
+ prefix->rdistance =
+ ((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->distance;
+ prefix->reported_metric =
+ ((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->total_metric;
+
+ if (prefix->state == EIGRP_FSM_STATE_ACTIVE_3)
+ {
+ struct list *successors = eigrp_topology_get_successor(prefix);
+
+ assert(successors); // It's like Napolean and Waterloo
+
+ eigrp_send_reply(((struct eigrp_neighbor_entry *)successors->head->data)->adv_router, prefix);
+ list_delete(successors);
+ }
+
+ prefix->state = EIGRP_FSM_STATE_PASSIVE;
+ prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
+ listnode_add(eigrp->topology_changes_internalIPV4,prefix);
+ eigrp_topology_update_node_flags(prefix);
+ eigrp_update_routing_table(prefix);
+ eigrp_update_topology_table_prefix(eigrp->topology_table, prefix);
+
+ return 1;
+}
+
+int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg)
+{
+ struct list *successors = eigrp_topology_get_successor(msg->prefix);
+
+ assert(successors); // Trump and his big hands
+
+ msg->prefix->state =
+ msg->prefix->state == EIGRP_FSM_STATE_ACTIVE_1 ?
+ EIGRP_FSM_STATE_ACTIVE_0 : EIGRP_FSM_STATE_ACTIVE_2;
+ msg->prefix->distance =
+ ((struct eigrp_neighbor_entry *)successors->head->data)->distance;
+ if (!msg->prefix->rij->count)
+ (*(NSM[msg->prefix->state][eigrp_get_fsm_event(msg)].func))(msg);
+
+
+ list_delete(successors);
+ return 1;
+}
+
+int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg)
+{
+ struct eigrp *eigrp = msg->eigrp;
+ struct eigrp_prefix_entry *prefix = msg->prefix;
+ prefix->state = EIGRP_FSM_STATE_PASSIVE;
+ prefix->distance =
+ prefix->rdistance =
+ ((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->distance;
+ prefix->reported_metric =
+ ((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->total_metric;
+ prefix->fdistance =
+ prefix->fdistance > prefix->distance ?
+ prefix->distance : prefix->fdistance;
+ if (prefix->state == EIGRP_FSM_STATE_ACTIVE_2)
+ {
+ struct list *successors = eigrp_topology_get_successor(prefix);
+
+ assert(successors); // Having a spoon and all you need is a knife
+
+ eigrp_send_reply(((struct eigrp_neighbor_entry *)successors->head->data)->adv_router, prefix);
+
+ list_delete(successors);
+ }
+ prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
+ listnode_add(eigrp->topology_changes_internalIPV4,prefix);
+ eigrp_topology_update_node_flags(prefix);
+ eigrp_update_routing_table(prefix);
+ eigrp_update_topology_table_prefix(eigrp->topology_table, prefix);
+
+ return 1;
+}
+
+int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg)
+{
+ struct eigrp *eigrp = msg->eigrp;
+ struct eigrp_prefix_entry *prefix = msg->prefix;
+ struct list *successors = eigrp_topology_get_successor(prefix);
+
+ assert(successors); // Routing without a stack
+
+ prefix->state =
+ prefix->state == EIGRP_FSM_STATE_ACTIVE_0 ?
+ EIGRP_FSM_STATE_ACTIVE_1 : EIGRP_FSM_STATE_ACTIVE_3;
+ struct eigrp_neighbor_entry *best_successor =
+ ((struct eigrp_neighbor_entry *) (successors->head->data));
+ prefix->rdistance = prefix->distance = best_successor->distance;
+ prefix->reported_metric = best_successor->total_metric;
+
+ if (eigrp_nbr_count_get())
+ {
+ prefix->req_action |= EIGRP_FSM_NEED_QUERY;
+ listnode_add(eigrp->topology_changes_internalIPV4,prefix);
+ }
+ else
+ {
+ eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left
+ }
+
+ list_delete(successors);
+
+ return 1;
+}
+
+int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg)
+{
+ struct list *successors = eigrp_topology_get_successor(msg->prefix);
+
+ assert(successors); // Cats and no Dogs
+
+ msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2;
+ msg->prefix->distance =
+ ((struct eigrp_neighbor_entry *) (successors->head->data))->distance;
+
+ list_delete(successors);
+ return 1;
+}
diff --git a/eigrpd/eigrp_fsm.h b/eigrpd/eigrp_fsm.h
new file mode 100644
index 0000000000..4ba0d88739
--- /dev/null
+++ b/eigrpd/eigrp_fsm.h
@@ -0,0 +1,36 @@
+/*
+ * EIGRP Finite State Machine (DUAL).
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 _ZEBRA_EIGRP_FSM_H
+#define _ZEBRA_EIGRP_FSM_H
+
+
+extern int eigrp_get_fsm_event (struct eigrp_fsm_action_message *);
+extern int eigrp_fsm_event (struct eigrp_fsm_action_message *, int);
+
+
+#endif /* _ZEBRA_EIGRP_DUAL_H */
diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c
new file mode 100644
index 0000000000..0b370219b8
--- /dev/null
+++ b/eigrpd/eigrp_hello.c
@@ -0,0 +1,780 @@
+/*
+ * EIGRP Sending and Receiving EIGRP Hello Packets.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "sockunion.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "checksum.h"
+#include "vty.h"
+#include "md5.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_macros.h"
+
+/* Packet Type String. */
+static const struct message eigrp_general_tlv_type_str[] =
+{
+ { EIGRP_TLV_PARAMETER, "PARAMETER" },
+ { EIGRP_TLV_AUTH, "AUTH" },
+ { EIGRP_TLV_SEQ, "SEQ" },
+ { EIGRP_TLV_SW_VERSION, "SW_VERSION" },
+ { EIGRP_TLV_NEXT_MCAST_SEQ, "NEXT_MCAST_SEQ" },
+ { EIGRP_TLV_PEER_TERMINATION, "PEER_TERMINATION" },
+ { EIGRP_TLV_PEER_MTRLIST, "PEER_MTRLIST" },
+ { EIGRP_TLV_PEER_TIDLIST, "PEER_TIDLIST" },
+};
+
+static const size_t eigrp_general_tlv_type_str_max = sizeof(eigrp_general_tlv_type_str) /
+ sizeof(eigrp_general_tlv_type_str[0]);
+
+
+/*
+ * @fn eigrp_hello_timer
+ *
+ * @param[in] thread current execution thread timer is associated with
+ *
+ * @return int always returns 0
+ *
+ * @par
+ * Called once per "hello" time interval, default 5 seconds
+ * Sends hello packet via multicast for all interfaces eigrp
+ * is configured for
+ */
+int
+eigrp_hello_timer (struct thread *thread)
+{
+ struct eigrp_interface *ei;
+
+ ei = THREAD_ARG(thread);
+ ei->t_hello = NULL;
+
+ if (IS_DEBUG_EIGRP(0, TIMERS))
+ zlog_debug ("Start Hello Timer (%s) Expire [%u]",
+ IF_NAME(ei), EIGRP_IF_PARAM(ei, v_hello));
+
+ /* Sending hello packet. */
+ eigrp_hello_send(ei, EIGRP_HELLO_NORMAL, NULL);
+
+ /* Hello timer set. */
+ ei->t_hello = NULL;
+ thread_add_timer(master, eigrp_hello_timer, ei, EIGRP_IF_PARAM(ei, v_hello),
+ &ei->t_hello);
+
+ return 0;
+}
+
+/**
+ * @fn eigrp_hello_parameter_decode
+ *
+ * @param[in] nbr neighbor the ACK should be sent to
+ * @param[in] param pointer packet TLV is stored to
+ *
+ * @return u_int16_t number of bytes added to packet stream
+ *
+ * @par
+ * Encode Parameter TLV, used to convey metric weights and the hold time.
+ *
+ * @usage
+ * Note the addition of K6 for the new extended metrics, and does not apply to
+ * older TLV packet formats.
+ */
+static void
+eigrp_hello_parameter_decode (struct eigrp_neighbor *nbr,
+ struct eigrp_tlv_hdr_type *tlv)
+{
+ struct eigrp *eigrp = nbr->ei->eigrp;
+ struct TLV_Parameter_Type *param = (struct TLV_Parameter_Type *)tlv;
+
+ /* copy over the values passed in by the neighbor */
+ nbr->K1 = param->K1;
+ nbr->K2 = param->K2;
+ nbr->K3 = param->K3;
+ nbr->K4 = param->K4;
+ nbr->K5 = param->K5;
+ nbr->K6 = param->K6;
+ nbr->v_holddown = ntohs(param->hold_time);
+
+ /*
+ * Check K1-K5 have the correct values to be able to become neighbors
+ * K6 does not have to match
+ */
+ if ((eigrp->k_values[0] == nbr->K1) &&
+ (eigrp->k_values[1] == nbr->K2) &&
+ (eigrp->k_values[2] == nbr->K3) &&
+ (eigrp->k_values[3] == nbr->K4) &&
+ (eigrp->k_values[4] == nbr->K5))
+ {
+
+ if (eigrp_nbr_state_get(nbr) == EIGRP_NEIGHBOR_DOWN)
+ {
+ zlog_info("Neighbor %s (%s) is pending: new adjacency",
+ inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+
+ /* Expedited hello sent */
+ eigrp_hello_send(nbr->ei, EIGRP_HELLO_NORMAL, NULL);
+
+ // if(ntohl(nbr->ei->address->u.prefix4.s_addr) > ntohl(nbr->src.s_addr))
+ eigrp_update_send_init(nbr);
+
+ eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING);
+ }
+ }
+ else
+ {
+ if (eigrp_nbr_state_get(nbr) != EIGRP_NEIGHBOR_DOWN)
+ {
+ if ((param->K1 & param->K2 & param->K3 & param->K4 & param->K5) == 255)
+ {
+ zlog_info ("Neighbor %s (%s) is down: Interface PEER-TERMINATION received",
+ inet_ntoa (nbr->src),ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ eigrp_nbr_delete (nbr);
+ }
+ else
+ {
+ zlog_info ("Neighbor %s (%s) going down: Kvalue mismatch",
+ inet_ntoa (nbr->src),ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN);
+ }
+ }
+ }
+}
+
+static u_char
+eigrp_hello_authentication_decode(struct stream *s, struct eigrp_tlv_hdr_type *tlv_header,
+ struct eigrp_neighbor *nbr)
+{
+ struct TLV_MD5_Authentication_Type *md5;
+
+ md5 = (struct TLV_MD5_Authentication_Type *) tlv_header;
+
+ if(md5->auth_type == EIGRP_AUTH_TYPE_MD5)
+ return eigrp_check_md5_digest(s, md5, nbr, EIGRP_AUTH_BASIC_HELLO_FLAG);
+ else if (md5->auth_type == EIGRP_AUTH_TYPE_SHA256)
+ return eigrp_check_sha256_digest(s, (struct TLV_SHA256_Authentication_Type *)tlv_header,
+ nbr, EIGRP_AUTH_BASIC_HELLO_FLAG);
+
+ return 0;
+}
+
+/**
+ * @fn eigrp_sw_version_decode
+ *
+ * @param[in] nbr neighbor the ACK shoudl be sent to
+ * @param[in] param pointer to TLV software version information
+ *
+ * @return void
+ *
+ * @par
+ * Read the software version in the specified location.
+ * This consists of two bytes of OS version, and two bytes of EIGRP
+ * revision number.
+ */
+static void
+eigrp_sw_version_decode (struct eigrp_neighbor *nbr,
+ struct eigrp_tlv_hdr_type *tlv)
+{
+ struct TLV_Software_Type *version = (struct TLV_Software_Type *)tlv;
+
+ nbr->os_rel_major = version->vender_major;
+ nbr->os_rel_minor = version->vender_minor;
+ nbr->tlv_rel_major = version->eigrp_major;
+ nbr->tlv_rel_minor = version->eigrp_minor;
+ return;
+}
+
+/**
+ * @fn eigrp_peer_termination_decode
+ *
+ * @param[in] nbr neighbor the ACK shoudl be sent to
+ * @param[in] tlv pointer to TLV software version information
+ *
+ * @return void
+ *
+ * @par
+ * Read the address in the TLV and match to out address. If
+ * a match is found, move the sending neighbor to the down state. If
+ * out address is not in the TLV, then ignore the peer termination
+ */
+static void
+eigrp_peer_termination_decode (struct eigrp_neighbor *nbr,
+ struct eigrp_tlv_hdr_type *tlv)
+{
+ struct TLV_Peer_Termination_type *param = (struct TLV_Peer_Termination_type *)tlv;
+
+ uint32_t my_ip = nbr->ei->address->u.prefix4.s_addr;
+ uint32_t received_ip = param->neighbor_ip;
+
+ if(my_ip == received_ip)
+ {
+ zlog_info ("Neighbor %s (%s) is down: Peer Termination received",
+ inet_ntoa (nbr->src),
+ ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ /* set neighbor to DOWN */
+ nbr->state = EIGRP_NEIGHBOR_DOWN;
+ /* delete neighbor */
+ eigrp_nbr_delete (nbr);
+ }
+}
+
+/**
+ * @fn eigrp_peer_termination_encode
+ *
+ * @param[in,out] s packet stream TLV is stored to
+ * @param[in] nbr_addr pointer to neighbor address for Peer Termination TLV
+ *
+ * @return u_int16_t number of bytes added to packet stream
+ *
+ * @par
+ * Function used to encode Peer Termination TLV to Hello packet.
+ */
+static u_int16_t
+eigrp_peer_termination_encode (struct stream *s, struct in_addr *nbr_addr)
+{
+ u_int16_t length = EIGRP_TLV_PEER_TERMINATION_LEN;
+
+ /* fill in type and length */
+ stream_putw(s, EIGRP_TLV_PEER_TERMINATION);
+ stream_putw(s, length);
+
+ /* fill in unknown field 0x04 */
+ stream_putc(s, 0x04);
+
+ /* finally neighbor IP address */
+ stream_put_ipv4(s, nbr_addr->s_addr);
+
+ return(length);
+}
+
+/*
+ * @fn eigrp_hello_receive
+ *
+ * @param[in] eigrp eigrp routing process
+ * @param[in] iph pointer to ip header
+ * @param[in] eigrph pointer to eigrp header
+ * @param[in] s input ip stream
+ * @param[in] ei eigrp interface packet arrived on
+ * @param[in] size size of eigrp packet
+ *
+ * @return void
+ *
+ * @par
+ * This is the main worker function for processing hello packets. It
+ * will validate the peer associated with the src ip address of the ip
+ * header, and then decode each of the general TLVs which the packet
+ * may contain.
+ *
+ * @usage
+ * Not all TLVs are current decoder. This is a work in progress..
+ */
+void
+eigrp_hello_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
+ struct stream *s, struct eigrp_interface *ei, int size)
+{
+ struct eigrp_tlv_hdr_type *tlv_header;
+ struct eigrp_neighbor *nbr;
+ uint16_t type;
+ uint16_t length;
+
+ /* get neighbor struct */
+ nbr = eigrp_nbr_get(ei, eigrph, iph);
+
+ /* neighbor must be valid, eigrp_nbr_get creates if none existed */
+ assert(nbr);
+
+ if (IS_DEBUG_EIGRP_PACKET(eigrph->opcode - 1, RECV))
+ zlog_debug("Processing Hello size[%u] int(%s) nbr(%s)",
+ size, ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT),
+ inet_ntoa(nbr->src));
+
+ size -= EIGRP_HEADER_LEN;
+ if (size < 0)
+ return;
+
+ tlv_header = (struct eigrp_tlv_hdr_type *)eigrph->tlv;
+
+ do {
+ type = ntohs(tlv_header->type);
+ length = ntohs(tlv_header->length);
+
+ if ((length > 0) && (length <= size))
+ {
+ if (IS_DEBUG_EIGRP_PACKET(0, RECV))
+ zlog_debug(" General TLV(%s)", LOOKUP(eigrp_general_tlv_type_str, type));
+
+ // determine what General TLV is being processed
+ switch (type)
+ {
+ case EIGRP_TLV_PARAMETER:
+ eigrp_hello_parameter_decode(nbr, tlv_header);
+ break;
+ case EIGRP_TLV_AUTH:
+ {
+ if(eigrp_hello_authentication_decode(s,tlv_header,nbr) == 0)
+ return;
+ else
+ break;
+ break;
+ }
+ case EIGRP_TLV_SEQ:
+ break;
+ case EIGRP_TLV_SW_VERSION:
+ eigrp_sw_version_decode(nbr, tlv_header);
+ break;
+ case EIGRP_TLV_NEXT_MCAST_SEQ:
+ break;
+ case EIGRP_TLV_PEER_TERMINATION:
+ eigrp_peer_termination_decode(nbr, tlv_header);
+ return;
+ break;
+ case EIGRP_TLV_PEER_MTRLIST:
+ case EIGRP_TLV_PEER_TIDLIST:
+ break;
+ default:
+ break;
+ }
+ }
+
+ tlv_header = (struct eigrp_tlv_hdr_type *)(((char *)tlv_header) + length);
+ size -= length;
+
+ } while (size > 0);
+
+
+ /*If received packet is hello with Parameter TLV*/
+ if (ntohl(eigrph->ack) == 0)
+ {
+ /* increment statistics. */
+ ei->hello_in++;
+ if (nbr)
+ eigrp_nbr_state_update(nbr);
+
+ }
+
+ if (IS_DEBUG_EIGRP_PACKET(0, RECV))
+ zlog_debug("Hello Packet received from %s", inet_ntoa(nbr->src));
+}
+
+/**
+ * @fn eigrp_sw_version_encode
+ *
+ * @param[in,out] s packet stream TLV is stored to
+ *
+ * @return u_int16_t number of bytes added to packet stream
+ *
+ * @par
+ * Store the software version in the specified location.
+ * This consists of two bytes of OS version, and two bytes of EIGRP
+ * revision number.
+ */
+static u_int16_t
+eigrp_sw_version_encode (struct stream *s)
+{
+ u_int16_t length = EIGRP_TLV_SW_VERSION_LEN;
+
+ // setup the tlv fields
+ stream_putw(s, EIGRP_TLV_SW_VERSION);
+ stream_putw(s, length);
+
+ // encode the version of quagga we're running
+ // DVS: need to figure out a cleaner way to do this
+ stream_putc(s, 0); //!< major os version
+ stream_putc(s, 99); //!< minor os version
+
+ /* and the core eigrp version */
+ stream_putc(s, EIGRP_MAJOR_VERSION);
+ stream_putc(s, EIGRP_MINOR_VERSION);
+
+ return(length);
+}
+
+/**
+ * @fn eigrp_tidlist_encode
+ *
+ * @param[in,out] s packet stream TLV is stored to
+ *
+ * @return void
+ *
+ * @par
+ * If doing mutli-topology, then store the supported TID list.
+ * This is currently a place holder function
+ */
+static u_int16_t
+eigrp_tidlist_encode (struct stream *s)
+{
+ //u_int16_t length = EIGRP_TLV_SW_VERSION_LEN;
+ return 0;
+}
+
+/**
+ * @fn eigrp_sequence_encode
+ *
+ * @param[in,out] s packet stream TLV is stored to
+ *
+ * @return u_int16_t number of bytes added to packet stream
+ *
+ * @par
+ * Part of conditional receive process
+ *
+ */
+static u_int16_t
+eigrp_sequence_encode (struct stream *s)
+{
+ u_int16_t length = EIGRP_TLV_SEQ_BASE_LEN;
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct listnode *node, *node2, *nnode2;
+ struct eigrp_neighbor *nbr;
+ size_t backup_end, size_end;
+ int found;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ return 0;
+ }
+
+ // add in the parameters TLV
+ backup_end = stream_get_endp(s);
+ stream_putw(s, EIGRP_TLV_SEQ);
+ size_end = s->endp;
+ stream_putw(s, 0x0000);
+ stream_putc(s, IPV4_MAX_BYTELEN);
+
+ found = 0;
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
+ {
+ if(nbr->multicast_queue->count > 0)
+ {
+ length += (u_int16_t) stream_put_ipv4(s,nbr->src.s_addr);
+ found = 1;
+ }
+ }
+ }
+
+ if(found == 0)
+ {
+ stream_set_endp(s,backup_end);
+ return 0;
+ }
+
+ backup_end = stream_get_endp (s);
+ stream_set_endp (s,size_end);
+ stream_putw (s, length);
+ stream_set_endp (s, backup_end);
+
+ return length;
+}
+
+/**
+ * @fn eigrp_sequence_encode
+ *
+ * @param[in,out] s packet stream TLV is stored to
+ *
+ * @return u_int16_t number of bytes added to packet stream
+ *
+ * @par
+ * Part of conditional receive process
+ *
+ */
+static u_int16_t
+eigrp_next_sequence_encode (struct stream *s)
+{
+ u_int16_t length = EIGRP_NEXT_SEQUENCE_TLV_SIZE;
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ return 0;
+ }
+
+ // add in the parameters TLV
+ stream_putw(s, EIGRP_TLV_NEXT_MCAST_SEQ);
+ stream_putw(s, EIGRP_NEXT_SEQUENCE_TLV_SIZE);
+ stream_putl(s,eigrp->sequence_number+1);
+
+ return length;
+}
+
+/**
+ * @fn eigrp_hello_parameter_encode
+ *
+ * @param[in] ei pointer to interface hello packet came in on
+ * @param[in,out] s packet stream TLV is stored to
+ *
+ * @return u_int16_t number of bytes added to packet stream
+ *
+ * @par
+ * Encode Parameter TLV, used to convey metric weights and the hold time.
+ *
+ * @usage
+ * Note the addition of K6 for the new extended metrics, and does not apply to
+ * older TLV packet formats.
+ */
+static u_int16_t
+eigrp_hello_parameter_encode (struct eigrp_interface *ei, struct stream *s, u_char flags)
+{
+ u_int16_t length = EIGRP_TLV_PARAMETER_LEN;
+
+ // add in the parameters TLV
+ stream_putw(s, EIGRP_TLV_PARAMETER);
+ stream_putw(s, EIGRP_TLV_PARAMETER_LEN);
+
+ //if graceful shutdown is needed to be announced, send all 255 in K values
+ if(flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN)
+ {
+ stream_putc(s, 0xff); /* K1 */
+ stream_putc(s, 0xff); /* K2 */
+ stream_putc(s, 0xff); /* K3 */
+ stream_putc(s, 0xff); /* K4 */
+ stream_putc(s, 0xff); /* K5 */
+ stream_putc(s, 0xff); /* K6 */
+ }
+ else // set k values
+ {
+ stream_putc(s, ei->eigrp->k_values[0]); /* K1 */
+ stream_putc(s, ei->eigrp->k_values[1]); /* K2 */
+ stream_putc(s, ei->eigrp->k_values[2]); /* K3 */
+ stream_putc(s, ei->eigrp->k_values[3]); /* K4 */
+ stream_putc(s, ei->eigrp->k_values[4]); /* K5 */
+ stream_putc(s, ei->eigrp->k_values[5]); /* K6 */
+ }
+
+ // and set hold time value..
+ stream_putw(s, IF_DEF_PARAMS(ei->ifp)->v_wait);
+
+ return length;
+}
+
+/**
+ * @fn eigrp_hello_encode
+ *
+ * @param[in] ei pointer to interface hello packet came in on
+ * @param[in] s packet stream TLV is stored to
+ * @param[in] ack if non-zero, neigbors sequence packet to ack
+ * @param[in] flags type of hello packet
+ * @param[in] nbr_addr pointer to neighbor address for Peer Termination TLV
+ *
+ * @return eigrp_packet pointer initialize hello packet
+ *
+ * @par
+ * Allocate an EIGRP hello packet, and add in the the approperate TLVs
+ *
+ */
+static struct eigrp_packet *
+eigrp_hello_encode (struct eigrp_interface *ei, in_addr_t addr, u_int32_t ack,
+ u_char flags, struct in_addr *nbr_addr)
+{
+ struct eigrp_packet *ep;
+ u_int16_t length = EIGRP_HEADER_LEN;
+
+ // allocate a new packet to be sent
+ ep = eigrp_packet_new(ei->ifp->mtu);
+
+ if (ep)
+ {
+ // encode common header feilds
+ eigrp_packet_header_init(EIGRP_OPC_HELLO, ei, ep->s, 0, 0, ack);
+
+ // encode Authentication TLV
+ if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei);
+ }
+ else if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_SHA256) &&
+ (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_SHA256_to_stream(ep->s,ei);
+ }
+
+ /* encode appropriate parameters to Hello packet */
+ if(flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN)
+ length += eigrp_hello_parameter_encode(ei, ep->s, EIGRP_HELLO_GRACEFUL_SHUTDOWN);
+ else
+ length += eigrp_hello_parameter_encode(ei, ep->s, EIGRP_HELLO_NORMAL);
+
+ // figure out the version of code we're running
+ length += eigrp_sw_version_encode(ep->s);
+
+ if(flags & EIGRP_HELLO_ADD_SEQUENCE)
+ {
+ length += eigrp_sequence_encode(ep->s);
+ length += eigrp_next_sequence_encode(ep->s);
+ }
+
+ // add in the TID list if doing multi-topology
+ length += eigrp_tidlist_encode(ep->s);
+
+ /* encode Peer Termination TLV if needed */
+ if(flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN_NBR)
+ length += eigrp_peer_termination_encode(ep->s, nbr_addr);
+
+ // Set packet length
+ ep->length = length;
+
+ // set soruce address for the hello packet
+ ep->dst.s_addr = addr;
+
+ if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL))
+ {
+ eigrp_make_md5_digest(ei,ep->s, EIGRP_AUTH_BASIC_HELLO_FLAG);
+ }
+ else if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_SHA256) &&
+ (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL))
+ {
+ eigrp_make_sha256_digest(ei,ep->s, EIGRP_AUTH_BASIC_HELLO_FLAG);
+ }
+
+ // EIGRP Checksum
+ eigrp_packet_checksum(ei, ep->s, length);
+ }
+
+ return(ep);
+}
+
+/**
+ * @fn eigrp_hello_send
+ *
+ * @param[in] nbr neighbor the ACK should be sent to
+ *
+ * @return void
+ *
+ * @par
+ * Send (unicast) a hello packet with the destination address
+ * associated with the neighbor. The eigrp header ACK feild will be
+ * updated to the neighbor's sequence number to acknolodge any
+ * outstanding packets
+ */
+void
+eigrp_hello_send_ack (struct eigrp_neighbor *nbr)
+{
+ struct eigrp_packet *ep;
+
+ /* if packet succesfully created, add it to the interface queue */
+ ep = eigrp_hello_encode(nbr->ei, nbr->src.s_addr, nbr->recv_sequence_number, EIGRP_HELLO_NORMAL, NULL);
+
+ if (ep)
+ {
+ if (IS_DEBUG_EIGRP_PACKET(0, SEND))
+ zlog_debug("Queueing [Hello] Ack Seq [%u] nbr [%s]",
+ nbr->recv_sequence_number, inet_ntoa(nbr->src));
+
+ /* Add packet to the top of the interface output queue*/
+ eigrp_fifo_push_head(nbr->ei->obuf, ep);
+
+ /* Hook thread to write packet. */
+ if (nbr->ei->on_write_q == 0)
+ {
+ listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei);
+ nbr->ei->on_write_q = 1;
+ }
+ thread_add_write(master, eigrp_write, nbr->ei->eigrp, nbr->ei->eigrp->fd,
+ &nbr->ei->eigrp->t_write);
+ }
+}
+
+/**
+ * @fn eigrp_hello_send
+ *
+ * @param[in] ei pointer to interface hello should be sent
+ * @param[in] flags type of hello packet
+ * @param[in] nbr_addr pointer to neighbor address for Peer Termination TLV
+ *
+ * @return void
+ *
+ * @par
+ * Build and enqueue a generic (multicast) periodic hello packet for
+ * sending. If no packets are currently queues, the packet will be
+ * sent immadiatly
+ */
+void
+eigrp_hello_send (struct eigrp_interface *ei, u_char flags, struct in_addr *nbr_addr)
+{
+ struct eigrp_packet *ep = NULL;
+
+ /* If this is passive interface, do not send EIGRP Hello.
+ if ((EIGRP_IF_PASSIVE_STATUS (ei) == EIGRP_IF_PASSIVE) ||
+ (ei->type != EIGRP_IFTYPE_NBMA))
+ return;
+ */
+
+ if (IS_DEBUG_EIGRP_PACKET(0, SEND))
+ zlog_debug("Queueing [Hello] Interface(%s)", IF_NAME(ei));
+
+ /* if packet was succesfully created, then add it to the interface queue */
+ ep = eigrp_hello_encode(ei, htonl(EIGRP_MULTICAST_ADDRESS), 0, flags, nbr_addr);
+
+ if (ep)
+ {
+ // Add packet to the top of the interface output queue
+ eigrp_fifo_push_head(ei->obuf, ep);
+
+ /* Hook thread to write packet. */
+ if (ei->on_write_q == 0)
+ {
+ listnode_add(ei->eigrp->oi_write_q, ei);
+ ei->on_write_q = 1;
+ }
+
+ if (ei->eigrp->t_write == NULL)
+ {
+ if(flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN)
+ {
+ thread_execute(master, eigrp_write, ei->eigrp, ei->eigrp->fd);
+ }
+ else
+ {
+ thread_add_write(master, eigrp_write, ei->eigrp, ei->eigrp->fd,
+ &ei->eigrp->t_write);
+ }
+ }
+ }
+}
diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c
new file mode 100644
index 0000000000..7e38a8da59
--- /dev/null
+++ b/eigrpd/eigrp_interface.c
@@ -0,0 +1,622 @@
+/*
+ * EIGRP Interface Functions.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 "thread.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "memory.h"
+#include "command.h"
+#include "stream.h"
+#include "log.h"
+#include "keychain.h"
+#include "vrf.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_memory.h"
+
+static void
+eigrp_delete_from_if (struct interface *, struct eigrp_interface *);
+
+static void
+eigrp_add_to_if (struct interface *ifp, struct eigrp_interface *ei)
+{
+ struct route_node *rn;
+ struct prefix p;
+
+ p = *ei->address;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+
+ rn = route_node_get (IF_OIFS (ifp), &p);
+ /* rn->info should either be NULL or equal to this ei
+ * as route_node_get may return an existing node
+ */
+ assert (!rn->info || rn->info == ei);
+ rn->info = ei;
+}
+
+struct eigrp_interface *
+eigrp_if_new (struct eigrp *eigrp, struct interface *ifp, struct prefix *p)
+{
+ struct eigrp_interface *ei;
+ int i;
+
+ if ((ei = eigrp_if_table_lookup (ifp, p)) == NULL)
+ {
+ ei = XCALLOC (MTYPE_EIGRP_IF, sizeof (struct eigrp_interface));
+ memset (ei, 0, sizeof (struct eigrp_interface));
+ }
+ else
+ return ei;
+
+ /* Set zebra interface pointer. */
+ ei->ifp = ifp;
+ ei->address = p;
+
+ eigrp_add_to_if (ifp, ei);
+ listnode_add (eigrp->eiflist, ei);
+
+ ei->type = EIGRP_IFTYPE_BROADCAST;
+
+ /* Initialize neighbor list. */
+ ei->nbrs = list_new ();
+
+ ei->crypt_seqnum = time (NULL);
+
+ /* Initialize lists */
+ for (i = 0; i < EIGRP_FILTER_MAX; i++)
+ {
+ ei->list[i] = NULL;
+ ei->prefix[i] = NULL;
+ ei->routemap[i] = NULL;
+ }
+
+ return ei;
+}
+
+/* lookup ei for specified prefix/ifp */
+struct eigrp_interface *
+eigrp_if_table_lookup (struct interface *ifp, struct prefix *prefix)
+{
+ struct prefix p;
+ struct route_node *rn;
+ struct eigrp_interface *rninfo = NULL;
+
+ p = *prefix;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+
+ /* route_node_get implicitly locks */
+ if ((rn = route_node_lookup (IF_OIFS (ifp), &p)))
+ {
+ rninfo = (struct eigrp_interface *) rn->info;
+ route_unlock_node (rn);
+ }
+
+ return rninfo;
+}
+
+int
+eigrp_if_delete_hook (struct interface *ifp)
+{
+ struct route_node *rn;
+
+ route_table_finish (IF_OIFS (ifp));
+
+ for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
+ if (rn->info)
+ eigrp_del_if_params (rn->info);
+ route_table_finish (IF_OIFS_PARAMS (ifp));
+
+ XFREE (MTYPE_EIGRP_IF_INFO, ifp->info);
+ ifp->info = NULL;
+
+ return 0;
+}
+
+struct list *eigrp_iflist;
+
+void
+eigrp_if_init ()
+{
+ /* Initialize Zebra interface data structure. */
+ if_add_hook (IF_NEW_HOOK, eigrp_if_new_hook);
+ if_add_hook (IF_DELETE_HOOK, eigrp_if_delete_hook);
+}
+
+int
+eigrp_if_new_hook (struct interface *ifp)
+{
+ int rc = 0;
+
+ ifp->info = XCALLOC (MTYPE_EIGRP_IF_INFO, sizeof (struct eigrp_if_info));
+
+ IF_OIFS (ifp) = route_table_init ();
+ IF_OIFS_PARAMS (ifp) = route_table_init ();
+
+ IF_DEF_PARAMS (ifp) = eigrp_new_if_params ();
+
+ SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello);
+ IF_DEF_PARAMS (ifp)->v_hello = (u_int32_t) EIGRP_HELLO_INTERVAL_DEFAULT;
+
+ SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait);
+ IF_DEF_PARAMS (ifp)->v_wait = (u_int16_t) EIGRP_HOLD_INTERVAL_DEFAULT;
+
+ SET_IF_PARAM (IF_DEF_PARAMS (ifp), bandwidth);
+ IF_DEF_PARAMS (ifp)->bandwidth = (u_int32_t) EIGRP_BANDWIDTH_DEFAULT;
+
+ SET_IF_PARAM (IF_DEF_PARAMS (ifp), delay);
+ IF_DEF_PARAMS (ifp)->delay = (u_int32_t) EIGRP_DELAY_DEFAULT;
+
+ SET_IF_PARAM (IF_DEF_PARAMS (ifp), reliability);
+ IF_DEF_PARAMS (ifp)->reliability = (u_char) EIGRP_RELIABILITY_DEFAULT;
+
+ SET_IF_PARAM (IF_DEF_PARAMS (ifp), load);
+ IF_DEF_PARAMS (ifp)->load = (u_char) EIGRP_LOAD_DEFAULT;
+
+ SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type);
+ IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_NONE;
+
+ SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_keychain);
+ IF_DEF_PARAMS (ifp)->auth_keychain= NULL;
+
+ return rc;
+}
+
+struct eigrp_if_params *
+eigrp_new_if_params (void)
+{
+ struct eigrp_if_params *eip;
+
+ eip = XCALLOC (MTYPE_EIGRP_IF_PARAMS, sizeof (struct eigrp_if_params));
+ if (!eip)
+ return NULL;
+
+ UNSET_IF_PARAM (eip, passive_interface);
+ UNSET_IF_PARAM (eip, v_hello);
+ UNSET_IF_PARAM (eip, v_wait);
+ UNSET_IF_PARAM (eip, bandwidth);
+ UNSET_IF_PARAM (eip, delay);
+ UNSET_IF_PARAM (eip, reliability);
+ UNSET_IF_PARAM (eip, load);
+ UNSET_IF_PARAM (eip, auth_keychain);
+ UNSET_IF_PARAM (eip, auth_type);
+
+ return eip;
+}
+
+void
+eigrp_del_if_params (struct eigrp_if_params *eip)
+{
+ if(eip->auth_keychain)
+ free(eip->auth_keychain);
+
+ XFREE (MTYPE_EIGRP_IF_PARAMS, eip);
+}
+
+struct eigrp_if_params *
+eigrp_lookup_if_params (struct interface *ifp, struct in_addr addr)
+{
+ struct prefix_ipv4 p;
+ struct route_node *rn;
+
+ p.family = AF_INET;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefix = addr;
+
+ rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*) &p);
+
+ if (rn)
+ {
+ route_unlock_node (rn);
+ return rn->info;
+ }
+
+ return NULL;
+}
+
+int
+eigrp_if_up (struct eigrp_interface *ei)
+{
+ struct eigrp_prefix_entry *pe;
+ struct eigrp_neighbor_entry *ne;
+ struct eigrp_metrics metric;
+ struct eigrp_interface *ei2;
+ struct listnode *node, *nnode;
+ struct eigrp *eigrp = eigrp_lookup ();
+
+ if (ei == NULL)
+ return 0;
+
+ if (eigrp != NULL)
+ eigrp_adjust_sndbuflen (eigrp, ei->ifp->mtu);
+ else
+ zlog_warn ("%s: eigrp_lookup () returned NULL", __func__);
+ eigrp_if_stream_set (ei);
+
+ /* Set multicast memberships appropriately for new state. */
+ eigrp_if_set_multicast (ei);
+
+ thread_add_event(master, eigrp_hello_timer, ei, (1), NULL);
+
+ /*Prepare metrics*/
+ metric.bandwith = eigrp_bandwidth_to_scaled (EIGRP_IF_PARAM (ei,bandwidth));
+ metric.delay = eigrp_delay_to_scaled (EIGRP_IF_PARAM (ei,delay));
+ metric.load = EIGRP_IF_PARAM (ei,load);
+ metric.reliability = EIGRP_IF_PARAM (ei,reliability);
+ metric.mtu[0] = 0xDC;
+ metric.mtu[1] = 0x05;
+ metric.mtu[2] = 0x00;
+ metric.hop_count = 0;
+ metric.flags = 0;
+ metric.tag = 0;
+
+ /*Add connected entry to topology table*/
+
+ struct prefix_ipv4 *dest_addr = prefix_ipv4_new ();
+
+ dest_addr->family = AF_INET;
+ dest_addr->prefix = ei->connected->address->u.prefix4;
+ dest_addr->prefixlen = ei->connected->address->prefixlen;
+ apply_mask_ipv4 (dest_addr);
+ pe = eigrp_topology_table_lookup_ipv4 (eigrp->topology_table, dest_addr);
+
+ if (pe == NULL)
+ {
+ pe = eigrp_prefix_entry_new ();
+ pe->serno = eigrp->serno;
+ pe->destination_ipv4 = prefix_ipv4_new ();
+ prefix_copy ((struct prefix *)pe->destination_ipv4,
+ (struct prefix *)&dest_addr);
+ pe->af = AF_INET;
+ pe->nt = EIGRP_TOPOLOGY_TYPE_CONNECTED;
+
+ pe->state = EIGRP_FSM_STATE_PASSIVE;
+ pe->fdistance = eigrp_calculate_metrics (eigrp, &metric);
+ pe->req_action |= EIGRP_FSM_NEED_UPDATE;
+ eigrp_prefix_entry_add (eigrp->topology_table, pe);
+ listnode_add(eigrp->topology_changes_internalIPV4, pe);
+ }
+ ne = eigrp_neighbor_entry_new ();
+ ne->ei = ei;
+ ne->reported_metric = metric;
+ ne->total_metric = metric;
+ ne->distance = eigrp_calculate_metrics (eigrp, &metric);
+ ne->reported_distance = 0;
+ ne->prefix = pe;
+ ne->adv_router = eigrp->neighbor_self;
+ ne->flags = EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG;
+ eigrp_neighbor_entry_add (pe, ne);
+
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei2))
+ {
+ if (ei2->nbrs->count != 0)
+ {
+ eigrp_update_send (ei2);
+ }
+ }
+
+ pe->req_action &= ~EIGRP_FSM_NEED_UPDATE;
+ listnode_delete(eigrp->topology_changes_internalIPV4, pe);
+
+ return 1;
+}
+
+int
+eigrp_if_down (struct eigrp_interface *ei)
+{
+ struct listnode *node, *nnode;
+ struct eigrp_neighbor *nbr;
+
+ if (ei == NULL)
+ return 0;
+
+ /* Shutdown packet reception and sending */
+ if(ei->t_hello)
+ THREAD_OFF (ei->t_hello);
+
+ eigrp_if_stream_unset (ei);
+
+ /*Set infinite metrics to routes learned by this interface and start query process*/
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node, nnode, nbr))
+ {
+ eigrp_nbr_delete(nbr);
+ }
+
+ return 1;
+}
+
+void
+eigrp_if_stream_set (struct eigrp_interface *ei)
+{
+ /* set output fifo queue. */
+ if (ei->obuf == NULL)
+ ei->obuf = eigrp_fifo_new ();
+}
+
+void
+eigrp_if_stream_unset (struct eigrp_interface *ei)
+{
+ struct eigrp *eigrp = ei->eigrp;
+
+ if (ei->obuf)
+ {
+ eigrp_fifo_free (ei->obuf);
+ ei->obuf = NULL;
+
+ if (ei->on_write_q)
+ {
+ listnode_delete (eigrp->oi_write_q, ei);
+ if (list_isempty (eigrp->oi_write_q))
+ thread_cancel (eigrp->t_write);
+ ei->on_write_q = 0;
+ }
+ }
+}
+
+void
+eigrp_if_set_multicast (struct eigrp_interface *ei)
+{
+ if ((EIGRP_IF_PASSIVE_STATUS (ei) == EIGRP_IF_ACTIVE))
+ {
+ /* The interface should belong to the EIGRP-all-routers group. */
+ if (!EI_MEMBER_CHECK (ei, MEMBER_ALLROUTERS)
+ && (eigrp_if_add_allspfrouters (ei->eigrp, ei->address,
+ ei->ifp->ifindex) >= 0))
+ /* Set the flag only if the system call to join succeeded. */
+ EI_MEMBER_JOINED (ei, MEMBER_ALLROUTERS);
+ }
+ else
+ {
+ /* The interface should NOT belong to the EIGRP-all-routers group. */
+ if (EI_MEMBER_CHECK (ei, MEMBER_ALLROUTERS))
+ {
+ /* Only actually drop if this is the last reference */
+ if (EI_MEMBER_COUNT (ei, MEMBER_ALLROUTERS) == 1)
+ eigrp_if_drop_allspfrouters (ei->eigrp, ei->address,
+ ei->ifp->ifindex);
+ /* Unset the flag regardless of whether the system call to leave
+ the group succeeded, since it's much safer to assume that
+ we are not a member. */
+ EI_MEMBER_LEFT (ei, MEMBER_ALLROUTERS);
+ }
+ }
+}
+
+u_char
+eigrp_default_iftype (struct interface *ifp)
+{
+ if (if_is_pointopoint (ifp))
+ return EIGRP_IFTYPE_POINTOPOINT;
+ else if (if_is_loopback (ifp))
+ return EIGRP_IFTYPE_LOOPBACK;
+ else
+ return EIGRP_IFTYPE_BROADCAST;
+}
+
+void
+eigrp_if_free (struct eigrp_interface *ei, int source)
+{
+ struct prefix_ipv4 dest_addr;
+ struct eigrp_prefix_entry *pe;
+ struct eigrp *eigrp = eigrp_lookup ();
+
+ if (source == INTERFACE_DOWN_BY_VTY)
+ {
+ THREAD_OFF (ei->t_hello);
+ eigrp_hello_send(ei,EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
+ }
+
+ dest_addr.family = AF_INET;
+ dest_addr.prefix = ei->connected->address->u.prefix4;
+ dest_addr.prefixlen = ei->connected->address->prefixlen;
+ apply_mask_ipv4(&dest_addr);
+ pe = eigrp_topology_table_lookup_ipv4 (eigrp->topology_table, &dest_addr);
+ if (pe)
+ eigrp_prefix_entry_delete (eigrp->topology_table, pe);
+
+ eigrp_if_down (ei);
+
+ list_delete (ei->nbrs);
+ eigrp_delete_from_if (ei->ifp, ei);
+ listnode_delete (ei->eigrp->eiflist, ei);
+
+ thread_cancel_event (master, ei);
+
+ memset (ei, 0, sizeof (*ei));
+ XFREE (MTYPE_EIGRP_IF, ei);
+}
+
+static void
+eigrp_delete_from_if (struct interface *ifp, struct eigrp_interface *ei)
+{
+ struct route_node *rn;
+ struct prefix p;
+
+ p = *ei->address;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+
+ rn = route_node_lookup (IF_OIFS (ei->ifp), &p);
+ assert (rn);
+ assert (rn->info);
+ rn->info = NULL;
+ route_unlock_node (rn);
+ route_unlock_node (rn);
+}
+
+/* Simulate down/up on the interface. This is needed, for example, when
+ the MTU changes. */
+void
+eigrp_if_reset (struct interface *ifp)
+{
+ struct route_node *rn;
+
+ for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
+ {
+ struct eigrp_interface *ei;
+
+ if ((ei = rn->info) == NULL)
+ continue;
+
+ eigrp_if_down (ei);
+ eigrp_if_up (ei);
+ }
+}
+
+struct eigrp_interface *
+eigrp_if_lookup_by_local_addr (struct eigrp *eigrp, struct interface *ifp,
+ struct in_addr address)
+{
+ struct listnode *node;
+ struct eigrp_interface *ei;
+
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ if (ifp && ei->ifp != ifp)
+ continue;
+
+ if (IPV4_ADDR_SAME (&address, &ei->address->u.prefix4))
+ return ei;
+ }
+
+ return NULL;
+}
+
+/**
+ * @fn eigrp_if_lookup_by_name
+ *
+ * @param[in] eigrp EIGRP process
+ * @param[in] if_name Name of the interface
+ *
+ * @return struct eigrp_interface *
+ *
+ * @par
+ * Function is used for lookup interface by name.
+ */
+struct eigrp_interface *
+eigrp_if_lookup_by_name (struct eigrp *eigrp, const char *if_name)
+{
+ struct eigrp_interface *ei;
+ struct listnode *node;
+
+ /* iterate over all eigrp interfaces */
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ /* compare int name with eigrp interface's name */
+ if(strcmp(ei->ifp->name, if_name) == 0)
+ {
+ return ei;
+ }
+ }
+
+ return NULL;
+}
+
+/* determine receiving interface by ifp and source address */
+struct eigrp_interface *
+eigrp_if_lookup_recv_if (struct eigrp *eigrp, struct in_addr src,
+ struct interface *ifp)
+{
+ struct route_node *rn;
+ struct prefix_ipv4 addr;
+ struct eigrp_interface *ei, *match;
+
+ addr.family = AF_INET;
+ addr.prefix = src;
+ addr.prefixlen = IPV4_MAX_BITLEN;
+
+ match = NULL;
+
+ for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
+ {
+ ei = rn->info;
+
+ if (!ei) /* oi can be NULL for PtP aliases */
+ continue;
+
+ if (if_is_loopback (ei->ifp))
+ continue;
+
+ if (prefix_match (CONNECTED_PREFIX (ei->connected),
+ (struct prefix *) &addr))
+ {
+ if ((match == NULL)
+ || (match->address->prefixlen < ei->address->prefixlen))
+ match = ei;
+ }
+ }
+
+ return match;
+}
+
+u_int32_t
+eigrp_bandwidth_to_scaled (u_int32_t bandwidth)
+{
+ uint64_t temp_bandwidth = (256ull * 10000000) / bandwidth;
+
+ temp_bandwidth =
+ temp_bandwidth < EIGRP_MAX_METRIC ? temp_bandwidth : EIGRP_MAX_METRIC;
+
+ return (u_int32_t) temp_bandwidth;
+}
+
+u_int32_t
+eigrp_scaled_to_bandwidth (u_int32_t scaled)
+{
+ uint64_t temp_scaled = scaled * (256ull * 10000000);
+
+ temp_scaled =
+ temp_scaled < EIGRP_MAX_METRIC ? temp_scaled : EIGRP_MAX_METRIC;
+
+ return (u_int32_t) temp_scaled;
+}
+
+u_int32_t
+eigrp_delay_to_scaled (u_int32_t delay)
+{
+ return delay * 256;
+}
+
+u_int32_t
+eigrp_scaled_to_delay (u_int32_t scaled)
+{
+ return scaled / 256;
+}
diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h
new file mode 100644
index 0000000000..0c57f0cbd6
--- /dev/null
+++ b/eigrpd/eigrp_interface.h
@@ -0,0 +1,72 @@
+/*
+ * EIGRP Interface Functions.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 _ZEBRA_EIGRP_INTERFACE_H_
+#define _ZEBRA_EIGRP_INTERFACE_H_
+
+/*Prototypes*/
+extern void eigrp_if_init (void);
+extern int eigrp_if_new_hook (struct interface *);
+extern int eigrp_if_delete_hook (struct interface *);
+
+extern void eigrp_del_if_params (struct eigrp_if_params *);
+extern struct eigrp_if_params *eigrp_new_if_params (void);
+extern struct eigrp_interface * eigrp_if_new (struct eigrp *, struct interface *,
+ struct prefix *);
+extern struct eigrp_interface * eigrp_if_table_lookup (struct interface *,
+ struct prefix *);
+extern struct eigrp_if_params *eigrp_lookup_if_params (struct interface *,
+ struct in_addr);
+extern int eigrp_if_up (struct eigrp_interface *);
+extern void eigrp_if_stream_set (struct eigrp_interface *);
+extern void eigrp_if_set_multicast (struct eigrp_interface *);
+extern u_char eigrp_default_iftype (struct interface *);
+extern void eigrp_if_free (struct eigrp_interface *, int);
+extern int eigrp_if_down (struct eigrp_interface *);
+extern void eigrp_if_stream_unset (struct eigrp_interface *);
+
+extern struct eigrp_interface *eigrp_if_lookup_by_local_addr (struct eigrp *,
+ struct interface *,
+ struct in_addr);
+extern struct eigrp_interface *eigrp_if_lookup_by_name (struct eigrp *, const char *);
+struct eigrp_interface * eigrp_if_lookup_recv_if (struct eigrp *, struct in_addr,
+ struct interface *);
+
+/* Simulate down/up on the interface. */
+extern void eigrp_if_reset (struct interface *);
+
+extern u_int32_t eigrp_bandwidth_to_scaled (u_int32_t);
+extern u_int32_t eigrp_scaled_to_bandwidth (u_int32_t);
+extern u_int32_t eigrp_delay_to_scaled (u_int32_t);
+extern u_int32_t eigrp_scaled_to_delay (u_int32_t);
+
+
+#endif /* ZEBRA_EIGRP_INTERFACE_H_ */
diff --git a/eigrpd/eigrp_macros.h b/eigrpd/eigrp_macros.h
new file mode 100644
index 0000000000..08c2fc34cc
--- /dev/null
+++ b/eigrpd/eigrp_macros.h
@@ -0,0 +1,84 @@
+/*
+ * EIGRP Macros Definition.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 _ZEBRA_EIGRP_MACROS_H_
+#define _ZEBRA_EIGRP_MACROS_H_
+
+#define DECLARE_IF_PARAM(T, P) T P; u_char P##__config:1
+#define IF_EIGRP_IF_INFO(I) ((struct eigrp_if_info *)((I)->info))
+#define IF_OIFS(I) (IF_EIGRP_IF_INFO (I)->eifs)
+#define IF_OIFS_PARAMS(I) (IF_EIGRP_IF_INFO (I)->params)
+
+#define SET_IF_PARAM(S, P) ((S)->P##__config) = 1
+#define IF_DEF_PARAMS(I) (IF_EIGRP_IF_INFO (I)->def_params)
+
+#define UNSET_IF_PARAM(S, P) ((S)->P##__config) = 0
+
+#define EIGRP_IF_PARAM_CONFIGURED(S, P) ((S) && (S)->P##__config)
+#define EIGRP_IF_PARAM(O, P) \
+ (EIGRP_IF_PARAM_CONFIGURED ((O)->params, P)?\
+ (O)->params->P:IF_DEF_PARAMS((O)->ifp)->P)
+
+#define EIGRP_IF_PASSIVE_STATUS(O) \
+ (EIGRP_IF_PARAM_CONFIGURED((O)->params, passive_interface) ? \
+ (O)->params->passive_interface : \
+ (EIGRP_IF_PARAM_CONFIGURED(IF_DEF_PARAMS((O)->ifp), passive_interface) ? \
+ IF_DEF_PARAMS((O)->ifp)->passive_interface : \
+ (O)->eigrp->passive_interface_default))
+
+//------------------------------------------------------------------------------------------------------------------------------------
+
+#define EIGRP_IF_STRING_MAXLEN 40
+#define IF_NAME(I) eigrp_if_name_string ((I))
+
+//------------------------------------------------------------------------------------------------------------------------------------
+
+/*Macros for EIGRP interface multicast membership*/
+#define EI_MEMBER_FLAG(M) (1 << (M))
+#define EI_MEMBER_COUNT(O,M) (IF_EIGRP_IF_INFO(ei->ifp)->membership_counts[(M)])
+#define EI_MEMBER_CHECK(O,M) \
+ (CHECK_FLAG((O)->multicast_memberships, EI_MEMBER_FLAG(M)))
+#define EI_MEMBER_JOINED(O,M) \
+ do { \
+ SET_FLAG ((O)->multicast_memberships, EI_MEMBER_FLAG(M)); \
+ IF_EIGRP_IF_INFO((O)->ifp)->membership_counts[(M)]++; \
+ } while (0)
+#define EI_MEMBER_LEFT(O,M) \
+ do { \
+ UNSET_FLAG ((O)->multicast_memberships, EI_MEMBER_FLAG(M)); \
+ IF_EIGRP_IF_INFO((O)->ifp)->membership_counts[(M)]--; \
+ } while (0)
+
+//-----------------------------------------------------------------------------------------------------------------------------------
+/* Topology Macros */
+
+
+/* FSM macros*/
+#define EIGRP_FSM_EVENT_SCHEDULE(I,E) \
+ thread_add_event (master, eigrp_fsm_event, (I), (E))
+
+#endif /* _ZEBRA_EIGRP_MACROS_H_ */
diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c
new file mode 100644
index 0000000000..08a1cb6598
--- /dev/null
+++ b/eigrpd/eigrp_main.c
@@ -0,0 +1,230 @@
+/*
+ * EIGRP Main Routine.
+ * Copyright (C) 2013-2015
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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/version.h>
+#include "getopt.h"
+#include "thread.h"
+#include "prefix.h"
+#include "linklist.h"
+#include "if.h"
+#include "vector.h"
+#include "vty.h"
+#include "command.h"
+#include "filter.h"
+#include "plist.h"
+#include "stream.h"
+#include "log.h"
+#include "memory.h"
+#include "privs.h"
+#include "sigevent.h"
+#include "zclient.h"
+#include "keychain.h"
+#include "distribute.h"
+#include "libfrr.h"
+//#include "routemap.h"
+//#include "if_rmap.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_snmp.h"
+#include "eigrpd/eigrp_filter.h"
+//#include "eigrpd/eigrp_routemap.h"
+
+/* eigprd privileges */
+zebra_capabilities_t _caps_p [] =
+{
+ ZCAP_NET_RAW,
+ ZCAP_BIND,
+ ZCAP_NET_ADMIN,
+};
+
+struct zebra_privs_t eigrpd_privs =
+{
+#if defined (FRR_USER) && defined (FRR_GROUP)
+ .user = FRR_USER,
+ .group = FRR_GROUP,
+#endif
+#if defined (VTY_GROUP)
+ .vty_group = VTY_GROUP,
+#endif
+ .caps_p = _caps_p,
+ .cap_num_p = array_size (_caps_p),
+ .cap_num_i = 0
+};
+
+/* EIGRPd options. */
+struct option longopts[] =
+ {
+ { 0 }
+ };
+
+/* Master of threads. */
+struct thread_master *master;
+
+/* SIGHUP handler. */
+static void
+sighup (void)
+{
+ zlog_info ("SIGHUP received");
+}
+
+/* SIGINT / SIGTERM handler. */
+static void
+sigint (void)
+{
+ zlog_notice ("Terminating on signal");
+ eigrp_terminate ();
+}
+
+/* SIGUSR1 handler. */
+static void
+sigusr1 (void)
+{
+ zlog_rotate ();
+}
+
+struct quagga_signal_t eigrp_signals[] =
+{
+ {
+ .signal = SIGHUP,
+ .handler = &sighup,
+ },
+ {
+ .signal = SIGUSR1,
+ .handler = &sigusr1,
+ },
+ {
+ .signal = SIGINT,
+ .handler = &sigint,
+ },
+ {
+ .signal = SIGTERM,
+ .handler = &sigint,
+ },
+};
+
+FRR_DAEMON_INFO(eigrpd, EIGRP,
+ .vty_port = EIGRP_VTY_PORT,
+
+ .proghelp = "Implementation of the EIGRP routing protocol.",
+
+ .signals = eigrp_signals,
+ .n_signals = array_size(eigrp_signals),
+
+ .privs = &eigrpd_privs,
+ )
+
+/* EIGRPd main routine. */
+int
+main (int argc, char **argv, char **envp)
+{
+ frr_preinit (&eigrpd_di, argc, argv);
+ frr_opt_add ("", longopts, "");
+
+ while (1)
+ {
+ int opt;
+
+ opt = frr_getopt (argc, argv, NULL);
+
+ if (opt == EOF)
+ break;
+
+ switch (opt)
+ {
+ case 0:
+ break;
+ default:
+ frr_help_exit (1);
+ break;
+ }
+ }
+
+ /* EIGRP master init. */
+ eigrp_master_init ();
+ eigrp_om->master = frr_init();
+ master = eigrp_om->master;
+
+ vrf_init (NULL, NULL, NULL, NULL);
+
+ /*EIGRPd init*/
+ eigrp_if_init ();
+ eigrp_zebra_init ();
+ eigrp_debug_init ();
+
+ /* Get configuration file. */
+ /* EIGRP VTY inits */
+ eigrp_vty_init ();
+ keychain_init();
+ eigrp_vty_show_init ();
+ eigrp_vty_if_init ();
+
+#ifdef HAVE_SNMP
+ eigrp_snmp_init ();
+#endif /* HAVE_SNMP */
+
+ /* Access list install. */
+ access_list_init ();
+ access_list_add_hook (eigrp_distribute_update_all_wrapper);
+ access_list_delete_hook (eigrp_distribute_update_all_wrapper);
+
+ /* Prefix list initialize.*/
+ prefix_list_init ();
+ prefix_list_add_hook (eigrp_distribute_update_all);
+ prefix_list_delete_hook (eigrp_distribute_update_all);
+
+ /*eigrp_route_map_init();
+ route_map_add_hook (eigrp_rmap_update);
+ route_map_delete_hook (eigrp_rmap_update);*/
+ /*if_rmap_init (EIGRP_NODE);
+ if_rmap_hook_add (eigrp_if_rmap_update);
+ if_rmap_hook_delete (eigrp_if_rmap_update);*/
+
+ /* Distribute list install. */
+ distribute_list_init (EIGRP_NODE);
+ distribute_list_add_hook (eigrp_distribute_update);
+ distribute_list_delete_hook (eigrp_distribute_update);
+
+ frr_config_fork ();
+ frr_run(master);
+
+ /* Not reached. */
+ return (0);
+
+}
diff --git a/eigrpd/eigrp_memory.c b/eigrpd/eigrp_memory.c
new file mode 100644
index 0000000000..4aa76018a2
--- /dev/null
+++ b/eigrpd/eigrp_memory.c
@@ -0,0 +1,42 @@
+/* eigrpd memory type definitions
+ *
+ * Copyright (C) 2017 Donald Sharp
+ *
+ * This file is part of 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 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "eigrp_memory.h"
+
+DEFINE_MGROUP(EIGRPD, "eigrpd")
+DEFINE_MTYPE(EIGRPD, EIGRP_TOP, "EIGRP structure")
+DEFINE_MTYPE(EIGRPD, EIGRP_IF, "EIGRP interface")
+DEFINE_MTYPE(EIGRPD, EIGRP_NEIGHBOR, "EIGRP neighbor")
+DEFINE_MTYPE(EIGRPD, EIGRP_IF_PARAMS, "EIGRP Interface Parameters")
+DEFINE_MTYPE(EIGRPD, EIGRP_IF_INFO, "EIGRP Interface Information")
+DEFINE_MTYPE(EIGRPD, EIGRP_FIFO, "EIGRP FIFO")
+DEFINE_MTYPE(EIGRPD, EIGRP_PACKET, "EIGRP Packet")
+DEFINE_MTYPE(EIGRPD, EIGRP_IPV4_INT_TLV, "EIGRP IPv4 TLV")
+DEFINE_MTYPE(EIGRPD, EIGRP_SEQ_TLV, "EIGRP SEQ TLV")
+DEFINE_MTYPE(EIGRPD, EIGRP_AUTH_TLV, "EIGRP AUTH TLV")
+DEFINE_MTYPE(EIGRPD, EIGRP_AUTH_SHA256_TLV, "EIGRP SHA TLV")
+DEFINE_MTYPE(EIGRPD, EIGRP_PREFIX_ENTRY, "EIGRP Prefix")
+DEFINE_MTYPE(EIGRPD, EIGRP_NEIGHBOR_ENTRY, "EIGRP Neighbor Entry")
+DEFINE_MTYPE(EIGRPD, EIGRP_FSM_MSG, "EIGRP FSM Message")
diff --git a/eigrpd/eigrp_memory.h b/eigrpd/eigrp_memory.h
new file mode 100644
index 0000000000..cd29f1725e
--- /dev/null
+++ b/eigrpd/eigrp_memory.h
@@ -0,0 +1,43 @@
+/* eigrpd memory type declarations
+ *
+ * Copyright (C) 2017 Donald Sharp
+ *
+ * This file is part of 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 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 _FRR_EIGRP_MEMORY_H
+#define _FRR_EIGRP_MEMORY_H
+
+#include "memory.h"
+
+DECLARE_MGROUP(EIGRPD)
+DECLARE_MTYPE(EIGRP_TOP)
+DECLARE_MTYPE(EIGRP_IF)
+DECLARE_MTYPE(EIGRP_NEIGHBOR)
+DECLARE_MTYPE(EIGRP_IF_PARAMS)
+DECLARE_MTYPE(EIGRP_IF_INFO)
+DECLARE_MTYPE(EIGRP_FIFO)
+DECLARE_MTYPE(EIGRP_PACKET)
+DECLARE_MTYPE(EIGRP_IPV4_INT_TLV)
+DECLARE_MTYPE(EIGRP_SEQ_TLV)
+DECLARE_MTYPE(EIGRP_AUTH_TLV)
+DECLARE_MTYPE(EIGRP_AUTH_SHA256_TLV)
+DECLARE_MTYPE(EIGRP_PREFIX_ENTRY)
+DECLARE_MTYPE(EIGRP_NEIGHBOR_ENTRY)
+DECLARE_MTYPE(EIGRP_FSM_MSG)
+
+#endif /* _FRR_EIGRP_MEMORY_H */
diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c
new file mode 100644
index 0000000000..ea39d6e90e
--- /dev/null
+++ b/eigrpd/eigrp_neighbor.c
@@ -0,0 +1,381 @@
+/*
+ * EIGRP Neighbor Handling.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 "prefix.h"
+#include "memory.h"
+#include "command.h"
+#include "thread.h"
+#include "stream.h"
+#include "table.h"
+#include "log.h"
+#include "keychain.h"
+#include "vty.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_memory.h"
+
+struct eigrp_neighbor *
+eigrp_nbr_new (struct eigrp_interface *ei)
+{
+ struct eigrp_neighbor *nbr;
+
+ /* Allcate new neighbor. */
+ nbr = XCALLOC (MTYPE_EIGRP_NEIGHBOR, sizeof (struct eigrp_neighbor));
+
+ /* Relate neighbor to the interface. */
+ nbr->ei = ei;
+
+ /* Set default values. */
+ eigrp_nbr_state_set (nbr, EIGRP_NEIGHBOR_DOWN);
+
+ return nbr;
+}
+
+/**
+ *@fn void dissect_eigrp_sw_version (tvbuff_t *tvb, proto_tree *tree,
+ * proto_item *ti)
+ *
+ * @par
+ * Create a new neighbor structure and initalize it.
+ */
+static struct eigrp_neighbor *
+eigrp_nbr_add (struct eigrp_interface *ei, struct eigrp_header *eigrph,
+ struct ip *iph)
+{
+ struct eigrp_neighbor *nbr;
+
+ nbr = eigrp_nbr_new (ei);
+ nbr->src = iph->ip_src;
+
+ // if (IS_DEBUG_EIGRP_EVENT)
+ // zlog_debug("NSM[%s:%s]: start", IF_NAME (nbr->oi),
+ // inet_ntoa (nbr->router_id));
+
+ return nbr;
+}
+
+struct eigrp_neighbor *
+eigrp_nbr_get (struct eigrp_interface *ei, struct eigrp_header *eigrph,
+ struct ip *iph)
+{
+ struct eigrp_neighbor *nbr;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node, nnode, nbr))
+ {
+ if (iph->ip_src.s_addr == nbr->src.s_addr)
+ {
+ return nbr;
+ }
+ }
+
+ nbr = eigrp_nbr_add (ei, eigrph, iph);
+ listnode_add (ei->nbrs, nbr);
+
+ return nbr;
+}
+
+/**
+ * @fn eigrp_nbr_lookup_by_addr
+ *
+ * @param[in] ei EIGRP interface
+ * @param[in] nbr_addr Address of neighbor
+ *
+ * @return void
+ *
+ * @par
+ * Function is used for neighbor lookup by address
+ * in specified interface.
+ */
+struct eigrp_neighbor *
+eigrp_nbr_lookup_by_addr (struct eigrp_interface *ei, struct in_addr *addr)
+{
+ struct eigrp_neighbor *nbr;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node, nnode, nbr))
+ {
+ if (addr->s_addr == nbr->src.s_addr)
+ {
+ return nbr;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * @fn eigrp_nbr_lookup_by_addr_process
+ *
+ * @param[in] eigrp EIGRP process
+ * @param[in] nbr_addr Address of neighbor
+ *
+ * @return void
+ *
+ * @par
+ * Function is used for neighbor lookup by address
+ * in whole EIGRP process.
+ */
+struct eigrp_neighbor *
+eigrp_nbr_lookup_by_addr_process (struct eigrp *eigrp, struct in_addr nbr_addr)
+{
+ struct eigrp_interface *ei;
+ struct listnode *node, *node2, *nnode2;
+ struct eigrp_neighbor *nbr;
+
+ /* iterate over all eigrp interfaces */
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ /* iterate over all neighbors on eigrp interface */
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
+ {
+ /* compare if neighbor address is same as arg address */
+ if (nbr->src.s_addr == nbr_addr.s_addr)
+ {
+ return nbr;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Delete specified EIGRP neighbor from interface. */
+void
+eigrp_nbr_delete (struct eigrp_neighbor *nbr)
+{
+ eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN);
+ if (nbr->ei)
+ eigrp_topology_neighbor_down(nbr->ei->eigrp, nbr);
+
+ /* Cancel all events. *//* Thread lookup cost would be negligible. */
+ thread_cancel_event (master, nbr);
+ eigrp_fifo_free (nbr->multicast_queue);
+ eigrp_fifo_free (nbr->retrans_queue);
+ THREAD_OFF (nbr->t_holddown);
+
+ if (nbr->ei)
+ listnode_delete (nbr->ei->nbrs,nbr);
+ XFREE (MTYPE_EIGRP_NEIGHBOR, nbr);
+}
+
+int
+holddown_timer_expired (struct thread *thread)
+{
+ struct eigrp_neighbor *nbr;
+
+ nbr = THREAD_ARG (thread);
+
+ zlog_info ("Neighbor %s (%s) is down: holding time expired",
+ inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ nbr->state = EIGRP_NEIGHBOR_DOWN;
+ eigrp_nbr_delete (nbr);
+
+ return 0;
+}
+
+u_char
+eigrp_nbr_state_get (struct eigrp_neighbor *nbr)
+{
+ return(nbr->state);
+}
+
+void
+eigrp_nbr_state_set (struct eigrp_neighbor *nbr, u_char state)
+{
+ nbr->state = state;
+
+ if (eigrp_nbr_state_get(nbr) == EIGRP_NEIGHBOR_DOWN)
+ {
+ // reset all the seq/ack counters
+ nbr->recv_sequence_number = 0;
+ nbr->init_sequence_number = 0;
+ nbr->retrans_counter = 0;
+
+ // Kvalues
+ nbr->K1 = EIGRP_K1_DEFAULT;
+ nbr->K2 = EIGRP_K2_DEFAULT;
+ nbr->K3 = EIGRP_K3_DEFAULT;
+ nbr->K4 = EIGRP_K4_DEFAULT;
+ nbr->K5 = EIGRP_K5_DEFAULT;
+ nbr->K6 = EIGRP_K6_DEFAULT;
+
+ // hold time..
+ nbr->v_holddown = EIGRP_HOLD_INTERVAL_DEFAULT;
+ THREAD_OFF(nbr->t_holddown);
+
+ /* out with the old */
+ if (nbr->multicast_queue)
+ eigrp_fifo_free (nbr->multicast_queue);
+ if (nbr->retrans_queue)
+ eigrp_fifo_free (nbr->retrans_queue);
+
+ /* in with the new */
+ nbr->retrans_queue = eigrp_fifo_new ();
+ nbr->multicast_queue = eigrp_fifo_new ();
+
+ nbr->crypt_seqnum = 0;
+ }
+}
+
+const char *
+eigrp_nbr_state_str (struct eigrp_neighbor *nbr)
+{
+ const char *state;
+ switch (nbr->state)
+ {
+ case EIGRP_NEIGHBOR_DOWN:
+ state = "Down";
+ break;
+ case EIGRP_NEIGHBOR_PENDING:
+ state = "Waiting for Init";
+ break;
+ case EIGRP_NEIGHBOR_UP:
+ state = "Up";
+ break;
+ default:
+ state = "Unknown";
+ break;
+ }
+
+ return(state);
+}
+
+void
+eigrp_nbr_state_update (struct eigrp_neighbor *nbr)
+{
+ switch (nbr->state)
+ {
+ case EIGRP_NEIGHBOR_DOWN:
+ {
+ /*Start Hold Down Timer for neighbor*/
+ // THREAD_OFF(nbr->t_holddown);
+ // THREAD_TIMER_ON(master, nbr->t_holddown, holddown_timer_expired,
+ // nbr, nbr->v_holddown);
+ break;
+ }
+ case EIGRP_NEIGHBOR_PENDING:
+ {
+ /*Reset Hold Down Timer for neighbor*/
+ THREAD_OFF(nbr->t_holddown);
+ thread_add_timer(master, holddown_timer_expired, nbr,
+ nbr->v_holddown, &nbr->t_holddown);
+ break;
+ }
+ case EIGRP_NEIGHBOR_UP:
+ {
+ /*Reset Hold Down Timer for neighbor*/
+ THREAD_OFF(nbr->t_holddown);
+ thread_add_timer(master, holddown_timer_expired, nbr,
+ nbr->v_holddown, &nbr->t_holddown);
+ break;
+ }
+ }
+}
+
+int eigrp_nbr_count_get(void){
+ struct eigrp_interface *iface;
+ struct listnode *node, *node2, *nnode2;
+ struct eigrp_neighbor *nbr;
+ struct eigrp *eigrp = eigrp_lookup();
+ u_int32_t counter;
+
+ if (eigrp == NULL)
+ {
+ zlog_debug("EIGRP Routing Process not enabled");
+ return 0;
+ }
+
+ counter=0;
+ for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface))
+ {
+ for (ALL_LIST_ELEMENTS(iface->nbrs, node2, nnode2, nbr))
+ {
+ if (nbr->state == EIGRP_NEIGHBOR_UP){
+ counter++;
+ }
+ }
+ }
+ return counter;
+}
+
+/**
+ * @fn eigrp_nbr_hard_restart
+ *
+ * @param[in] nbr Neighbor who would receive hard restart
+ * @param[in] vty Virtual terminal for log output
+ * @return void
+ *
+ * @par
+ * Function used for executing hard restart for neighbor:
+ * Send Hello packet with Peer Termination TLV with
+ * neighbor's address, set it's state to DOWN and delete the neighbor
+ */
+void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty)
+{
+ if(nbr == NULL)
+ {
+ zlog_err("Nbr Hard restart: Neighbor not specified.");
+ return;
+ }
+
+ zlog_debug ("Neighbor %s (%s) is down: manually cleared",
+ inet_ntoa (nbr->src),
+ ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ if(vty != NULL)
+ {
+ vty_time_print (vty, 0);
+ vty_out (vty, "Neighbor %s (%s) is down: manually cleared%s",
+ inet_ntoa (nbr->src),
+ ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT),
+ VTY_NEWLINE);
+ }
+
+ /* send Hello with Peer Termination TLV */
+ eigrp_hello_send(nbr->ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN_NBR, &(nbr->src));
+ /* set neighbor to DOWN */
+ nbr->state = EIGRP_NEIGHBOR_DOWN;
+ /* delete neighbor */
+ eigrp_nbr_delete (nbr);
+}
diff --git a/eigrpd/eigrp_neighbor.h b/eigrpd/eigrp_neighbor.h
new file mode 100644
index 0000000000..66fa0e71bc
--- /dev/null
+++ b/eigrpd/eigrp_neighbor.h
@@ -0,0 +1,54 @@
+/*
+ * EIGRP Neighbor Handling.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 _ZEBRA_EIGRP_NEIGHBOR_H
+#define _ZEBRA_EIGRP_NEIGHBOR_H
+
+/* Prototypes */
+extern struct eigrp_neighbor *eigrp_nbr_get(struct eigrp_interface *,
+ struct eigrp_header *,
+ struct ip *);
+extern struct eigrp_neighbor *eigrp_nbr_new (struct eigrp_interface *);
+extern void eigrp_nbr_delete(struct eigrp_neighbor *);
+
+extern int holddown_timer_expired(struct thread *);
+
+extern int eigrp_neighborship_check(struct eigrp_neighbor *,struct TLV_Parameter_Type *);
+extern void eigrp_nbr_state_update(struct eigrp_neighbor *);
+extern void eigrp_nbr_state_set(struct eigrp_neighbor *, u_char state);
+extern u_char eigrp_nbr_state_get(struct eigrp_neighbor *);
+extern int eigrp_nbr_count_get(void);
+extern const char *eigrp_nbr_state_str(struct eigrp_neighbor *);
+extern struct eigrp_neighbor *eigrp_nbr_lookup_by_addr (struct eigrp_interface *, struct in_addr *);
+extern struct eigrp_neighbor *eigrp_nbr_lookup_by_addr_process (struct eigrp *, struct in_addr);
+extern void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty);
+
+#endif /* _ZEBRA_EIGRP_NEIGHBOR_H */
diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c
new file mode 100644
index 0000000000..45d91025d1
--- /dev/null
+++ b/eigrpd/eigrp_network.c
@@ -0,0 +1,460 @@
+/*
+ * EIGRP Network Related Functions.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 "thread.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "sockunion.h"
+#include "log.h"
+#include "sockopt.h"
+#include "privs.h"
+#include "table.h"
+#include "vty.h"
+
+extern struct zebra_privs_t eigrpd_privs;
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_network.h"
+
+static int
+eigrp_network_match_iface(const struct connected *, const struct prefix *);
+static void
+eigrp_network_run_interface(struct eigrp *, struct prefix *, struct interface *);
+
+int
+eigrp_sock_init(void)
+{
+ int eigrp_sock;
+ int ret, hincl = 1;
+
+ if (eigrpd_privs.change(ZPRIVS_RAISE))
+ zlog_err("eigrp_sock_init: could not raise privs, %s",
+ safe_strerror(errno));
+
+ eigrp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP);
+ if (eigrp_sock < 0)
+ {
+ int save_errno = errno;
+ if (eigrpd_privs.change(ZPRIVS_LOWER))
+ zlog_err("eigrp_sock_init: could not lower privs, %s",
+ safe_strerror(errno));
+ zlog_err("eigrp_read_sock_init: socket: %s", safe_strerror(save_errno));
+ exit(1);
+ }
+
+#ifdef IP_HDRINCL
+ /* we will include IP header with packet */
+ ret = setsockopt(eigrp_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl));
+ if (ret < 0)
+ {
+ int save_errno = errno;
+ if (eigrpd_privs.change(ZPRIVS_LOWER))
+ zlog_err("eigrp_sock_init: could not lower privs, %s",
+ safe_strerror(errno));
+ zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", eigrp_sock,
+ safe_strerror(save_errno));
+
+ }
+#elif defined (IPTOS_PREC_INTERNETCONTROL)
+#warning "IP_HDRINCL not available on this system"
+#warning "using IPTOS_PREC_INTERNETCONTROL"
+ ret = setsockopt_ipv4_tos (eigrp_sock, IPTOS_PREC_INTERNETCONTROL);
+ if (ret < 0)
+ {
+ int save_errno = errno;
+ if ( eigrpd_privs.change (ZPRIVS_LOWER) )
+ zlog_err ("eigrpd_sock_init: could not lower privs, %s",
+ safe_strerror (errno) );
+ zlog_warn ("can't set sockopt IP_TOS %d to socket %d: %s",
+ tos, eigrp_sock, safe_strerror (save_errno));
+ close (eigrp_sock); /* Prevent sd leak. */
+ return ret;
+ }
+#else /* !IPTOS_PREC_INTERNETCONTROL */
+#warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL"
+ zlog_warn ("IP_HDRINCL option not available");
+#endif /* IP_HDRINCL */
+
+ ret = setsockopt_ifindex(AF_INET, eigrp_sock, 1);
+
+ if (ret < 0)
+ zlog_warn("Can't set pktinfo option for fd %d", eigrp_sock);
+
+ if (eigrpd_privs.change(ZPRIVS_LOWER))
+ {
+ zlog_err("eigrp_sock_init: could not lower privs, %s",
+ safe_strerror(errno));
+ }
+
+ return eigrp_sock;
+}
+
+void
+eigrp_adjust_sndbuflen(struct eigrp * eigrp, unsigned int buflen)
+{
+ int newbuflen;
+ /* Check if any work has to be done at all. */
+ if (eigrp->maxsndbuflen >= buflen)
+ return;
+ if (eigrpd_privs.change(ZPRIVS_RAISE))
+ zlog_err("%s: could not raise privs, %s", __func__, safe_strerror(errno));
+
+ /* Now we try to set SO_SNDBUF to what our caller has requested
+ * (the MTU of a newly added interface). However, if the OS has
+ * truncated the actual buffer size to somewhat less size, try
+ * to detect it and update our records appropriately. The OS
+ * may allocate more buffer space, than requested, this isn't
+ * a error.
+ */
+ setsockopt_so_sendbuf(eigrp->fd, buflen);
+ newbuflen = getsockopt_so_sendbuf(eigrp->fd);
+ if (newbuflen < 0 || newbuflen < (int) buflen)
+ zlog_warn("%s: tried to set SO_SNDBUF to %u, but got %d", __func__, buflen,
+ newbuflen);
+ if (newbuflen >= 0)
+ eigrp->maxsndbuflen = (unsigned int) newbuflen;
+ else
+ zlog_warn("%s: failed to get SO_SNDBUF", __func__);
+ if (eigrpd_privs.change(ZPRIVS_LOWER))
+ zlog_err("%s: could not lower privs, %s", __func__, safe_strerror(errno));
+}
+
+int
+eigrp_if_ipmulticast(struct eigrp *top, struct prefix *p, unsigned int ifindex)
+{
+ u_char val;
+ int ret, len;
+
+ val = 0;
+ len = sizeof(val);
+
+ /* Prevent receiving self-origined multicast packets. */
+ ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *) &val, len);
+ if (ret < 0)
+ zlog_warn("can't setsockopt IP_MULTICAST_LOOP (0) for fd %d: %s", top->fd,
+ safe_strerror(errno));
+
+ /* Explicitly set multicast ttl to 1 -- endo. */
+ val = 1;
+ ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *) &val, len);
+ if (ret < 0)
+ zlog_warn("can't setsockopt IP_MULTICAST_TTL (1) for fd %d: %s", top->fd,
+ safe_strerror(errno));
+
+ ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
+ if (ret < 0)
+ zlog_warn("can't setsockopt IP_MULTICAST_IF (fd %d, addr %s, "
+ "ifindex %u): %s", top->fd, inet_ntoa(p->u.prefix4), ifindex,
+ safe_strerror(errno));
+
+ return ret;
+}
+
+/* Join to the EIGRP multicast group. */
+int
+eigrp_if_add_allspfrouters(struct eigrp *top, struct prefix *p,
+ unsigned int ifindex)
+{
+ int ret;
+
+ ret = setsockopt_ipv4_multicast(top->fd, IP_ADD_MEMBERSHIP, p->u.prefix4,
+ htonl(EIGRP_MULTICAST_ADDRESS), ifindex);
+ if (ret < 0)
+ zlog_warn("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
+ "ifindex %u, AllSPFRouters): %s; perhaps a kernel limit "
+ "on # of multicast group memberships has been exceeded?", top->fd,
+ inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
+ else
+ zlog_debug("interface %s [%u] join EIGRP Multicast group.",
+ inet_ntoa(p->u.prefix4), ifindex);
+
+ return ret;
+}
+
+int
+eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p,
+ unsigned int ifindex)
+{
+ int ret;
+
+ ret = setsockopt_ipv4_multicast(top->fd, IP_DROP_MEMBERSHIP, p->u.prefix4,
+ htonl(EIGRP_MULTICAST_ADDRESS), ifindex);
+ if (ret < 0)
+ zlog_warn("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
+ "ifindex %u, AllSPFRouters): %s", top->fd, inet_ntoa(p->u.prefix4),
+ ifindex, safe_strerror(errno));
+ else
+ zlog_debug("interface %s [%u] leave EIGRP Multicast group.",
+ inet_ntoa(p->u.prefix4), ifindex);
+
+ return ret;
+}
+
+int
+eigrp_network_set(struct eigrp *eigrp, struct prefix_ipv4 *p)
+{
+ struct route_node *rn;
+ struct interface *ifp;
+ struct listnode *node;
+
+ rn = route_node_get(eigrp->networks, (struct prefix *) p);
+ if (rn->info)
+ {
+ /* There is already same network statement. */
+ route_unlock_node(rn);
+ return 0;
+ }
+
+ struct prefix_ipv4 *pref = prefix_ipv4_new();
+ PREFIX_COPY_IPV4(pref,p);
+ rn->info = (void *) pref;
+
+ /* Schedule Router ID Update. */
+ // if (eigrp->router_id == 0)
+ // eigrp_router_id_update(eigrp);
+ /* Run network config now. */
+ /* Get target interface. */
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
+ {
+ zlog_debug("Setting up %s", ifp->name);
+ eigrp_network_run_interface(eigrp, (struct prefix *) p, ifp);
+ }
+ return 1;
+}
+
+/* Check whether interface matches given network
+ * returns: 1, true. 0, false
+ */
+static int
+eigrp_network_match_iface(const struct connected *co, const struct prefix *net)
+{
+ /* new approach: more elegant and conceptually clean */
+ return prefix_match(net, CONNECTED_PREFIX (co));
+}
+
+static void
+eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p,
+ struct interface *ifp)
+{
+ struct listnode *cnode;
+ struct connected *co;
+
+ /* if interface prefix is match specified prefix,
+ then create socket and join multicast group. */
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co))
+ {
+
+ if (CHECK_FLAG (co->flags,ZEBRA_IFA_SECONDARY))
+ continue;
+
+ if (p->family == co->address->family
+ && !eigrp_if_table_lookup(ifp, co->address)
+ && eigrp_network_match_iface(co, p))
+ {
+ struct eigrp_interface *ei;
+
+ ei = eigrp_if_new(eigrp, ifp, co->address);
+ ei->connected = co;
+
+ ei->params = eigrp_lookup_if_params(ifp, ei->address->u.prefix4);
+
+ /* Relate eigrp interface to eigrp instance. */
+ ei->eigrp = eigrp;
+
+ /* update network type as interface flag */
+ /* If network type is specified previously,
+ skip network type setting. */
+ ei->type = IF_DEF_PARAMS (ifp)->type;
+
+ /* if router_id is not configured, dont bring up
+ * interfaces.
+ * eigrp_router_id_update() will call eigrp_if_update
+ * whenever r-id is configured instead.
+ */
+ if (if_is_operative(ifp))
+ eigrp_if_up(ei);
+ }
+ }
+}
+
+void
+eigrp_if_update(struct interface *ifp)
+{
+ struct listnode *node, *nnode;
+ struct route_node *rn;
+ struct eigrp *eigrp;
+
+ /*
+ * In the event there are multiple eigrp autonymnous systems running,
+ * we need to check eac one and add the interface as approperate
+ */
+ for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp))
+ {
+ /* EIGRP must be on and Router-ID must be configured. */
+ if (!eigrp || eigrp->router_id == 0)
+ continue;
+
+ /* Run each network for this interface. */
+ for (rn = route_top(eigrp->networks); rn; rn = route_next(rn))
+ if (rn->info != NULL)
+ {
+ eigrp_network_run_interface(eigrp, &rn->p, ifp);
+ }
+ }
+}
+
+int
+eigrp_network_unset(struct eigrp *eigrp, struct prefix_ipv4 *p)
+{
+ struct route_node *rn;
+ struct listnode *node, *nnode;
+ struct eigrp_interface *ei;
+ struct prefix *pref;
+
+ rn = route_node_lookup(eigrp->networks, (struct prefix *) p);
+ if (rn == NULL)
+ return 0;
+
+ pref = rn->info;
+ route_unlock_node (rn);
+
+ if (!IPV4_ADDR_SAME (&pref->u.prefix4, &p->prefix))
+ return 0;
+
+ prefix_ipv4_free(rn->info);
+ rn->info = NULL;
+ route_unlock_node(rn); /* initial reference */
+
+ /* Find interfaces that not configured already. */
+ for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei))
+ {
+ int found = 0;
+ struct connected *co = ei->connected;
+
+ for (rn = route_top(eigrp->networks); rn; rn = route_next(rn))
+ {
+ if (rn->info == NULL)
+ continue;
+
+ if (eigrp_network_match_iface(co, &rn->p))
+ {
+ found = 1;
+ route_unlock_node(rn);
+ break;
+ }
+ }
+
+ if (found == 0)
+ {
+ eigrp_if_free(ei, INTERFACE_DOWN_BY_VTY);
+ }
+ }
+
+ return 1;
+}
+
+u_int32_t
+eigrp_calculate_metrics(struct eigrp *eigrp, struct eigrp_metrics *metric)
+{
+ uint64_t temp_metric;
+ temp_metric = 0;
+
+ if(metric->delay == EIGRP_MAX_METRIC)
+ return EIGRP_MAX_METRIC;
+
+ // EIGRP Metric = {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)}
+
+ if (eigrp->k_values[0])
+ temp_metric += (eigrp->k_values[0] * metric->bandwith);
+ if (eigrp->k_values[1])
+ temp_metric += ((eigrp->k_values[1] * metric->bandwith)
+ / (256 - metric->load));
+ if (eigrp->k_values[2])
+ temp_metric += (eigrp->k_values[2] * metric->delay);
+ if (eigrp->k_values[3] && !eigrp->k_values[4])
+ temp_metric *= eigrp->k_values[3];
+ if (!eigrp->k_values[3] && eigrp->k_values[4])
+ temp_metric *= (eigrp->k_values[4] / metric->reliability);
+ if (eigrp->k_values[3] && eigrp->k_values[4])
+ temp_metric *= ((eigrp->k_values[4] / metric->reliability)
+ + eigrp->k_values[3]);
+
+ if (temp_metric <= EIGRP_MAX_METRIC)
+ return (u_int32_t) temp_metric;
+ else
+ return EIGRP_MAX_METRIC;
+}
+
+u_int32_t
+eigrp_calculate_total_metrics(struct eigrp *eigrp,
+ struct eigrp_neighbor_entry *entry)
+{
+ entry->total_metric = entry->reported_metric;
+ uint64_t temp_delay = (uint64_t) entry->total_metric.delay
+ + (uint64_t) eigrp_delay_to_scaled (EIGRP_IF_PARAM (entry->ei, delay));
+ entry->total_metric.delay =
+ temp_delay > EIGRP_MAX_METRIC ? EIGRP_MAX_METRIC : (u_int32_t) temp_delay;
+
+ u_int32_t bw = eigrp_bandwidth_to_scaled (EIGRP_IF_PARAM (entry->ei,bandwidth));
+ entry->total_metric.bandwith =
+ entry->total_metric.bandwith > bw ? bw : entry->total_metric.bandwith;
+
+ return eigrp_calculate_metrics(eigrp, &entry->total_metric);
+}
+
+u_char
+eigrp_metrics_is_same(struct eigrp_metrics *metric1,
+ struct eigrp_metrics *metric2)
+{
+ if ((metric1->bandwith == metric2->bandwith)
+ && (metric1->delay == metric2->delay)
+ && (metric1->hop_count == metric2->hop_count)
+ && (metric1->load == metric2->load)
+ && (metric1->reliability == metric2->reliability)
+ && (metric1->mtu[0] == metric2->mtu[0])
+ && (metric1->mtu[1] == metric2->mtu[1])
+ && (metric1->mtu[2] == metric2->mtu[2]))
+ return 1;
+
+ return 0; // if different
+}
+
+void
+eigrp_external_routes_refresh (struct eigrp *eigrp, int type)
+{
+
+}
+
diff --git a/eigrpd/eigrp_network.h b/eigrpd/eigrp_network.h
new file mode 100644
index 0000000000..bcca2609a8
--- /dev/null
+++ b/eigrpd/eigrp_network.h
@@ -0,0 +1,51 @@
+/*
+ * EIGRP Network Related Functions.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 _ZEBRA_EIGRP_NETWORK_H
+#define _ZEBRA_EIGRP_NETWORK_H
+
+/* Prototypes */
+
+extern int eigrp_sock_init (void);
+extern int eigrp_if_ipmulticast (struct eigrp *, struct prefix *, unsigned int);
+extern int eigrp_network_set (struct eigrp *, struct prefix_ipv4 *);
+extern int eigrp_network_unset (struct eigrp *eigrp, struct prefix_ipv4 *p);
+
+extern int eigrp_hello_timer (struct thread *);
+extern void eigrp_if_update (struct interface *);
+extern int eigrp_if_add_allspfrouters (struct eigrp *, struct prefix *,
+ unsigned int);
+extern int eigrp_if_drop_allspfrouters (struct eigrp *top, struct prefix *p,
+ unsigned int ifindex);
+extern void eigrp_adjust_sndbuflen (struct eigrp *, unsigned int);
+
+extern u_int32_t eigrp_calculate_metrics (struct eigrp *, struct eigrp_metrics *);
+extern u_int32_t eigrp_calculate_total_metrics (struct eigrp *, struct eigrp_neighbor_entry *);
+extern u_char eigrp_metrics_is_same(struct eigrp_metrics *,struct eigrp_metrics *);
+extern void eigrp_external_routes_refresh (struct eigrp *, int);
+
+#endif /* EIGRP_NETWORK_H_ */
diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c
new file mode 100644
index 0000000000..2d02acc00b
--- /dev/null
+++ b/eigrpd/eigrp_packet.c
@@ -0,0 +1,1419 @@
+/*
+ * EIGRP General Sending and Receiving of EIGRP Packets.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "vty.h"
+#include "keychain.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "sockunion.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "checksum.h"
+#include "md5.h"
+#include "sha256.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_memory.h"
+
+/* Packet Type String. */
+const struct message eigrp_packet_type_str[] =
+ {
+ { EIGRP_OPC_UPDATE, "Update"},
+ { EIGRP_OPC_REQUEST, "Request"},
+ { EIGRP_OPC_QUERY, "Query"},
+ { EIGRP_OPC_REPLY, "Reply"},
+ { EIGRP_OPC_HELLO, "Hello"},
+ { EIGRP_OPC_IPXSAP, "IPX-SAP"},
+ { EIGRP_OPC_PROBE, "Probe"},
+ { EIGRP_OPC_ACK, "Ack"},
+ { EIGRP_OPC_SIAQUERY, "SIAQuery"},
+ { EIGRP_OPC_SIAREPLY, "SIAReply"},
+};
+
+const size_t eigrp_packet_type_str_max = sizeof(eigrp_packet_type_str) /
+ sizeof(eigrp_packet_type_str[0]);
+
+static unsigned char zeropad[16] = {0};
+
+/* Forward function reference*/
+static struct stream * eigrp_recv_packet (int, struct interface **, struct stream *);
+static int eigrp_verify_header (struct stream *, struct eigrp_interface *, struct ip *,
+ struct eigrp_header *);
+static int eigrp_check_network_mask (struct eigrp_interface *, struct in_addr);
+
+static int eigrp_retrans_count_exceeded(struct eigrp_packet *ep, struct eigrp_neighbor *nbr)
+{
+ return 1;
+}
+
+int
+eigrp_make_md5_digest (struct eigrp_interface *ei, struct stream *s, u_char flags)
+{
+ struct key *key = NULL;
+ struct keychain *keychain;
+
+ unsigned char digest[EIGRP_AUTH_TYPE_MD5_LEN];
+ MD5_CTX ctx;
+ u_char *ibuf;
+ size_t backup_get, backup_end;
+ struct TLV_MD5_Authentication_Type *auth_TLV;
+
+ ibuf = s->data;
+ backup_end = s->endp;
+ backup_get = s->getp;
+
+ auth_TLV = eigrp_authTLV_MD5_new();
+
+ stream_set_getp(s,EIGRP_HEADER_LEN);
+ stream_get(auth_TLV,s,EIGRP_AUTH_MD5_TLV_SIZE);
+ stream_set_getp(s, backup_get);
+
+ keychain = keychain_lookup(IF_DEF_PARAMS (ei->ifp)->auth_keychain);
+ if(keychain)
+ key = key_lookup_for_send(keychain);
+ else
+ {
+ eigrp_authTLV_MD5_free(auth_TLV);
+ return EIGRP_AUTH_TYPE_NONE;
+ }
+
+ memset(&ctx, 0, sizeof(ctx));
+ MD5Init(&ctx);
+
+ /* Generate a digest. Each situation needs different handling */
+ if(flags & EIGRP_AUTH_BASIC_HELLO_FLAG)
+ {
+ MD5Update(&ctx, ibuf, EIGRP_MD5_BASIC_COMPUTE);
+ MD5Update(&ctx, key->string, strlen(key->string));
+ if(strlen(key->string) < 16)
+ MD5Update(&ctx, zeropad, 16 - strlen(key->string));
+ }
+ else if(flags & EIGRP_AUTH_UPDATE_INIT_FLAG)
+ {
+ MD5Update(&ctx, ibuf, EIGRP_MD5_UPDATE_INIT_COMPUTE);
+ }
+ else if(flags & EIGRP_AUTH_UPDATE_FLAG)
+ {
+ MD5Update(&ctx, ibuf, EIGRP_MD5_BASIC_COMPUTE);
+ MD5Update(&ctx, key->string, strlen(key->string));
+ if(strlen(key->string) < 16)
+ MD5Update(&ctx, zeropad, 16 - strlen(key->string));
+ if(backup_end > (EIGRP_HEADER_LEN + EIGRP_AUTH_MD5_TLV_SIZE))
+ {
+ MD5Update(&ctx, ibuf + (EIGRP_HEADER_LEN + EIGRP_AUTH_MD5_TLV_SIZE),
+ backup_end - 20 - (EIGRP_HEADER_LEN + EIGRP_AUTH_MD5_TLV_SIZE));
+ }
+ }
+
+ MD5Final(digest, &ctx);
+
+ /* Append md5 digest to the end of the stream. */
+ memcpy(auth_TLV->digest,digest,EIGRP_AUTH_TYPE_MD5_LEN);
+
+ stream_set_endp(s,EIGRP_HEADER_LEN);
+ stream_put(s,auth_TLV,EIGRP_AUTH_MD5_TLV_SIZE);
+ stream_set_endp(s, backup_end);
+
+ eigrp_authTLV_MD5_free(auth_TLV);
+ return EIGRP_AUTH_TYPE_MD5_LEN;
+}
+
+int
+eigrp_check_md5_digest (struct stream *s,
+ struct TLV_MD5_Authentication_Type *authTLV,struct eigrp_neighbor *nbr, u_char flags)
+{
+ MD5_CTX ctx;
+ unsigned char digest[EIGRP_AUTH_TYPE_MD5_LEN];
+ struct key *key = NULL;
+ struct keychain *keychain;
+ u_char *ibuf;
+ size_t backup_end;
+ struct TLV_MD5_Authentication_Type *auth_TLV;
+ struct eigrp_header *eigrph;
+
+ if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(authTLV->key_sequence))
+ {
+ zlog_warn ("interface %s: eigrp_check_md5 bad sequence %d (expect %d)",
+ IF_NAME (nbr->ei),
+ ntohl(authTLV->key_sequence),
+ ntohl(nbr->crypt_seqnum));
+ return 0;
+ }
+
+ eigrph = (struct eigrp_header *) s->data;
+ eigrph->checksum = 0;
+
+ auth_TLV =(struct TLV_MD5_Authentication_Type *) (s->data + EIGRP_HEADER_LEN);
+ memcpy(auth_TLV->digest, "0", sizeof(auth_TLV->digest));
+
+ ibuf = s->data;
+ backup_end = s->endp;
+
+ keychain = keychain_lookup(IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain);
+ if(keychain)
+ key = key_lookup_for_send(keychain);
+
+ memset(&ctx, 0, sizeof(ctx));
+ MD5Init(&ctx);
+
+ /* Generate a digest. Each situation needs different handling */
+ if(flags & EIGRP_AUTH_BASIC_HELLO_FLAG)
+ {
+ MD5Update(&ctx, ibuf, EIGRP_MD5_BASIC_COMPUTE);
+ MD5Update(&ctx, key->string, strlen(key->string));
+ if(strlen(key->string) < 16)
+ MD5Update(&ctx, zeropad, 16 - strlen(key->string));
+ }
+ else if(flags & EIGRP_AUTH_UPDATE_INIT_FLAG)
+ {
+ MD5Update(&ctx, ibuf, EIGRP_MD5_UPDATE_INIT_COMPUTE);
+ }
+ else if(flags & EIGRP_AUTH_UPDATE_FLAG)
+ {
+ MD5Update(&ctx, ibuf, EIGRP_MD5_BASIC_COMPUTE);
+ MD5Update(&ctx, key->string, strlen(key->string));
+ if(strlen(key->string) < 16)
+ MD5Update(&ctx, zeropad, 16 - strlen(key->string));
+ if(backup_end > (EIGRP_HEADER_LEN + EIGRP_AUTH_MD5_TLV_SIZE))
+ {
+ MD5Update(&ctx, ibuf + (EIGRP_HEADER_LEN + EIGRP_AUTH_MD5_TLV_SIZE),
+ backup_end - 20 - (EIGRP_HEADER_LEN + EIGRP_AUTH_MD5_TLV_SIZE));
+ }
+ }
+
+ MD5Final(digest, &ctx);
+
+ /* compare the two */
+ if (memcmp (authTLV->digest, digest, EIGRP_AUTH_TYPE_MD5_LEN) == 0)
+ {
+ zlog_debug("VSETKO OK");
+ }
+ else
+ {
+ zlog_warn ("interface %s: eigrp_check_md5 checksum mismatch",
+ IF_NAME (nbr->ei));
+ return 0;
+ }
+
+ /* save neighbor's crypt_seqnum */
+ nbr->crypt_seqnum = authTLV->key_sequence;
+
+ return 1;
+}
+
+int
+eigrp_make_sha256_digest (struct eigrp_interface *ei, struct stream *s, u_char flags)
+{
+ struct key *key = NULL;
+ struct keychain *keychain;
+ char *source_ip;
+
+ unsigned char digest[EIGRP_AUTH_TYPE_SHA256_LEN];
+ unsigned char buffer[1 + PLAINTEXT_LENGTH + 45 + 1] = { 0 };
+ HMAC_SHA256_CTX ctx;
+ void *ibuf;
+ size_t backup_get, backup_end;
+ struct TLV_SHA256_Authentication_Type *auth_TLV;
+
+ ibuf = s->data;
+ backup_end = s->endp;
+ backup_get = s->getp;
+
+ auth_TLV = eigrp_authTLV_SHA256_new ();
+
+ stream_set_getp(s,EIGRP_HEADER_LEN);
+ stream_get(auth_TLV,s,EIGRP_AUTH_SHA256_TLV_SIZE);
+ stream_set_getp(s, backup_get);
+
+ keychain = keychain_lookup(IF_DEF_PARAMS (ei->ifp)->auth_keychain);
+ if(keychain)
+ key = key_lookup_for_send(keychain);
+
+ // saved_len[index] = strnzcpyn(saved_key[index], key,
+ // PLAINTEXT_LENGTH + 1);
+
+ source_ip = calloc(16, sizeof(char));
+ inet_ntop(AF_INET, &ei->address->u.prefix4, source_ip, 16);
+
+ memset(&ctx, 0, sizeof(ctx));
+ buffer[0] = '\n';
+ memcpy(buffer + 1, key, strlen (key->string));
+ memcpy(buffer + 1 + strlen(key->string), source_ip, strlen(source_ip));
+ HMAC__SHA256_Init(&ctx, buffer, 1 + strlen (key->string) + strlen(source_ip));
+ HMAC__SHA256_Update(&ctx, ibuf, strlen(ibuf));
+ HMAC__SHA256_Final(digest, &ctx);
+
+
+ /* Put hmac-sha256 digest to it's place */
+ memcpy(auth_TLV->digest,digest,EIGRP_AUTH_TYPE_SHA256_LEN);
+
+ stream_set_endp(s,EIGRP_HEADER_LEN);
+ stream_put(s,auth_TLV,EIGRP_AUTH_SHA256_TLV_SIZE);
+ stream_set_endp(s, backup_end);
+
+ eigrp_authTLV_SHA256_free(auth_TLV);
+ free(source_ip);
+
+ return EIGRP_AUTH_TYPE_SHA256_LEN;
+}
+
+int
+eigrp_check_sha256_digest (struct stream *s,
+ struct TLV_SHA256_Authentication_Type *authTLV,
+ struct eigrp_neighbor *nbr, u_char flags)
+{
+ return 1;
+}
+
+/*
+ * eigrp_packet_dump
+ *
+ * This routing dumps the contents of the IP packet either received or
+ * built by EIGRP.
+ */
+static void
+eigrp_packet_dump (struct stream *s)
+{
+ // not yet...
+ return;
+}
+
+int
+eigrp_write (struct thread *thread)
+{
+ struct eigrp *eigrp = THREAD_ARG(thread);
+ struct eigrp_header *eigrph;
+ struct eigrp_interface *ei;
+ struct eigrp_packet *ep;
+ struct sockaddr_in sa_dst;
+ struct ip iph;
+ struct msghdr msg;
+ struct iovec iov[2];
+ u_int16_t opcode = 0;
+
+ int ret;
+ int flags = 0;
+ struct listnode *node;
+#ifdef WANT_EIGRP_WRITE_FRAGMENT
+ static u_int16_t ipid = 0;
+#endif /* WANT_EIGRP_WRITE_FRAGMENT */
+#define EIGRP_WRITE_IPHL_SHIFT 2
+
+ eigrp->t_write = NULL;
+
+ node = listhead(eigrp->oi_write_q);
+ assert(node);
+ ei = listgetdata(node);
+ assert(ei);
+
+#ifdef WANT_EIGRP_WRITE_FRAGMENT
+ /* seed ipid static with low order bits of time */
+ if (ipid == 0)
+ ipid = (time(NULL) & 0xffff);
+#endif /* WANT_EIGRP_WRITE_FRAGMENT */
+
+ /* Get one packet from queue. */
+ ep = eigrp_fifo_head(ei->obuf);
+ assert(ep);
+ assert(ep->length >= EIGRP_HEADER_LEN);
+
+ if (ep->dst.s_addr == htonl(EIGRP_MULTICAST_ADDRESS))
+ eigrp_if_ipmulticast(eigrp, ei->address, ei->ifp->ifindex);
+
+ memset(&iph, 0, sizeof(struct ip));
+ memset(&sa_dst, 0, sizeof(sa_dst));
+
+ sa_dst.sin_family = AF_INET;
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+ sa_dst.sin_len = sizeof(sa_dst);
+#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
+ sa_dst.sin_addr = ep->dst;
+ sa_dst.sin_port = htons(0);
+
+ /* Set DONTROUTE flag if dst is unicast. */
+ if (!IN_MULTICAST(htonl(ep->dst.s_addr)))
+ flags = MSG_DONTROUTE;
+
+ iph.ip_hl = sizeof(struct ip) >> EIGRP_WRITE_IPHL_SHIFT;
+ /* it'd be very strange for header to not be 4byte-word aligned but.. */
+ if (sizeof(struct ip) > (unsigned int)(iph.ip_hl << EIGRP_WRITE_IPHL_SHIFT))
+ iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
+
+ iph.ip_v = IPVERSION;
+ iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
+ iph.ip_len = (iph.ip_hl << EIGRP_WRITE_IPHL_SHIFT) + ep->length;
+
+#if defined (__DragonFly__)
+ /*
+ * DragonFly's raw socket expects ip_len/ip_off in network byte order.
+ */
+ iph.ip_len = htons(iph.ip_len);
+#endif
+
+ iph.ip_off = 0;
+ iph.ip_ttl = EIGRP_IP_TTL;
+ iph.ip_p = IPPROTO_EIGRPIGP;
+ iph.ip_sum = 0;
+ iph.ip_src.s_addr = ei->address->u.prefix4.s_addr;
+ iph.ip_dst.s_addr = ep->dst.s_addr;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = (caddr_t) &sa_dst;
+ msg.msg_namelen = sizeof(sa_dst);
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 2;
+
+ iov[0].iov_base = (char*)&iph;
+ iov[0].iov_len = iph.ip_hl << EIGRP_WRITE_IPHL_SHIFT;
+ iov[1].iov_base = STREAM_PNT(ep->s);
+ iov[1].iov_len = ep->length;
+
+ /* send final fragment (could be first) */
+ sockopt_iphdrincl_swab_htosys(&iph);
+ ret = sendmsg(eigrp->fd, &msg, flags);
+ sockopt_iphdrincl_swab_systoh(&iph);
+
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND))
+ {
+ eigrph = (struct eigrp_header *) STREAM_DATA(ep->s);
+ opcode = eigrph->opcode;
+ zlog_debug("Sending [%s] to [%s] via [%s] ret [%d].",
+ LOOKUP(eigrp_packet_type_str, opcode), inet_ntoa(ep->dst),
+ IF_NAME(ei), ret);
+ }
+
+ if (ret < 0)
+ zlog_warn("*** sendmsg in eigrp_write failed to %s, "
+ "id %d, off %d, len %d, interface %s, mtu %u: %s",
+ inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len, ei->ifp->name,
+ ei->ifp->mtu, safe_strerror(errno));
+
+ /* Show debug sending packet. */
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND) && (IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL)))
+ {
+ zlog_debug("-----------------------------------------------------");
+ eigrp_ip_header_dump(&iph);
+ stream_set_getp(ep->s, 0);
+ eigrp_packet_dump(ep->s);
+ zlog_debug("-----------------------------------------------------");
+ }
+
+ /* Now delete packet from queue. */
+ eigrp_packet_delete(ei);
+
+ if (eigrp_fifo_head(ei->obuf) == NULL)
+ {
+ ei->on_write_q = 0;
+ list_delete_node(eigrp->oi_write_q, node);
+ }
+
+ /* If packets still remain in queue, call write thread. */
+ if (!list_isempty(eigrp->oi_write_q)) {
+ eigrp->t_write = NULL;
+ thread_add_write(master, eigrp_write, eigrp, eigrp->fd, &eigrp->t_write);
+ }
+
+ return 0;
+}
+
+/* Starting point of packet process function. */
+int
+eigrp_read (struct thread *thread)
+{
+ int ret;
+ struct stream *ibuf;
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct ip *iph;
+ struct eigrp_header *eigrph;
+ struct interface *ifp;
+ struct eigrp_neighbor *nbr;
+
+ u_int16_t opcode = 0;
+ u_int16_t length = 0;
+
+ /* first of all get interface pointer. */
+ eigrp = THREAD_ARG(thread);
+
+ /* prepare for next packet. */
+ eigrp->t_read = NULL;
+ thread_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read);
+
+ stream_reset(eigrp->ibuf);
+ if (!(ibuf = eigrp_recv_packet(eigrp->fd, &ifp, eigrp->ibuf)))
+ {
+ /* This raw packet is known to be at least as big as its IP header. */
+ return -1;
+ }
+
+ /* Note that there should not be alignment problems with this assignment
+ because this is at the beginning of the stream data buffer. */
+ iph = (struct ip *)STREAM_DATA(ibuf);
+
+ //Substract IPv4 header size from EIGRP Packet itself
+ if(iph->ip_v == 4)
+ length = (iph->ip_len) - 20U;
+
+
+ /* IP Header dump. */
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV) && IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL))
+ eigrp_ip_header_dump(iph);
+
+ /* Note that sockopt_iphdrincl_swab_systoh was called in eigrp_recv_packet. */
+ if (ifp == NULL)
+ {
+ struct connected *c;
+ /* Handle cases where the platform does not support retrieving the ifindex,
+ and also platforms (such as Solaris 8) that claim to support ifindex
+ retrieval but do not. */
+ c = if_lookup_address((void *)&iph->ip_src, AF_INET, VRF_DEFAULT);
+
+ if (c == NULL)
+ return 0;
+
+ ifp = c->ifp;
+ }
+
+ /* associate packet with eigrp interface */
+ ei = eigrp_if_lookup_recv_if(eigrp, iph->ip_src, ifp);
+
+ /* eigrp_verify_header() relies on a valid "ei" and thus can be called only
+ after the checks below are passed. These checks in turn access the
+ fields of unverified "eigrph" structure for their own purposes and
+ must remain very accurate in doing this.
+ */
+ if (!ei)
+ return 0;
+
+ /* Self-originated packet should be discarded silently. */
+ if (eigrp_if_lookup_by_local_addr(eigrp, NULL, iph->ip_src) ||
+ (IPV4_ADDR_SAME(&iph->ip_src.s_addr, &ei->address->u.prefix4)))
+ {
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
+ zlog_debug("eigrp_read[%s]: Dropping self-originated packet",
+ inet_ntoa(iph->ip_src));
+ return 0;
+ }
+
+ /* Advance from IP header to EIGRP header (iph->ip_hl has been verified
+ by eigrp_recv_packet() to be correct). */
+
+ stream_forward_getp(ibuf, (iph->ip_hl * 4));
+ eigrph = (struct eigrp_header *) STREAM_PNT(ibuf);
+
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV) && IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL))
+ eigrp_header_dump(eigrph);
+
+ // if (MSG_OK != eigrp_packet_examin(eigrph, stream_get_endp(ibuf) - stream_get_getp(ibuf)))
+ // return -1;
+
+ /* Now it is safe to access all fields of EIGRP packet header. */
+ /* associate packet with eigrp interface */
+ ei = eigrp_if_lookup_recv_if(eigrp, iph->ip_src, ifp);
+
+ /* eigrp_verify_header() relies on a valid "ei" and thus can be called only
+ after the checks below are passed. These checks in turn access the
+ fields of unverified "eigrph" structure for their own purposes and
+ must remain very accurate in doing this.
+ */
+ if (!ei)
+ return 0;
+
+ /* If incoming interface is passive one, ignore it. */
+ if (ei && EIGRP_IF_PASSIVE_STATUS(ei) == EIGRP_IF_PASSIVE)
+ {
+ char buf[3][INET_ADDRSTRLEN];
+
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
+ zlog_debug("ignoring packet from router %s sent to %s, "
+ "received on a passive interface, %s",
+ inet_ntop(AF_INET, &eigrph->vrid, buf[0], sizeof(buf[0])),
+ inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
+ inet_ntop(AF_INET, &ei->address->u.prefix4,
+ buf[2], sizeof(buf[2])));
+
+ if (iph->ip_dst.s_addr == htonl(EIGRP_MULTICAST_ADDRESS))
+ {
+ /* Try to fix multicast membership.
+ * Some OS:es may have problems in this area,
+ * make sure it is removed.
+ */
+ EI_MEMBER_JOINED(ei, MEMBER_ALLROUTERS);
+ eigrp_if_set_multicast(ei);
+ }
+ return 0;
+ }
+
+ /* else it must be a local eigrp interface, check it was received on
+ * correct link
+ */
+ else if (ei->ifp != ifp)
+ {
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
+ zlog_warn("Packet from [%s] received on wrong link %s",
+ inet_ntoa(iph->ip_src), ifp->name);
+ return 0;
+ }
+
+ /* Verify more EIGRP header fields. */
+ ret = eigrp_verify_header(ibuf, ei, iph, eigrph);
+ if (ret < 0)
+ {
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
+ zlog_debug("eigrp_read[%s]: Header check failed, dropping.",
+ inet_ntoa(iph->ip_src));
+ return ret;
+ }
+
+ /* calcualte the eigrp packet length, and move the pounter to the
+ start of the eigrp TLVs */
+ opcode = eigrph->opcode;
+
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
+ zlog_debug("Received [%s] length [%u] via [%s] src [%s] dst [%s]",
+ LOOKUP(eigrp_packet_type_str, opcode), length,
+ IF_NAME(ei), inet_ntoa(iph->ip_src), inet_ntoa(iph->ip_dst));
+
+ /* Read rest of the packet and call each sort of packet routine. */
+ stream_forward_getp(ibuf, EIGRP_HEADER_LEN);
+
+ /* New testing block of code for handling Acks */
+ if (ntohl(eigrph->ack) != 0)
+ {
+ nbr = eigrp_nbr_get(ei, eigrph, iph);
+
+ /* neighbor must be valid, eigrp_nbr_get creates if none existed */
+ assert(nbr);
+
+ struct eigrp_packet *ep;
+
+ ep = eigrp_fifo_tail(nbr->retrans_queue);
+ if (ep)
+ {
+ if (ntohl(eigrph->ack) == ep->sequence_number)
+ {
+ if((nbr->state == EIGRP_NEIGHBOR_PENDING) &&
+ (ntohl(eigrph->ack) == nbr->init_sequence_number))
+ {
+ eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_UP);
+ zlog_info("Neighbor adjacency became full");
+ nbr->init_sequence_number = 0;
+ nbr->recv_sequence_number = ntohl(eigrph->sequence);
+ eigrp_update_send_EOT(nbr);
+ }
+ ep = eigrp_fifo_pop_tail(nbr->retrans_queue);
+ eigrp_packet_free(ep);
+ if (nbr->retrans_queue->count > 0)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+ }
+ }
+ ep = eigrp_fifo_tail(nbr->multicast_queue);
+ if (ep)
+ {
+ if (ntohl(eigrph->ack) == ep->sequence_number)
+ {
+ ep = eigrp_fifo_pop_tail(nbr->multicast_queue);
+ eigrp_packet_free(ep);
+ if (nbr->multicast_queue->count > 0)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+ }
+ }
+ }
+
+
+ switch (opcode)
+ {
+ case EIGRP_OPC_HELLO:
+ eigrp_hello_receive(eigrp, iph, eigrph, ibuf, ei, length);
+ break;
+ case EIGRP_OPC_PROBE:
+ // eigrp_probe_receive(eigrp, iph, eigrph, ibuf, ei, length);
+ break;
+ case EIGRP_OPC_QUERY:
+ eigrp_query_receive(eigrp, iph, eigrph, ibuf, ei, length);
+ break;
+ case EIGRP_OPC_REPLY:
+ eigrp_reply_receive(eigrp, iph, eigrph, ibuf, ei, length);
+ break;
+ case EIGRP_OPC_REQUEST:
+ // eigrp_request_receive(eigrp, iph, eigrph, ibuf, ei, length);
+ break;
+ case EIGRP_OPC_SIAQUERY:
+ eigrp_query_receive(eigrp, iph, eigrph, ibuf, ei, length);
+ break;
+ case EIGRP_OPC_SIAREPLY:
+ eigrp_reply_receive(eigrp, iph, eigrph, ibuf, ei, length);
+ break;
+ case EIGRP_OPC_UPDATE:
+ eigrp_update_receive(eigrp, iph, eigrph, ibuf, ei, length);
+ break;
+ default:
+ zlog_warn("interface %s: EIGRP packet header type %d unsupported",
+ IF_NAME(ei), opcode);
+ break;
+ }
+
+ return 0;
+}
+
+static struct stream *
+eigrp_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
+{
+ int ret;
+ struct ip *iph;
+ u_int16_t ip_len;
+ unsigned int ifindex = 0;
+ struct iovec iov;
+ /* Header and data both require alignment. */
+ char buff[CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
+ struct msghdr msgh;
+
+ memset(&msgh, 0, sizeof(struct msghdr));
+ msgh.msg_iov = &iov;
+ msgh.msg_iovlen = 1;
+ msgh.msg_control = (caddr_t) buff;
+ msgh.msg_controllen = sizeof(buff);
+
+ ret = stream_recvmsg(ibuf, fd, &msgh, 0, (EIGRP_PACKET_MAX_LEN + 1));
+ if (ret < 0)
+ {
+ zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
+ return NULL;
+ }
+ if ((unsigned int) ret < sizeof(iph)) /* ret must be > 0 now */
+ {
+ zlog_warn("eigrp_recv_packet: discarding runt packet of length %d "
+ "(ip header size is %u)", ret, (u_int) sizeof(iph));
+ return NULL;
+ }
+
+ /* Note that there should not be alignment problems with this assignment
+ because this is at the beginning of the stream data buffer. */
+ iph = (struct ip *) STREAM_DATA(ibuf);
+ sockopt_iphdrincl_swab_systoh(iph);
+
+ ip_len = iph->ip_len;
+
+#if !defined (GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
+ /*
+ * Kernel network code touches incoming IP header parameters,
+ * before protocol specific processing.
+ *
+ * 1) Convert byteorder to host representation.
+ * --> ip_len, ip_id, ip_off
+ *
+ * 2) Adjust ip_len to strip IP header size!
+ * --> If user process receives entire IP packet via RAW
+ * socket, it must consider adding IP header size to
+ * the "ip_len" field of "ip" structure.
+ *
+ * For more details, see <netinet/ip_input.c>.
+ */
+ ip_len = ip_len + (iph->ip_hl << 2);
+#endif
+
+#if defined (__DragonFly__)
+ /*
+ * in DragonFly's raw socket, ip_len/ip_off are read
+ * in network byte order.
+ * As OpenBSD < 200311 adjust ip_len to strip IP header size!
+ */
+ ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
+#endif
+
+ ifindex = getsockopt_ifindex(AF_INET, &msgh);
+
+ *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
+
+ if (ret != ip_len)
+ {
+ zlog_warn("eigrp_recv_packet read length mismatch: ip_len is %d, "
+ "but recvmsg returned %d", ip_len, ret);
+ return NULL;
+ }
+
+ return ibuf;
+}
+
+struct eigrp_fifo *
+eigrp_fifo_new (void)
+{
+ struct eigrp_fifo *new;
+
+ new = XCALLOC(MTYPE_EIGRP_FIFO, sizeof(struct eigrp_fifo));
+ return new;
+}
+
+/* Free eigrp packet fifo. */
+void
+eigrp_fifo_free (struct eigrp_fifo *fifo)
+{
+ struct eigrp_packet *ep;
+ struct eigrp_packet *next;
+
+ for (ep = fifo->head; ep; ep = next)
+ {
+ next = ep->next;
+ eigrp_packet_free(ep);
+ }
+ fifo->head = fifo->tail = NULL;
+ fifo->count = 0;
+
+ XFREE(MTYPE_EIGRP_FIFO, fifo);
+}
+
+/* Free eigrp fifo entries without destroying fifo itself*/
+void
+eigrp_fifo_reset (struct eigrp_fifo *fifo)
+{
+ struct eigrp_packet *ep;
+ struct eigrp_packet *next;
+
+ for (ep = fifo->head; ep; ep = next)
+ {
+ next = ep->next;
+ eigrp_packet_free(ep);
+ }
+ fifo->head = fifo->tail = NULL;
+ fifo->count = 0;
+}
+
+struct eigrp_packet *
+eigrp_packet_new (size_t size)
+{
+ struct eigrp_packet *new;
+
+ new = XCALLOC(MTYPE_EIGRP_PACKET, sizeof(struct eigrp_packet));
+ new->s = stream_new(size);
+ new->retrans_counter = 0;
+
+ return new;
+}
+
+void
+eigrp_send_packet_reliably (struct eigrp_neighbor *nbr)
+{
+ struct eigrp_packet *ep;
+
+ ep = eigrp_fifo_tail(nbr->retrans_queue);
+
+ if (ep)
+ {
+ struct eigrp_packet *duplicate;
+ duplicate = eigrp_packet_duplicate(ep, nbr);
+ /* Add packet to the top of the interface output queue*/
+ eigrp_fifo_push_head(nbr->ei->obuf, duplicate);
+
+ /*Start retransmission timer*/
+ thread_add_timer(master, eigrp_unack_packet_retrans, nbr,
+ EIGRP_PACKET_RETRANS_TIME, &ep->t_retrans_timer);
+
+ /*Increment sequence number counter*/
+ nbr->ei->eigrp->sequence_number++;
+
+ /* Hook thread to write packet. */
+ if (nbr->ei->on_write_q == 0)
+ {
+ listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei);
+ nbr->ei->on_write_q = 1;
+ }
+ thread_add_write(master, eigrp_write, nbr->ei->eigrp, nbr->ei->eigrp->fd,
+ &nbr->ei->eigrp->t_write);
+ }
+}
+
+/* Calculate EIGRP checksum */
+void
+eigrp_packet_checksum (struct eigrp_interface *ei, struct stream *s,
+ u_int16_t length)
+{
+ struct eigrp_header *eigrph;
+
+ eigrph = (struct eigrp_header *) STREAM_DATA(s);
+
+ /* Calculate checksum. */
+ eigrph->checksum = in_cksum(eigrph, length);
+}
+
+/* Make EIGRP header. */
+void
+eigrp_packet_header_init (int type, struct eigrp_interface *ei, struct stream *s,
+ u_int32_t flags, u_int32_t sequence, u_int32_t ack)
+{
+ struct eigrp_header *eigrph;
+
+ eigrph = (struct eigrp_header *) STREAM_DATA(s);
+
+ eigrph->version = (u_char) EIGRP_HEADER_VERSION;
+ eigrph->opcode = (u_char) type;
+ eigrph->checksum = 0;
+
+ eigrph->vrid = htons(ei->eigrp->vrid);
+ eigrph->ASNumber = htons(ei->eigrp->AS);
+ eigrph->ack = htonl(ack);
+ eigrph->sequence = htonl(sequence);
+ // if(flags == EIGRP_INIT_FLAG)
+ // eigrph->sequence = htonl(3);
+ eigrph->flags = htonl(flags);
+
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
+ zlog_debug("Packet Header Init Seq [%u] Ack [%u]",
+ htonl(eigrph->sequence), htonl(eigrph->ack));
+
+ stream_forward_endp(s, EIGRP_HEADER_LEN);
+}
+
+/* Add new packet to head of fifo. */
+void
+eigrp_fifo_push_head (struct eigrp_fifo *fifo, struct eigrp_packet *ep)
+{
+ ep->next = fifo->head;
+ ep->previous = NULL;
+
+ if (fifo->tail == NULL)
+ fifo->tail = ep;
+
+ if (fifo->count != 0)
+ fifo->head->previous = ep;
+
+ fifo->head = ep;
+
+ fifo->count++;
+}
+
+/* Return first fifo entry. */
+struct eigrp_packet *
+eigrp_fifo_head (struct eigrp_fifo *fifo)
+{
+ return fifo->head;
+}
+
+/* Return last fifo entry. */
+struct eigrp_packet *
+eigrp_fifo_tail (struct eigrp_fifo *fifo)
+{
+ return fifo->tail;
+}
+
+void
+eigrp_packet_delete (struct eigrp_interface *ei)
+{
+ struct eigrp_packet *ep;
+
+ ep = eigrp_fifo_pop (ei->obuf);
+
+ if (ep)
+ eigrp_packet_free(ep);
+}
+
+/* Delete first packet from fifo. */
+struct eigrp_packet *
+eigrp_fifo_pop (struct eigrp_fifo *fifo)
+{
+ struct eigrp_packet *ep;
+
+ ep = fifo->head;
+
+ if (ep)
+ {
+ fifo->head = ep->next;
+
+ if (fifo->head == NULL)
+ fifo->tail = NULL;
+ else
+ fifo->head->previous = NULL;
+
+ fifo->count--;
+ }
+
+ return ep;
+}
+
+void
+eigrp_packet_free (struct eigrp_packet *ep)
+{
+ if (ep->s)
+ stream_free(ep->s);
+
+ THREAD_OFF(ep->t_retrans_timer);
+
+ XFREE(MTYPE_EIGRP_PACKET, ep);
+
+ ep = NULL;
+}
+
+/* EIGRP Header verification. */
+static int
+eigrp_verify_header (struct stream *ibuf, struct eigrp_interface *ei,
+ struct ip *iph, struct eigrp_header *eigrph)
+{
+ /* Check network mask, Silently discarded. */
+ if (!eigrp_check_network_mask(ei, iph->ip_src))
+ {
+ zlog_warn("interface %s: eigrp_read network address is not same [%s]",
+ IF_NAME(ei), inet_ntoa(iph->ip_src));
+ return -1;
+ }
+ //
+ // /* Check authentication. The function handles logging actions, where required. */
+ // if (! eigrp_check_auth(ei, eigrph))
+ // return -1;
+
+ return 0;
+}
+
+/* Unbound socket will accept any Raw IP packets if proto is matched.
+ To prevent it, compare src IP address and i/f address with masking
+ i/f network mask. */
+static int
+eigrp_check_network_mask (struct eigrp_interface *ei, struct in_addr ip_src)
+{
+ struct in_addr mask, me, him;
+
+ if (ei->type == EIGRP_IFTYPE_POINTOPOINT)
+ return 1;
+
+ masklen2ip(ei->address->prefixlen, &mask);
+
+ me.s_addr = ei->address->u.prefix4.s_addr & mask.s_addr;
+ him.s_addr = ip_src.s_addr & mask.s_addr;
+
+ if (IPV4_ADDR_SAME(&me, &him))
+ return 1;
+
+ return 0;
+}
+
+int
+eigrp_unack_packet_retrans (struct thread *thread)
+{
+ struct eigrp_neighbor *nbr;
+ nbr = (struct eigrp_neighbor *) THREAD_ARG(thread);
+
+ struct eigrp_packet *ep;
+ ep = eigrp_fifo_tail(nbr->retrans_queue);
+
+ if (ep)
+ {
+ struct eigrp_packet *duplicate;
+ duplicate = eigrp_packet_duplicate(ep, nbr);
+
+ /* Add packet to the top of the interface output queue*/
+ eigrp_fifo_push_head(nbr->ei->obuf, duplicate);
+
+ ep->retrans_counter++;
+ if(ep->retrans_counter == EIGRP_PACKET_RETRANS_MAX)
+ return eigrp_retrans_count_exceeded(ep, nbr);
+
+ /*Start retransmission timer*/
+ ep->t_retrans_timer = NULL;
+ thread_add_timer(master, eigrp_unack_packet_retrans, nbr, EIGRP_PACKET_RETRANS_TIME,
+ &ep->t_retrans_timer);
+
+ /* Hook thread to write packet. */
+ if (nbr->ei->on_write_q == 0)
+ {
+ listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei);
+ nbr->ei->on_write_q = 1;
+ }
+ thread_add_write(master, eigrp_write, nbr->ei->eigrp, nbr->ei->eigrp->fd,
+ &nbr->ei->eigrp->t_write);
+ }
+
+ return 0;
+}
+
+int
+eigrp_unack_multicast_packet_retrans (struct thread *thread)
+{
+ struct eigrp_neighbor *nbr;
+ nbr = (struct eigrp_neighbor *) THREAD_ARG(thread);
+
+ struct eigrp_packet *ep;
+ ep = eigrp_fifo_tail(nbr->multicast_queue);
+
+ if (ep)
+ {
+ struct eigrp_packet *duplicate;
+ duplicate = eigrp_packet_duplicate(ep, nbr);
+ /* Add packet to the top of the interface output queue*/
+ eigrp_fifo_push_head(nbr->ei->obuf, duplicate);
+
+ ep->retrans_counter++;
+ if(ep->retrans_counter == EIGRP_PACKET_RETRANS_MAX)
+ return eigrp_retrans_count_exceeded(ep, nbr);
+
+ /*Start retransmission timer*/
+ ep->t_retrans_timer = NULL;
+ thread_add_timer(master, eigrp_unack_multicast_packet_retrans, nbr, EIGRP_PACKET_RETRANS_TIME,
+ &ep->t_retrans_timer);
+
+ /* Hook thread to write packet. */
+ if (nbr->ei->on_write_q == 0)
+ {
+ listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei);
+ nbr->ei->on_write_q = 1;
+ }
+ thread_add_write(master, eigrp_write, nbr->ei->eigrp, nbr->ei->eigrp->fd,
+ &nbr->ei->eigrp->t_write);
+ }
+
+ return 0;
+}
+
+/* Get packet from tail of fifo. */
+struct eigrp_packet *
+eigrp_fifo_pop_tail (struct eigrp_fifo *fifo)
+{
+ struct eigrp_packet *ep;
+
+ ep = fifo->tail;
+
+ if (ep)
+ {
+ fifo->tail = ep->previous;
+
+ if (fifo->tail == NULL)
+ fifo->head = NULL;
+ else
+ fifo->tail->next = NULL;
+
+ fifo->count--;
+ }
+
+ return ep;
+}
+
+struct eigrp_packet *
+eigrp_packet_duplicate (struct eigrp_packet *old, struct eigrp_neighbor *nbr)
+{
+ struct eigrp_packet *new;
+
+ new = eigrp_packet_new(nbr->ei->ifp->mtu);
+ new->length = old->length;
+ new->retrans_counter = old->retrans_counter;
+ new->dst = old->dst;
+ new->sequence_number = old->sequence_number;
+ stream_copy(new->s, old->s);
+
+ return new;
+}
+
+struct TLV_IPv4_Internal_type *
+eigrp_read_ipv4_tlv (struct stream *s)
+{
+ struct TLV_IPv4_Internal_type *tlv;
+
+ tlv = eigrp_IPv4_InternalTLV_new ();
+
+ tlv->type = stream_getw(s);
+ tlv->length = stream_getw(s);
+ tlv->forward.s_addr = stream_getl(s);
+ tlv->metric.delay = stream_getl(s);
+ tlv->metric.bandwith = stream_getl(s);
+ tlv->metric.mtu[0] = stream_getc(s);
+ tlv->metric.mtu[1] = stream_getc(s);
+ tlv->metric.mtu[2] = stream_getc(s);
+ tlv->metric.hop_count = stream_getc(s);
+ tlv->metric.reliability = stream_getc(s);
+ tlv->metric.load = stream_getc(s);
+ tlv->metric.tag = stream_getc(s);
+ tlv->metric.flags = stream_getc(s);
+
+ tlv->prefix_length = stream_getc(s);
+
+ if (tlv->prefix_length <= 8)
+ {
+ tlv->destination_part[0] = stream_getc(s);
+ tlv->destination.s_addr = (tlv->destination_part[0]);
+ }
+ else if (tlv->prefix_length > 8 && tlv->prefix_length <= 16)
+ {
+ tlv->destination_part[0] = stream_getc(s);
+ tlv->destination_part[1] = stream_getc(s);
+ tlv->destination.s_addr = ((tlv->destination_part[1] << 8)
+ + tlv->destination_part[0]);
+ }
+ else if (tlv->prefix_length > 16 && tlv->prefix_length <= 24)
+ {
+ tlv->destination_part[0] = stream_getc(s);
+ tlv->destination_part[1] = stream_getc(s);
+ tlv->destination_part[2] = stream_getc(s);
+ tlv->destination.s_addr = ((tlv->destination_part[2] << 16) +
+ (tlv->destination_part[1] << 8) +
+ tlv->destination_part[0]);
+ }
+ else if (tlv->prefix_length > 24 && tlv->prefix_length <= 32)
+ {
+ tlv->destination_part[0] = stream_getc(s);
+ tlv->destination_part[1] = stream_getc(s);
+ tlv->destination_part[2] = stream_getc(s);
+ tlv->destination_part[3] = stream_getc(s);
+ tlv->destination.s_addr = ((tlv->destination_part[3] << 24) +
+ (tlv->destination_part[2] << 16) +
+ (tlv->destination_part[1] << 8) +
+ tlv->destination_part[0]);
+ }
+ return tlv;
+}
+
+u_int16_t
+eigrp_add_internalTLV_to_stream (struct stream *s,
+ struct eigrp_prefix_entry *pe)
+{
+ u_int16_t length;
+
+ stream_putw(s, EIGRP_TLV_IPv4_INT);
+ if (pe->destination_ipv4->prefixlen <= 8)
+ {
+ stream_putw(s, 0x001A);
+ length = 0x001A;
+ }
+ if ((pe->destination_ipv4->prefixlen > 8)
+ && (pe->destination_ipv4->prefixlen <= 16))
+ {
+ stream_putw(s, 0x001B);
+ length = 0x001B;
+ }
+ if ((pe->destination_ipv4->prefixlen > 16)
+ && (pe->destination_ipv4->prefixlen <= 24))
+ {
+ stream_putw(s, 0x001C);
+ length = 0x001C;
+ }
+ if (pe->destination_ipv4->prefixlen > 24)
+ {
+ stream_putw(s, 0x001D);
+ length = 0x001D;
+ }
+
+ stream_putl(s, 0x00000000);
+
+ /*Metric*/
+ stream_putl(s, pe->reported_metric.delay);
+ stream_putl(s, pe->reported_metric.bandwith);
+ stream_putc(s, pe->reported_metric.mtu[2]);
+ stream_putc(s, pe->reported_metric.mtu[1]);
+ stream_putc(s, pe->reported_metric.mtu[0]);
+ stream_putc(s, pe->reported_metric.hop_count);
+ stream_putc(s, pe->reported_metric.reliability);
+ stream_putc(s, pe->reported_metric.load);
+ stream_putc(s, pe->reported_metric.tag);
+ stream_putc(s, pe->reported_metric.flags);
+
+ stream_putc(s, pe->destination_ipv4->prefixlen);
+
+ if (pe->destination_ipv4->prefixlen <= 8)
+ {
+ stream_putc(s, pe->destination_ipv4->prefix.s_addr & 0xFF);
+ }
+ if ((pe->destination_ipv4->prefixlen > 8)
+ && (pe->destination_ipv4->prefixlen <= 16))
+ {
+ stream_putc(s, pe->destination_ipv4->prefix.s_addr & 0xFF);
+ stream_putc(s, (pe->destination_ipv4->prefix.s_addr >> 8) & 0xFF);
+ }
+ if ((pe->destination_ipv4->prefixlen > 16)
+ && (pe->destination_ipv4->prefixlen <= 24))
+ {
+ stream_putc(s, pe->destination_ipv4->prefix.s_addr & 0xFF);
+ stream_putc(s, (pe->destination_ipv4->prefix.s_addr >> 8) & 0xFF);
+ stream_putc(s, (pe->destination_ipv4->prefix.s_addr >> 16) & 0xFF);
+ }
+ if (pe->destination_ipv4->prefixlen > 24)
+ {
+ stream_putc(s, pe->destination_ipv4->prefix.s_addr & 0xFF);
+ stream_putc(s, (pe->destination_ipv4->prefix.s_addr >> 8) & 0xFF);
+ stream_putc(s, (pe->destination_ipv4->prefix.s_addr >> 16) & 0xFF);
+ stream_putc(s, (pe->destination_ipv4->prefix.s_addr >> 24) & 0xFF);
+ }
+
+ return length;
+}
+
+u_int16_t
+eigrp_add_authTLV_MD5_to_stream (struct stream *s,
+ struct eigrp_interface *ei)
+{
+ struct key *key;
+ struct keychain *keychain;
+ struct TLV_MD5_Authentication_Type *authTLV;
+
+ authTLV = eigrp_authTLV_MD5_new();
+
+ authTLV->type = htons(EIGRP_TLV_AUTH);
+ authTLV->length = htons(EIGRP_AUTH_MD5_TLV_SIZE);
+ authTLV->auth_type = htons(EIGRP_AUTH_TYPE_MD5);
+ authTLV->auth_length = htons(EIGRP_AUTH_TYPE_MD5_LEN);
+ authTLV->key_sequence = 0;
+ memset(authTLV->Nullpad,0,sizeof(authTLV->Nullpad));
+
+ keychain = keychain_lookup(IF_DEF_PARAMS (ei->ifp)->auth_keychain);
+ if(keychain)
+ key = key_lookup_for_send(keychain);
+ else
+ {
+ free(IF_DEF_PARAMS (ei->ifp)->auth_keychain);
+ IF_DEF_PARAMS (ei->ifp)->auth_keychain = NULL;
+ eigrp_authTLV_MD5_free(authTLV);
+ return 0;
+ }
+
+ if(key)
+ {
+ authTLV->key_id = htonl(key->index);
+ memset(authTLV->digest,0,EIGRP_AUTH_TYPE_MD5_LEN);
+ stream_put(s,authTLV, sizeof(struct TLV_MD5_Authentication_Type));
+ eigrp_authTLV_MD5_free(authTLV);
+ return EIGRP_AUTH_MD5_TLV_SIZE;
+ }
+
+ eigrp_authTLV_MD5_free(authTLV);
+
+ return 0;
+}
+
+u_int16_t
+eigrp_add_authTLV_SHA256_to_stream (struct stream *s,
+ struct eigrp_interface *ei)
+{
+ struct key *key;
+ struct keychain *keychain;
+ struct TLV_SHA256_Authentication_Type *authTLV;
+
+ authTLV = eigrp_authTLV_SHA256_new();
+
+ authTLV->type = htons(EIGRP_TLV_AUTH);
+ authTLV->length = htons(EIGRP_AUTH_SHA256_TLV_SIZE);
+ authTLV->auth_type = htons(EIGRP_AUTH_TYPE_SHA256);
+ authTLV->auth_length = htons(EIGRP_AUTH_TYPE_SHA256_LEN);
+ authTLV->key_sequence = 0;
+ memset(authTLV->Nullpad,0,sizeof(authTLV->Nullpad));
+
+ keychain = keychain_lookup(IF_DEF_PARAMS (ei->ifp)->auth_keychain);
+ if(keychain)
+ key = key_lookup_for_send(keychain);
+ else
+ {
+ free(IF_DEF_PARAMS (ei->ifp)->auth_keychain);
+ IF_DEF_PARAMS (ei->ifp)->auth_keychain = NULL;
+ eigrp_authTLV_SHA256_free(authTLV);
+ return 0;
+ }
+
+ if(key)
+ {
+ authTLV->key_id = 0;
+ memset(authTLV->digest,0,EIGRP_AUTH_TYPE_SHA256_LEN);
+ stream_put(s,authTLV, sizeof(struct TLV_SHA256_Authentication_Type));
+ eigrp_authTLV_SHA256_free(authTLV);
+ return EIGRP_AUTH_SHA256_TLV_SIZE;
+ }
+
+ eigrp_authTLV_SHA256_free(authTLV);
+
+ return 0;
+}
+
+struct TLV_MD5_Authentication_Type *
+eigrp_authTLV_MD5_new ()
+{
+ struct TLV_MD5_Authentication_Type *new;
+
+ new = XCALLOC(MTYPE_EIGRP_AUTH_TLV, sizeof(struct TLV_MD5_Authentication_Type));
+
+ return new;
+}
+
+void
+eigrp_authTLV_MD5_free (struct TLV_MD5_Authentication_Type *authTLV)
+{
+ XFREE(MTYPE_EIGRP_AUTH_TLV, authTLV);
+}
+
+struct TLV_SHA256_Authentication_Type *
+eigrp_authTLV_SHA256_new ()
+{
+ struct TLV_SHA256_Authentication_Type *new;
+
+ new = XCALLOC(MTYPE_EIGRP_AUTH_SHA256_TLV, sizeof(struct TLV_SHA256_Authentication_Type));
+
+ return new;
+}
+
+void
+eigrp_authTLV_SHA256_free (struct TLV_SHA256_Authentication_Type *authTLV)
+{
+ XFREE(MTYPE_EIGRP_AUTH_SHA256_TLV, authTLV);
+}
+
+struct TLV_IPv4_Internal_type *
+eigrp_IPv4_InternalTLV_new ()
+{
+ struct TLV_IPv4_Internal_type *new;
+
+ new = XCALLOC(MTYPE_EIGRP_IPV4_INT_TLV,sizeof(struct TLV_IPv4_Internal_type));
+
+ return new;
+}
+
+void
+eigrp_IPv4_InternalTLV_free (struct TLV_IPv4_Internal_type *IPv4_InternalTLV)
+{
+ XFREE(MTYPE_EIGRP_IPV4_INT_TLV, IPv4_InternalTLV);
+}
+
+struct TLV_Sequence_Type *
+eigrp_SequenceTLV_new ()
+{
+ struct TLV_Sequence_Type *new;
+
+ new = XCALLOC(MTYPE_EIGRP_SEQ_TLV,sizeof(struct TLV_Sequence_Type));
+
+ return new;
+}
diff --git a/eigrpd/eigrp_packet.h b/eigrpd/eigrp_packet.h
new file mode 100644
index 0000000000..0996eb2ff6
--- /dev/null
+++ b/eigrpd/eigrp_packet.h
@@ -0,0 +1,142 @@
+/*
+ * EIGRP General Sending and Receiving of EIGRP Packets.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 _ZEBRA_EIGRP_PACKET_H
+#define _ZEBRA_EIGRP_PACKET_H
+
+/*Prototypes*/
+extern int eigrp_read (struct thread *);
+extern int eigrp_write (struct thread *);
+
+extern struct eigrp_packet *eigrp_packet_new (size_t);
+extern struct eigrp_packet *eigrp_packet_duplicate (struct eigrp_packet *, struct eigrp_neighbor *);
+extern void eigrp_packet_free (struct eigrp_packet *);
+extern void eigrp_packet_delete (struct eigrp_interface *);
+extern void eigrp_packet_header_init (int, struct eigrp_interface *, struct stream *,
+ u_int32_t, u_int32_t, u_int32_t);
+extern void eigrp_packet_checksum (struct eigrp_interface *, struct stream *, u_int16_t);
+
+extern struct eigrp_fifo *eigrp_fifo_new (void);
+extern struct eigrp_packet *eigrp_fifo_head (struct eigrp_fifo *);
+extern struct eigrp_packet *eigrp_fifo_tail (struct eigrp_fifo *);
+extern struct eigrp_packet *eigrp_fifo_pop (struct eigrp_fifo *);
+extern struct eigrp_packet *eigrp_fifo_pop_tail (struct eigrp_fifo *);
+extern void eigrp_fifo_push_head (struct eigrp_fifo *, struct eigrp_packet *);
+extern void eigrp_fifo_free (struct eigrp_fifo *);
+extern void eigrp_fifo_reset (struct eigrp_fifo *);
+
+extern void eigrp_send_packet_reliably (struct eigrp_neighbor *);
+
+extern struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv (struct stream *);
+extern u_int16_t eigrp_add_internalTLV_to_stream (struct stream *, struct eigrp_prefix_entry *);
+extern u_int16_t eigrp_add_authTLV_MD5_to_stream (struct stream *, struct eigrp_interface *);
+extern u_int16_t eigrp_add_authTLV_SHA256_to_stream (struct stream *, struct eigrp_interface *);
+
+extern int eigrp_unack_packet_retrans (struct thread *);
+extern int eigrp_unack_multicast_packet_retrans (struct thread *);
+
+/*
+ * untill there is reason to have their own header, these externs are found in
+ * eigrp_hello.c
+ */
+extern void eigrp_hello_send (struct eigrp_interface *, u_char, struct in_addr *);
+extern void eigrp_hello_send_ack (struct eigrp_neighbor *);
+extern void eigrp_hello_receive (struct eigrp *, struct ip *, struct eigrp_header *,
+ struct stream *, struct eigrp_interface *, int);
+extern int eigrp_hello_timer (struct thread *);
+
+/*
+ * These externs are found in eigrp_update.c
+ */
+extern void eigrp_update_send (struct eigrp_interface *);
+extern void eigrp_update_receive (struct eigrp *, struct ip *, struct eigrp_header *,
+ struct stream *, struct eigrp_interface *, int);
+extern void eigrp_update_send_all (struct eigrp *, struct eigrp_interface *);
+extern void eigrp_update_send_init (struct eigrp_neighbor *);
+extern void eigrp_update_send_EOT (struct eigrp_neighbor *);
+extern int eigrp_update_send_GR_thread(struct thread *);
+extern void eigrp_update_send_GR (struct eigrp_neighbor *, enum GR_type, struct vty *);
+extern void eigrp_update_send_interface_GR (struct eigrp_interface *, enum GR_type, struct vty *);
+extern void eigrp_update_send_process_GR (struct eigrp *, enum GR_type, struct vty *);
+
+/*
+ * These externs are found in eigrp_query.c
+ */
+
+extern void eigrp_send_query (struct eigrp_interface *);
+extern void eigrp_query_receive (struct eigrp *, struct ip *, struct eigrp_header *,
+ struct stream *, struct eigrp_interface *, int);
+extern u_int32_t eigrp_query_send_all (struct eigrp *);
+
+/*
+ * These externs are found in eigrp_reply.c
+ */
+extern void eigrp_send_reply (struct eigrp_neighbor *, struct eigrp_prefix_entry *);
+extern void eigrp_reply_receive (struct eigrp *, struct ip *, struct eigrp_header *,
+ struct stream *, struct eigrp_interface *, int);
+
+/*
+ * These externs are found in eigrp_siaquery.c
+ */
+extern void eigrp_send_siaquery (struct eigrp_neighbor *, struct eigrp_prefix_entry *);
+extern void eigrp_siaquery_receive (struct eigrp *, struct ip *, struct eigrp_header *,
+ struct stream *, struct eigrp_interface *, int);
+
+/*
+ * These externs are found in eigrp_siareply.c
+ */
+extern void eigrp_send_siareply (struct eigrp_neighbor *, struct eigrp_prefix_entry *);
+extern void eigrp_siareply_receive (struct eigrp *, struct ip *, struct eigrp_header *,
+ struct stream *, struct eigrp_interface *, int);
+
+extern struct TLV_MD5_Authentication_Type *eigrp_authTLV_MD5_new (void);
+extern void eigrp_authTLV_MD5_free (struct TLV_MD5_Authentication_Type *);
+extern struct TLV_SHA256_Authentication_Type *eigrp_authTLV_SHA256_new (void);
+extern void eigrp_authTLV_SHA256_free (struct TLV_SHA256_Authentication_Type *);
+
+extern int eigrp_make_md5_digest (struct eigrp_interface *, struct stream *,
+ u_char);
+extern int eigrp_check_md5_digest (struct stream *, struct TLV_MD5_Authentication_Type *,
+ struct eigrp_neighbor *, u_char);
+extern int eigrp_make_sha256_digest (struct eigrp_interface *, struct stream *, u_char);
+extern int eigrp_check_sha256_digest (struct stream *, struct TLV_SHA256_Authentication_Type *,
+ struct eigrp_neighbor *, u_char );
+
+
+extern struct TLV_IPv4_Internal_type *eigrp_IPv4_InternalTLV_new (void);
+extern void eigrp_IPv4_InternalTLV_free (struct TLV_IPv4_Internal_type *);
+
+extern struct TLV_Sequence_Type *eigrp_SequenceTLV_new (void);
+
+extern const struct message eigrp_packet_type_str[];
+extern const size_t eigrp_packet_type_str_max;
+
+#endif /* _ZEBRA_EIGRP_PACKET_H */
diff --git a/eigrpd/eigrp_pkt_tlv1.c b/eigrpd/eigrp_pkt_tlv1.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/eigrpd/eigrp_pkt_tlv1.c
diff --git a/eigrpd/eigrp_pkt_tlv2.c b/eigrpd/eigrp_pkt_tlv2.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/eigrpd/eigrp_pkt_tlv2.c
diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c
new file mode 100644
index 0000000000..774461a097
--- /dev/null
+++ b/eigrpd/eigrp_query.c
@@ -0,0 +1,228 @@
+/*
+ * EIGRP Sending and Receiving EIGRP Query Packets.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "sockunion.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "checksum.h"
+#include "md5.h"
+#include "vty.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_macros.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_memory.h"
+
+u_int32_t
+eigrp_query_send_all (struct eigrp *eigrp)
+{
+ struct eigrp_interface *iface;
+ struct listnode *node, *node2, *nnode2;
+ struct eigrp_prefix_entry *pe;
+ u_int32_t counter;
+
+ if (eigrp == NULL)
+ {
+ zlog_debug("EIGRP Routing Process not enabled");
+ return 0;
+ }
+
+ counter=0;
+ for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface))
+ {
+ eigrp_send_query(iface);
+ counter++;
+ }
+
+ for (ALL_LIST_ELEMENTS(eigrp->topology_changes_internalIPV4, node2, nnode2, pe))
+ {
+ if(pe->req_action & EIGRP_FSM_NEED_QUERY)
+ {
+ pe->req_action &= ~EIGRP_FSM_NEED_QUERY;
+ listnode_delete(eigrp->topology_changes_internalIPV4, pe);
+ }
+ }
+
+ return counter;
+}
+
+/*EIGRP QUERY read function*/
+void
+eigrp_query_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
+ struct stream * s, struct eigrp_interface *ei, int size)
+{
+ struct eigrp_neighbor *nbr;
+ struct TLV_IPv4_Internal_type *tlv;
+
+ u_int16_t type;
+
+ /* increment statistics. */
+ ei->query_in++;
+
+ /* get neighbor struct */
+ nbr = eigrp_nbr_get(ei, eigrph, iph);
+
+ /* neighbor must be valid, eigrp_nbr_get creates if none existed */
+ assert(nbr);
+
+ nbr->recv_sequence_number = ntohl(eigrph->sequence);
+
+ while (s->endp > s->getp)
+ {
+ type = stream_getw(s);
+ if (type == EIGRP_TLV_IPv4_INT)
+ {
+ struct prefix_ipv4 dest_addr;
+
+ stream_set_getp(s, s->getp - sizeof(u_int16_t));
+
+ tlv = eigrp_read_ipv4_tlv(s);
+
+ dest_addr.family = AFI_IP;
+ dest_addr.prefix = tlv->destination;
+ dest_addr.prefixlen = tlv->prefix_length;
+ struct eigrp_prefix_entry *dest =
+ eigrp_topology_table_lookup_ipv4(eigrp->topology_table, &dest_addr);
+
+ /* If the destination exists (it should, but one never know)*/
+ if (dest != NULL)
+ {
+ struct eigrp_fsm_action_message *msg;
+ msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
+ sizeof(struct eigrp_fsm_action_message));
+ struct eigrp_neighbor_entry *entry =
+ eigrp_prefix_entry_lookup(dest->entries, nbr);
+ msg->packet_type = EIGRP_OPC_QUERY;
+ msg->eigrp = eigrp;
+ msg->data_type = EIGRP_TLV_IPv4_INT;
+ msg->adv_router = nbr;
+ msg->data.ipv4_int_type = tlv;
+ msg->entry = entry;
+ msg->prefix = dest;
+ int event = eigrp_get_fsm_event(msg);
+ eigrp_fsm_event(msg, event);
+ }
+ eigrp_IPv4_InternalTLV_free (tlv);
+ }
+ }
+ eigrp_hello_send_ack(nbr);
+ eigrp_query_send_all(eigrp);
+ eigrp_update_send_all(eigrp,nbr->ei);
+}
+
+void
+eigrp_send_query (struct eigrp_interface *ei)
+{
+ struct eigrp_packet *ep;
+ u_int16_t length = EIGRP_HEADER_LEN;
+ struct listnode *node, *nnode, *node2, *nnode2;
+ struct eigrp_neighbor *nbr;
+ struct eigrp_prefix_entry *pe;
+ char has_tlv;
+
+ ep = eigrp_packet_new(ei->ifp->mtu);
+
+ /* Prepare EIGRP INIT UPDATE header */
+ eigrp_packet_header_init(EIGRP_OPC_QUERY, ei, ep->s, 0,
+ ei->eigrp->sequence_number, 0);
+
+ // encode Authentication TLV, if needed
+ if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei);
+ }
+
+ has_tlv = 0;
+ for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node, nnode, pe))
+ {
+ if(pe->req_action & EIGRP_FSM_NEED_QUERY)
+ {
+ length += eigrp_add_internalTLV_to_stream(ep->s, pe);
+ for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr))
+ {
+ if(nbr->state == EIGRP_NEIGHBOR_UP)
+ {
+ listnode_add(pe->rij, nbr);
+ has_tlv = 1;
+ }
+ }
+ }
+ }
+
+ if(!has_tlv)
+ {
+ eigrp_packet_free(ep);
+ return;
+ }
+
+ if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL))
+ {
+ eigrp_make_md5_digest(ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
+ }
+
+ /* EIGRP Checksum */
+ eigrp_packet_checksum(ei, ep->s, length);
+
+ ep->length = length;
+ ep->dst.s_addr = htonl(EIGRP_MULTICAST_ADDRESS);
+
+ /*This ack number we await from neighbor*/
+ ep->sequence_number = ei->eigrp->sequence_number;
+
+ for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr))
+ {
+ if (nbr->state == EIGRP_NEIGHBOR_UP)
+ {
+ /*Put packet to retransmission queue*/
+ eigrp_fifo_push_head(nbr->retrans_queue, ep);
+
+ if (nbr->retrans_queue->count == 1)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+ }
+ }
+}
diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c
new file mode 100644
index 0000000000..e64a3d022f
--- /dev/null
+++ b/eigrpd/eigrp_reply.c
@@ -0,0 +1,249 @@
+/*
+ * EIGRP Sending and Receiving EIGRP Reply Packets.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "sockunion.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "checksum.h"
+#include "md5.h"
+#include "vty.h"
+#include "keychain.h"
+#include "plist.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_macros.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_memory.h"
+
+void
+eigrp_send_reply (struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
+{
+ struct eigrp_packet *ep;
+ u_int16_t length = EIGRP_HEADER_LEN;
+
+ struct access_list *alist;
+ struct prefix_list *plist;
+ struct access_list *alist_i;
+ struct prefix_list *plist_i;
+ struct eigrp *e;
+ struct eigrp_prefix_entry *pe2;
+
+ //TODO: Work in progress
+ /* Filtering */
+ /* get list from eigrp process */
+ e = eigrp_lookup();
+ pe2 = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY, sizeof(struct eigrp_prefix_entry));
+ memcpy(pe2,pe,sizeof(struct eigrp_prefix_entry));
+ /* Get access-lists and prefix-lists from process and interface */
+ alist = e->list[EIGRP_FILTER_OUT];
+ plist = e->prefix[EIGRP_FILTER_OUT];
+ alist_i = nbr->ei->list[EIGRP_FILTER_OUT];
+ plist_i = nbr->ei->prefix[EIGRP_FILTER_OUT];
+ zlog_info("REPLY Send: Filtering");
+
+ zlog_info("REPLY SEND Prefix: %s", inet_ntoa(nbr->src));
+ /* Check if any list fits */
+ if ((alist &&
+ access_list_apply (alist, (struct prefix *) pe2->destination_ipv4) == FILTER_DENY) ||
+ (plist && prefix_list_apply (plist, (struct prefix *) pe2->destination_ipv4) == PREFIX_DENY)||
+ (alist_i && access_list_apply (alist_i, (struct prefix *) pe2->destination_ipv4) == FILTER_DENY)||
+ (plist_i && prefix_list_apply (plist_i, (struct prefix *) pe2->destination_ipv4) == PREFIX_DENY))
+ {
+ zlog_info("REPLY SEND: Setting Metric to max");
+ pe2->reported_metric.delay = EIGRP_MAX_METRIC;
+
+ }
+ else
+ {
+ zlog_info("REPLY SEND: Not setting metric");
+ }
+
+ /*
+ * End of filtering
+ */
+
+ ep = eigrp_packet_new(nbr->ei->ifp->mtu);
+
+ /* Prepare EIGRP INIT UPDATE header */
+ eigrp_packet_header_init(EIGRP_OPC_REPLY, nbr->ei, ep->s, 0,
+ nbr->ei->eigrp->sequence_number, 0);
+
+ // encode Authentication TLV, if needed
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_MD5_to_stream(ep->s,nbr->ei);
+ }
+
+
+ length += eigrp_add_internalTLV_to_stream(ep->s, pe2);
+
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
+ }
+
+ /* EIGRP Checksum */
+ eigrp_packet_checksum(nbr->ei, ep->s, length);
+
+ ep->length = length;
+ ep->dst.s_addr = nbr->src.s_addr;
+
+ /*This ack number we await from neighbor*/
+ ep->sequence_number = nbr->ei->eigrp->sequence_number;
+
+ /*Put packet to retransmission queue*/
+ eigrp_fifo_push_head(nbr->retrans_queue, ep);
+
+ if (nbr->retrans_queue->count == 1)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+
+ XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe2);
+}
+
+/*EIGRP REPLY read function*/
+void
+eigrp_reply_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
+ struct stream * s, struct eigrp_interface *ei, int size)
+{
+ struct eigrp_neighbor *nbr;
+ struct TLV_IPv4_Internal_type *tlv;
+
+ struct access_list *alist;
+ struct prefix_list *plist;
+ struct access_list *alist_i;
+ struct prefix_list *plist_i;
+ struct eigrp *e;
+
+ u_int16_t type;
+
+ /* increment statistics. */
+ ei->reply_in++;
+
+ /* get neighbor struct */
+ nbr = eigrp_nbr_get(ei, eigrph, iph);
+
+ /* neighbor must be valid, eigrp_nbr_get creates if none existed */
+ assert(nbr);
+
+ nbr->recv_sequence_number = ntohl(eigrph->sequence);
+
+ while (s->endp > s->getp)
+ {
+ type = stream_getw(s);
+ if (type == EIGRP_TLV_IPv4_INT)
+ {
+ struct prefix_ipv4 dest_addr;
+
+ stream_set_getp(s, s->getp - sizeof(u_int16_t));
+
+ tlv = eigrp_read_ipv4_tlv(s);
+
+ dest_addr.family = AFI_IP;
+ dest_addr.prefix = tlv->destination;
+ dest_addr.prefixlen = tlv->prefix_length;
+ struct eigrp_prefix_entry *dest =
+ eigrp_topology_table_lookup_ipv4 (eigrp->topology_table, &dest_addr);
+ /*
+ * Destination must exists
+ */
+ assert(dest);
+
+ struct eigrp_fsm_action_message *msg;
+ msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
+ sizeof(struct eigrp_fsm_action_message));
+ struct eigrp_neighbor_entry *entry =
+ eigrp_prefix_entry_lookup(dest->entries, nbr);
+
+ /*
+ * Filtering
+ */
+ //TODO: Work in progress
+ /* get list from eigrp process */
+ e = eigrp_lookup();
+ /* Get access-lists and prefix-lists from process and interface */
+ alist = e->list[EIGRP_FILTER_IN];
+ plist = e->prefix[EIGRP_FILTER_IN];
+ alist_i = ei->list[EIGRP_FILTER_IN];
+ plist_i = ei->prefix[EIGRP_FILTER_IN];
+ /* Check if any list fits */
+ if ((alist &&
+ access_list_apply (alist, (struct prefix *)&dest_addr) == FILTER_DENY) ||
+ (plist &&
+ prefix_list_apply (plist, (struct prefix *)&dest_addr) == PREFIX_DENY) ||
+ (alist_i &&
+ access_list_apply (alist_i, (struct prefix *)&dest_addr) == FILTER_DENY) ||
+ (plist_i &&
+ prefix_list_apply (plist_i, (struct prefix *)&dest_addr) == PREFIX_DENY))
+ {
+ tlv->metric.delay = EIGRP_MAX_METRIC;
+ }
+ /*
+ * End of filtering
+ */
+
+ msg->packet_type = EIGRP_OPC_REPLY;
+ msg->eigrp = eigrp;
+ msg->data_type = EIGRP_TLV_IPv4_INT;
+ msg->adv_router = nbr;
+ msg->data.ipv4_int_type = tlv;
+ msg->entry = entry;
+ msg->prefix = dest;
+ int event = eigrp_get_fsm_event(msg);
+ eigrp_fsm_event(msg, event);
+
+
+ eigrp_IPv4_InternalTLV_free (tlv);
+ }
+ }
+ eigrp_hello_send_ack(nbr);
+}
+
diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c
new file mode 100644
index 0000000000..6a6168e4ff
--- /dev/null
+++ b/eigrpd/eigrp_routemap.c
@@ -0,0 +1,1242 @@
+/*
+ * EIGRP Filter Functions.
+ * Copyright (C) 2013-2015
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * Note: This file contains skeleton for all possible matches and sets,
+ * but they are hidden in comment block and not properly implemented.
+ * At this time, the only function we consider useful for our use
+ * in distribute command in EIGRP is matching destination IP (with both
+ * access and prefix list).
+ *
+ *
+ * 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 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 "memory.h"
+#include "prefix.h"
+#include "if_rmap.h"
+#include "routemap.h"
+#include "command.h"
+#include "filter.h"
+#include "log.h"
+#include "sockunion.h" /* for inet_aton () */
+#include "plist.h"
+
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrp_const.h"
+#include "eigrpd/eigrp_macros.h"
+#include "eigrpd/eigrp_routemap.h"
+
+void
+eigrp_if_rmap_update (struct if_rmap *if_rmap)
+{
+ struct interface *ifp;
+ struct eigrp_interface *ei, *ei2;
+ struct listnode *node, *nnode;
+ struct route_map *rmap;
+ struct eigrp *e;
+
+ ifp = if_lookup_by_name (if_rmap->ifname);
+ if (ifp == NULL)
+ return;
+
+ ei = NULL;
+ e = eigrp_lookup();
+ for (ALL_LIST_ELEMENTS (e->eiflist, node, nnode, ei2))
+ {
+ if(strcmp(ei2->ifp->name,ifp->name) == 0){
+ ei = ei2;
+ break;
+ }
+ }
+
+ if (if_rmap->routemap[IF_RMAP_IN])
+ {
+ rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_IN]);
+ if (rmap)
+ ei->routemap[IF_RMAP_IN] = rmap;
+ else
+ ei->routemap[IF_RMAP_IN] = NULL;
+ }
+ else
+ ei->routemap[EIGRP_FILTER_IN] = NULL;
+
+ if (if_rmap->routemap[IF_RMAP_OUT])
+ {
+ rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_OUT]);
+ if (rmap)
+ ei->routemap[IF_RMAP_OUT] = rmap;
+ else
+ ei->routemap[IF_RMAP_OUT] = NULL;
+ }
+ else
+ ei->routemap[EIGRP_FILTER_OUT] = NULL;
+}
+
+void
+eigrp_if_rmap_update_interface (struct interface *ifp)
+{
+ struct if_rmap *if_rmap;
+
+ if_rmap = if_rmap_lookup (ifp->name);
+ if (if_rmap)
+ eigrp_if_rmap_update (if_rmap);
+}
+
+void
+eigrp_routemap_update_redistribute (void)
+{
+ int i;
+ struct eigrp *e;
+
+ e = eigrp_lookup();
+
+ if (e)
+ {
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
+ {
+ if (e->route_map[i].name)
+ e->route_map[i].map =
+ route_map_lookup_by_name (e->route_map[i].name);
+ }
+ }
+}
+
+/* ARGSUSED */
+void
+eigrp_rmap_update (const char *notused)
+{
+ struct interface *ifp;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
+ eigrp_if_rmap_update_interface (ifp);
+
+ eigrp_routemap_update_redistribute ();
+}
+
+/* Add eigrp route map rule. */
+static int
+eigrp_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, "%% 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;
+}
+
+/* Delete rip route map rule. */
+static int
+eigrp_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, "%% 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;
+}
+
+/* Add eigrp route map rule. */
+static int
+eigrp_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, "%% 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, "%% Argument is malformed.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+/* Delete eigrp route map rule. */
+static int
+eigrp_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, "%% 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;
+}
+
+/* Hook function for updating route_map assignment. */
+/* ARGSUSED */
+void
+eigrp_route_map_update (const char *notused)
+{
+ int i;
+ struct eigrp *e;
+ e = eigrp_lookup();
+
+ if (e)
+ {
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
+ {
+ if (e->route_map[i].name)
+ e->route_map[i].map =
+ route_map_lookup_by_name (e->route_map[i].name);
+ }
+ }
+}
+
+
+
+/* `match metric METRIC' */
+/* 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_map_object_t type, void *object)
+{
+ // u_int32_t *metric;
+ // u_int32_t check;
+ // struct rip_info *rinfo;
+ // struct eigrp_neighbor_entry *te;
+ // struct eigrp_prefix_entry *pe;
+ // struct listnode *node, *node2, *nnode, *nnode2;
+ // struct eigrp *e;
+ //
+ // e = eigrp_lookup();
+ //
+ // if (type == RMAP_EIGRP)
+ // {
+ // metric = rule;
+ // rinfo = object;
+ //
+ // /* If external metric is available, the route-map should
+ // work on this one (for redistribute purpose) */
+ // /*check = (rinfo->external_metric) ? rinfo->external_metric :
+ // rinfo->metric;*/
+ //
+ // if (check == *metric)
+ // return RMAP_MATCH;
+ // else
+ // return RMAP_NOMATCH;
+ // }
+ return RMAP_NOMATCH;
+}
+
+/* Route map `match metric' match statement. `arg' is METRIC value */
+static void *
+route_match_metric_compile (const char *arg)
+{
+ // u_int32_t *metric;
+ //
+ // metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
+ // *metric = atoi (arg);
+ //
+ // if(*metric > 0)
+ // return metric;
+ //
+ // XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
+ return NULL;
+}
+
+/* Free route map's compiled `match metric' value. */
+static void
+route_match_metric_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for metric matching. */
+struct route_map_rule_cmd route_match_metric_cmd =
+{
+ "metric",
+ route_match_metric,
+ route_match_metric_compile,
+ route_match_metric_free
+};
+
+/* `match interface IFNAME' */
+/* Match function return 1 if match is success else return zero. */
+static route_map_result_t
+route_match_interface (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ // struct rip_info *rinfo;
+ // struct interface *ifp;
+ // char *ifname;
+ //
+ // if (type == RMAP_EIGRP)
+ // {
+ // ifname = rule;
+ // ifp = if_lookup_by_name(ifname);
+ //
+ // if (!ifp)
+ // return RMAP_NOMATCH;
+ //
+ // rinfo = object;
+ //
+ // /*if (rinfo->ifindex_out == ifp->ifindex || rinfo->ifindex == ifp->ifindex)
+ // return RMAP_MATCH;
+ // else
+ // return RMAP_NOMATCH;*/
+ // }
+ return RMAP_NOMATCH;
+}
+
+/* Route map `match interface' match statement. `arg' is IFNAME value */
+/* XXX I don`t know if I need to check does interface exist? */
+static void *
+route_match_interface_compile (const char *arg)
+{
+ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+/* Free route map's compiled `match interface' value. */
+static void
+route_match_interface_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for interface matching. */
+struct route_map_rule_cmd route_match_interface_cmd =
+{
+ "interface",
+ route_match_interface,
+ route_match_interface_compile,
+ route_match_interface_free
+};
+
+/* `match ip next-hop IP_ACCESS_LIST' */
+
+/* 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_map_object_t type, void *object)
+{
+ // struct access_list *alist;
+ // struct rip_info *rinfo;
+ // struct prefix_ipv4 p;
+ //
+ // if (type == RMAP_EIGRP)
+ // {
+ // rinfo = object;
+ // p.family = AF_INET;
+ // /*p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;*/
+ // p.prefixlen = IPV4_MAX_BITLEN;
+ //
+ // alist = access_list_lookup (AFI_IP, (char *) rule);
+ // if (alist == NULL)
+ // return RMAP_NOMATCH;
+ //
+ // return (access_list_apply (alist, &p) == FILTER_DENY ?
+ // RMAP_NOMATCH : RMAP_MATCH);
+ // }
+ return RMAP_NOMATCH;
+}
+
+/* Route map `ip next-hop' match statement. `arg' should be
+ access-list name. */
+static void *
+route_match_ip_next_hop_compile (const char *arg)
+{
+ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+/* Free route map's compiled `. */
+static void
+route_match_ip_next_hop_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for ip next-hop matching. */
+static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
+ {
+ "ip next-hop",
+ route_match_ip_next_hop,
+ route_match_ip_next_hop_compile,
+ route_match_ip_next_hop_free
+ };
+
+/* `match ip next-hop prefix-list PREFIX_LIST' */
+
+static route_map_result_t
+route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ // struct prefix_list *plist;
+ // struct rip_info *rinfo;
+ // struct prefix_ipv4 p;
+ //
+ // if (type == RMAP_EIGRP)
+ // {
+ // rinfo = object;
+ // p.family = AF_INET;
+ // /*p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;*/
+ // p.prefixlen = IPV4_MAX_BITLEN;
+ //
+ // plist = prefix_list_lookup (AFI_IP, (char *) rule);
+ // if (plist == NULL)
+ // return RMAP_NOMATCH;
+ //
+ // return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
+ // RMAP_NOMATCH : RMAP_MATCH);
+ // }
+ return RMAP_NOMATCH;
+}
+
+static void *
+route_match_ip_next_hop_prefix_list_compile (const char *arg)
+{
+ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+static void
+route_match_ip_next_hop_prefix_list_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
+{
+ "ip next-hop prefix-list",
+ route_match_ip_next_hop_prefix_list,
+ route_match_ip_next_hop_prefix_list_compile,
+ route_match_ip_next_hop_prefix_list_free
+};
+
+/* `match ip address IP_ACCESS_LIST' */
+
+/* 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_map_object_t type, void *object)
+{
+ struct access_list *alist;
+
+ if (type == RMAP_EIGRP)
+ {
+ 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);
+ }
+ return RMAP_NOMATCH;
+}
+
+/* Route map `ip address' match statement. `arg' should be
+ access-list name. */
+static void *
+route_match_ip_address_compile (const char *arg)
+{
+ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+/* Free route map's compiled `ip address' value. */
+static void
+route_match_ip_address_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for ip address matching. */
+static struct route_map_rule_cmd route_match_ip_address_cmd =
+ {
+ "ip address",
+ route_match_ip_address,
+ route_match_ip_address_compile,
+ route_match_ip_address_free
+ };
+
+/* `match ip address prefix-list PREFIX_LIST' */
+
+static route_map_result_t
+route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct prefix_list *plist;
+
+ if (type == RMAP_EIGRP)
+ {
+ 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);
+ }
+ return RMAP_NOMATCH;
+}
+
+static void *
+route_match_ip_address_prefix_list_compile (const char *arg)
+{
+ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+static void
+route_match_ip_address_prefix_list_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
+ {
+ "ip address prefix-list",
+ route_match_ip_address_prefix_list,
+ route_match_ip_address_prefix_list_compile,
+ route_match_ip_address_prefix_list_free
+ };
+
+/* `match tag TAG' */
+/* Match function return 1 if match is success else return zero. */
+static route_map_result_t
+route_match_tag (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ // u_short *tag;
+ // struct rip_info *rinfo;
+ //
+ // if (type == RMAP_EIGRP)
+ // {
+ // tag = rule;
+ // rinfo = object;
+ //
+ // /* The information stored by rinfo is host ordered. */
+ // /*if (rinfo->tag == *tag)
+ // return RMAP_MATCH;
+ // else
+ // return RMAP_NOMATCH;*/
+ // }
+ return RMAP_NOMATCH;
+}
+
+/* Route map `match tag' match statement. `arg' is TAG value */
+static void *
+route_match_tag_compile (const char *arg)
+{
+ // u_short *tag;
+ //
+ // tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
+ // *tag = atoi (arg);
+ //
+ // return tag;
+}
+
+/* Free route map's compiled `match tag' value. */
+static void
+route_match_tag_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for tag matching. */
+struct route_map_rule_cmd route_match_tag_cmd =
+ {
+ "tag",
+ route_match_tag,
+ route_match_tag_compile,
+ route_match_tag_free
+ };
+
+/* Set metric to attribute. */
+static route_map_result_t
+route_set_metric (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ // if (type == RMAP_RIP)
+ // {
+ // struct rip_metric_modifier *mod;
+ // struct rip_info *rinfo;
+ //
+ // mod = rule;
+ // rinfo = object;
+ //
+ // /*if (mod->type == metric_increment)
+ // rinfo->metric_out += mod->metric;
+ // else if (mod->type == metric_decrement)
+ // rinfo->metric_out -= mod->metric;
+ // else if (mod->type == metric_absolute)
+ // rinfo->metric_out = mod->metric;
+ //
+ // if ((signed int)rinfo->metric_out < 1)
+ // rinfo->metric_out = 1;
+ // if (rinfo->metric_out > RIP_METRIC_INFINITY)
+ // rinfo->metric_out = RIP_METRIC_INFINITY;*/
+ //
+ // rinfo->metric_set = 1;
+ // }
+ return RMAP_OKAY;
+}
+
+/* set metric compilation. */
+static void *
+route_set_metric_compile (const char *arg)
+{
+ // int len;
+ // const char *pnt;
+ // int type;
+ // long metric;
+ // char *endptr = NULL;
+ // struct rip_metric_modifier *mod;
+ //
+ // len = strlen (arg);
+ // pnt = arg;
+ //
+ // if (len == 0)
+ // return NULL;
+ //
+ // /* Examine first character. */
+ // if (arg[0] == '+')
+ // {
+ // //type = metric_increment;
+ // pnt++;
+ // }
+ // else if (arg[0] == '-')
+ // {
+ // //type = metric_decrement;
+ // pnt++;
+ // }
+ // /*else
+ // type = metric_absolute;*/
+ //
+ // /* Check beginning with digit string. */
+ // if (*pnt < '0' || *pnt > '9')
+ // return NULL;
+ //
+ // /* Convert string to integer. */
+ // metric = strtol (pnt, &endptr, 10);
+ //
+ // if (metric == LONG_MAX || *endptr != '\0')
+ // return NULL;
+ // /*if (metric < 0 || metric > RIP_METRIC_INFINITY)
+ // return NULL;*/
+ //
+ // mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
+ // sizeof (struct rip_metric_modifier));
+ // mod->type = type;
+ // mod->metric = metric;
+
+ // return mod;
+}
+
+/* Free route map's compiled `set metric' value. */
+static void
+route_set_metric_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Set metric rule structure. */
+static struct route_map_rule_cmd route_set_metric_cmd =
+ {
+ "metric",
+ route_set_metric,
+ route_set_metric_compile,
+ route_set_metric_free,
+ };
+
+/* `set ip next-hop IP_ADDRESS' */
+
+/* Set nexthop to object. ojbect must be pointer to struct attr. */
+static route_map_result_t
+route_set_ip_nexthop (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ // struct in_addr *address;
+ // struct rip_info *rinfo;
+ //
+ // if(type == RMAP_RIP)
+ // {
+ // /* Fetch routemap's rule information. */
+ // address = rule;
+ // rinfo = object;
+ //
+ // /* Set next hop value. */
+ // rinfo->nexthop_out = *address;
+ // }
+
+ return RMAP_OKAY;
+}
+
+/* Route map `ip nexthop' compile function. Given string is converted
+ to struct in_addr structure. */
+static void *
+route_set_ip_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;
+}
+
+/* Free route map's compiled `ip nexthop' value. */
+static void
+route_set_ip_nexthop_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for ip nexthop set. */
+static struct route_map_rule_cmd route_set_ip_nexthop_cmd =
+ {
+ "ip next-hop",
+ route_set_ip_nexthop,
+ route_set_ip_nexthop_compile,
+ route_set_ip_nexthop_free
+ };
+
+/* `set tag TAG' */
+
+/* Set tag to object. ojbect must be pointer to struct attr. */
+static route_map_result_t
+route_set_tag (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ // u_short *tag;
+ // struct rip_info *rinfo;
+ //
+ // if(type == RMAP_RIP)
+ // {
+ // /* Fetch routemap's rule information. */
+ // tag = rule;
+ // rinfo = object;
+ //
+ // /* Set next hop value. */
+ // rinfo->tag_out = *tag;
+ // }
+
+ return RMAP_OKAY;
+}
+
+/* Route map `tag' compile function. Given string is converted
+ to u_short. */
+static void *
+route_set_tag_compile (const char *arg)
+{
+ // u_short *tag;
+ //
+ // tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
+ // *tag = atoi (arg);
+ //
+ // return tag;
+}
+
+/* Free route map's compiled `ip nexthop' value. */
+static void
+route_set_tag_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for tag set. */
+static struct route_map_rule_cmd route_set_tag_cmd =
+ {
+ "tag",
+ route_set_tag,
+ route_set_tag_compile,
+ route_set_tag_free
+ };
+
+#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 eigrp_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 eigrp_route_match_delete (vty, vty->index, "metric", NULL);
+
+ return eigrp_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 eigrp_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 eigrp_route_match_delete (vty, vty->index, "interface", NULL);
+
+ return eigrp_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 eigrp_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 eigrp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
+
+ return eigrp_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 eigrp_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 eigrp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
+
+ return eigrp_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 eigrp_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 eigrp_route_match_delete (vty, vty->index, "ip address", NULL);
+
+ return eigrp_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 eigrp_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 eigrp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
+
+ return eigrp_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 <0-65535>",
+ MATCH_STR
+ "Match tag of route\n"
+ "Metric value\n")
+{
+ return eigrp_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 eigrp_route_match_delete (vty, vty->index, "tag", NULL);
+
+ return eigrp_route_match_delete (vty, vty->index, "tag", argv[0]);
+}
+
+ALIAS (no_match_tag,
+ no_match_tag_val_cmd,
+ "no match tag <0-65535>",
+ 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")
+{
+ return eigrp_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")
+{
+ if (argc == 0)
+ return eigrp_route_set_delete (vty, vty->index, "metric", NULL);
+
+ return eigrp_route_set_delete (vty, vty->index, "metric", argv[0]);
+}
+
+ALIAS (no_set_metric,
+ no_set_metric_val_cmd,
+ "no set metric (<0-4294967295>|<+/-metric>)",
+ NO_STR
+ SET_STR
+ "Metric value for destination routing protocol\n"
+ "Metric value\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;
+
+ ret = str2sockunion (argv[0], &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return eigrp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
+}
+
+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 eigrp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
+
+ return eigrp_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")
+
+DEFUN (set_tag,
+ set_tag_cmd,
+ "set tag <0-65535>",
+ SET_STR
+ "Tag value for routing protocol\n"
+ "Tag value\n")
+{
+ return eigrp_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 eigrp_route_set_delete (vty, vty->index, "tag", NULL);
+
+ return eigrp_route_set_delete (vty, vty->index, "tag", argv[0]);
+}
+
+ALIAS (no_set_tag,
+ no_set_tag_val_cmd,
+ "no set tag <0-65535>",
+ NO_STR
+ SET_STR
+ "Tag value for routing protocol\n"
+ "Tag value\n")
+
+
+/* Route-map init */
+void
+eigrp_route_map_init ()
+{
+ route_map_init ();
+ route_map_init_vty ();
+ route_map_add_hook (eigrp_route_map_update);
+ route_map_delete_hook (eigrp_route_map_update);
+
+ /*route_map_install_match (&route_match_metric_cmd);
+ route_map_install_match (&route_match_interface_cmd);*/
+ /*route_map_install_match (&route_match_ip_next_hop_cmd);
+ route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
+ route_map_install_match (&route_match_ip_address_cmd);
+ route_map_install_match (&route_match_ip_address_prefix_list_cmd);*/
+ /*route_map_install_match (&route_match_tag_cmd);*/
+
+ /*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, &route_match_metric_cmd);
+ install_element (RMAP_NODE, &no_match_metric_cmd);
+ install_element (RMAP_NODE, &no_match_metric_val_cmd);
+ install_element (RMAP_NODE, &route_match_interface_cmd);
+ install_element (RMAP_NODE, &no_match_interface_cmd);
+ install_element (RMAP_NODE, &no_match_interface_val_cmd);
+ install_element (RMAP_NODE, &route_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, &route_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, &route_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, &route_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, &route_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, &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/eigrpd/eigrp_routemap.h b/eigrpd/eigrp_routemap.h
new file mode 100644
index 0000000000..0fee25b9ab
--- /dev/null
+++ b/eigrpd/eigrp_routemap.h
@@ -0,0 +1,18 @@
+/*
+ * eigrp_routemap.h
+ *
+ * Created on: Nov 19, 2015
+ * Author: root
+ */
+
+#ifndef EIGRPD_EIGRP_ROUTEMAP_H_
+#define EIGRPD_EIGRP_ROUTEMAP_H_
+
+extern void eigrp_route_map_update (const char *);
+extern void eigrp_route_map_init ();
+extern void eigrp_if_rmap_update (struct if_rmap *);
+extern void eigrp_if_rmap_update_interface (struct interface *);
+extern void eigrp_routemap_update_redistribute (void);
+extern void eigrp_rmap_update (const char *);
+
+#endif /* EIGRPD_EIGRP_ROUTEMAP_H_ */
diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c
new file mode 100644
index 0000000000..d521a57baf
--- /dev/null
+++ b/eigrpd/eigrp_siaquery.c
@@ -0,0 +1,167 @@
+/*
+ * EIGRP Sending and Receiving EIGRP SIA-Query Packets.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "sockunion.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "checksum.h"
+#include "md5.h"
+#include "vty.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_macros.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_memory.h"
+
+/*EIGRP SIA-QUERY read function*/
+void
+eigrp_siaquery_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
+ struct stream * s, struct eigrp_interface *ei, int size)
+{
+ struct eigrp_neighbor *nbr;
+ struct TLV_IPv4_Internal_type *tlv;
+
+ u_int16_t type;
+
+ /* increment statistics. */
+ ei->siaQuery_in++;
+
+ /* get neighbor struct */
+ nbr = eigrp_nbr_get(ei, eigrph, iph);
+
+ /* neighbor must be valid, eigrp_nbr_get creates if none existed */
+ assert(nbr);
+
+ nbr->recv_sequence_number = ntohl(eigrph->sequence);
+
+ while (s->endp > s->getp)
+ {
+ type = stream_getw(s);
+ if (type == EIGRP_TLV_IPv4_INT)
+ {
+ struct prefix_ipv4 dest_addr;
+
+ stream_set_getp(s, s->getp - sizeof(u_int16_t));
+
+ tlv = eigrp_read_ipv4_tlv(s);
+
+ dest_addr.family = AFI_IP;
+ dest_addr.prefix = tlv->destination;
+ dest_addr.prefixlen = tlv->prefix_length;
+ struct eigrp_prefix_entry *dest =
+ eigrp_topology_table_lookup_ipv4(eigrp->topology_table, &dest_addr);
+
+ /* If the destination exists (it should, but one never know)*/
+ if (dest != NULL)
+ {
+ struct eigrp_fsm_action_message *msg;
+ msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
+ sizeof(struct eigrp_fsm_action_message));
+ struct eigrp_neighbor_entry *entry =
+ eigrp_prefix_entry_lookup(dest->entries, nbr);
+ msg->packet_type = EIGRP_OPC_SIAQUERY;
+ msg->eigrp = eigrp;
+ msg->data_type = EIGRP_TLV_IPv4_INT;
+ msg->adv_router = nbr;
+ msg->data.ipv4_int_type = tlv;
+ msg->entry = entry;
+ msg->prefix = dest;
+ int event = eigrp_get_fsm_event(msg);
+ eigrp_fsm_event(msg, event);
+ }
+ eigrp_IPv4_InternalTLV_free (tlv);
+ }
+ }
+ eigrp_hello_send_ack(nbr);
+}
+
+void
+eigrp_send_siaquery (struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
+{
+ struct eigrp_packet *ep;
+ u_int16_t length = EIGRP_HEADER_LEN;
+
+ ep = eigrp_packet_new(nbr->ei->ifp->mtu);
+
+ /* Prepare EIGRP INIT UPDATE header */
+ eigrp_packet_header_init(EIGRP_OPC_SIAQUERY, nbr->ei, ep->s, 0,
+ nbr->ei->eigrp->sequence_number, 0);
+
+ // encode Authentication TLV, if needed
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_MD5_to_stream(ep->s,nbr->ei);
+ }
+
+ length += eigrp_add_internalTLV_to_stream(ep->s, pe);
+
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
+ }
+
+ /* EIGRP Checksum */
+ eigrp_packet_checksum(nbr->ei, ep->s, length);
+
+ ep->length = length;
+ ep->dst.s_addr = nbr->src.s_addr;
+
+ /*This ack number we await from neighbor*/
+ ep->sequence_number = nbr->ei->eigrp->sequence_number;
+
+ if (nbr->state == EIGRP_NEIGHBOR_UP)
+ {
+ /*Put packet to retransmission queue*/
+ eigrp_fifo_push_head(nbr->retrans_queue, ep);
+
+ if (nbr->retrans_queue->count == 1)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+ }
+ else
+ eigrp_packet_free(ep);
+}
diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c
new file mode 100644
index 0000000000..dbf451800e
--- /dev/null
+++ b/eigrpd/eigrp_siareply.c
@@ -0,0 +1,168 @@
+/*
+ * EIGRP Sending and Receiving EIGRP SIA-Reply Packets.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "sockunion.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "checksum.h"
+#include "md5.h"
+#include "vty.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_macros.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_memory.h"
+
+/*EIGRP SIA-REPLY read function*/
+void
+eigrp_siareply_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
+ struct stream * s, struct eigrp_interface *ei, int size)
+{
+ struct eigrp_neighbor *nbr;
+ struct TLV_IPv4_Internal_type *tlv;
+
+ u_int16_t type;
+
+ /* increment statistics. */
+ ei->siaReply_in++;
+
+ /* get neighbor struct */
+ nbr = eigrp_nbr_get(ei, eigrph, iph);
+
+ /* neighbor must be valid, eigrp_nbr_get creates if none existed */
+ assert(nbr);
+
+ nbr->recv_sequence_number = ntohl(eigrph->sequence);
+
+ while (s->endp > s->getp)
+ {
+ type = stream_getw(s);
+ if (type == EIGRP_TLV_IPv4_INT)
+ {
+ struct prefix_ipv4 dest_addr;
+
+ stream_set_getp(s, s->getp - sizeof(u_int16_t));
+
+ tlv = eigrp_read_ipv4_tlv(s);
+
+ dest_addr.family = AFI_IP;
+ dest_addr.prefix = tlv->destination;
+ dest_addr.prefixlen = tlv->prefix_length;
+ struct eigrp_prefix_entry *dest =
+ eigrp_topology_table_lookup_ipv4(eigrp->topology_table, &dest_addr);
+
+ /* If the destination exists (it should, but one never know)*/
+ if (dest != NULL)
+ {
+ struct eigrp_fsm_action_message *msg;
+ msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
+ sizeof(struct eigrp_fsm_action_message));
+ struct eigrp_neighbor_entry *entry =
+ eigrp_prefix_entry_lookup(dest->entries, nbr);
+ msg->packet_type = EIGRP_OPC_SIAQUERY;
+ msg->eigrp = eigrp;
+ msg->data_type = EIGRP_TLV_IPv4_INT;
+ msg->adv_router = nbr;
+ msg->data.ipv4_int_type = tlv;
+ msg->entry = entry;
+ msg->prefix = dest;
+ int event = eigrp_get_fsm_event(msg);
+ eigrp_fsm_event(msg, event);
+ }
+ eigrp_IPv4_InternalTLV_free (tlv);
+ }
+ }
+ eigrp_hello_send_ack(nbr);
+}
+
+void
+eigrp_send_siareply (struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
+{
+ struct eigrp_packet *ep;
+ u_int16_t length = EIGRP_HEADER_LEN;
+
+ ep = eigrp_packet_new(nbr->ei->ifp->mtu);
+
+ /* Prepare EIGRP INIT UPDATE header */
+ eigrp_packet_header_init(EIGRP_OPC_SIAREPLY, nbr->ei, ep->s, 0,
+ nbr->ei->eigrp->sequence_number, 0);
+
+ // encode Authentication TLV, if needed
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_MD5_to_stream(ep->s,nbr->ei);
+ }
+
+ length += eigrp_add_internalTLV_to_stream(ep->s, pe);
+
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
+ }
+
+ /* EIGRP Checksum */
+ eigrp_packet_checksum(nbr->ei, ep->s, length);
+
+ ep->length = length;
+ ep->dst.s_addr = nbr->src.s_addr;
+
+ /*This ack number we await from neighbor*/
+ ep->sequence_number = nbr->ei->eigrp->sequence_number;
+
+ if (nbr->state == EIGRP_NEIGHBOR_UP)
+ {
+ /*Put packet to retransmission queue*/
+ eigrp_fifo_push_head(nbr->retrans_queue, ep);
+
+ if (nbr->retrans_queue->count == 1)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+ }
+ else
+ eigrp_packet_free(ep);
+}
+
+
diff --git a/eigrpd/eigrp_snmp.c b/eigrpd/eigrp_snmp.c
new file mode 100644
index 0000000000..4b8d1bb393
--- /dev/null
+++ b/eigrpd/eigrp_snmp.c
@@ -0,0 +1,1388 @@
+/*
+ * EIGRP SNMP Support.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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>
+
+#ifdef HAVE_SNMP
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+
+#include "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "sockunion.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "checksum.h"
+#include "md5.h"
+#include "keychain.h"
+#include "smux.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_snmp.h"
+
+struct list *eigrp_snmp_iflist;
+
+/* Declare static local variables for convenience. */
+SNMP_LOCAL_VARIABLES
+
+/* EIGRP-MIB - 1.3.6.1.4.1.9.9.449.1*/
+#define EIGRPMIB 1,3,6,1,4,1,9,9,449,1
+
+/* EIGRP-MIB instances. */
+oid eigrp_oid [] = { EIGRPMIB };
+
+/* EIGRP VPN entry */
+#define EIGRPVPNID 1
+#define EIGRPVPNNAME 2
+
+/* EIGRP Traffic statistics entry */
+#define EIGRPASNUMBER 1
+#define EIGRPNBRCOUNT 2
+#define EIGRPHELLOSSENT 3
+#define EIGRPHELLOSRCVD 4
+#define EIGRPUPDATESSENT 5
+#define EIGRPUPDATESRCVD 6
+#define EIGRPQUERIESSENT 7
+#define EIGRPQUERIESRCVD 8
+#define EIGRPREPLIESSENT 9
+#define EIGRPREPLIESRCVD 10
+#define EIGRPACKSSENT 11
+#define EIGRPACKSRCVD 12
+#define EIGRPINPUTQHIGHMARK 13
+#define EIGRPINPUTQDROPS 14
+#define EIGRPSIAQUERIESSENT 15
+#define EIGRPSIAQUERIESRCVD 16
+#define EIGRPASROUTERIDTYPE 17
+#define EIGRPASROUTERID 18
+#define EIGRPTOPOROUTES 19
+#define EIGRPHEADSERIAL 20
+#define EIGRPNEXTSERIAL 21
+#define EIGRPXMITPENDREPLIES 22
+#define EIGRPXMITDUMMIES 23
+
+/* EIGRP topology entry */
+#define EIGRPDESTNETTYPE 1
+#define EIGRPDESTNET 2
+#define EIGRPDESTNETPREFIXLEN 4
+#define EIGRPACTIVE 5
+#define EIGRPSTUCKINACTIVE 6
+#define EIGRPDESTSUCCESSORS 7
+#define EIGRPFDISTANCE 8
+#define EIGRPROUTEORIGINTYPE 9
+#define EIGRPROUTEORIGINADDRTYPE 10
+#define EIGRPROUTEORIGINADDR 11
+#define EIGRPNEXTHOPADDRESSTYPE 12
+#define EIGRPNEXTHOPADDRESS 13
+#define EIGRPNEXTHOPINTERFACE 14
+#define EIGRPDISTANCE 15
+#define EIGRPREPORTDISTANCE 16
+
+/* EIGRP peer entry */
+#define EIGRPHANDLE 1
+#define EIGRPPEERADDRTYPE 2
+#define EIGRPPEERADDR 3
+#define EIGRPPEERIFINDEX 4
+#define EIGRPHOLDTIME 5
+#define EIGRPUPTIME 6
+#define EIGRPSRTT 7
+#define EIGRPRTO 8
+#define EIGRPPKTSENQUEUED 9
+#define EIGRPLASTSEQ 10
+#define EIGRPVERSION 11
+#define EIGRPRETRANS 12
+#define EIGRPRETRIES 13
+
+/* EIGRP interface entry */
+#define EIGRPPEERCOUNT 3
+#define EIGRPXMITRELIABLEQ 4
+#define EIGRPXMITUNRELIABLEQ 5
+#define EIGRPMEANSRTT 6
+#define EIGRPPACINGRELIABLE 7
+#define EIGRPPACINGUNRELIABLE 8
+#define EIGRPMFLOWTIMER 9
+#define EIGRPPENDINGROUTES 10
+#define EIGRPHELLOINTERVAL 11
+#define EIGRPXMITNEXTSERIAL 12
+#define EIGRPUMCASTS 13
+#define EIGRPRMCASTS 14
+#define EIGRPUUCASTS 15
+#define EIGRPRUCASTS 16
+#define EIGRPMCASTEXCEPTS 17
+#define EIGRPCRPKTS 18
+#define EIGRPACKSSUPPRESSED 19
+#define EIGRPRETRANSSENT 20
+#define EIGRPOOSRCVD 21
+#define EIGRPAUTHMODE 22
+#define EIGRPAUTHKEYCHAIN 23
+
+/* SNMP value hack. */
+#define COUNTER ASN_COUNTER
+#define INTEGER ASN_INTEGER
+#define GAUGE ASN_GAUGE
+#define TIMETICKS ASN_TIMETICKS
+#define IPADDRESS ASN_IPADDRESS
+#define STRING ASN_OCTET_STR
+#define IPADDRESSPREFIXLEN ASN_INTEGER
+#define IPADDRESSTYPE ASN_INTEGER
+#define INTERFACEINDEXORZERO ASN_INTEGER
+#define UINTEGER ASN_UNSIGNED
+
+
+
+
+/* Hook functions. */
+static u_char *eigrpVpnEntry (struct variable *, oid *, size_t *,
+ int, size_t *, WriteMethod **);
+static u_char *eigrpTraffStatsEntry (struct variable *, oid *, size_t *, int,
+ size_t *, WriteMethod **);
+static u_char *eigrpTopologyEntry (struct variable *, oid *, size_t *,
+ int, size_t *, WriteMethod **);
+static u_char *eigrpPeerEntry (struct variable *, oid *, size_t *, int,
+ size_t *, WriteMethod **);
+static u_char *eigrpInterfaceEntry (struct variable *, oid *, size_t *, int,
+ size_t *, WriteMethod **);
+
+
+struct variable eigrp_variables[] =
+ {
+ /* EIGRP vpn variables */
+ {EIGRPVPNID, INTEGER, NOACCESS, eigrpVpnEntry,
+ 4, {1, 1, 1, 1}},
+ {EIGRPVPNNAME, STRING, RONLY, eigrpVpnEntry,
+ 4, {1, 1, 1, 2}},
+
+ /* EIGRP traffic stats variables */
+ {EIGRPASNUMBER, UINTEGER, NOACCESS, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 1}},
+ {EIGRPNBRCOUNT, UINTEGER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 2}},
+ {EIGRPHELLOSSENT, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 3}},
+ {EIGRPHELLOSRCVD, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 4}},
+ {EIGRPUPDATESSENT, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 5}},
+ {EIGRPUPDATESRCVD, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 6}},
+ {EIGRPQUERIESSENT, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 7}},
+ {EIGRPQUERIESRCVD, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 8}},
+ {EIGRPREPLIESSENT, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 9}},
+ {EIGRPREPLIESRCVD, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 10}},
+ {EIGRPACKSSENT, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 11}},
+ {EIGRPACKSRCVD, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 12}},
+ {EIGRPINPUTQHIGHMARK, INTEGER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 13}},
+ {EIGRPINPUTQDROPS, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 14}},
+ {EIGRPSIAQUERIESSENT, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 15}},
+ {EIGRPSIAQUERIESRCVD, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 16}},
+ {EIGRPASROUTERIDTYPE, IPADDRESSTYPE, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 17}},
+ {EIGRPASROUTERID, IPADDRESS, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 18}},
+ {EIGRPTOPOROUTES, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 19}},
+ {EIGRPHEADSERIAL, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 20}},
+ {EIGRPNEXTSERIAL, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 21}},
+ {EIGRPXMITPENDREPLIES, INTEGER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 22}},
+ {EIGRPXMITDUMMIES, COUNTER, RONLY, eigrpTraffStatsEntry,
+ 4, {2, 1, 1, 23}},
+
+ /* EIGRP topology variables */
+ {EIGRPDESTNETTYPE, IPADDRESSTYPE, NOACCESS, eigrpTopologyEntry,
+ 4, {3, 1, 1, 1}},
+ {EIGRPDESTNET, IPADDRESSPREFIXLEN, NOACCESS, eigrpTopologyEntry,
+ 4, {3, 1, 1, 2}},
+ {EIGRPDESTNETPREFIXLEN, IPADDRESSTYPE, NOACCESS, eigrpTopologyEntry,
+ 4, {3, 1, 1, 4}},
+ {EIGRPACTIVE, INTEGER, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 5}},
+ {EIGRPSTUCKINACTIVE, INTEGER, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 6}},
+ {EIGRPDESTSUCCESSORS, INTEGER, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 7}},
+ {EIGRPFDISTANCE, INTEGER, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 8}},
+ {EIGRPROUTEORIGINTYPE, STRING, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 9}},
+ {EIGRPROUTEORIGINADDRTYPE, IPADDRESSTYPE, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 10}},
+ {EIGRPROUTEORIGINADDR, IPADDRESS, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 11}},
+ {EIGRPNEXTHOPADDRESSTYPE, IPADDRESSTYPE, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 12}},
+ {EIGRPNEXTHOPADDRESS, IPADDRESS, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 13}},
+ {EIGRPNEXTHOPINTERFACE, STRING, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 14}},
+ {EIGRPDISTANCE, INTEGER, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 15}},
+ {EIGRPREPORTDISTANCE, INTEGER, RONLY, eigrpTopologyEntry,
+ 4, {3, 1, 1, 16}},
+
+ /* EIGRP peer variables */
+ {EIGRPHANDLE, INTEGER, NOACCESS, eigrpPeerEntry,
+ 4, {4, 1, 1, 1}},
+ {EIGRPPEERADDRTYPE, IPADDRESSTYPE, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 2}},
+ {EIGRPPEERADDR, IPADDRESS, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 3}},
+ {EIGRPPEERIFINDEX, INTERFACEINDEXORZERO, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 4}},
+ {EIGRPHOLDTIME, INTEGER, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 5}},
+ {EIGRPUPTIME, STRING, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 6}},
+ {EIGRPSRTT, INTEGER, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 7}},
+ {EIGRPRTO, INTEGER, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 8}},
+ {EIGRPPKTSENQUEUED, INTEGER, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 9}},
+ {EIGRPLASTSEQ, INTEGER, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 10}},
+ {EIGRPVERSION, STRING, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 11}},
+ {EIGRPRETRANS, COUNTER, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 12}},
+ {EIGRPRETRIES, INTEGER, RONLY, eigrpPeerEntry,
+ 4, {4, 1, 1, 13}},
+
+ /* EIGRP interface variables */
+ {EIGRPPEERCOUNT, GAUGE, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 3}},
+ {EIGRPXMITRELIABLEQ, GAUGE, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 4}},
+ {EIGRPXMITUNRELIABLEQ, GAUGE, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 5}},
+ {EIGRPMEANSRTT, INTEGER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 6}},
+ {EIGRPPACINGRELIABLE, INTEGER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 7}},
+ {EIGRPPACINGUNRELIABLE, INTEGER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 8}},
+ {EIGRPMFLOWTIMER, INTEGER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 9}},
+ {EIGRPPENDINGROUTES, GAUGE, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 10}},
+ {EIGRPHELLOINTERVAL, INTEGER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 11}},
+ {EIGRPXMITNEXTSERIAL, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 12}},
+ {EIGRPUMCASTS, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 13}},
+ {EIGRPRMCASTS, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 14}},
+ {EIGRPUUCASTS, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 15}},
+ {EIGRPRUCASTS, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 16}},
+ {EIGRPMCASTEXCEPTS, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 17}},
+ {EIGRPCRPKTS, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 18}},
+ {EIGRPACKSSUPPRESSED, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 19}},
+ {EIGRPRETRANSSENT, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 20}},
+ {EIGRPOOSRCVD, COUNTER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 21}},
+ {EIGRPAUTHMODE, INTEGER, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 22}},
+ {EIGRPAUTHKEYCHAIN, STRING, RONLY, eigrpInterfaceEntry,
+ 4, {5, 1, 1, 23}}
+};
+
+static struct eigrp_neighbor *
+eigrp_snmp_nbr_lookup (struct eigrp *eigrp, struct in_addr *nbr_addr,
+ unsigned int *ifindex)
+{
+ struct listnode *node, *nnode, *node2, *nnode2;
+ struct eigrp_interface *ei;
+ struct eigrp_neighbor *nbr;
+
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
+ {
+ if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
+ {
+ return nbr;
+ }
+ }
+ }
+ return NULL;
+}
+
+static struct eigrp_neighbor *
+eigrp_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
+ int first)
+{
+ struct listnode *node, *nnode, *node2, *nnode2;
+ struct eigrp_interface *ei;
+ struct eigrp_neighbor *nbr;
+ struct route_node *rn;
+ struct eigrp_neighbor *min = NULL;
+ struct eigrp *eigrp = eigrp;
+
+ eigrp = eigrp_lookup ();
+
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
+ {
+ if (first)
+ {
+ if (! min)
+ min = nbr;
+ else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
+ min = nbr;
+ }
+ else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
+ {
+ if (! min)
+ min = nbr;
+ else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
+ min = nbr;
+ }
+ }
+ }
+ if (min)
+ {
+ *nbr_addr = min->src;
+ *ifindex = 0;
+ return min;
+ }
+ return NULL;
+}
+
+static struct eigrp_neighbor *
+eigrpNbrLookup (struct variable *v, oid *name, size_t *length,
+ struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
+{
+ unsigned int len;
+ int first;
+ struct eigrp_neighbor *nbr;
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+
+ if (! eigrp)
+ return NULL;
+
+ if (exact)
+ {
+ if (*length != v->namelen + IN_ADDR_SIZE + 1)
+ return NULL;
+
+ oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
+ *ifindex = name[v->namelen + IN_ADDR_SIZE];
+
+ return eigrp_snmp_nbr_lookup (eigrp, nbr_addr, ifindex);
+ }
+ else
+ {
+ first = 0;
+ len = *length - v->namelen;
+
+ if (len <= 0)
+ first = 1;
+
+ if (len > IN_ADDR_SIZE)
+ len = IN_ADDR_SIZE;
+
+ oid2in_addr (name + v->namelen, len, nbr_addr);
+
+ len = *length - v->namelen - IN_ADDR_SIZE;
+ if (len >= 1)
+ *ifindex = name[v->namelen + IN_ADDR_SIZE];
+
+ nbr = eigrp_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
+
+ if (nbr)
+ {
+ *length = v->namelen + IN_ADDR_SIZE + 1;
+ oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
+ name[v->namelen + IN_ADDR_SIZE] = *ifindex;
+ return nbr;
+ }
+ }
+ return NULL;
+}
+
+
+static u_char *
+eigrpVpnEntry (struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+
+ /* Check whether the instance identifier is valid */
+ if (smux_header_generic (v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ /* Return the current value of the variable */
+ switch (v->magic)
+ {
+ case EIGRPVPNID: /* 1 */
+ /* The unique VPN identifier */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPVPNNAME: /* 2 */
+ /* The name given to the VPN */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ default:
+ return NULL;
+ }
+ return NULL;
+}
+
+static uint32_t
+eigrp_neighbor_count(struct eigrp *eigrp)
+{
+ uint32_t count;
+ struct eigrp_interface *ei;
+ struct listnode *node, *node2, *nnode2;
+ struct eigrp_neighbor *nbr;
+
+ if (eigrp == NULL)
+ {
+ return 0;
+ }
+
+ count = 0;
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
+ {
+ if (nbr->state == EIGRP_NEIGHBOR_UP)
+ count++;
+ }
+ }
+
+ return count;
+}
+
+
+static u_char *
+eigrpTraffStatsEntry (struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct listnode *node, *nnode;
+ int counter;
+
+ eigrp = eigrp_lookup ();
+
+ /* Check whether the instance identifier is valid */
+ if (smux_header_generic (v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ /* Return the current value of the variable */
+ switch (v->magic)
+ {
+ case EIGRPASNUMBER: /* 1 */
+ /* AS-number of this EIGRP instance. */
+ if (eigrp)
+ return SNMP_INTEGER (eigrp->AS);
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPNBRCOUNT: /* 2 */
+ /* Neighbor count of this EIGRP instance */
+ if (eigrp)
+ return SNMP_INTEGER (eigrp_neighbor_count (eigrp));
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPHELLOSSENT: /* 3 */
+ /* Hello packets output count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->hello_out;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPHELLOSRCVD: /* 4 */
+ /* Hello packets input count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->hello_in;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPUPDATESSENT: /* 5 */
+ /* Update packets output count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->update_out;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPUPDATESRCVD: /* 6 */
+ /* Update packets input count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->update_in;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPQUERIESSENT: /* 7 */
+ /* Querry packets output count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->query_out;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPQUERIESRCVD: /* 8 */
+ /* Querry packets input count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->query_in;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPREPLIESSENT: /* 9 */
+ /* Reply packets output count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->reply_out;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPREPLIESRCVD: /* 10 */
+ /* Reply packets input count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->reply_in;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPACKSSENT: /* 11 */
+ /* Acknowledgement packets output count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->ack_out;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPACKSRCVD: /* 12 */
+ /* Acknowledgement packets input count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->ack_in;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPINPUTQHIGHMARK: /* 13 */
+ /* The highest number of EIGRP packets in the input queue */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPINPUTQDROPS: /* 14 */
+ /* The number of EIGRP packets dropped from the input queue */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPSIAQUERIESSENT: /* 15 */
+ /* SIA querry packets output count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->siaQuery_out;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPSIAQUERIESRCVD: /* 16 */
+ /* SIA querry packets input count */
+ if (eigrp)
+ {
+ counter = 0;
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ counter += ei->siaQuery_in;
+ }
+ return SNMP_INTEGER (counter);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPASROUTERIDTYPE: /* 17 */
+ /* Whether the router ID is set manually or automatically */
+ if (eigrp)
+ if(eigrp->router_id_static!=0)
+ return SNMP_INTEGER(1);
+ else
+ return SNMP_INTEGER(1);
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPASROUTERID: /* 18 */
+ /* Router ID for this EIGRP AS */
+ if (eigrp)
+ if(eigrp->router_id_static!=0)
+ return SNMP_INTEGER (eigrp->router_id_static);
+ else
+ return SNMP_INTEGER (eigrp->router_id);
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPTOPOROUTES: /* 19 */
+ /* The total number of EIGRP derived routes currently existing
+ in the topology table for the AS */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPHEADSERIAL: /* 20 */
+ /* The serial number of the first route in the internal
+ sequence for an AS*/
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPNEXTSERIAL: /* 21 */
+ /* The serial number that would be assigned to the next new
+ or changed route in the topology table for the AS*/
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPXMITPENDREPLIES: /* 22 */
+ /* Total number of outstanding replies expected to queries
+ that have been sent to peers in the current AS*/
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPXMITDUMMIES: /* 23 */
+ /* Total number of currently existing dummies associated with the AS*/
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ default:
+ return NULL;
+ }
+ return NULL;
+}
+
+static u_char *
+eigrpTopologyEntry (struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct listnode *node, *nnode;
+
+ eigrp = eigrp_lookup ();
+
+ /* Check whether the instance identifier is valid */
+ if (smux_header_generic (v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ /* Return the current value of the variable */
+ switch (v->magic)
+ {
+ case EIGRPDESTNETTYPE: /* 1 */
+ /* The format of the destination IP network number for a single
+ route in the topology table*/
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPDESTNET: /* 2 */
+ /* The destination IP network number for a single route in the topology table*/
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPDESTNETPREFIXLEN: /* 4 */
+ /* The prefix length associated with the destination IP network address
+ for a single route in the topology table in the AS*/
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPACTIVE: /* 5 */
+ /* A value of true(1) indicates the route to the destination network has failed
+ A value of false(2) indicates the route is stable (passive).*/
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPSTUCKINACTIVE: /* 6 */
+ /* A value of true(1) indicates that that this route which is in active state
+ has not received any replies to queries for alternate paths */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPDESTSUCCESSORS: /* 7 */
+ /* Next routing hop for a path to the destination IP network */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPFDISTANCE: /* 8 */
+ /* Minimum distance from this router to the destination IP network */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPROUTEORIGINTYPE: /* 9 */
+ /* Text string describing the internal origin of the EIGRP route */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPROUTEORIGINADDRTYPE: /* 10 */
+ /* The format of the IP address defined as the origin of this
+ topology route entry */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPROUTEORIGINADDR: /* 11 */
+ /* If the origin of the topology route entry is external to this router,
+ then this object is the IP address of the router from which it originated */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPNEXTHOPADDRESSTYPE: /* 12 */
+ /* The format of the next hop IP address */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPNEXTHOPADDRESS: /* 13 */
+ /* Next hop IP address for the route */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPNEXTHOPINTERFACE: /* 14 */
+ /* The interface through which the next hop IP address is reached */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPDISTANCE: /* 15 */
+ /* The computed distance to the destination network entry from this router */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPREPORTDISTANCE: /* 16 */
+ /* The computed distance to the destination network in the topology entry
+ reported to this router by the originator of this route */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ default:
+ return NULL;
+ }
+ return NULL;
+}
+
+static u_char *
+eigrpPeerEntry (struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct listnode *node, *nnode;
+ struct eigrp_neighbor *nbr;
+ struct in_addr nbr_addr;
+ unsigned int ifindex;
+
+ eigrp = eigrp_lookup ();
+
+ /* Check whether the instance identifier is valid */
+ if (smux_header_generic (v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ memset (&nbr_addr, 0, sizeof (struct in_addr));
+ ifindex = 0;
+
+ nbr = eigrpNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
+ if (! nbr)
+ return NULL;
+ ei = nbr->ei;
+ if (! ei)
+ return NULL;
+
+ /* Return the current value of the variable */
+ switch (v->magic)
+ {
+ case EIGRPHANDLE: /* 1 */
+ /* The unique internal identifier for the peer in the AS */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPPEERADDRTYPE: /* 2 */
+ /* The format of the remote source IP address used by the peer */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPPEERADDR: /* 3 */
+ /* The source IP address used by the peer */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPPEERIFINDEX: /* 4 */
+ /* The ifIndex of the interface on this router */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPHOLDTIME: /* 5 */
+ /* How much time must pass without receiving a hello packet from this
+ EIGRP peer before this router declares the peer down */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPUPTIME: /* 6 */
+ /* The elapsed time since the EIGRP adjacency was first established */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPSRTT: /* 7 */
+ /* The computed smooth round trip time for packets to and from the peer */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPRTO: /* 8 */
+ /* The computed retransmission timeout for the peer */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPPKTSENQUEUED: /* 9 */
+ /* The number of any EIGRP packets currently enqueued */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPLASTSEQ: /* 10 */
+ /* sequence number of the last EIGRP packet sent to this peer */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPVERSION: /* 11 */
+ /* The EIGRP version information reported by the remote peer */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPRETRANS: /* 12 */
+ /* The cumulative number of retransmissions to this peer */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPRETRIES: /* 13 */
+ /* The number of times the current unacknowledged packet has been retried */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ default:
+ return NULL;
+ }
+ return NULL;
+}
+
+static u_char *
+eigrpInterfaceEntry (struct variable *v, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct listnode *node, *nnode;
+ struct keychain *keychain;
+ struct list *keylist;
+ int counter;
+
+ eigrp = eigrp_lookup ();
+
+ /* Check whether the instance identifier is valid */
+ if (smux_header_generic (v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
+ return NULL;
+
+ /* Return the current value of the variable */
+ switch (v->magic)
+ {
+ case EIGRPPEERCOUNT: /* 3 */
+ /* The number of EIGRP adjacencies currently formed with
+ peers reached through this interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER (eigrp_neighbor_count (eigrp));
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPXMITRELIABLEQ: /* 4 */
+ /* The number of EIGRP packets currently waiting in the reliable
+ transport transmission queue */
+ if (eigrp)
+ {
+ return SNMP_INTEGER (1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPXMITUNRELIABLEQ: /* 5 */
+ /* The number of EIGRP packets currently waiting in the unreliable
+ transport transmission queue */
+ if (eigrp)
+ {
+ return SNMP_INTEGER (1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPMEANSRTT: /* 6 */
+ /* The average of all the computed smooth round trip time values
+ for a packet to and from all peers established on this interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPPACINGRELIABLE: /* 7 */
+ /* The configured time interval between EIGRP packet transmissions */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPPACINGUNRELIABLE: /* 8 */
+ /* The configured time interval between EIGRP packet transmissions
+ on the interface when the unreliable transport method is used */
+ if (eigrp)
+ {
+ return SNMP_INTEGER (1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPMFLOWTIMER: /* 9 */
+ /* The configured multicast flow control timer value */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPPENDINGROUTES: /* 10 */
+ /* The number of queued EIGRP routing updates awaiting transmission */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPHELLOINTERVAL: /* 11 */
+ /* The configured time interval between Hello packet transmissions */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPXMITNEXTSERIAL: /* 12 */
+ /* The serial number of the next EIGRP packet that is to be queued
+ for transmission */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPUMCASTS: /* 13 */
+ /* The total number of unreliable EIGRP multicast packets sent
+ on this interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPRMCASTS: /* 14 */
+ /* The total number of reliable EIGRP multicast packets sent
+ on this interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPUUCASTS: /* 15 */
+ /* The total number of unreliable EIGRP unicast packets sent
+ on this interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPRUCASTS: /* 16 */
+ /* The total number of reliable EIGRP unicast packets sent
+ on this interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPMCASTEXCEPTS: /* 17 */
+ /* The total number of EIGRP multicast exception transmissions */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPCRPKTS: /* 18 */
+ /* The total number EIGRP Conditional-Receive packets sent on this interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPACKSSUPPRESSED: /* 19 */
+ /* The total number of individual EIGRP acknowledgement packets that have been
+ suppressed and combined in an already enqueued outbound reliable packet on this interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPRETRANSSENT: /* 20 */
+ /* The total number EIGRP packet retransmissions sent on the interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPOOSRCVD: /* 21 */
+ /* The total number of out-of-sequence EIGRP packets received */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPAUTHMODE: /* 22 */
+ /* The EIGRP authentication mode of the interface */
+ if (eigrp)
+ {
+ return SNMP_INTEGER(1);
+ }
+ else
+ return SNMP_INTEGER (0);
+ break;
+ case EIGRPAUTHKEYCHAIN: /* 23 */
+ /* The name of the authentication key-chain configured
+ on this interface. */
+ keylist = keychain_list_get();
+ for (ALL_LIST_ELEMENTS (keylist, node, nnode, keychain))
+ {
+ return (u_char *) keychain->name;
+ }
+ if (eigrp && keychain)
+ {
+ *var_len = str_len (keychain->name);
+ return (u_char *) keychain->name;
+ }
+ else
+ return (u_char *) "TEST";
+ break;
+ default:
+ return NULL;
+ }
+ return NULL;
+}
+
+/* Register EIGRP-MIB. */
+void
+eigrp_snmp_init ()
+{
+ eigrp_snmp_iflist = list_new ();
+ smux_init (eigrp_om->master);
+ REGISTER_MIB("ciscoEigrpMIB", eigrp_variables, variable, eigrp_oid);
+}
+#endif
diff --git a/eigrpd/eigrp_snmp.h b/eigrpd/eigrp_snmp.h
new file mode 100644
index 0000000000..559852d58d
--- /dev/null
+++ b/eigrpd/eigrp_snmp.h
@@ -0,0 +1,35 @@
+/*
+ * EIGRP SNMP Support.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 _ZEBRA_EIGRP_SNMP_H
+#define _ZEBRA_EIGRP_SNMP_H
+
+extern void eigrp_snmp_init (void);
+
+
+#endif /* _ZEBRA_EIGRP_SNMP_H */
diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h
new file mode 100644
index 0000000000..4d307005c9
--- /dev/null
+++ b/eigrpd/eigrp_structs.h
@@ -0,0 +1,532 @@
+/*
+ * EIGRP Definition of Data Structures.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 _ZEBRA_EIGRP_STRUCTS_H_
+#define _ZEBRA_EIGRP_STRUCTS_H_
+
+#include "filter.h"
+
+#include "eigrpd/eigrp_const.h"
+#include "eigrpd/eigrp_macros.h"
+
+/* EIGRP master for system wide configuration and variables. */
+struct eigrp_master
+{
+ /* EIGRP instance. */
+ struct list *eigrp;
+
+ /* EIGRP thread master. */
+ struct thread_master *master;
+
+ /* Zebra interface list. */
+ struct list *iflist;
+
+ /* EIGRP start time. */
+ time_t start_time;
+
+ /* Various EIGRP global configuration. */
+ u_char options;
+
+#define EIGRP_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */
+};
+
+struct eigrp_metrics
+{
+ u_int32_t delay;
+ u_int32_t bandwith;
+ unsigned char mtu[3];
+ u_char hop_count;
+ u_char reliability;
+ u_char load;
+ u_char tag;
+ u_char flags;
+};
+
+struct eigrp
+{
+ u_int16_t AS; /* Autonomous system number */
+ u_int16_t vrid; /* Virtual Router ID */
+ u_char k_values[6]; /*Array for K values configuration*/
+ u_char variance; /*Metric variance multiplier*/
+ u_char max_paths; /*Maximum allowed paths for 1 prefix*/
+
+ /*Name of this EIGRP instance*/
+ char *name;
+
+ /* EIGRP Router ID. */
+ u_int32_t router_id; /* Configured automatically. */
+ u_int32_t router_id_static; /* Configured manually. */
+
+ struct list *eiflist; /* eigrp interfaces */
+ u_char passive_interface_default; /* passive-interface default */
+
+ unsigned int fd;
+ unsigned int maxsndbuflen;
+
+ u_int32_t sequence_number; /*Global EIGRP sequence number*/
+
+ struct stream *ibuf;
+ struct list *oi_write_q;
+
+ /*Threads*/
+ struct thread *t_write;
+ struct thread *t_read;
+ struct thread *t_distribute; /* timer for distribute list */
+
+ struct route_table *networks; /* EIGRP config networks. */
+
+ struct list *topology_table;
+
+ uint64_t serno; /* Global serial number counter for topology entry changes*/
+ uint64_t serno_last_update; /* Highest serial number of information send by last update*/
+ struct list *topology_changes_internalIPV4;
+ struct list *topology_changes_externalIPV4;
+
+ /*Neighbor self*/
+ struct eigrp_neighbor *neighbor_self;
+
+ /*Configured metric for redistributed routes*/
+ struct eigrp_metrics dmetric[ZEBRA_ROUTE_MAX + 1];
+ int redistribute; /* Num of redistributed protocols. */
+
+ /* Access-list. */
+ struct access_list *list[EIGRP_FILTER_MAX];
+ /* Prefix-list. */
+ struct prefix_list *prefix[EIGRP_FILTER_MAX];
+ /* Route-map. */
+ struct route_map *routemap[EIGRP_FILTER_MAX];
+
+ /* For redistribute route map. */
+ struct
+ {
+ char *name;
+ struct route_map *map;
+ int metric_config;
+ u_int32_t metric;
+ } route_map[ZEBRA_ROUTE_MAX];
+
+ QOBJ_FIELDS
+};
+DECLARE_QOBJ_TYPE(eigrp)
+//------------------------------------------------------------------------------------------------------------------------------------------
+
+/*EIGRP interface structure*/
+struct eigrp_interface
+{
+ /* This interface's parent eigrp instance. */
+ struct eigrp *eigrp;
+
+ /* Interface data from zebra. */
+ struct interface *ifp;
+
+ /* Packet send buffer. */
+ struct eigrp_fifo *obuf; /* Output queue */
+
+ /* To which multicast groups do we currently belong? */
+
+ /* Configured varables. */
+ struct eigrp_if_params *params;
+
+ u_char multicast_memberships;
+
+ /* EIGRP Network Type. */
+ u_char type;
+
+ struct prefix *address; /* Interface prefix */
+ struct connected *connected; /* Pointer to connected */
+
+ /* Neighbor information. */
+ struct list *nbrs; /* EIGRP Neighbor List */
+
+ /* Threads. */
+ struct thread *t_hello; /* timer */
+ struct thread *t_distribute; /* timer for distribute list */
+
+ int on_write_q;
+
+ /* Statistics fields. */
+ u_int32_t hello_in; /* Hello message input count. */
+ u_int32_t update_in; /* Update message input count. */
+ u_int32_t query_in; /* Querry message input count. */
+ u_int32_t reply_in; /* Reply message input count. */
+ u_int32_t hello_out; /* Hello message output count. */
+ u_int32_t update_out; /* Update message output count. */
+ u_int32_t query_out; /* Query message output count. */
+ u_int32_t reply_out; /* Reply message output count. */
+ u_int32_t siaQuery_in;
+ u_int32_t siaQuery_out;
+ u_int32_t siaReply_in;
+ u_int32_t siaReply_out;
+ u_int32_t ack_out;
+ u_int32_t ack_in;
+
+ u_int32_t crypt_seqnum; /* Cryptographic Sequence Number */
+
+ /* Access-list. */
+ struct access_list *list[EIGRP_FILTER_MAX];
+ /* Prefix-list. */
+ struct prefix_list *prefix[EIGRP_FILTER_MAX];
+ /* Route-map. */
+ struct route_map *routemap[EIGRP_FILTER_MAX];
+};
+
+struct eigrp_if_params
+{
+ DECLARE_IF_PARAM (u_char, passive_interface); /* EIGRP Interface is passive: no sending or receiving (no need to join multicast groups) */
+ DECLARE_IF_PARAM (u_int32_t, v_hello); /* Hello Interval */
+ DECLARE_IF_PARAM (u_int16_t, v_wait); /* Router Hold Time Interval */
+ DECLARE_IF_PARAM (u_char, type); /* type of interface */
+ DECLARE_IF_PARAM (u_int32_t, bandwidth);
+ DECLARE_IF_PARAM (u_int32_t, delay);
+ DECLARE_IF_PARAM (u_char, reliability);
+ DECLARE_IF_PARAM (u_char, load);
+
+ DECLARE_IF_PARAM (char *, auth_keychain ); /* Associated keychain with interface*/
+ DECLARE_IF_PARAM (int, auth_type); /* EIGRP authentication type */
+};
+
+enum
+{
+ MEMBER_ALLROUTERS = 0, MEMBER_MAX,
+};
+
+struct eigrp_if_info
+{
+ struct eigrp_if_params *def_params;
+ struct route_table *params;
+ struct route_table *eifs;
+ unsigned int membership_counts[MEMBER_MAX]; /* multicast group refcnts */
+};
+
+//------------------------------------------------------------------------------------------------------------------------------------------
+
+/* Determines if it is first or last packet
+ * when packet consists of multiple packet
+ * chunks because of many route TLV
+ * (all won't fit into one packet) */
+enum Packet_part_type
+{
+ EIGRP_PACKET_PART_NA,
+ EIGRP_PACKET_PART_FIRST,
+ EIGRP_PACKET_PART_LAST
+};
+
+/* Neighbor Data Structure */
+struct eigrp_neighbor
+{
+ /* This neighbor's parent eigrp interface. */
+ struct eigrp_interface *ei;
+
+ /* EIGRP neighbor Information */
+ u_char state; /* neigbor status. */
+
+ u_int32_t recv_sequence_number; /* Last received sequence Number. */
+ u_int32_t init_sequence_number;
+
+ /*If packet is unacknowledged, we try to send it again 16 times*/
+ u_char retrans_counter;
+
+ struct in_addr src; /* Neighbor Src address. */
+
+ u_char os_rel_major; // system version - just for show
+ u_char os_rel_minor; // system version - just for show
+ u_char tlv_rel_major; // eigrp version - tells us what TLV format to use
+ u_char tlv_rel_minor; // eigrp version - tells us what TLV format to use
+
+ u_char K1;
+ u_char K2;
+ u_char K3;
+ u_char K4;
+ u_char K5;
+ u_char K6;
+
+ /* Timer values. */
+ u_int16_t v_holddown;
+
+ /* Threads. */
+ struct thread *t_holddown;
+ struct thread *t_nbr_send_gr; /* thread for sending multiple GR packet chunks */
+
+ struct eigrp_fifo *retrans_queue;
+ struct eigrp_fifo *multicast_queue;
+
+ u_int32_t crypt_seqnum; /* Cryptographic Sequence Number. */
+
+ /* prefixes not received from neighbor during Graceful restart */
+ struct list *nbr_gr_prefixes;
+ /* prefixes not yet send to neighbor during Graceful restart */
+ struct list *nbr_gr_prefixes_send;
+ /* if packet is first or last during Graceful restart */
+ enum Packet_part_type nbr_gr_packet_type;
+};
+
+//---------------------------------------------------------------------------------------------------------------------------------------------
+
+
+struct eigrp_packet
+{
+ struct eigrp_packet *next;
+ struct eigrp_packet *previous;
+
+ /* Pointer to data stream. */
+ struct stream *s;
+
+ /* IP destination address. */
+ struct in_addr dst;
+
+ /*Packet retransmission thread*/
+ struct thread *t_retrans_timer;
+
+ /*Packet retransmission counter*/
+ u_char retrans_counter;
+
+ u_int32_t sequence_number;
+
+ /* EIGRP packet length. */
+ u_int16_t length;
+};
+
+struct eigrp_fifo
+{
+ struct eigrp_packet *head;
+ struct eigrp_packet *tail;
+
+ unsigned long count;
+};
+
+struct eigrp_header
+{
+ u_char version;
+ u_char opcode;
+ u_int16_t checksum;
+ u_int32_t flags;
+ u_int32_t sequence;
+ u_int32_t ack;
+ u_int16_t vrid;
+ u_int16_t ASNumber;
+ char *tlv[0];
+
+}__attribute__((packed));
+
+
+/**
+ * Generic TLV type used for packet decoding.
+ *
+ * +-----+------------------+
+ * | | | |
+ * | Type| Len | Vector |
+ * | | | |
+ * +-----+------------------+
+ */
+struct eigrp_tlv_hdr_type
+{
+ u_int16_t type;
+ u_int16_t length;
+ uint8_t value[0];
+}__attribute__((packed));
+
+struct TLV_Parameter_Type
+{
+ u_int16_t type;
+ u_int16_t length;
+ u_char K1;
+ u_char K2;
+ u_char K3;
+ u_char K4;
+ u_char K5;
+ u_char K6;
+ u_int16_t hold_time;
+}__attribute__((packed));
+
+struct TLV_MD5_Authentication_Type
+{
+ u_int16_t type;
+ u_int16_t length;
+ u_int16_t auth_type;
+ u_int16_t auth_length;
+ u_int32_t key_id;
+ u_int32_t key_sequence;
+ u_char Nullpad[8];
+ u_char digest[EIGRP_AUTH_TYPE_MD5_LEN];
+
+}__attribute__((packed));
+
+struct TLV_SHA256_Authentication_Type
+{
+ u_int16_t type;
+ u_int16_t length;
+ u_int16_t auth_type;
+ u_int16_t auth_length;
+ u_int32_t key_id;
+ u_int32_t key_sequence;
+ u_char Nullpad[8];
+ u_char digest[EIGRP_AUTH_TYPE_SHA256_LEN];
+
+}__attribute__((packed));
+
+struct TLV_Sequence_Type
+{
+ u_int16_t type;
+ u_int16_t length;
+ u_char addr_length;
+ struct in_addr *addresses;
+}__attribute__((packed));
+
+struct TLV_Next_Multicast_Sequence
+{
+ u_int16_t type;
+ u_int16_t length;
+ u_int32_t multicast_sequence;
+}__attribute__((packed));
+
+struct TLV_Software_Type
+{
+ u_int16_t type;
+ u_int16_t length;
+ u_char vender_major;
+ u_char vender_minor;
+ u_char eigrp_major;
+ u_char eigrp_minor;
+}__attribute__((packed));
+
+struct TLV_IPv4_Internal_type
+{
+ u_int16_t type;
+ u_int16_t length;
+ struct in_addr forward;
+
+ /*Metrics*/
+ struct eigrp_metrics metric;
+
+ u_char prefix_length;
+
+ unsigned char destination_part[4];
+ struct in_addr destination;
+}__attribute__((packed));
+
+struct TLV_IPv4_External_type
+{
+ u_int16_t type;
+ u_int16_t length;
+ struct in_addr next_hop;
+ struct in_addr originating_router;
+ u_int32_t originating_as;
+ u_int32_t administrative_tag;
+ u_int32_t external_metric;
+ u_int16_t reserved;
+ u_char external_protocol;
+ u_char external_flags;
+
+ /*Metrics*/
+ struct eigrp_metrics metric;
+
+ u_char prefix_length;
+ unsigned char destination_part[4];
+ struct in_addr destination;
+}__attribute__((packed));
+
+/* EIGRP Peer Termination TLV - used for hard restart */
+struct TLV_Peer_Termination_type
+{
+ u_int16_t type;
+ u_int16_t length;
+ u_char unknown;
+ u_int32_t neighbor_ip;
+} __attribute__((packed));
+
+/* Who executed Graceful restart */
+enum GR_type
+{
+ EIGRP_GR_MANUAL,
+ EIGRP_GR_FILTER
+};
+
+//---------------------------------------------------------------------------------------------------------------------------------------------
+
+/* EIGRP Topology table node structure */
+struct eigrp_prefix_entry
+{
+ struct list *entries, *rij;
+ u_int32_t fdistance; // FD
+ u_int32_t rdistance; // RD
+ u_int32_t distance; // D
+ struct eigrp_metrics reported_metric; // RD for sending
+
+ u_char nt; //network type
+ u_char state; //route fsm state
+ u_char af; // address family
+ u_char req_action; // required action
+
+ struct prefix_ipv4 *destination_ipv4; // pointer to struct with ipv4 address
+ struct prefix_ipv6 *destination_ipv6; // pointer to struct with ipv6 address
+
+ //If network type is REMOTE_EXTERNAL, pointer will have reference to its external TLV
+ struct TLV_IPv4_External_type *extTLV;
+
+ uint64_t serno; /*Serial number for this entry. Increased with each change of entry*/
+};
+
+/* EIGRP Topology table record structure */
+struct eigrp_neighbor_entry
+{
+ struct eigrp_prefix_entry *prefix;
+ u_int32_t reported_distance; //distance reported by neighbor
+ u_int32_t distance; //sum of reported distance and link cost to advertised neighbor
+
+ struct eigrp_metrics reported_metric;
+ struct eigrp_metrics total_metric;
+
+ struct eigrp_neighbor *adv_router; //ip address of advertising neighbor
+ u_char flags; //used for marking successor and FS
+
+ struct eigrp_interface *ei; //pointer for case of connected entry
+
+};
+
+//---------------------------------------------------------------------------------------------------------------------------------------------
+
+/* EIGRP Finite State Machine */
+
+struct eigrp_fsm_action_message
+{
+ u_char packet_type; //UPDATE, QUERY, SIAQUERY, SIAREPLY
+ struct eigrp *eigrp; // which thread sent mesg
+ struct eigrp_neighbor *adv_router; //advertising neighbor
+ struct eigrp_neighbor_entry *entry;
+ struct eigrp_prefix_entry *prefix;
+ int data_type; // internal or external tlv type
+ union{
+ struct TLV_IPv4_External_type *ipv4_ext_data;
+ struct TLV_IPv4_Internal_type *ipv4_int_type;
+ }data;
+};
+
+#endif /* _ZEBRA_EIGRP_STRUCTURES_H_ */
diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c
new file mode 100644
index 0000000000..d422b450ed
--- /dev/null
+++ b/eigrpd/eigrp_topology.c
@@ -0,0 +1,572 @@
+/*
+ * EIGRP Topology Table.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 "prefix.h"
+#include "table.h"
+#include "memory.h"
+#include "log.h"
+#include "linklist.h"
+#include "vty.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_memory.h"
+
+static int eigrp_prefix_entry_cmp(struct eigrp_prefix_entry *, struct eigrp_prefix_entry *);
+static void eigrp_prefix_entry_del(struct eigrp_prefix_entry *);
+static int eigrp_neighbor_entry_cmp(struct eigrp_neighbor_entry *,
+ struct eigrp_neighbor_entry *);
+
+/*
+ * Returns linkedlist used as topology table
+ * cmp - assigned function for comparing topology nodes
+ * del - assigned function executed before deleting topology node by list function
+ */
+struct list *
+eigrp_topology_new()
+{
+ struct list* new = list_new();
+ new->cmp = (int
+ (*)(void *, void *)) eigrp_prefix_entry_cmp;
+ new->del = (void
+ (*)(void *)) eigrp_prefix_entry_del;
+
+ return new;
+}
+
+/*
+ * Topology node comparison
+ */
+
+static int
+eigrp_prefix_entry_cmp(struct eigrp_prefix_entry *node1,
+ struct eigrp_prefix_entry *node2)
+{
+ if (node1->af == AF_INET)
+ {
+ if (node2->af == AF_INET)
+ {
+ if (node1->destination_ipv4->prefix.s_addr
+ < node2->destination_ipv4->prefix.s_addr)
+ {
+ return -1; // if it belong above node2
+ }
+ else
+ {
+ if (node1->destination_ipv4->prefix.s_addr
+ > node2->destination_ipv4->prefix.s_addr)
+ {
+ return 1; //if it belongs under node2
+ }
+ else
+ {
+ return 0; // same value... ERROR...in case of adding same prefix again
+ }
+ }
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else
+ { // TODO check if the prefix dont exists
+ return 1; // add to end
+ }
+}
+
+/*
+ * Topology node delete
+ */
+
+static void
+eigrp_prefix_entry_del(struct eigrp_prefix_entry *node)
+{
+ list_delete_all_node(node->entries);
+ list_free(node->entries);
+}
+
+/*
+ * Returns new created toplogy node
+ * cmp - assigned function for comparing topology entry
+ */
+struct eigrp_prefix_entry *
+eigrp_prefix_entry_new()
+{
+ struct eigrp_prefix_entry *new;
+ new = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY, sizeof(struct eigrp_prefix_entry));
+ new->entries = list_new();
+ new->rij = list_new();
+ new->entries->cmp = (int (*)(void *, void *))eigrp_neighbor_entry_cmp;
+ new->distance = new->fdistance = new->rdistance = EIGRP_MAX_METRIC;
+ new->destination_ipv4 = NULL;
+ new->destination_ipv6 = NULL;
+
+ return new;
+}
+
+/*
+ * Topology entry comparison
+ */
+static int
+eigrp_neighbor_entry_cmp(struct eigrp_neighbor_entry *entry1,
+ struct eigrp_neighbor_entry *entry2)
+{
+ if (entry1->distance < entry2->distance) // parameter used in list_add_sort ()
+ return -1; // actually set to sort by distance
+ if (entry1->distance > entry2->distance)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * Returns new topology entry
+ */
+
+struct eigrp_neighbor_entry *
+eigrp_neighbor_entry_new()
+{
+ struct eigrp_neighbor_entry *new;
+
+ new = XCALLOC(MTYPE_EIGRP_NEIGHBOR_ENTRY,
+ sizeof(struct eigrp_neighbor_entry));
+ new->reported_distance = EIGRP_MAX_METRIC;
+ new->distance = EIGRP_MAX_METRIC;
+
+ return new;
+}
+
+/*
+ * Freeing topology table list
+ */
+void
+eigrp_topology_free(struct list *list)
+{
+ list_free(list);
+}
+
+/*
+ * Deleting all topology nodes in table
+ */
+void
+eigrp_topology_cleanup(struct list *topology)
+{
+ assert(topology);
+
+ eigrp_topology_delete_all(topology);
+}
+
+/*
+ * Adding topology node to topology table
+ */
+void
+eigrp_prefix_entry_add(struct list *topology, struct eigrp_prefix_entry *node)
+{
+ if (listnode_lookup(topology, node) == NULL)
+ {
+ listnode_add_sort(topology, node);
+ }
+}
+
+/*
+ * Adding topology entry to topology node
+ */
+void
+eigrp_neighbor_entry_add(struct eigrp_prefix_entry *node,
+ struct eigrp_neighbor_entry *entry)
+{
+ struct list *l = list_new ();
+
+ listnode_add (l, entry);
+
+ if (listnode_lookup (node->entries, entry) == NULL)
+ {
+ listnode_add_sort (node->entries, entry);
+ entry->prefix = node;
+
+ eigrp_zebra_route_add (node->destination_ipv4, l);
+ }
+
+ list_delete (l);
+}
+
+/*
+ * Deleting topology node from topology table
+ */
+void
+eigrp_prefix_entry_delete(struct list *topology,
+ struct eigrp_prefix_entry *node)
+{
+ struct eigrp *eigrp = eigrp_lookup ();
+
+ /*
+ * Emergency removal of the node from this list.
+ * Whatever it is.
+ */
+ listnode_delete (eigrp->topology_changes_internalIPV4, node);
+
+ if (listnode_lookup (topology, node) != NULL)
+ {
+ list_delete_all_node (node->entries);
+ list_free (node->entries);
+ list_free (node->rij);
+ listnode_delete (topology, node);
+ eigrp_zebra_route_delete (node->destination_ipv4);
+ XFREE (MTYPE_EIGRP_PREFIX_ENTRY,node);
+ }
+}
+
+/*
+ * Deleting topology entry from topology node
+ */
+void
+eigrp_neighbor_entry_delete(struct eigrp_prefix_entry *node,
+ struct eigrp_neighbor_entry *entry)
+{
+ if (listnode_lookup(node->entries, entry) != NULL)
+ {
+ listnode_delete(node->entries, entry);
+ eigrp_zebra_route_delete (node->destination_ipv4);
+ XFREE(MTYPE_EIGRP_NEIGHBOR_ENTRY,entry);
+ }
+}
+
+/*
+ * Deleting all nodes from topology table
+ */
+void
+eigrp_topology_delete_all(struct list *topology)
+{
+ list_delete_all_node(topology);
+}
+
+/*
+ * Return 0 if topology is not empty
+ * otherwise return 1
+ */
+unsigned int
+eigrp_topology_table_isempty(struct list *topology)
+{
+ if (topology->count)
+ return 1;
+ else
+ return 0;
+}
+
+struct eigrp_prefix_entry *
+eigrp_topology_table_lookup_ipv4(struct list *topology_table,
+ struct prefix_ipv4 * address)
+{
+ struct eigrp_prefix_entry *data;
+ struct listnode *node;
+ for (ALL_LIST_ELEMENTS_RO(topology_table, node, data))
+ {
+ if ((data->af == AF_INET)
+ && (data->destination_ipv4->prefix.s_addr == address->prefix.s_addr)
+ && (data->destination_ipv4->prefixlen == address->prefixlen))
+ return data;
+ }
+
+ return NULL;
+}
+
+/*
+ * For a future optimization, put the successor list into it's
+ * own separate list from the full list?
+ *
+ * That way we can clean up all the list_new and list_delete's
+ * that we are doing. DBS
+ */
+struct list *
+eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node)
+{
+ struct list *successors = list_new();
+ struct eigrp_neighbor_entry *data;
+ struct listnode *node1, *node2;
+
+ for (ALL_LIST_ELEMENTS(table_node->entries, node1, node2, data))
+ {
+ if (data->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)
+ {
+ listnode_add(successors, data);
+ }
+ }
+
+ /*
+ * If we have no successors return NULL
+ */
+ if (!successors->count)
+ {
+ list_delete(successors);
+ successors = NULL;
+ }
+
+ return successors;
+}
+
+struct list *
+eigrp_topology_get_successor_max(struct eigrp_prefix_entry *table_node,
+ unsigned int maxpaths)
+{
+ struct list *successors = eigrp_topology_get_successor(table_node);
+
+ if (successors && successors->count > maxpaths)
+ {
+ do
+ {
+ struct listnode *node = listtail(successors);
+
+ list_delete_node(successors, node);
+
+ } while (successors->count > maxpaths);
+ }
+
+ return successors;
+}
+
+struct eigrp_neighbor_entry *
+eigrp_prefix_entry_lookup(struct list *entries, struct eigrp_neighbor *nbr)
+{
+ struct eigrp_neighbor_entry *data;
+ struct listnode *node, *nnode;
+ for (ALL_LIST_ELEMENTS(entries, node, nnode, data))
+ {
+ if (data->adv_router == nbr)
+ {
+ return data;
+ }
+ }
+
+ return NULL;
+}
+
+/* Lookup all prefixes from specified neighbor */
+struct list *
+eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp, struct eigrp_neighbor *nbr)
+{
+ struct listnode *node1, *node11, *node2, *node22;
+ struct eigrp_prefix_entry *prefix;
+ struct eigrp_neighbor_entry *entry;
+
+ /* create new empty list for prefixes storage */
+ struct list *prefixes = list_new();
+
+ /* iterate over all prefixes in topology table */
+ for (ALL_LIST_ELEMENTS(eigrp->topology_table, node1, node11, prefix))
+ {
+ /* iterate over all neighbor entry in prefix */
+ for (ALL_LIST_ELEMENTS(prefix->entries, node2, node22, entry))
+ {
+ /* if entry is from specified neighbor, add to list */
+ if (entry->adv_router == nbr)
+ {
+ listnode_add(prefixes, prefix);
+ }
+ }
+ }
+
+ /* return list of prefixes from specified neighbor */
+ return prefixes;
+}
+
+int
+eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg)
+{
+ struct eigrp *eigrp = msg->eigrp;
+ struct eigrp_prefix_entry *prefix = msg->prefix;
+ struct eigrp_neighbor_entry *entry = msg->entry;
+ int change = 0;
+ assert(entry);
+
+ struct TLV_IPv4_External_type *ext_data = NULL;
+ struct TLV_IPv4_Internal_type *int_data = NULL;
+ if (msg->data_type == EIGRP_TLV_IPv4_INT)
+ {
+ int_data = msg->data.ipv4_int_type;
+ if (eigrp_metrics_is_same(&int_data->metric,&entry->reported_metric))
+ {
+ return 0; // No change
+ }
+ change =
+ entry->reported_distance
+ < eigrp_calculate_metrics(eigrp, &int_data->metric) ? 1 :
+ entry->reported_distance
+ > eigrp_calculate_metrics(eigrp, &int_data->metric) ? 2 : 3; // Increase : Decrease : No change
+ entry->reported_metric = int_data->metric;
+ entry->reported_distance =
+ eigrp_calculate_metrics(eigrp, &int_data->metric);
+ entry->distance = eigrp_calculate_total_metrics(eigrp, entry);
+ }
+ else
+ {
+ ext_data = msg->data.ipv4_ext_data;
+ if (eigrp_metrics_is_same (&ext_data->metric, &entry->reported_metric))
+ return 0;
+ }
+ /*
+ * Move to correct position in list according to new distance
+ */
+ listnode_delete(prefix->entries, entry);
+ listnode_add_sort(prefix->entries, entry);
+
+ return change;
+}
+
+void
+eigrp_topology_update_all_node_flags(struct eigrp *eigrp)
+{
+ struct list *table = eigrp->topology_table;
+ struct eigrp_prefix_entry *data;
+ struct listnode *node, *nnode;
+ for (ALL_LIST_ELEMENTS(table, node, nnode, data))
+ {
+ eigrp_topology_update_node_flags(data);
+ }
+}
+
+void
+eigrp_topology_update_node_flags(struct eigrp_prefix_entry *dest)
+{
+ struct listnode *node;
+ struct eigrp_neighbor_entry *entry;
+ struct eigrp * eigrp = eigrp_lookup();
+
+ for (ALL_LIST_ELEMENTS_RO(dest->entries, node, entry))
+ {
+ if ((entry->distance <= (uint64_t)(dest->distance*eigrp->variance)) &&
+ entry->distance != EIGRP_MAX_METRIC) // is successor
+ {
+ entry->flags |= EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG;
+ entry->flags &= ~EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG;
+ }
+ else if (entry->reported_distance < dest->fdistance) // is feasible successor
+ {
+ entry->flags |= EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG;
+ entry->flags &= ~EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG;
+ }
+ else
+ {
+ entry->flags &= ~EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG;
+ entry->flags &= ~EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG;
+ }
+ }
+}
+
+void
+eigrp_update_routing_table(struct eigrp_prefix_entry * prefix)
+{
+ struct eigrp *eigrp = eigrp_lookup();
+ struct list *successors = eigrp_topology_get_successor_max(prefix, eigrp->max_paths);
+ struct listnode *node;
+ struct eigrp_neighbor_entry *entry;
+
+ if (successors)
+ {
+ eigrp_zebra_route_add(prefix->destination_ipv4, successors);
+ for (ALL_LIST_ELEMENTS_RO (successors, node, entry))
+ entry->flags |= EIGRP_NEIGHBOR_ENTRY_INTABLE_FLAG;
+
+ list_delete(successors);
+ }
+ else
+ {
+ eigrp_zebra_route_delete(prefix->destination_ipv4);
+ for (ALL_LIST_ELEMENTS_RO (prefix->entries, node, entry))
+ entry->flags &= ~EIGRP_NEIGHBOR_ENTRY_INTABLE_FLAG;
+ }
+}
+
+void
+eigrp_topology_neighbor_down(struct eigrp *eigrp, struct eigrp_neighbor * nbr)
+{
+ struct listnode *node1, *node11, *node2, *node22;
+ struct eigrp_prefix_entry *prefix;
+ struct eigrp_neighbor_entry *entry;
+
+ for (ALL_LIST_ELEMENTS(eigrp->topology_table, node1, node11, prefix))
+ {
+ for (ALL_LIST_ELEMENTS(prefix->entries, node2, node22, entry))
+ {
+ if (entry->adv_router == nbr)
+ {
+ struct eigrp_fsm_action_message *msg;
+ msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
+ sizeof(struct eigrp_fsm_action_message));
+ struct TLV_IPv4_Internal_type * tlv = eigrp_IPv4_InternalTLV_new();
+ tlv->metric.delay = EIGRP_MAX_METRIC;
+ msg->packet_type = EIGRP_OPC_UPDATE;
+ msg->eigrp = eigrp;
+ msg->data_type = EIGRP_TLV_IPv4_INT;
+ msg->adv_router = nbr;
+ msg->data.ipv4_int_type = tlv;
+ msg->entry = entry;
+ msg->prefix = prefix;
+ int event = eigrp_get_fsm_event(msg);
+ eigrp_fsm_event(msg, event);
+ }
+ }
+ }
+
+ eigrp_query_send_all(eigrp);
+ eigrp_update_send_all(eigrp,nbr->ei);
+
+}
+
+void
+eigrp_update_topology_table_prefix(struct list * table, struct eigrp_prefix_entry * prefix)
+{
+ struct listnode *node1, *node2;
+
+ struct eigrp_neighbor_entry *entry;
+ for (ALL_LIST_ELEMENTS(prefix->entries, node1, node2, entry))
+ {
+ if(entry->distance == EIGRP_MAX_METRIC)
+ {
+ eigrp_neighbor_entry_delete(prefix,entry);
+ }
+ }
+ if(prefix->distance == EIGRP_MAX_METRIC && prefix->nt != EIGRP_TOPOLOGY_TYPE_CONNECTED)
+ {
+ eigrp_prefix_entry_delete(table,prefix);
+ }
+}
diff --git a/eigrpd/eigrp_topology.h b/eigrpd/eigrp_topology.h
new file mode 100644
index 0000000000..4ddc71f6fe
--- /dev/null
+++ b/eigrpd/eigrp_topology.h
@@ -0,0 +1,61 @@
+/*
+ * EIGRP Topology Table.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 _ZEBRA_EIGRP_TOPOLOGY_H
+#define _ZEBRA_EIGRP_TOPOLOGY_H
+
+
+/* EIGRP Topology table related functions. */
+extern struct list *eigrp_topology_new (void);
+extern void eigrp_topology_init (struct list*);
+extern struct eigrp_prefix_entry *eigrp_prefix_entry_new (void);
+extern struct eigrp_neighbor_entry *eigrp_neighbor_entry_new (void);
+extern void eigrp_topology_free (struct list *);
+extern void eigrp_topology_cleanup (struct list *);
+extern void eigrp_prefix_entry_add (struct list *, struct eigrp_prefix_entry *);
+extern void eigrp_neighbor_entry_add (struct eigrp_prefix_entry *, struct eigrp_neighbor_entry *);
+extern void eigrp_prefix_entry_delete (struct list *, struct eigrp_prefix_entry *);
+extern void eigrp_neighbor_entry_delete (struct eigrp_prefix_entry *, struct eigrp_neighbor_entry *);
+extern void eigrp_topology_delete_all (struct list *);
+extern unsigned int eigrp_topology_table_isempty (struct list *);
+extern struct eigrp_prefix_entry *eigrp_topology_table_lookup_ipv4 (struct list *, struct prefix_ipv4 *);
+extern struct list *eigrp_topology_get_successor (struct eigrp_prefix_entry *);
+extern struct list *eigrp_topology_get_successor_max (struct eigrp_prefix_entry *pe, unsigned int maxpaths);
+extern struct eigrp_neighbor_entry *eigrp_prefix_entry_lookup (struct list *, struct eigrp_neighbor *);
+extern struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *, struct eigrp_neighbor *);
+extern void eigrp_topology_update_all_node_flags (struct eigrp *);
+extern void eigrp_topology_update_node_flags (struct eigrp_prefix_entry *);
+extern int eigrp_topology_update_distance ( struct eigrp_fsm_action_message *);
+extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
+extern void eigrp_topology_neighbor_down(struct eigrp *, struct eigrp_neighbor *);
+extern void eigrp_update_topology_table_prefix(struct list *, struct eigrp_prefix_entry * );
+
+#endif
diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c
new file mode 100644
index 0000000000..98b2defea0
--- /dev/null
+++ b/eigrpd/eigrp_update.c
@@ -0,0 +1,1125 @@
+/*
+ * EIGRP Sending and Receiving EIGRP Update Packets.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "sockunion.h"
+#include "stream.h"
+#include "log.h"
+#include "sockopt.h"
+#include "checksum.h"
+#include "md5.h"
+#include "vty.h"
+#include "plist.h"
+#include "plist_int.h"
+#include "routemap.h"
+#include "vty.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_macros.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_memory.h"
+
+/**
+ * @fn remove_received_prefix_gr
+ *
+ * @param[in] nbr_prefixes List of neighbor prefixes
+ * @param[in] recv_prefix Prefix which needs to be removed from list
+ *
+ * @return void
+ *
+ * @par
+ * Function is used for removing received prefix
+ * from list of neighbor prefixes
+ */
+static void
+remove_received_prefix_gr (struct list *nbr_prefixes, struct eigrp_prefix_entry *recv_prefix)
+{
+ struct listnode *node1, *node11;
+ struct eigrp_prefix_entry *prefix = NULL;
+
+ /* iterate over all prefixes in list */
+ for (ALL_LIST_ELEMENTS(nbr_prefixes, node1, node11, prefix))
+ {
+ /* remove prefix from list if found */
+ if (prefix == recv_prefix)
+ {
+ listnode_delete(nbr_prefixes, prefix);
+ }
+ }
+}
+
+/**
+ * @fn eigrp_update_receive_GR_ask
+ *
+ * @param[in] eigrp EIGRP process
+ * @param[in] nbr Neighbor update of who we received
+ * @param[in] nbr_prefixes Prefixes which weren't advertised
+ *
+ * @return void
+ *
+ * @par
+ * Function is used for notifying FSM about prefixes which
+ * weren't advertised by neighbor:
+ * We will send message to FSM with prefix delay set to infinity.
+ */
+static void
+eigrp_update_receive_GR_ask (struct eigrp *eigrp, struct eigrp_neighbor *nbr, struct list *nbr_prefixes)
+{
+ struct listnode *node1;
+ struct eigrp_prefix_entry *prefix;
+ struct TLV_IPv4_Internal_type *tlv_max;
+
+ /* iterate over all prefixes which weren't advertised by neighbor */
+ for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix))
+ {
+ zlog_debug("GR receive: Neighbor not advertised %s/%d",
+ inet_ntoa(prefix->destination_ipv4->prefix),
+ prefix->destination_ipv4->prefixlen);
+
+ /* create internal IPv4 TLV with infinite delay */
+ tlv_max = eigrp_IPv4_InternalTLV_new();
+ tlv_max->type = EIGRP_TLV_IPv4_INT;
+ tlv_max->length = 28U;
+ tlv_max->metric = prefix->reported_metric;
+ /* set delay to MAX */
+ tlv_max->metric.delay = EIGRP_MAX_METRIC;
+ tlv_max->destination = prefix->destination_ipv4->prefix;
+ tlv_max->prefix_length = prefix->destination_ipv4->prefixlen;
+
+
+ /* prepare message for FSM */
+ struct eigrp_fsm_action_message *fsm_msg;
+ fsm_msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
+ sizeof(struct eigrp_fsm_action_message));
+
+ struct eigrp_neighbor_entry *entry =
+ eigrp_prefix_entry_lookup(prefix->entries, nbr);
+
+ fsm_msg->packet_type = EIGRP_OPC_UPDATE;
+ fsm_msg->eigrp = eigrp;
+ fsm_msg->data_type = EIGRP_TLV_IPv4_INT;
+ fsm_msg->adv_router = nbr;
+ fsm_msg->data.ipv4_int_type = tlv_max;
+ fsm_msg->entry = entry;
+ fsm_msg->prefix = prefix;
+
+ /* send message to FSM */
+ int event = eigrp_get_fsm_event(fsm_msg);
+ eigrp_fsm_event(fsm_msg, event);
+
+ /* free memory used by TLV */
+ eigrp_IPv4_InternalTLV_free (tlv_max);
+ }
+}
+
+/*
+ * EIGRP UPDATE read function
+ */
+void
+eigrp_update_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
+ struct stream * s, struct eigrp_interface *ei, int size)
+{
+ struct eigrp_neighbor *nbr;
+ struct TLV_IPv4_Internal_type *tlv;
+ struct eigrp_prefix_entry *pe;
+ struct eigrp_neighbor_entry *ne;
+ u_int32_t flags;
+ u_int16_t type;
+ u_char same;
+ struct access_list *alist;
+ struct prefix_list *plist;
+ struct eigrp *e;
+ u_char graceful_restart;
+ u_char graceful_restart_final;
+ struct list *nbr_prefixes = NULL;
+
+ /* increment statistics. */
+ ei->update_in++;
+
+ /* get neighbor struct */
+ nbr = eigrp_nbr_get(ei, eigrph, iph);
+
+ /* neighbor must be valid, eigrp_nbr_get creates if none existed */
+ assert(nbr);
+
+ flags = ntohl(eigrph->flags);
+
+ if (flags & EIGRP_CR_FLAG)
+ {
+ return;
+ }
+
+ same = 0;
+ graceful_restart = 0;
+ graceful_restart_final = 0;
+ if((nbr->recv_sequence_number) == (ntohl(eigrph->sequence)))
+ same = 1;
+
+ nbr->recv_sequence_number = ntohl(eigrph->sequence);
+ if (IS_DEBUG_EIGRP_PACKET(0, RECV))
+ zlog_debug("Processing Update size[%u] int(%s) nbr(%s) seq [%u] flags [%0x]",
+ size, ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT),
+ inet_ntoa(nbr->src),
+ nbr->recv_sequence_number, flags);
+
+
+ if((flags == (EIGRP_INIT_FLAG+EIGRP_RS_FLAG+EIGRP_EOT_FLAG)) && (!same))
+ {
+ /* Graceful restart Update received with all routes */
+
+ zlog_info("Neighbor %s (%s) is resync: peer graceful-restart",
+ inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+
+ /* get all prefixes from neighbor from topology table */
+ nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr);
+ graceful_restart = 1;
+ graceful_restart_final = 1;
+ }
+ else if((flags == (EIGRP_INIT_FLAG+EIGRP_RS_FLAG)) && (!same))
+ {
+ /* Graceful restart Update received, routes also in next packet */
+
+ zlog_info("Neighbor %s (%s) is resync: peer graceful-restart",
+ inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+
+ /* get all prefixes from neighbor from topology table */
+ nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr);
+ /* save prefixes to neighbor for later use */
+ nbr->nbr_gr_prefixes = nbr_prefixes;
+ graceful_restart = 1;
+ graceful_restart_final = 0;
+ }
+ else if((flags == (EIGRP_EOT_FLAG)) && (!same))
+ {
+ /* If there was INIT+RS Update packet before,
+ * consider this as GR EOT */
+
+ if(nbr->nbr_gr_prefixes != NULL)
+ {
+ /* this is final packet of GR */
+ nbr_prefixes = nbr->nbr_gr_prefixes;
+ nbr->nbr_gr_prefixes = NULL;
+
+ graceful_restart = 1;
+ graceful_restart_final = 1;
+ }
+
+ }
+ else if((flags == (0)) && (!same))
+ {
+ /* If there was INIT+RS Update packet before,
+ * consider this as GR not final packet */
+
+ if(nbr->nbr_gr_prefixes != NULL)
+ {
+ /* this is GR not final route packet */
+ nbr_prefixes = nbr->nbr_gr_prefixes;
+
+ graceful_restart = 1;
+ graceful_restart_final = 0;
+ }
+
+ }
+ else if((flags & EIGRP_INIT_FLAG) && (!same))
+ { /* When in pending state, send INIT update only if it wasn't
+ already sent before (only if init_sequence is 0) */
+ if((nbr->state == EIGRP_NEIGHBOR_PENDING) && (nbr->init_sequence_number == 0))
+ eigrp_update_send_init(nbr);
+
+ if (nbr->state == EIGRP_NEIGHBOR_UP)
+ {
+ eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN);
+ eigrp_topology_neighbor_down(nbr->ei->eigrp,nbr);
+ nbr->recv_sequence_number = ntohl(eigrph->sequence);
+ zlog_info("Neighbor %s (%s) is down: peer restarted",
+ inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING);
+ zlog_info("Neighbor %s (%s) is pending: new adjacency",
+ inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ eigrp_update_send_init(nbr);
+ }
+ }
+
+ /*If there is topology information*/
+ while (s->endp > s->getp)
+ {
+ type = stream_getw(s);
+ if (type == EIGRP_TLV_IPv4_INT)
+ {
+ struct prefix_ipv4 dest_addr;
+
+ stream_set_getp(s, s->getp - sizeof(u_int16_t));
+
+ tlv = eigrp_read_ipv4_tlv(s);
+
+ /*searching if destination exists */
+ dest_addr.family = AFI_IP;
+ dest_addr.prefix = tlv->destination;
+ dest_addr.prefixlen = tlv->prefix_length;
+ struct eigrp_prefix_entry *dest =
+ eigrp_topology_table_lookup_ipv4(eigrp->topology_table, &dest_addr);
+
+ /*if exists it comes to DUAL*/
+ if (dest != NULL)
+ {
+ /* remove received prefix from neighbor prefix list if in GR */
+ if(graceful_restart)
+ remove_received_prefix_gr(nbr_prefixes, dest);
+
+ struct eigrp_fsm_action_message *msg;
+ msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
+ sizeof(struct eigrp_fsm_action_message));
+ struct eigrp_neighbor_entry *entry =
+ eigrp_prefix_entry_lookup(dest->entries, nbr);
+
+ msg->packet_type = EIGRP_OPC_UPDATE;
+ msg->eigrp = eigrp;
+ msg->data_type = EIGRP_TLV_IPv4_INT;
+ msg->adv_router = nbr;
+ msg->data.ipv4_int_type = tlv;
+ msg->entry = entry;
+ msg->prefix = dest;
+ int event = eigrp_get_fsm_event(msg);
+ eigrp_fsm_event(msg, event);
+ }
+ else
+ {
+ /*Here comes topology information save*/
+ pe = eigrp_prefix_entry_new();
+ pe->serno = eigrp->serno;
+ pe->destination_ipv4 = prefix_ipv4_new();
+ prefix_copy((struct prefix *)pe->destination_ipv4,
+ (struct prefix *)&dest_addr);
+ pe->af = AF_INET;
+ pe->state = EIGRP_FSM_STATE_PASSIVE;
+ pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE;
+
+ ne = eigrp_neighbor_entry_new();
+ ne->ei = ei;
+ ne->adv_router = nbr;
+ ne->reported_metric = tlv->metric;
+ ne->reported_distance =
+ eigrp_calculate_metrics(eigrp,
+ &tlv->metric);
+ /*
+ * Filtering
+ */
+ e = eigrp_lookup();
+ /*
+ * Check if there is any access-list on interface (IN direction)
+ * and set distance to max
+ */
+ alist = ei->list[EIGRP_FILTER_IN];
+
+ /* Check if access-list fits */
+ if (alist &&
+ access_list_apply (alist, (struct prefix *)&dest_addr) == FILTER_DENY)
+ {
+ /* If yes, set reported metric to Max */
+ ne->reported_metric.delay = EIGRP_MAX_METRIC;
+ } else {
+ ne->distance = eigrp_calculate_total_metrics(eigrp, ne);
+ }
+
+ plist = e->prefix[EIGRP_FILTER_IN];
+
+ /* Check if prefix-list fits */
+ if (plist &&
+ prefix_list_apply (plist, (struct prefix *)&dest_addr) == PREFIX_DENY)
+ {
+ /* If yes, set reported metric to Max */
+ ne->reported_metric.delay = EIGRP_MAX_METRIC;
+ }
+
+ /*Get access-list from current interface */
+ alist = ei->list[EIGRP_FILTER_IN];
+
+ /* Check if access-list fits */
+ if (alist &&
+ access_list_apply (alist, (struct prefix *)&dest_addr) == FILTER_DENY)
+ {
+ /* If yes, set reported metric to Max */
+ ne->reported_metric.delay = EIGRP_MAX_METRIC;
+ }
+
+ plist = ei->prefix[EIGRP_FILTER_IN];
+
+ /* Check if prefix-list fits */
+ if (plist &&
+ prefix_list_apply (plist, (struct prefix *)&dest_addr) == PREFIX_DENY)
+ {
+ /* If yes, set reported metric to Max */
+ ne->reported_metric.delay = EIGRP_MAX_METRIC;
+ }
+ /*
+ * End of filtering
+ */
+
+ ne->distance = eigrp_calculate_total_metrics(eigrp, ne);
+
+ pe->fdistance = pe->distance = pe->rdistance =
+ ne->distance;
+ ne->prefix = pe;
+ ne->flags = EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG;
+
+ eigrp_prefix_entry_add(eigrp->topology_table, pe);
+ eigrp_neighbor_entry_add(pe, ne);
+ pe->distance = pe->fdistance = pe->rdistance =
+ ne->distance;
+ pe->reported_metric = ne->total_metric;
+ eigrp_topology_update_node_flags(pe);
+
+ pe->req_action |= EIGRP_FSM_NEED_UPDATE;
+ listnode_add(eigrp->topology_changes_internalIPV4, pe);
+ }
+ eigrp_IPv4_InternalTLV_free (tlv);
+ }
+ }
+
+ /* ask about prefixes not present in GR update,
+ * if this is final GR packet */
+ if(graceful_restart_final)
+ {
+ eigrp_update_receive_GR_ask(eigrp, nbr, nbr_prefixes);
+ }
+
+ /*
+ * We don't need to send separate Ack for INIT Update. INIT will be acked in EOT Update.
+ */
+ if ((nbr->state == EIGRP_NEIGHBOR_UP) && !(flags == EIGRP_INIT_FLAG))
+ {
+ eigrp_hello_send_ack(nbr);
+ }
+
+ eigrp_query_send_all(eigrp);
+ eigrp_update_send_all(eigrp, ei);
+}
+
+/*send EIGRP Update packet*/
+void
+eigrp_update_send_init (struct eigrp_neighbor *nbr)
+{
+ struct eigrp_packet *ep;
+ u_int16_t length = EIGRP_HEADER_LEN;
+
+ ep = eigrp_packet_new(nbr->ei->ifp->mtu);
+
+ /* Prepare EIGRP INIT UPDATE header */
+ if (IS_DEBUG_EIGRP_PACKET(0, RECV))
+ zlog_debug("Enqueuing Update Init Seq [%u] Ack [%u]",
+ nbr->ei->eigrp->sequence_number,
+ nbr->recv_sequence_number);
+
+ eigrp_packet_header_init(EIGRP_OPC_UPDATE, nbr->ei, ep->s, EIGRP_INIT_FLAG,
+ nbr->ei->eigrp->sequence_number,
+ nbr->recv_sequence_number);
+
+ // encode Authentication TLV, if needed
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_MD5_to_stream(ep->s,nbr->ei);
+ eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_INIT_FLAG);
+ }
+
+ /* EIGRP Checksum */
+ eigrp_packet_checksum(nbr->ei, ep->s, length);
+
+ ep->length = length;
+ ep->dst.s_addr = nbr->src.s_addr;
+
+ /*This ack number we await from neighbor*/
+ nbr->init_sequence_number = nbr->ei->eigrp->sequence_number;
+ ep->sequence_number = nbr->ei->eigrp->sequence_number;
+ if (IS_DEBUG_EIGRP_PACKET(0, RECV))
+ zlog_debug("Enqueuing Update Init Len [%u] Seq [%u] Dest [%s]",
+ ep->length, ep->sequence_number, inet_ntoa(ep->dst));
+
+ /*Put packet to retransmission queue*/
+ eigrp_fifo_push_head(nbr->retrans_queue, ep);
+
+ if (nbr->retrans_queue->count == 1)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+}
+
+void
+eigrp_update_send_EOT (struct eigrp_neighbor *nbr)
+{
+ struct eigrp_packet *ep;
+ // struct eigrp_packet *ep_multicast;
+ u_int16_t length = EIGRP_HEADER_LEN;
+ struct eigrp_neighbor_entry *te;
+ struct eigrp_prefix_entry *pe;
+ struct listnode *node, *node2, *nnode, *nnode2;
+ struct access_list *alist;
+ struct prefix_list *plist;
+ struct access_list *alist_i;
+ struct prefix_list *plist_i;
+ struct eigrp *e;
+ struct prefix_ipv4 *dest_addr;
+
+ ep = eigrp_packet_new(nbr->ei->ifp->mtu);
+
+ /* Prepare EIGRP EOT UPDATE header */
+ eigrp_packet_header_init(EIGRP_OPC_UPDATE, nbr->ei, ep->s, EIGRP_EOT_FLAG,
+ nbr->ei->eigrp->sequence_number,
+ nbr->recv_sequence_number);
+
+ // encode Authentication TLV, if needed
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) && (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_MD5_to_stream(ep->s,nbr->ei);
+ }
+
+ for (ALL_LIST_ELEMENTS(nbr->ei->eigrp->topology_table, node, nnode, pe))
+ {
+ for (ALL_LIST_ELEMENTS(pe->entries, node2, nnode2, te))
+ {
+ if ((te->ei == nbr->ei)
+ && (te->prefix->nt == EIGRP_TOPOLOGY_TYPE_REMOTE))
+ continue;
+
+ /* Get destination address from prefix */
+ dest_addr = pe->destination_ipv4;
+
+ /*
+ * Filtering
+ */
+ //TODO: Work in progress
+ /* get list from eigrp process */
+ e = eigrp_lookup();
+ /* Get access-lists and prefix-lists from process and interface */
+ alist = e->list[EIGRP_FILTER_OUT];
+ plist = e->prefix[EIGRP_FILTER_OUT];
+ alist_i = nbr->ei->list[EIGRP_FILTER_OUT];
+ plist_i = nbr->ei->prefix[EIGRP_FILTER_OUT];
+
+ /* Check if any list fits */
+ if ((alist && access_list_apply (alist,
+ (struct prefix *) dest_addr) == FILTER_DENY)||
+ (plist && prefix_list_apply (plist,
+ (struct prefix *) dest_addr) == PREFIX_DENY)||
+ (alist_i && access_list_apply (alist_i,
+ (struct prefix *) dest_addr) == FILTER_DENY)||
+ (plist_i && prefix_list_apply (plist_i,
+ (struct prefix *) dest_addr) == PREFIX_DENY))
+ {
+ zlog_info("PROC OUT EOT: Skipping");
+ //pe->reported_metric.delay = EIGRP_MAX_METRIC;
+ zlog_info("PROC OUT EOT Prefix: %s", inet_ntoa(dest_addr->prefix));
+ continue;
+ } else {
+ zlog_info("PROC OUT EOT: NENastavujem metriku ");
+ length += eigrp_add_internalTLV_to_stream(ep->s, pe);
+ }
+ /*
+ * End of filtering
+ */
+
+ /* NULL the pointer */
+ dest_addr = NULL;
+
+ }
+ }
+
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
+ }
+
+ /* EIGRP Checksum */
+ eigrp_packet_checksum(nbr->ei, ep->s, length);
+
+ ep->length = length;
+ ep->dst.s_addr = nbr->src.s_addr;
+
+ /*This ack number we await from neighbor*/
+ ep->sequence_number = nbr->ei->eigrp->sequence_number;
+
+ if (IS_DEBUG_EIGRP_PACKET(0, RECV))
+ zlog_debug("Enqueuing Update Init Len [%u] Seq [%u] Dest [%s]",
+ ep->length, ep->sequence_number, inet_ntoa(ep->dst));
+
+ /*Put packet to retransmission queue*/
+ eigrp_fifo_push_head(nbr->retrans_queue, ep);
+
+ if (nbr->retrans_queue->count == 1)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+}
+
+void
+eigrp_update_send (struct eigrp_interface *ei)
+{
+ struct eigrp_packet *ep;
+ struct listnode *node, *nnode;
+ struct eigrp_neighbor *nbr;
+ struct eigrp_prefix_entry *pe;
+ u_char has_tlv;
+ struct access_list *alist;
+ struct prefix_list *plist;
+ struct access_list *alist_i;
+ struct prefix_list *plist_i;
+ struct eigrp *e;
+ struct prefix_ipv4 *dest_addr;
+ bool packet_sent = false;
+
+ u_int16_t length = EIGRP_HEADER_LEN;
+
+ ep = eigrp_packet_new(ei->ifp->mtu);
+
+ /* Prepare EIGRP INIT UPDATE header */
+ eigrp_packet_header_init(EIGRP_OPC_UPDATE, ei, ep->s, 0,
+ ei->eigrp->sequence_number, 0);
+
+ // encode Authentication TLV, if needed
+ if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei);
+ }
+
+ has_tlv = 0;
+ for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node, nnode, pe))
+ {
+ if(pe->req_action & EIGRP_FSM_NEED_UPDATE)
+ {
+ /* Get destination address from prefix */
+ dest_addr = pe->destination_ipv4;
+
+ /*
+ * Filtering
+ */
+ //TODO: Work in progress
+ /* get list from eigrp process */
+ e = eigrp_lookup();
+ /* Get access-lists and prefix-lists from process and interface */
+ alist = e->list[EIGRP_FILTER_OUT];
+ plist = e->prefix[EIGRP_FILTER_OUT];
+ alist_i = ei->list[EIGRP_FILTER_OUT];
+ plist_i = ei->prefix[EIGRP_FILTER_OUT];
+
+ /* Check if any list fits */
+ if ((alist && access_list_apply (alist,
+ (struct prefix *) dest_addr) == FILTER_DENY)||
+ (plist && prefix_list_apply (plist,
+ (struct prefix *) dest_addr) == PREFIX_DENY)||
+ (alist_i && access_list_apply (alist_i,
+ (struct prefix *) dest_addr) == FILTER_DENY)||
+ (plist_i && prefix_list_apply (plist_i,
+ (struct prefix *) dest_addr) == PREFIX_DENY))
+ {
+ zlog_info("PROC OUT: Skipping");
+ //pe->reported_metric.delay = EIGRP_MAX_METRIC;
+ zlog_info("PROC OUT Prefix: %s", inet_ntoa(dest_addr->prefix));
+ continue;
+ } else {
+ zlog_info("PROC OUT: NENastavujem metriku ");
+ length += eigrp_add_internalTLV_to_stream(ep->s, pe);
+ has_tlv = 1;
+ }
+ /*
+ * End of filtering
+ */
+
+ /* NULL the pointer */
+ dest_addr = NULL;
+
+ }
+ }
+
+ if(!has_tlv)
+ {
+ eigrp_packet_free(ep);
+ return;
+ }
+
+ if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL))
+ {
+ eigrp_make_md5_digest(ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
+ }
+
+ /* EIGRP Checksum */
+ eigrp_packet_checksum(ei, ep->s, length);
+ ep->length = length;
+
+ ep->dst.s_addr = htonl(EIGRP_MULTICAST_ADDRESS);
+
+ /*This ack number we await from neighbor*/
+ ep->sequence_number = ei->eigrp->sequence_number;
+
+ if (IS_DEBUG_EIGRP_PACKET(0, RECV))
+ zlog_debug("Enqueuing Update length[%u] Seq [%u]",
+ length, ep->sequence_number);
+
+ for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr))
+ {
+ if (nbr->state == EIGRP_NEIGHBOR_UP)
+ {
+ packet_sent = true;
+ /*Put packet to retransmission queue*/
+ eigrp_fifo_push_head(nbr->retrans_queue, ep);
+
+ if (nbr->retrans_queue->count == 1)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+ }
+ }
+
+ if (!packet_sent)
+ eigrp_packet_free(ep);
+}
+
+void
+eigrp_update_send_all (struct eigrp *eigrp, struct eigrp_interface *exception)
+{
+ struct eigrp_interface *iface;
+ struct listnode *node, *node2, *nnode2;
+ struct eigrp_prefix_entry *pe;
+
+ for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface))
+ {
+ if (iface != exception)
+ {
+ eigrp_update_send(iface);
+ }
+ }
+
+ for (ALL_LIST_ELEMENTS(eigrp->topology_changes_internalIPV4, node2, nnode2, pe))
+ {
+ if(pe->req_action & EIGRP_FSM_NEED_UPDATE)
+ {
+ pe->req_action &= ~EIGRP_FSM_NEED_UPDATE;
+ listnode_delete(eigrp->topology_changes_internalIPV4, pe);
+ zlog_debug("UPDATE COUNT: %d", eigrp->topology_changes_internalIPV4->count);
+ }
+ }
+}
+
+/**
+ * @fn eigrp_update_send_GR_part
+ *
+ * @param[in] nbr contains neighbor who would receive Graceful restart
+ *
+ * @return void
+ *
+ * @par
+ * Function used for sending Graceful restart Update packet
+ * and if there are multiple chunks, send only one of them.
+ * It is called from thread. Do not call it directly.
+ *
+ * Uses nbr_gr_packet_type from neighbor.
+ */
+static void
+eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
+{
+ struct eigrp_packet *ep;
+ u_int16_t length = EIGRP_HEADER_LEN;
+ struct listnode *node, *nnode;
+ struct eigrp_prefix_entry *pe;
+ struct prefix_ipv4 *dest_addr;
+ struct eigrp *e;
+ struct access_list *alist, *alist_i;
+ struct prefix_list *plist, *plist_i;
+ struct list *prefixes;
+ u_int32_t flags;
+ unsigned int send_prefixes;
+ struct TLV_IPv4_Internal_type *tlv_max;
+
+ /* get prefixes to send to neighbor */
+ prefixes = nbr->nbr_gr_prefixes_send;
+
+ send_prefixes = 0;
+ length = EIGRP_HEADER_LEN;
+
+ /* if there already were last packet chunk, we won't continue */
+ if(nbr->nbr_gr_packet_type == EIGRP_PACKET_PART_LAST)
+ return;
+
+ /* if this is first packet chunk, we need to decide,
+ * if there will be one or more chunks */
+ if(nbr->nbr_gr_packet_type == EIGRP_PACKET_PART_FIRST)
+ {
+ if(prefixes->count <= EIGRP_TLV_MAX_IPv4)
+ {
+ /* there will be only one chunk */
+ flags = EIGRP_INIT_FLAG + EIGRP_RS_FLAG + EIGRP_EOT_FLAG;
+ nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_LAST;
+ }
+ else
+ {
+ /* there will be more chunks */
+ flags = EIGRP_INIT_FLAG + EIGRP_RS_FLAG;
+ nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_NA;
+ }
+ }
+ else
+ {
+ /* this is not first chunk, and we need to decide,
+ * if there will be more chunks */
+ if(prefixes->count <= EIGRP_TLV_MAX_IPv4)
+ {
+ /* this is last chunk */
+ flags = EIGRP_EOT_FLAG;
+ nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_LAST;
+ }
+ else
+ {
+ /* there will be more chunks */
+ flags = 0;
+ nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_NA;
+ }
+ }
+
+ ep = eigrp_packet_new(nbr->ei->ifp->mtu);
+
+ /* Prepare EIGRP Graceful restart UPDATE header */
+ eigrp_packet_header_init(EIGRP_OPC_UPDATE, nbr->ei, ep->s,
+ flags,
+ nbr->ei->eigrp->sequence_number,
+ nbr->recv_sequence_number);
+
+ // encode Authentication TLV, if needed
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ length += eigrp_add_authTLV_MD5_to_stream(ep->s,nbr->ei);
+ }
+
+ for (ALL_LIST_ELEMENTS(nbr->ei->eigrp->topology_table, node, nnode, pe))
+ {
+ /*
+ * Filtering
+ */
+ dest_addr = pe->destination_ipv4;
+ /* get list from eigrp process */
+ e = eigrp_lookup();
+ /* Get access-lists and prefix-lists from process and interface */
+ alist = e->list[EIGRP_FILTER_OUT];
+ plist = e->prefix[EIGRP_FILTER_OUT];
+ alist_i = nbr->ei->list[EIGRP_FILTER_OUT];
+ plist_i = nbr->ei->prefix[EIGRP_FILTER_OUT];
+
+ /* Check if any list fits */
+ if ((alist && access_list_apply (alist,
+ (struct prefix *) dest_addr) == FILTER_DENY)||
+ (plist && prefix_list_apply (plist,
+ (struct prefix *) dest_addr) == PREFIX_DENY)||
+ (alist_i && access_list_apply (alist_i,
+ (struct prefix *) dest_addr) == FILTER_DENY)||
+ (plist_i && prefix_list_apply (plist_i,
+ (struct prefix *) dest_addr) == PREFIX_DENY))
+ {
+ /* do not send filtered route */
+ zlog_info("Filtered prefix %s won't be sent out.",
+ inet_ntoa(dest_addr->prefix));
+ }
+ else
+ {
+ /* sending route which wasn't filtered */
+ length += eigrp_add_internalTLV_to_stream(ep->s, pe);
+ send_prefixes++;
+ }
+
+ alist = e->list[EIGRP_FILTER_IN];
+ plist = e->prefix[EIGRP_FILTER_IN];
+ alist_i = nbr->ei->list[EIGRP_FILTER_IN];
+ plist_i = nbr->ei->prefix[EIGRP_FILTER_IN];
+
+ /* Check if any list fits */
+ if ((alist && access_list_apply (alist,
+ (struct prefix *) dest_addr) == FILTER_DENY)||
+ (plist && prefix_list_apply (plist,
+ (struct prefix *) dest_addr) == PREFIX_DENY)||
+ (alist_i && access_list_apply (alist_i,
+ (struct prefix *) dest_addr) == FILTER_DENY)||
+ (plist_i && prefix_list_apply (plist_i,
+ (struct prefix *) dest_addr) == PREFIX_DENY))
+ {
+ /* do not send filtered route */
+ zlog_info("Filtered prefix %s will be removed.",
+ inet_ntoa(dest_addr->prefix));
+
+ tlv_max = eigrp_IPv4_InternalTLV_new();
+ tlv_max->type = EIGRP_TLV_IPv4_INT;
+ tlv_max->length = 28U;
+ tlv_max->metric = pe->reported_metric;
+ /* set delay to MAX */
+ tlv_max->metric.delay = EIGRP_MAX_METRIC;
+ tlv_max->destination = pe->destination_ipv4->prefix;
+ tlv_max->prefix_length = pe->destination_ipv4->prefixlen;
+
+ /* prepare message for FSM */
+ struct eigrp_fsm_action_message *fsm_msg;
+ fsm_msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
+ sizeof(struct eigrp_fsm_action_message));
+
+ struct eigrp_neighbor_entry *entry =
+ eigrp_prefix_entry_lookup(pe->entries, nbr);
+
+ fsm_msg->packet_type = EIGRP_OPC_UPDATE;
+ fsm_msg->eigrp = e;
+ fsm_msg->data_type = EIGRP_TLV_IPv4_INT;
+ fsm_msg->adv_router = nbr;
+ fsm_msg->data.ipv4_int_type = tlv_max;
+ fsm_msg->entry = entry;
+ fsm_msg->prefix = pe;
+
+ /* send message to FSM */
+ int event = eigrp_get_fsm_event(fsm_msg);
+ eigrp_fsm_event(fsm_msg, event);
+
+ /* free memory used by TLV */
+ eigrp_IPv4_InternalTLV_free (tlv_max);
+ }
+ /*
+ * End of filtering
+ */
+
+ /* NULL the pointer */
+ dest_addr = NULL;
+
+ /* delete processed prefix from list */
+ listnode_delete(prefixes, pe);
+
+ /* if there are enough prefixes, send packet */
+ if(send_prefixes >= EIGRP_TLV_MAX_IPv4)
+ break;
+ }
+
+ /* compute Auth digest */
+ if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL))
+ {
+ eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
+ }
+
+ /* EIGRP Checksum */
+ eigrp_packet_checksum(nbr->ei, ep->s, length);
+
+ ep->length = length;
+ ep->dst.s_addr = nbr->src.s_addr;
+
+ /*This ack number we await from neighbor*/
+ ep->sequence_number = nbr->ei->eigrp->sequence_number;
+
+ if (IS_DEBUG_EIGRP_PACKET(0, RECV))
+ zlog_debug("Enqueuing Update Init Len [%u] Seq [%u] Dest [%s]",
+ ep->length, ep->sequence_number, inet_ntoa(ep->dst));
+
+ /*Put packet to retransmission queue*/
+ eigrp_fifo_push_head(nbr->retrans_queue, ep);
+
+ if (nbr->retrans_queue->count == 1)
+ {
+ eigrp_send_packet_reliably(nbr);
+ }
+}
+
+/**
+ * @fn eigrp_update_send_GR_thread
+ *
+ * @param[in] thread contains neighbor who would receive Graceful restart
+ *
+ * @return int always 0
+ *
+ * @par
+ * Function used for sending Graceful restart Update packet
+ * in thread, it is prepared for multiple chunks of packet.
+ *
+ * Uses nbr_gr_packet_type and t_nbr_send_gr from neighbor.
+ */
+int
+eigrp_update_send_GR_thread(struct thread *thread)
+{
+ struct eigrp_neighbor *nbr;
+
+ /* get argument from thread */
+ nbr = THREAD_ARG(thread);
+ /* remove this thread pointer */
+ nbr->t_nbr_send_gr = NULL;
+
+ /* if there is packet waiting in queue,
+ * schedule this thread again with small delay */
+ if(nbr->retrans_queue->count > 0)
+ {
+ nbr->t_nbr_send_gr = NULL;
+ thread_add_timer_msec(master, eigrp_update_send_GR_thread, nbr, 10,
+ &nbr->t_nbr_send_gr);
+ return 0;
+ }
+
+ /* send GR EIGRP packet chunk */
+ eigrp_update_send_GR_part(nbr);
+
+ /* if it wasn't last chunk, schedule this thread again */
+ if(nbr->nbr_gr_packet_type != EIGRP_PACKET_PART_LAST) {
+ thread_execute(master, eigrp_update_send_GR_thread, nbr, 0);
+ nbr->t_nbr_send_gr = NULL;
+ }
+
+ return 0;
+}
+
+/**
+ * @fn eigrp_update_send_GR
+ *
+ * @param[in] nbr Neighbor who would receive Graceful restart
+ * @param[in] gr_type Who executed Graceful restart
+ * @param[in] vty Virtual terminal for log output
+ *
+ * @return void
+ *
+ * @par
+ * Function used for sending Graceful restart Update packet:
+ * Creates Update packet with INIT, RS, EOT flags and include
+ * all route except those filtered
+ */
+void
+eigrp_update_send_GR (struct eigrp_neighbor *nbr, enum GR_type gr_type, struct vty *vty)
+{
+ struct eigrp_prefix_entry *pe2;
+ struct listnode *node2, *nnode2;
+ struct list *prefixes;
+
+ if(gr_type == EIGRP_GR_FILTER)
+ {
+ /* function was called after applying filtration */
+ zlog_info("Neighbor %s (%s) is resync: route configuration changed",
+ inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ }
+ else if(gr_type == EIGRP_GR_MANUAL)
+ {
+ /* Graceful restart was called manually */
+ zlog_info("Neighbor %s (%s) is resync: manually cleared",
+ inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+
+ if(vty != NULL)
+ {
+ vty_time_print (vty, 0);
+ vty_out (vty, "Neighbor %s (%s) is resync: manually cleared%s",
+ inet_ntoa (nbr->src),
+ ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT),
+ VTY_NEWLINE);
+ }
+ }
+
+ prefixes = list_new();
+ /* add all prefixes from topology table to list */
+ for (ALL_LIST_ELEMENTS(nbr->ei->eigrp->topology_table, node2, nnode2, pe2))
+ {
+ listnode_add(prefixes, pe2);
+ }
+
+ /* save prefixes to neighbor */
+ nbr->nbr_gr_prefixes_send = prefixes;
+ /* indicate, that this is first GR Update packet chunk */
+ nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_FIRST;
+ /* execute packet sending in thread */
+ thread_execute(master, eigrp_update_send_GR_thread, nbr, 0);
+ nbr->t_nbr_send_gr = NULL;
+}
+
+/**
+ * @fn eigrp_update_send_interface_GR
+ *
+ * @param[in] ei Interface to neighbors of which the GR is sent
+ * @param[in] gr_type Who executed Graceful restart
+ * @param[in] vty Virtual terminal for log output
+ *
+ * @return void
+ *
+ * @par
+ * Function used for sending Graceful restart Update packet
+ * to all neighbors on specified interface.
+ */
+void
+eigrp_update_send_interface_GR (struct eigrp_interface *ei, enum GR_type gr_type, struct vty *vty)
+{
+ struct listnode *node;
+ struct eigrp_neighbor *nbr;
+
+ /* iterate over all neighbors on eigrp interface */
+ for (ALL_LIST_ELEMENTS_RO(ei->nbrs, node, nbr))
+ {
+ /* send GR to neighbor */
+ eigrp_update_send_GR(nbr, gr_type, vty);
+ }
+}
+
+/**
+ * @fn eigrp_update_send_process_GR
+ *
+ * @param[in] eigrp EIGRP process
+ * @param[in] gr_type Who executed Graceful restart
+ * @param[in] vty Virtual terminal for log output
+ *
+ * @return void
+ *
+ * @par
+ * Function used for sending Graceful restart Update packet
+ * to all neighbors in eigrp process.
+ */
+void
+eigrp_update_send_process_GR (struct eigrp *eigrp, enum GR_type gr_type, struct vty *vty)
+{
+ struct listnode *node;
+ struct eigrp_interface *ei;
+
+ /* iterate over all eigrp interfaces */
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ /* send GR to all neighbors on interface */
+ eigrp_update_send_interface_GR(ei, gr_type, vty);
+ }
+}
diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c
new file mode 100644
index 0000000000..c6ff7b5a80
--- /dev/null
+++ b/eigrpd/eigrp_vty.c
@@ -0,0 +1,1568 @@
+/*
+ * EIGRP VTY Interface.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 "memory.h"
+#include "thread.h"
+#include "prefix.h"
+#include "table.h"
+#include "vty.h"
+#include "command.h"
+#include "plist.h"
+#include "log.h"
+#include "zclient.h"
+#include "keychain.h"
+#include "linklist.h"
+#include "distribute.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_const.h"
+
+static int
+config_write_network (struct vty *vty, struct eigrp *eigrp)
+{
+ struct route_node *rn;
+
+ /* `network area' print. */
+ for (rn = route_top (eigrp->networks); rn; rn = route_next (rn))
+ if (rn->info)
+ {
+ /* Network print. */
+ vty_out (vty, " network %s/%d %s",
+ inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen, VTY_NEWLINE);
+ }
+
+ if (eigrp->max_paths != EIGRP_MAX_PATHS_DEFAULT)
+ vty_out (vty, " maximum-paths %d%s", eigrp->max_paths, VTY_NEWLINE);
+
+ if (eigrp->variance != EIGRP_VARIANCE_DEFAULT)
+ vty_out (vty, " variance %d%s", eigrp->variance, VTY_NEWLINE);
+
+ /*Separate EIGRP configuration from the rest of the config*/
+ vty_out (vty, "!%s", VTY_NEWLINE);
+
+ return 0;
+}
+
+static int
+config_write_interfaces (struct vty *vty, struct eigrp *eigrp)
+{
+ struct eigrp_interface *ei;
+ struct listnode *node;
+
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ vty_out (vty, "interface %s%s", ei->ifp->name, VTY_NEWLINE);
+
+ if ((IF_DEF_PARAMS (ei->ifp)->auth_type) == EIGRP_AUTH_TYPE_MD5)
+ {
+ vty_out (vty, " ip authentication mode eigrp %d md5%s", eigrp->AS, VTY_NEWLINE);
+ }
+
+ if ((IF_DEF_PARAMS (ei->ifp)->auth_type) == EIGRP_AUTH_TYPE_SHA256)
+ {
+ vty_out (vty, " ip authentication mode eigrp %d hmac-sha-256%s", eigrp->AS, VTY_NEWLINE);
+ }
+
+ if(IF_DEF_PARAMS (ei->ifp)->auth_keychain)
+ {
+ vty_out (vty, " ip authentication key-chain eigrp %d %s%s",eigrp->AS,IF_DEF_PARAMS (ei->ifp)->auth_keychain, VTY_NEWLINE);
+ }
+
+ if ((IF_DEF_PARAMS (ei->ifp)->v_hello) != EIGRP_HELLO_INTERVAL_DEFAULT)
+ {
+ vty_out (vty, " ip hello-interval eigrp %d%s", IF_DEF_PARAMS (ei->ifp)->v_hello, VTY_NEWLINE);
+ }
+
+ if ((IF_DEF_PARAMS (ei->ifp)->v_wait) != EIGRP_HOLD_INTERVAL_DEFAULT)
+ {
+ vty_out (vty, " ip hold-time eigrp %d%s", IF_DEF_PARAMS (ei->ifp)->v_wait, VTY_NEWLINE);
+ }
+
+ /*Separate this EIGRP interface configuration from the others*/
+ vty_out (vty, "!%s", VTY_NEWLINE);
+ }
+
+ return 0;
+}
+
+static int
+eigrp_write_interface (struct vty *vty)
+{
+ struct listnode *node;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ vty_out (vty, "interface %s%s", ifp->name,
+ VTY_NEWLINE);
+
+ if (ifp->desc)
+ vty_out (vty, " description %s%s", ifp->desc,
+ VTY_NEWLINE);
+
+ if (IF_DEF_PARAMS (ifp)->bandwidth != EIGRP_BANDWIDTH_DEFAULT)
+ vty_out (vty, " bandwidth %u%s", IF_DEF_PARAMS (ifp)->bandwidth,
+ VTY_NEWLINE);
+ if (IF_DEF_PARAMS (ifp)->delay != EIGRP_DELAY_DEFAULT)
+ vty_out (vty, " delay %u%s", IF_DEF_PARAMS (ifp)->delay, VTY_NEWLINE);
+ if (IF_DEF_PARAMS (ifp)->v_hello != EIGRP_HELLO_INTERVAL_DEFAULT)
+ vty_out (vty, " ip hello-interval eigrp %u%s",
+ IF_DEF_PARAMS (ifp)->v_hello, VTY_NEWLINE);
+ if (IF_DEF_PARAMS (ifp)->v_wait != EIGRP_HOLD_INTERVAL_DEFAULT)
+ vty_out (vty, " ip hold-time eigrp %u%s",
+ IF_DEF_PARAMS (ifp)->v_wait, VTY_NEWLINE);
+
+ vty_out (vty, "!%s", VTY_NEWLINE);
+ }
+
+ return 0;
+}
+
+/**
+ * Writes distribute lists to config
+ */
+static int
+config_write_eigrp_distribute (struct vty *vty, struct eigrp *eigrp)
+{
+ int write=0;
+
+ /* Distribute configuration. */
+ write += config_write_distribute (vty);
+
+ return write;
+}
+
+/**
+ * Writes 'router eigrp' section to config
+ */
+static int
+config_write_eigrp_router (struct vty *vty, struct eigrp *eigrp)
+{
+ int write=0;
+
+ /* `router eigrp' print. */
+ vty_out (vty, "router eigrp %d%s", eigrp->AS, VTY_NEWLINE);
+
+ write++;
+
+ if (!eigrp->networks)
+ return write;
+
+ /* Router ID print. */
+ if (eigrp->router_id_static != 0)
+ {
+ struct in_addr router_id_static;
+ router_id_static.s_addr = htonl(eigrp->router_id_static);
+ vty_out (vty, " eigrp router-id %s%s",
+ inet_ntoa (router_id_static), VTY_NEWLINE);
+ }
+
+ /* Network area print. */
+ config_write_network (vty, eigrp);
+
+ /* Distribute-list and default-information print. */
+ config_write_eigrp_distribute (vty, eigrp);
+
+ /*Separate EIGRP configuration from the rest of the config*/
+ vty_out (vty, "!%s", VTY_NEWLINE);
+
+ return write;
+}
+
+DEFUN_NOSH (router_eigrp,
+ router_eigrp_cmd,
+ "router eigrp (1-65535)",
+ "Enable a routing process\n"
+ "Start EIGRP configuration\n"
+ "AS Number to use\n")
+{
+ struct eigrp *eigrp = eigrp_get (argv[2]->arg);
+ VTY_PUSH_CONTEXT(EIGRP_NODE, eigrp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_router_eigrp,
+ no_router_eigrp_cmd,
+ "no router eigrp (1-65535)",
+ NO_STR
+ "Routing process\n"
+ "EIGRP configuration\n"
+ "AS number to use\n")
+{
+ vty->node = CONFIG_NODE;
+
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp->AS != atoi (argv[3]->arg))
+ {
+ vty_out (vty, "%% Attempting to deconfigure non-existent AS%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ eigrp_finish_final (eigrp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_router_id,
+ eigrp_router_id_cmd,
+ "eigrp router-id A.B.C.D",
+ "EIGRP specific commands\n"
+ "Router ID for this EIGRP process\n"
+ "EIGRP Router-ID in IP address format\n")
+{
+ //struct eigrp *eigrp = vty->index;
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_router_id,
+ no_eigrp_router_id_cmd,
+ "no eigrp router-id A.B.C.D",
+ NO_STR
+ "EIGRP specific commands\n"
+ "Router ID for this EIGRP process\n"
+ "EIGRP Router-ID in IP address format\n")
+{
+ //struct eigrp *eigrp = vty->index;
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_passive_interface,
+ eigrp_passive_interface_cmd,
+ "passive-interface IFNAME",
+ "Suppress routing updates on an interface\n"
+ "Interface to suppress on\n")
+{
+ VTY_DECLVAR_CONTEXT(eigrp, eigrp);
+ struct eigrp_interface *ei;
+ struct listnode *node;
+ char *ifname = argv[1]->arg;
+
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ if (strcmp (ifname, ei->ifp->name) == 0)
+ SET_IF_PARAM (IF_DEF_PARAMS (ei->ifp), passive_interface);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_passive_interface,
+ no_eigrp_passive_interface_cmd,
+ "no passive-interface IFNAME",
+ NO_STR
+ "Suppress routing updates on an interface\n"
+ "Interface to suppress on\n")
+{
+ VTY_DECLVAR_CONTEXT(eigrp, eigrp);
+ struct eigrp_interface *ei;
+ struct listnode *node;
+ char *ifname = argv[2]->arg;
+
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ if (strcmp (ifname, ei->ifp->name) == 0)
+ UNSET_IF_PARAM (IF_DEF_PARAMS (ei->ifp), passive_interface);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_timers_active,
+ eigrp_timers_active_cmd,
+ "timers active-time <(1-65535)|disabled>",
+ "Adjust routing timers\n"
+ "Time limit for active state\n"
+ "Active state time limit in minutes\n"
+ "Disable time limit for active state\n")
+{
+ //struct eigrp *eigrp = vty->index;
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_timers_active,
+ no_eigrp_timers_active_cmd,
+ "no timers active-time <(1-65535)|disabled>",
+ NO_STR
+ "Adjust routing timers\n"
+ "Time limit for active state\n"
+ "Active state time limit in minutes\n"
+ "Disable time limit for active state\n")
+{
+ //struct eigrp *eigrp = vty->index;
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (eigrp_metric_weights,
+ eigrp_metric_weights_cmd,
+ "metric weights (0-255) (0-255) (0-255) (0-255) (0-255) ",
+ "Modify metrics and parameters for advertisement\n"
+ "Modify metric coefficients\n"
+ "K1\n"
+ "K2\n"
+ "K3\n"
+ "K4\n"
+ "K5\n")
+{
+ //struct eigrp *eigrp = vty->index;
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_metric_weights,
+ no_eigrp_metric_weights_cmd,
+ "no metric weights <0-255> <0-255> <0-255> <0-255> <0-255>",
+ NO_STR
+ "Modify metrics and parameters for advertisement\n"
+ "Modify metric coefficients\n"
+ "K1\n"
+ "K2\n"
+ "K3\n"
+ "K4\n"
+ "K5\n")
+{
+ //struct eigrp *eigrp = vty->index;
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (eigrp_network,
+ eigrp_network_cmd,
+ "network A.B.C.D/M",
+ "Enable routing on an IP network\n"
+ "EIGRP network prefix\n")
+{
+ VTY_DECLVAR_CONTEXT(eigrp, eigrp);
+ struct prefix_ipv4 p;
+ int ret;
+
+ VTY_GET_IPV4_PREFIX ("network prefix", p, argv[1]->arg);
+
+ ret = eigrp_network_set (eigrp, &p);
+
+ if (ret == 0)
+ {
+ vty_out (vty, "There is already same network statement.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_network,
+ no_eigrp_network_cmd,
+ "no network A.B.C.D/M",
+ NO_STR
+ "Disable routing on an IP network\n"
+ "EIGRP network prefix\n")
+{
+ VTY_DECLVAR_CONTEXT(eigrp, eigrp);
+ struct prefix_ipv4 p;
+ int ret;
+
+ VTY_GET_IPV4_PREFIX ("network prefix", p, argv[2]->arg);
+
+ ret = eigrp_network_unset (eigrp, &p);
+
+ if (ret == 0)
+ {
+ vty_out (vty,"Can't find specified network configuration.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_neighbor,
+ eigrp_neighbor_cmd,
+ "neighbor A.B.C.D",
+ "Specify a neighbor router\n"
+ "Neighbor address\n")
+{
+ //struct eigrp *eigrp = vty->index;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_neighbor,
+ no_eigrp_neighbor_cmd,
+ "no neighbor A.B.C.D",
+ NO_STR
+ "Specify a neighbor router\n"
+ "Neighbor address\n")
+{
+ //struct eigrp *eigrp = vty->index;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_eigrp_topology,
+ show_ip_eigrp_topology_cmd,
+ "show ip eigrp topology [all-links]",
+ SHOW_STR
+ IP_STR
+ "IP-EIGRP show commands\n"
+ "IP-EIGRP topology\n"
+ "Show all links in topology table\n")
+{
+ struct eigrp *eigrp;
+ struct listnode *node, *node2;
+ struct eigrp_prefix_entry *tn;
+ struct eigrp_neighbor_entry *te;
+ int first;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ show_ip_eigrp_topology_header (vty, eigrp);
+
+ for (ALL_LIST_ELEMENTS_RO (eigrp->topology_table, node, tn))
+ {
+ first = 1;
+ for (ALL_LIST_ELEMENTS_RO (tn->entries, node2, te))
+ {
+ if (argc == 5 ||
+ (((te->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)||
+ ((te->flags & EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG)))
+ {
+ show_ip_eigrp_neighbor_entry (vty, eigrp, te, &first);
+ first = 0;
+ }
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+ALIAS (show_ip_eigrp_topology,
+ show_ip_eigrp_topology_detail_cmd,
+ "show ip eigrp topology <A.B.C.D|A.B.C.D/M|detail|summary>",
+ SHOW_STR
+ IP_STR
+ "IP-EIGRP show commands\n"
+ "IP-EIGRP topology\n"
+ "Netwok to display information about\n"
+ "IP prefix <network>/<length>, e.g., 192.168.0.0/16\n"
+ "Show all links in topology table\n"
+ "Show a summary of the topology table\n")
+
+DEFUN (show_ip_eigrp_interfaces,
+ show_ip_eigrp_interfaces_cmd,
+ "show ip eigrp interfaces [IFNAME] [detail]",
+ SHOW_STR
+ IP_STR
+ "IP-EIGRP show commands\n"
+ "IP-EIGRP interfaces\n"
+ "Interface name to look at\n"
+ "Detailed information\n")
+{
+ struct eigrp_interface *ei;
+ struct eigrp *eigrp;
+ struct listnode *node;
+ int idx = 0;
+ bool detail = false;
+ const char *ifname = NULL;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, "EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ if (argv_find (argv, argc, "IFNAME", &idx))
+ ifname = argv[idx]->arg;
+
+ if (argv_find (argv, argc, "detail", &idx))
+ detail = true;
+
+ if (!ifname)
+ show_ip_eigrp_interface_header (vty, eigrp);
+
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ if (!ifname || strcmp (ei->ifp->name, ifname) == 0)
+ {
+ show_ip_eigrp_interface_sub (vty, eigrp, ei);
+ if (detail)
+ show_ip_eigrp_interface_detail (vty, eigrp, ei);
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_eigrp_neighbors,
+ show_ip_eigrp_neighbors_cmd,
+ "show ip eigrp neighbors [IFNAME] [detail]",
+ SHOW_STR
+ IP_STR
+ "IP-EIGRP show commands\n"
+ "IP-EIGRP neighbors\n"
+ "Interface to show on\n"
+ "Detailed Information\n")
+{
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct listnode *node, *node2, *nnode2;
+ struct eigrp_neighbor *nbr;
+ bool detail = false;
+ int idx = 0;
+ const char *ifname = NULL;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ if (argv_find(argv, argc, "IFNAME", &idx))
+ ifname = argv[idx]->arg;
+
+ detail = (argv_find(argv, argc, "detail", &idx));
+
+ show_ip_eigrp_neighbor_header (vty, eigrp);
+
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ if (!ifname || strcmp(ei->ifp->name, ifname) == 0)
+ {
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
+ {
+ if (detail || (nbr->state == EIGRP_NEIGHBOR_UP))
+ show_ip_eigrp_neighbor_sub (vty, nbr, detail);
+ }
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_if_delay,
+ eigrp_if_delay_cmd,
+ "delay (1-16777215)",
+ "Specify interface throughput delay\n"
+ "Throughput delay (tens of microseconds)\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp *eigrp;
+ u_int32_t delay;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+ }
+
+ delay = atoi (argv[1]->arg);
+
+ IF_DEF_PARAMS (ifp)->delay = delay;
+ eigrp_if_reset (ifp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_if_delay,
+ no_eigrp_if_delay_cmd,
+ "no delay (1-16777215)",
+ NO_STR
+ "Specify interface throughput delay\n"
+ "Throughput delay (tens of microseconds)\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+ }
+
+ IF_DEF_PARAMS (ifp)->delay = EIGRP_DELAY_DEFAULT;
+ eigrp_if_reset (ifp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_if_bandwidth,
+ eigrp_if_bandwidth_cmd,
+ "eigrp bandwidth (1-10000000)",
+ "EIGRP specific commands\n"
+ "Set bandwidth informational parameter\n"
+ "Bandwidth in kilobits\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ u_int32_t bandwidth;
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ bandwidth = atoi (argv[1]->arg);
+
+ IF_DEF_PARAMS (ifp)->bandwidth = bandwidth;
+ eigrp_if_reset (ifp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_if_bandwidth,
+ no_eigrp_if_bandwidth_cmd,
+ "no eigrp bandwidth [(1-10000000)]",
+ NO_STR
+ "EIGRP specific commands\n"
+ "Set bandwidth informational parameter\n"
+ "Bandwidth in kilobits\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ IF_DEF_PARAMS (ifp)->bandwidth = EIGRP_BANDWIDTH_DEFAULT;
+ eigrp_if_reset (ifp);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_if_ip_hellointerval,
+ eigrp_if_ip_hellointerval_cmd,
+ "ip hello-interval eigrp (1-65535)",
+ "Interface Internet Protocol config commands\n"
+ "Configures EIGRP hello interval\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "Seconds between hello transmissions\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ u_int32_t hello;
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ hello = atoi (argv[3]->arg);
+
+ IF_DEF_PARAMS (ifp)->v_hello = hello;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_if_ip_hellointerval,
+ no_eigrp_if_ip_hellointerval_cmd,
+ "no ip hello-interval eigrp [(1-65535)]",
+ NO_STR
+ "Interface Internet Protocol config commands\n"
+ "Configures EIGRP hello interval\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "Seconds between hello transmissions\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct listnode *node, *nnode;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ IF_DEF_PARAMS (ifp)->v_hello = EIGRP_HELLO_INTERVAL_DEFAULT;
+
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ if (ei->ifp == ifp)
+ {
+ THREAD_TIMER_OFF (ei->t_hello);
+ thread_add_timer (master, eigrp_hello_timer, ei, 1, &ei->t_hello);
+ break;
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_if_ip_holdinterval,
+ eigrp_if_ip_holdinterval_cmd,
+ "ip hold-time eigrp (1-65535)",
+ "Interface Internet Protocol config commands\n"
+ "Configures EIGRP IPv4 hold time\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "Seconds before neighbor is considered down\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ u_int32_t hold;
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ hold = atoi (argv[3]->arg);
+
+ IF_DEF_PARAMS (ifp)->v_wait = hold;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_ip_summary_address,
+ eigrp_ip_summary_address_cmd,
+ "ip summary-address eigrp (1-65535) A.B.C.D/M",
+ "Interface Internet Protocol config commands\n"
+ "Perform address summarization\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "AS number\n"
+ "Summary <network>/<length>, e.g. 192.168.0.0/16\n")
+{
+ //VTY_DECLVAR_CONTEXT(interface, ifp);
+ //u_int32_t AS;
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ //AS = atoi (argv[3]->arg);
+
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_ip_summary_address,
+ no_eigrp_ip_summary_address_cmd,
+ "no ip summary-address eigrp (1-65535) A.B.C.D/M",
+ NO_STR
+ "Interface Internet Protocol config commands\n"
+ "Perform address summarization\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "AS number\n"
+ "Summary <network>/<length>, e.g. 192.168.0.0/16\n")
+{
+ //VTY_DECLVAR_CONTEXT(interface, ifp);
+ //u_int32_t AS;
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ //AS = atoi (argv[4]->arg);
+
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_if_ip_holdinterval,
+ no_eigrp_if_ip_holdinterval_cmd,
+ "no ip hold-time eigrp",
+ "No"
+ "Interface Internet Protocol config commands\n"
+ "Configures EIGRP hello interval\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "Seconds before neighbor is considered down\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ IF_DEF_PARAMS (ifp)->v_wait = EIGRP_HOLD_INTERVAL_DEFAULT;
+
+ return CMD_SUCCESS;
+}
+
+static int
+str2auth_type (const char *str, struct interface *ifp)
+{
+ /* Sanity check. */
+ if (str == NULL)
+ return CMD_WARNING;
+
+ if(strncmp(str, "md5",3) == 0)
+ {
+ IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_MD5;
+ return CMD_SUCCESS;
+ }
+ else if(strncmp(str, "hmac-sha-256",12) == 0)
+ {
+ IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_SHA256;
+ return CMD_SUCCESS;
+ }
+
+ return CMD_WARNING;
+}
+
+DEFUN (eigrp_authentication_mode,
+ eigrp_authentication_mode_cmd,
+ "ip authentication mode eigrp (1-65535) <md5|hmac-sha-256>",
+ "Interface Internet Protocol config commands\n"
+ "Authentication subcommands\n"
+ "Mode\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "Autonomous system number\n"
+ "Keyed message digest\n"
+ "HMAC SHA256 algorithm \n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ // if(strncmp(argv[2], "md5",3))
+ // IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_MD5;
+ // else if(strncmp(argv[2], "hmac-sha-256",12))
+ // IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_SHA256;
+
+ return str2auth_type(argv[5]->arg, ifp);
+}
+
+DEFUN (no_eigrp_authentication_mode,
+ no_eigrp_authentication_mode_cmd,
+ "no ip authentication mode eigrp (1-65535) <md5|hmac-sha-256>",
+ "Disable\n"
+ "Interface Internet Protocol config commands\n"
+ "Authentication subcommands\n"
+ "Mode\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "Autonomous system number\n"
+ "Keyed message digest\n"
+ "HMAC SHA256 algorithm \n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_NONE;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_authentication_keychain,
+ eigrp_authentication_keychain_cmd,
+ "ip authentication key-chain eigrp (1-65535) WORD",
+ "Interface Internet Protocol config commands\n"
+ "Authentication subcommands\n"
+ "Key-chain\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "Autonomous system number\n"
+ "Name of key-chain\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp *eigrp;
+ struct keychain *keychain;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, "EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ keychain = keychain_lookup (argv[4]->arg);
+ if(keychain != NULL)
+ {
+ if(IF_DEF_PARAMS (ifp)->auth_keychain)
+ {
+ free (IF_DEF_PARAMS (ifp)->auth_keychain);
+ IF_DEF_PARAMS (ifp)->auth_keychain = strdup(keychain->name);
+ }
+ else
+ IF_DEF_PARAMS (ifp)->auth_keychain = strdup(keychain->name);
+ }
+ else
+ vty_out(vty,"Key chain with specified name not found%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_authentication_keychain,
+ no_eigrp_authentication_keychain_cmd,
+ "no ip authentication key-chain eigrp (1-65535) WORD",
+ "Disable\n"
+ "Interface Internet Protocol config commands\n"
+ "Authentication subcommands\n"
+ "Key-chain\n"
+ "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
+ "Autonomous system number\n"
+ "Name of key-chain\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, "EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ if((IF_DEF_PARAMS (ifp)->auth_keychain != NULL) &&
+ (strcmp(IF_DEF_PARAMS (ifp)->auth_keychain,argv[5]->arg)==0))
+ {
+ free (IF_DEF_PARAMS (ifp)->auth_keychain);
+ IF_DEF_PARAMS (ifp)->auth_keychain = NULL;
+ }
+ else
+ vty_out(vty,"Key chain with specified name not configured on interface%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_redistribute_source_metric,
+ eigrp_redistribute_source_metric_cmd,
+ "redistribute " FRR_REDIST_STR_EIGRPD
+ " [metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)]",
+ REDIST_STR
+ FRR_REDIST_HELP_STR_EIGRPD
+ "Metric for redistributed routes\n"
+ "Bandwidth metric in Kbits per second\n"
+ "EIGRP delay metric, in 10 microsecond units\n"
+ "EIGRP reliability metric where 255 is 100% reliable2 ?\n"
+ "EIGRP Effective bandwidth metric (Loading) where 255 is 100% loaded\n"
+ "EIGRP MTU of the path\n")
+{
+ VTY_DECLVAR_CONTEXT(eigrp, eigrp);
+ struct eigrp_metrics metrics_from_command = { 0 };
+ int source;
+ int idx = 0;
+
+ /* Get distribute source. */
+ argv_find (argv, argc, "redistribute", &idx);
+ source = proto_redistnum(AFI_IP, argv[idx+1]->arg);
+ if (source < 0 )
+ return CMD_WARNING;
+
+ /* Get metrics values */
+
+ return eigrp_redistribute_set (eigrp, source, metrics_from_command);
+}
+
+DEFUN (no_eigrp_redistribute_source_metric,
+ no_eigrp_redistribute_source_metric_cmd,
+ "no redistribute " FRR_REDIST_STR_EIGRPD
+ " metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)",
+ "Disable\n"
+ REDIST_STR
+ FRR_REDIST_HELP_STR_EIGRPD
+ "Metric for redistributed routes\n"
+ "Bandwidth metric in Kbits per second\n"
+ "EIGRP delay metric, in 10 microsecond units\n"
+ "EIGRP reliability metric where 255 is 100% reliable2 ?\n"
+ "EIGRP Effective bandwidth metric (Loading) where 255 is 100% loaded\n"
+ "EIGRP MTU of the path\n")
+{
+ VTY_DECLVAR_CONTEXT(eigrp, eigrp);
+ int source;
+ int idx = 0;
+
+ /* Get distribute source. */
+ argv_find (argv, argc, "redistribute", &idx);
+ source = proto_redistnum(AFI_IP, argv[idx+1]->arg);
+ if (source < 0 )
+ return CMD_WARNING;
+
+ /* Get metrics values */
+
+ return eigrp_redistribute_unset (eigrp, source);
+}
+
+DEFUN (eigrp_variance,
+ eigrp_variance_cmd,
+ "variance (1-128)",
+ "Control load balancing variance\n"
+ "Metric variance multiplier\n")
+{
+ struct eigrp *eigrp;
+ u_char variance;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, "EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+ variance = atoi(argv[1]->arg);
+
+ eigrp->variance = variance;
+
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_variance,
+ no_eigrp_variance_cmd,
+ "no variance (1-128)",
+ "Disable\n"
+ "Control load balancing variance\n"
+ "Metric variance multiplier\n")
+{
+ struct eigrp *eigrp;
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, "EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ eigrp->variance = EIGRP_VARIANCE_DEFAULT;
+
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (eigrp_maximum_paths,
+ eigrp_maximum_paths_cmd,
+ "maximum-paths (1-32)",
+ "Forward packets over multiple paths\n"
+ "Number of paths\n")
+{
+ struct eigrp *eigrp;
+ u_char max;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, "EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ max = atoi(argv[1]->arg);
+
+ eigrp->max_paths = max;
+
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_eigrp_maximum_paths,
+ no_eigrp_maximum_paths_cmd,
+ "no maximum-paths <1-32>",
+ NO_STR
+ "Forward packets over multiple paths\n"
+ "Number of paths\n")
+{
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, "EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ eigrp->max_paths = EIGRP_MAX_PATHS_DEFAULT;
+
+ /*TODO: */
+
+ return CMD_SUCCESS;
+}
+
+/*
+ * Execute hard restart for all neighbors
+ */
+DEFUN (clear_ip_eigrp_neighbors,
+ clear_ip_eigrp_neighbors_cmd,
+ "clear ip eigrp neighbors",
+ CLEAR_STR
+ IP_STR
+ "Clear IP-EIGRP\n"
+ "Clear IP-EIGRP neighbors\n")
+{
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct listnode *node, *node2, *nnode2;
+ struct eigrp_neighbor *nbr;
+
+ /* Check if eigrp process is enabled */
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ /* iterate over all eigrp interfaces */
+ for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei))
+ {
+ /* send Goodbye Hello */
+ eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
+
+ /* iterate over all neighbors on eigrp interface */
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
+ {
+ if (nbr->state != EIGRP_NEIGHBOR_DOWN)
+ {
+ zlog_debug ("Neighbor %s (%s) is down: manually cleared",
+ inet_ntoa (nbr->src),
+ ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ vty_time_print (vty, 0);
+ vty_out (vty, "Neighbor %s (%s) is down: manually cleared%s",
+ inet_ntoa (nbr->src),
+ ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT),
+ VTY_NEWLINE);
+
+ /* set neighbor to DOWN */
+ nbr->state = EIGRP_NEIGHBOR_DOWN;
+ /* delete neighbor */
+ eigrp_nbr_delete (nbr);
+ }
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+/*
+ * Execute hard restart for all neighbors on interface
+ */
+DEFUN (clear_ip_eigrp_neighbors_int,
+ clear_ip_eigrp_neighbors_int_cmd,
+ "clear ip eigrp neighbors IFNAME",
+ CLEAR_STR
+ IP_STR
+ "Clear IP-EIGRP\n"
+ "Clear IP-EIGRP neighbors\n"
+ "Interface's name\n")
+{
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+ struct listnode *node2, *nnode2;
+ struct eigrp_neighbor *nbr;
+ int idx = 0;
+
+ /* Check if eigrp process is enabled */
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ /* lookup interface by specified name */
+ argv_find(argv, argc, "IFNAME", &idx);
+ ei = eigrp_if_lookup_by_name(eigrp, argv[idx]->arg);
+ if(ei == NULL)
+ {
+ vty_out (vty, " Interface (%s) doesn't exist%s", argv[idx]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* send Goodbye Hello */
+ eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
+
+ /* iterate over all neighbors on eigrp interface */
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
+ {
+ if (nbr->state != EIGRP_NEIGHBOR_DOWN)
+ {
+ zlog_debug ("Neighbor %s (%s) is down: manually cleared",
+ inet_ntoa (nbr->src),
+ ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT));
+ vty_time_print (vty, 0);
+ vty_out (vty, "Neighbor %s (%s) is down: manually cleared%s",
+ inet_ntoa (nbr->src),
+ ifindex2ifname (nbr->ei->ifp->ifindex, VRF_DEFAULT),
+ VTY_NEWLINE);
+
+ /* set neighbor to DOWN */
+ nbr->state = EIGRP_NEIGHBOR_DOWN;
+ /* delete neighbor */
+ eigrp_nbr_delete (nbr);
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+/*
+ * Execute hard restart for neighbor specified by IP
+ */
+DEFUN (clear_ip_eigrp_neighbors_IP,
+ clear_ip_eigrp_neighbors_IP_cmd,
+ "clear ip eigrp neighbors A.B.C.D",
+ CLEAR_STR
+ IP_STR
+ "Clear IP-EIGRP\n"
+ "Clear IP-EIGRP neighbors\n"
+ "IP-EIGRP neighbor address\n")
+{
+ struct eigrp *eigrp;
+ struct eigrp_neighbor *nbr;
+ struct in_addr nbr_addr;
+
+ VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[4]->arg);
+
+ /* Check if eigrp process is enabled */
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ /* lookup neighbor in whole process */
+ nbr = eigrp_nbr_lookup_by_addr_process(eigrp, nbr_addr);
+
+ /* if neighbor doesn't exists, notify user and exit */
+ if(nbr == NULL)
+ {
+ vty_out (vty, "Neighbor with entered address doesn't exists.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* execute hard reset on neighbor */
+ eigrp_nbr_hard_restart(nbr, vty);
+
+ return CMD_SUCCESS;
+}
+
+/*
+ * Execute graceful restart for all neighbors
+ */
+DEFUN (clear_ip_eigrp_neighbors_soft,
+ clear_ip_eigrp_neighbors_soft_cmd,
+ "clear ip eigrp neighbors soft",
+ CLEAR_STR
+ IP_STR
+ "Clear IP-EIGRP\n"
+ "Clear IP-EIGRP neighbors\n"
+ "Resync with peers without adjacency reset\n")
+{
+ struct eigrp *eigrp;
+
+ /* Check if eigrp process is enabled */
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ /* execute graceful restart on all neighbors */
+ eigrp_update_send_process_GR(eigrp, EIGRP_GR_MANUAL, vty);
+
+ return CMD_SUCCESS;
+}
+
+/*
+ * Execute graceful restart for all neighbors on interface
+ */
+DEFUN (clear_ip_eigrp_neighbors_int_soft,
+ clear_ip_eigrp_neighbors_int_soft_cmd,
+ "clear ip eigrp neighbors IFNAME soft",
+ CLEAR_STR
+ IP_STR
+ "Clear IP-EIGRP\n"
+ "Clear IP-EIGRP neighbors\n"
+ "Interface's name\n"
+ "Resync with peer without adjacency reset\n")
+{
+ struct eigrp *eigrp;
+ struct eigrp_interface *ei;
+
+ /* Check if eigrp process is enabled */
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ /* lookup interface by specified name */
+ ei = eigrp_if_lookup_by_name(eigrp, argv[4]->arg);
+ if(ei == NULL)
+ {
+ vty_out (vty, " Interface (%s) doesn't exist%s", argv[4]->arg, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* execute graceful restart for all neighbors on interface */
+ eigrp_update_send_interface_GR(ei, EIGRP_GR_MANUAL, vty);
+ return CMD_SUCCESS;
+}
+
+/*
+ * Execute graceful restart for neighbor specified by IP
+ */
+DEFUN (clear_ip_eigrp_neighbors_IP_soft,
+ clear_ip_eigrp_neighbors_IP_soft_cmd,
+ "clear ip eigrp neighbors A.B.C.D soft",
+ CLEAR_STR
+ IP_STR
+ "Clear IP-EIGRP\n"
+ "Clear IP-EIGRP neighbors\n"
+ "IP-EIGRP neighbor address\n"
+ "Resync with peer without adjacency reset\n")
+{
+ struct eigrp *eigrp;
+ struct eigrp_neighbor *nbr;
+ struct in_addr nbr_addr;
+
+ VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[4]->arg);
+
+ /* Check if eigrp process is enabled */
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ {
+ vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ /* lookup neighbor in whole process */
+ nbr = eigrp_nbr_lookup_by_addr_process(eigrp, nbr_addr);
+
+ /* if neighbor doesn't exists, notify user and exit */
+ if(nbr == NULL)
+ {
+ vty_out (vty, "Neighbor with entered address doesn't exists.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* execute graceful restart on neighbor */
+ eigrp_update_send_GR(nbr, EIGRP_GR_MANUAL, vty);
+
+ return CMD_SUCCESS;
+}
+
+static struct cmd_node eigrp_node =
+{
+ EIGRP_NODE,
+ "%s(config-router)# ",
+ 1
+};
+
+/* Save EIGRP configuration */
+static int
+eigrp_config_write (struct vty *vty)
+{
+ struct eigrp *eigrp;
+
+ int write = 0;
+
+ eigrp = eigrp_lookup ();
+ if (eigrp != NULL)
+ {
+ /* Writes 'router eigrp' section to config */
+ config_write_eigrp_router (vty, eigrp);
+
+ /* Interface config print */
+ config_write_interfaces (vty, eigrp);
+//
+// /* static neighbor print. */
+// config_write_eigrp_nbr_nbma (vty, eigrp);
+//
+// /* Virtual-Link print. */
+// config_write_virtual_link (vty, eigrp);
+//
+// /* Default metric configuration. */
+// config_write_eigrp_default_metric (vty, eigrp);
+//
+// /* Distribute-list and default-information print. */
+// config_write_eigrp_distribute (vty, eigrp);
+//
+// /* Distance configuration. */
+// config_write_eigrp_distance (vty, eigrp)
+ }
+
+ return write;
+}
+
+void
+eigrp_vty_show_init (void)
+{
+ install_element (VIEW_NODE, &show_ip_eigrp_interfaces_cmd);
+
+ install_element (VIEW_NODE, &show_ip_eigrp_neighbors_cmd);
+
+ install_element (VIEW_NODE, &show_ip_eigrp_topology_cmd);
+
+ install_element (VIEW_NODE, &show_ip_eigrp_topology_detail_cmd);
+
+}
+
+/* eigrpd's interface node. */
+static struct cmd_node eigrp_interface_node =
+{
+ INTERFACE_NODE,
+ "%s(config-if)# ",
+ 1
+};
+
+void
+eigrp_vty_if_init (void)
+{
+ install_node (&eigrp_interface_node, eigrp_write_interface);
+ if_cmd_init();
+
+ /* Delay and bandwidth configuration commands*/
+ install_element (INTERFACE_NODE, &eigrp_if_delay_cmd);
+ install_element (INTERFACE_NODE, &no_eigrp_if_delay_cmd);
+ install_element (INTERFACE_NODE, &eigrp_if_bandwidth_cmd);
+ install_element (INTERFACE_NODE, &no_eigrp_if_bandwidth_cmd);
+
+ /*Hello-interval and hold-time interval configuration commands*/
+ install_element (INTERFACE_NODE, &eigrp_if_ip_holdinterval_cmd);
+ install_element (INTERFACE_NODE, &no_eigrp_if_ip_holdinterval_cmd);
+ install_element (INTERFACE_NODE, &eigrp_if_ip_hellointerval_cmd);
+ install_element (INTERFACE_NODE, &no_eigrp_if_ip_hellointerval_cmd);
+
+ /* "Authentication configuration commands */
+ install_element (INTERFACE_NODE, &eigrp_authentication_mode_cmd);
+ install_element (INTERFACE_NODE, &no_eigrp_authentication_mode_cmd);
+ install_element (INTERFACE_NODE, &eigrp_authentication_keychain_cmd);
+ install_element (INTERFACE_NODE, &no_eigrp_authentication_keychain_cmd);
+
+ /*EIGRP Summarization commands*/
+ install_element (INTERFACE_NODE, &eigrp_ip_summary_address_cmd);
+ install_element (INTERFACE_NODE, &no_eigrp_ip_summary_address_cmd);
+}
+
+static void
+eigrp_vty_zebra_init (void)
+{
+ install_element (EIGRP_NODE, &eigrp_redistribute_source_metric_cmd);
+ install_element (EIGRP_NODE, &no_eigrp_redistribute_source_metric_cmd);
+}
+
+/* Install EIGRP related vty commands. */
+void
+eigrp_vty_init (void)
+{
+ install_node (&eigrp_node, eigrp_config_write);
+
+ install_default (EIGRP_NODE);
+
+ install_element (CONFIG_NODE, &router_eigrp_cmd);
+ install_element (CONFIG_NODE, &no_router_eigrp_cmd);
+ install_element (EIGRP_NODE, &eigrp_network_cmd);
+ install_element (EIGRP_NODE, &no_eigrp_network_cmd);
+ install_element (EIGRP_NODE, &eigrp_variance_cmd);
+ install_element (EIGRP_NODE, &no_eigrp_variance_cmd);
+ install_element (EIGRP_NODE, &eigrp_router_id_cmd);
+ install_element (EIGRP_NODE, &no_eigrp_router_id_cmd);
+ install_element (EIGRP_NODE, &eigrp_passive_interface_cmd);
+ install_element (EIGRP_NODE, &no_eigrp_passive_interface_cmd);
+ install_element (EIGRP_NODE, &eigrp_timers_active_cmd);
+ install_element (EIGRP_NODE, &no_eigrp_timers_active_cmd);
+ install_element (EIGRP_NODE, &eigrp_metric_weights_cmd);
+ install_element (EIGRP_NODE, &no_eigrp_metric_weights_cmd);
+ install_element (EIGRP_NODE, &eigrp_maximum_paths_cmd);
+ install_element (EIGRP_NODE, &no_eigrp_maximum_paths_cmd);
+ install_element (EIGRP_NODE, &eigrp_neighbor_cmd);
+ install_element (EIGRP_NODE, &no_eigrp_neighbor_cmd);
+
+ /* commands for manual hard restart */
+ install_element (ENABLE_NODE, &clear_ip_eigrp_neighbors_cmd);
+ install_element (ENABLE_NODE, &clear_ip_eigrp_neighbors_int_cmd);
+ install_element (ENABLE_NODE, &clear_ip_eigrp_neighbors_IP_cmd);
+ /* commands for manual graceful restart */
+ install_element (ENABLE_NODE, &clear_ip_eigrp_neighbors_soft_cmd);
+ install_element (ENABLE_NODE, &clear_ip_eigrp_neighbors_int_soft_cmd);
+ install_element (ENABLE_NODE, &clear_ip_eigrp_neighbors_IP_soft_cmd);
+
+ eigrp_vty_zebra_init ();
+}
diff --git a/eigrpd/eigrp_vty.h b/eigrpd/eigrp_vty.h
new file mode 100644
index 0000000000..f78a46f621
--- /dev/null
+++ b/eigrpd/eigrp_vty.h
@@ -0,0 +1,41 @@
+/*
+ * EIGRP VTY Interface.
+ * Copyright (C) 2013-2016
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ * Frantisek Gazo
+ * Tomas Hvorkovy
+ * Martin Kontsek
+ * Lukas Koribsky
+ *
+ * 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 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 _QUAGGA_EIGRP_VTY_H
+#define _QUAGGA_EIGRP_VTY_H
+
+
+/* Prototypes. */
+extern void eigrp_vty_init (void);
+extern void eigrp_vty_show_init (void);
+extern void eigrp_vty_if_init (void);
+
+#endif /* _Quagga_EIGRP_VTY_H_ */
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
new file mode 100644
index 0000000000..ba6ecf2452
--- /dev/null
+++ b/eigrpd/eigrp_zebra.c
@@ -0,0 +1,560 @@
+/*
+ * Zebra connect library for EIGRP.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 "thread.h"
+#include "command.h"
+#include "network.h"
+#include "prefix.h"
+#include "routemap.h"
+#include "table.h"
+#include "stream.h"
+#include "memory.h"
+#include "zclient.h"
+#include "filter.h"
+#include "plist.h"
+#include "log.h"
+#include "nexthop.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_dump.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_fsm.h"
+
+static int eigrp_interface_add (int , struct zclient *, zebra_size_t, vrf_id_t);
+static int eigrp_interface_delete (int , struct zclient *,
+ zebra_size_t, vrf_id_t);
+static int eigrp_interface_address_add (int, struct zclient *,
+ zebra_size_t, vrf_id_t vrf_id);
+static int eigrp_interface_address_delete (int, struct zclient *,
+ zebra_size_t, vrf_id_t vrf_id);
+static int eigrp_interface_state_up (int, struct zclient *,
+ zebra_size_t, vrf_id_t vrf_id);
+static int eigrp_interface_state_down (int, struct zclient *,
+ zebra_size_t, vrf_id_t vrf_id);
+static struct interface * zebra_interface_if_lookup (struct stream *);
+
+static int eigrp_zebra_read_ipv4 (int , struct zclient *,
+ zebra_size_t, vrf_id_t vrf_id);
+
+/* Zebra structure to hold current status. */
+struct zclient *zclient = NULL;
+
+/* For registering threads. */
+extern struct thread_master *master;
+struct in_addr router_id_zebra;
+
+/* Router-id update message from zebra. */
+static int
+eigrp_router_id_update_zebra (int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct eigrp *eigrp;
+ struct prefix router_id;
+ zebra_router_id_update_read (zclient->ibuf,&router_id);
+
+ router_id_zebra = router_id.u.prefix4;
+
+ eigrp = eigrp_lookup ();
+
+ if (eigrp != NULL)
+ eigrp_router_id_update (eigrp);
+
+ return 0;
+}
+
+static void
+eigrp_zebra_connected (struct zclient *zclient)
+{
+ zclient_send_reg_requests (zclient, VRF_DEFAULT);
+}
+
+void
+eigrp_zebra_init (void)
+{
+ zclient = zclient_new (master);
+
+ zclient_init (zclient, ZEBRA_ROUTE_EIGRP, 0);
+ zclient->zebra_connected = eigrp_zebra_connected;
+ zclient->router_id_update = eigrp_router_id_update_zebra;
+ zclient->interface_add = eigrp_interface_add;
+ zclient->interface_delete = eigrp_interface_delete;
+ zclient->interface_up = eigrp_interface_state_up;
+ zclient->interface_down = eigrp_interface_state_down;
+ zclient->interface_address_add = eigrp_interface_address_add;
+ zclient->interface_address_delete = eigrp_interface_address_delete;
+ zclient->redistribute_route_ipv4_add = eigrp_zebra_read_ipv4;
+ zclient->redistribute_route_ipv4_del = eigrp_zebra_read_ipv4;
+}
+
+
+/* Zebra route add and delete treatment. */
+static int
+eigrp_zebra_read_ipv4 (int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct stream *s;
+ struct zapi_ipv4 api;
+ struct prefix_ipv4 p;
+ struct eigrp *eigrp;
+
+ s = zclient->ibuf;
+
+ /* Type, flags, message. */
+ api.type = stream_getc (s);
+ api.instance = stream_getw (s);
+ api.flags = stream_getc (s);
+ api.message = stream_getc (s);
+
+ /* IPv4 prefix. */
+ memset (&p, 0, sizeof (struct prefix_ipv4));
+ p.family = AF_INET;
+ p.prefixlen = stream_getc (s);
+ stream_get (&p.prefix, s, PSIZE (p.prefixlen));
+
+ if (IPV4_NET127(ntohl(p.prefix.s_addr)))
+ return 0;
+
+ /* Nexthop, ifindex, distance, metric. */
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
+ {
+ api.nexthop_num = stream_getc (s);
+ stream_get_ipv4 (s);
+ }
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
+ {
+ api.ifindex_num = stream_getc (s);
+ /* XXX assert(api.ifindex_num == 1); */
+ stream_getl (s); /* ifindex, unused */
+ }
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
+ api.distance = stream_getc (s);
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
+ api.metric = stream_getl (s);
+
+ eigrp = eigrp_lookup ();
+ if (eigrp == NULL)
+ return 0;
+
+ if (command == ZEBRA_IPV4_ROUTE_ADD)
+ {
+
+ }
+ else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
+ {
+
+ }
+
+ return 0;
+}
+
+/* Inteface addition message from zebra. */
+static int
+eigrp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
+ vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+
+ ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
+
+ assert (ifp->info);
+
+ if (!EIGRP_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
+ {
+ SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
+ IF_DEF_PARAMS (ifp)->type = eigrp_default_iftype (ifp);
+ }
+
+ eigrp_if_update (ifp);
+
+ return 0;
+}
+
+static int
+eigrp_interface_delete (int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct stream *s;
+ struct route_node *rn;
+
+ s = zclient->ibuf;
+ /* zebra_interface_state_read () updates interface structure in iflist */
+ ifp = zebra_interface_state_read (s, vrf_id);
+
+ if (ifp == NULL)
+ return 0;
+
+ if (if_is_up (ifp))
+ zlog_warn ("Zebra: got delete of %s, but interface is still up",
+ ifp->name);
+
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
+ zlog_debug("Zebra: interface delete %s index %d flags %llx metric %d mtu %d",
+ ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
+
+ for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
+ if (rn->info)
+ eigrp_if_free ((struct eigrp_interface *) rn->info, INTERFACE_DOWN_BY_ZEBRA);
+
+ ifp->ifindex = IFINDEX_INTERNAL;
+ return 0;
+}
+
+static int
+eigrp_interface_address_add (int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct connected *c;
+
+ c = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
+
+ if (c == NULL)
+ return 0;
+
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
+ {
+ char buf[128];
+ prefix2str (c->address, buf, sizeof (buf));
+ zlog_debug ("Zebra: interface %s address add %s", c->ifp->name, buf);
+ }
+
+ eigrp_if_update (c->ifp);
+
+ return 0;
+}
+
+static int
+eigrp_interface_address_delete (int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct connected *c;
+ struct interface *ifp;
+ struct eigrp_interface *ei;
+ struct route_node *rn;
+ struct prefix p;
+
+ c = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
+
+ if (c == NULL)
+ return 0;
+
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
+ {
+ char buf[128];
+ prefix2str (c->address, buf, sizeof (buf));
+ zlog_debug ("Zebra: interface %s address delete %s", c->ifp->name, buf);
+ }
+
+ ifp = c->ifp;
+ p = *c->address;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+
+ rn = route_node_lookup (IF_OIFS (ifp), &p);
+ if (!rn)
+ {
+ connected_free (c);
+ return 0;
+ }
+
+ assert (rn->info);
+ ei = rn->info;
+
+ /* Call interface hook functions to clean up */
+ eigrp_if_free (ei, INTERFACE_DOWN_BY_ZEBRA);
+
+ connected_free (c);
+
+ return 0;
+}
+
+static int
+eigrp_interface_state_up (int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct eigrp_interface *ei;
+ struct route_node *rn;
+
+ ifp = zebra_interface_if_lookup (zclient->ibuf);
+
+ if (ifp == NULL)
+ return 0;
+
+ /* Interface is already up. */
+ if (if_is_operative (ifp))
+ {
+ /* Temporarily keep ifp values. */
+ struct interface if_tmp;
+ memcpy (&if_tmp, ifp, sizeof (struct interface));
+
+ zebra_interface_if_set_value (zclient->ibuf, ifp);
+
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
+ zlog_debug ("Zebra: Interface[%s] state update.", ifp->name);
+
+ if (if_tmp.bandwidth != ifp->bandwidth)
+ {
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
+ zlog_debug ("Zebra: Interface[%s] bandwidth change %d -> %d.",
+ ifp->name, if_tmp.bandwidth, ifp->bandwidth);
+
+ // eigrp_if_recalculate_output_cost (ifp);
+ }
+
+ if (if_tmp.mtu != ifp->mtu)
+ {
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
+ zlog_debug ("Zebra: Interface[%s] MTU change %u -> %u.",
+ ifp->name, if_tmp.mtu, ifp->mtu);
+
+ /* Must reset the interface (simulate down/up) when MTU changes. */
+ eigrp_if_reset (ifp);
+ }
+ return 0;
+ }
+
+ zebra_interface_if_set_value (zclient->ibuf, ifp);
+
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
+ zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name);
+
+ for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
+ {
+ if ((ei = rn->info) == NULL)
+ continue;
+
+ eigrp_if_up (ei);
+ }
+
+ return 0;
+}
+
+static int
+eigrp_interface_state_down (int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct eigrp_interface *ei;
+ struct route_node *node;
+
+ ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
+
+ if (ifp == NULL)
+ return 0;
+
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
+ zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name);
+
+ for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
+ {
+ if ((ei = node->info) == NULL)
+ continue;
+ eigrp_if_down (ei);
+ }
+
+ return 0;
+}
+
+static struct interface *
+zebra_interface_if_lookup (struct stream *s)
+{
+ char ifname_tmp[INTERFACE_NAMSIZ];
+
+ /* Read interface name. */
+ stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
+
+ /* And look it up. */
+ return if_lookup_by_name_len (ifname_tmp,
+ strnlen (ifname_tmp, INTERFACE_NAMSIZ),
+ VRF_DEFAULT);
+}
+
+void
+eigrp_zebra_route_add (struct prefix_ipv4 *p, struct list *successors)
+{
+ struct eigrp_neighbor_entry *te;
+ struct listnode *node;
+ u_char message;
+ u_char flags;
+ int psize;
+ struct stream *s;
+
+ if (zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
+ {
+ message = 0;
+ flags = 0;
+
+ /* EIGRP pass nexthop and metric */
+ SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
+
+ /* Make packet. */
+ s = zclient->obuf;
+ stream_reset (s);
+
+ /* Put command, type, flags, message. */
+ zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT);
+ stream_putc (s, ZEBRA_ROUTE_EIGRP);
+ stream_putw (s, 0);
+ stream_putl (s, flags);
+ stream_putc (s, message);
+ stream_putw (s, SAFI_UNICAST);
+
+ /* Put prefix information. */
+ psize = PSIZE (p->prefixlen);
+ stream_putc (s, p->prefixlen);
+ stream_write (s, (u_char *) & p->prefix, psize);
+
+ /* Nexthop count. */
+ stream_putc (s, successors->count);
+
+ /* Nexthop, ifindex, distance and metric information. */
+ for (ALL_LIST_ELEMENTS_RO (successors, node, te))
+ {
+ if (te->adv_router->src.s_addr)
+ {
+ stream_putc (s, NEXTHOP_TYPE_IPV4_IFINDEX);
+ stream_put_in_addr (s, &te->adv_router->src);
+ }
+ else
+ stream_putc (s, NEXTHOP_TYPE_IFINDEX);
+ stream_putl (s, te->ei->ifp->ifindex);
+ }
+
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
+ {
+ char buf[2][INET_ADDRSTRLEN];
+ zlog_debug ("Zebra: Route add %s/%d nexthop %s",
+ inet_ntop(AF_INET, &p->prefix, buf[0], sizeof (buf[0])),
+ p->prefixlen,
+ inet_ntop(AF_INET, 0 /*&p->nexthop*/, buf[1], sizeof (buf[1])));
+ }
+
+ stream_putw_at (s, 0, stream_get_endp (s));
+
+ zclient_send_message (zclient);
+ }
+}
+
+void
+eigrp_zebra_route_delete (struct prefix_ipv4 *p)
+{
+ struct zapi_ipv4 api;
+
+ if (zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
+ {
+ api.vrf_id = VRF_DEFAULT;
+ api.type = ZEBRA_ROUTE_EIGRP;
+ api.instance = 0;
+ api.flags = 0;
+ api.message = 0;
+ api.safi = SAFI_UNICAST;
+ zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
+
+ if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
+ {
+ char buf[2][INET_ADDRSTRLEN];
+ zlog_debug ("Zebra: Route del %s/%d nexthop %s",
+ inet_ntop (AF_INET, &p->prefix, buf[0], sizeof (buf[0])),
+ p->prefixlen,
+ inet_ntop (AF_INET, 0 /*&p->nexthop*/, buf[1], sizeof (buf[1])));
+ }
+ }
+
+ return;
+}
+
+vrf_bitmap_t
+eigrp_is_type_redistributed (int type)
+{
+ return (DEFAULT_ROUTE_TYPE (type)) ?
+ zclient->default_information : zclient->redist[AFI_IP][type];
+}
+
+int
+eigrp_redistribute_set (struct eigrp *eigrp, int type, struct eigrp_metrics metric)
+{
+
+ if (eigrp_is_type_redistributed (type))
+ {
+ if (eigrp_metrics_is_same(&metric, &eigrp->dmetric[type]))
+ {
+ eigrp->dmetric[type] = metric;
+ }
+
+ eigrp_external_routes_refresh (eigrp, type);
+
+ // if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE))
+ // zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
+ // eigrp_redist_string(type),
+ // metric_type (eigrp, type), metric_value (eigrp, type));
+ return CMD_SUCCESS;
+ }
+
+ eigrp->dmetric[type] = metric;
+
+ zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
+ AFI_IP, type, 0, VRF_DEFAULT);
+
+ // if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
+ // zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
+ // ospf_redist_string(type),
+ // metric_type (ospf, type), metric_value (ospf, type));
+
+ ++eigrp->redistribute;
+
+ return CMD_SUCCESS;
+}
+
+int
+eigrp_redistribute_unset (struct eigrp *eigrp, int type)
+{
+
+ if (eigrp_is_type_redistributed (type))
+ {
+ memset(&eigrp->dmetric[type], 0, sizeof(struct eigrp_metrics));
+ zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient,
+ AFI_IP, type, 0, VRF_DEFAULT);
+ --eigrp->redistribute;
+ }
+
+ // if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
+ // zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
+ // ospf_redist_string(type),
+ // metric_type (ospf, type), metric_value (ospf, type));
+
+ return CMD_SUCCESS;
+}
+
diff --git a/eigrpd/eigrp_zebra.h b/eigrpd/eigrp_zebra.h
new file mode 100644
index 0000000000..0991d35aba
--- /dev/null
+++ b/eigrpd/eigrp_zebra.h
@@ -0,0 +1,42 @@
+/*
+ * Zebra connect library for EIGRP.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 _ZEBRA_EIGRP_ZEBRA_H_
+#define _ZEBRA_EIGRP_ZEBRA_H_
+
+#include "vty.h"
+#include "vrf.h"
+
+extern void eigrp_zebra_init (void);
+
+extern void eigrp_zebra_route_add (struct prefix_ipv4 *, struct list *);
+extern void eigrp_zebra_route_delete (struct prefix_ipv4 *);
+extern int eigrp_redistribute_set (struct eigrp *, int, struct eigrp_metrics);
+extern int eigrp_redistribute_unset (struct eigrp *, int);
+extern vrf_bitmap_t eigrp_is_type_redistributed (int);
+
+#endif /* _ZEBRA_EIGRP_ZEBRA_H_ */
diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c
new file mode 100644
index 0000000000..93a69b776b
--- /dev/null
+++ b/eigrpd/eigrpd.c
@@ -0,0 +1,320 @@
+/*
+ * EIGRP Daemon Program.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 "thread.h"
+#include "vty.h"
+#include "command.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "table.h"
+#include "if.h"
+#include "memory.h"
+#include "stream.h"
+#include "log.h"
+#include "sockunion.h" /* for inet_aton () */
+#include "zclient.h"
+#include "plist.h"
+#include "sockopt.h"
+#include "keychain.h"
+
+#include "eigrpd/eigrp_structs.h"
+#include "eigrpd/eigrpd.h"
+#include "eigrpd/eigrp_interface.h"
+#include "eigrpd/eigrp_zebra.h"
+#include "eigrpd/eigrp_vty.h"
+#include "eigrpd/eigrp_neighbor.h"
+#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_network.h"
+#include "eigrpd/eigrp_topology.h"
+#include "eigrpd/eigrp_memory.h"
+
+DEFINE_QOBJ_TYPE(eigrp)
+
+static struct eigrp_master eigrp_master;
+
+struct eigrp_master *eigrp_om;
+
+static void eigrp_delete(struct eigrp *);
+static struct eigrp *eigrp_new(const char *);
+static void eigrp_add(struct eigrp *);
+
+extern struct zclient *zclient;
+extern struct in_addr router_id_zebra;
+
+
+/*
+ * void eigrp_router_id_update(struct eigrp *eigrp)
+ *
+ * Description:
+ * update routerid associated with this instance of EIGRP.
+ * If the id changes, then call if_update for each interface
+ * to resync the topology database with all neighbors
+ *
+ * Select the router ID based on these priorities:
+ * 1. Statically assigned router ID is always the first choice.
+ * 2. If there is no statically assigned router ID, then try to stick
+ * with the most recent value, since changing router ID's is very
+ * disruptive.
+ * 3. Last choice: just go with whatever the zebra daemon recommends.
+ *
+ * Note:
+ * router id for EIGRP is really just a 32 bit number. Cisco historically
+ * displays it in dotted decimal notation, and will pickup an IP address
+ * from an interface so it can be 'auto-configed" to a uniqe value
+ *
+ * This does not work for IPv6, and to make the code simpler, its
+ * stored and processed internerall as a 32bit number
+ */
+void
+eigrp_router_id_update (struct eigrp *eigrp)
+{
+ struct interface *ifp;
+ struct listnode *node;
+ u_int32_t router_id, router_id_old;
+
+ router_id_old = eigrp->router_id;
+
+ if (eigrp->router_id_static != 0)
+ router_id = eigrp->router_id_static;
+
+ else if (eigrp->router_id != 0)
+ router_id = eigrp->router_id;
+
+ else
+ router_id = router_id_zebra.s_addr;
+
+ eigrp->router_id = router_id;
+ if (router_id_old != router_id)
+ {
+ // if (IS_DEBUG_EIGRP_EVENT)
+ // zlog_debug("Router-ID[NEW:%s]: Update", inet_ntoa(eigrp->router_id));
+
+ /* update eigrp_interface's */
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
+ eigrp_if_update(ifp);
+ }
+}
+
+void
+eigrp_master_init ()
+{
+ struct timeval tv;
+
+ memset(&eigrp_master, 0, sizeof(struct eigrp_master));
+
+ eigrp_om = &eigrp_master;
+ eigrp_om->eigrp = list_new();
+
+ monotime(&tv);
+ eigrp_om->start_time = tv.tv_sec;
+}
+
+/* Allocate new eigrp structure. */
+static struct eigrp *
+eigrp_new (const char *AS)
+{
+ struct eigrp *eigrp = XCALLOC(MTYPE_EIGRP_TOP, sizeof (struct eigrp));
+ int eigrp_socket;
+
+ /* init information relevant to peers */
+ eigrp->vrid = 0;
+ eigrp->AS = atoi(AS);
+ eigrp->router_id = 0L;
+ eigrp->router_id_static = 0L;
+ eigrp->sequence_number = 1;
+
+ /*Configure default K Values for EIGRP Process*/
+ eigrp->k_values[0] = EIGRP_K1_DEFAULT;
+ eigrp->k_values[1] = EIGRP_K2_DEFAULT;
+ eigrp->k_values[2] = EIGRP_K3_DEFAULT;
+ eigrp->k_values[3] = EIGRP_K4_DEFAULT;
+ eigrp->k_values[4] = EIGRP_K5_DEFAULT;
+ eigrp->k_values[5] = EIGRP_K6_DEFAULT;
+
+ /* init internal data structures */
+ eigrp->eiflist = list_new();
+ eigrp->passive_interface_default = EIGRP_IF_ACTIVE;
+ eigrp->networks = route_table_init();
+
+ if ((eigrp_socket = eigrp_sock_init()) < 0)
+ {
+ zlog_err("eigrp_new: fatal error: eigrp_sock_init was unable to open "
+ "a socket");
+ exit (1);
+ }
+
+ eigrp->fd = eigrp_socket;
+ eigrp->maxsndbuflen = getsockopt_so_sendbuf(eigrp->fd);
+
+ if ((eigrp->ibuf = stream_new(EIGRP_PACKET_MAX_LEN+1)) == NULL)
+ {
+ zlog_err("eigrp_new: fatal error: stream_new (%u) failed allocating ibuf",
+ EIGRP_PACKET_MAX_LEN+1);
+ exit(1);
+ }
+
+ eigrp->t_read = NULL;
+ thread_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read);
+ eigrp->oi_write_q = list_new();
+
+ eigrp->topology_table = eigrp_topology_new();
+
+ eigrp->neighbor_self = eigrp_nbr_new(NULL);
+ inet_aton("0.0.0.0", &eigrp->neighbor_self->src);
+
+ eigrp->variance = EIGRP_VARIANCE_DEFAULT;
+ eigrp->max_paths = EIGRP_MAX_PATHS_DEFAULT;
+
+ eigrp->serno = 0;
+ eigrp->serno_last_update = 0;
+ eigrp->topology_changes_externalIPV4 = list_new ();
+ eigrp->topology_changes_internalIPV4 = list_new ();
+
+ eigrp->list[EIGRP_FILTER_IN] = NULL;
+ eigrp->list[EIGRP_FILTER_OUT] = NULL;
+
+ eigrp->prefix[EIGRP_FILTER_IN] = NULL;
+ eigrp->prefix[EIGRP_FILTER_OUT] = NULL;
+
+ eigrp->routemap[EIGRP_FILTER_IN] = NULL;
+ eigrp->routemap[EIGRP_FILTER_OUT] = NULL;
+
+ QOBJ_REG(eigrp, eigrp);
+ return eigrp;
+}
+
+static void
+eigrp_add (struct eigrp *eigrp)
+{
+ listnode_add(eigrp_om->eigrp, eigrp);
+}
+
+static void
+eigrp_delete (struct eigrp *eigrp)
+{
+ listnode_delete(eigrp_om->eigrp, eigrp);
+}
+
+struct eigrp *
+eigrp_get (const char *AS)
+{
+ struct eigrp *eigrp;
+
+ eigrp = eigrp_lookup();
+ if (eigrp == NULL)
+ {
+ eigrp = eigrp_new(AS);
+ eigrp_add(eigrp);
+ }
+
+ return eigrp;
+}
+
+/* Shut down the entire process */
+void
+eigrp_terminate (void)
+{
+ struct eigrp *eigrp;
+ struct listnode *node, *nnode;
+
+ /* shutdown already in progress */
+ if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN))
+ return;
+
+ SET_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN);
+
+ /* exit immediately if EIGRP not actually running */
+ if (listcount(eigrp_om->eigrp) == 0)
+ exit(0);
+
+ for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp))
+ eigrp_finish(eigrp);
+}
+
+void
+eigrp_finish (struct eigrp *eigrp)
+{
+ eigrp_finish_final(eigrp);
+
+ /* eigrp being shut-down? If so, was this the last eigrp instance? */
+ if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN)
+ && (listcount(eigrp_om->eigrp) == 0))
+ {
+ if (zclient)
+ zclient_free (zclient);
+
+ exit(0);
+ }
+
+ return;
+}
+
+/* Final cleanup of eigrp instance */
+void
+eigrp_finish_final (struct eigrp *eigrp)
+{
+ struct eigrp_interface *ei;
+ struct eigrp_neighbor *nbr;
+ struct listnode *node, *nnode, *node2, *nnode2;
+
+ for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
+ {
+ for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
+ eigrp_nbr_delete (nbr);
+ eigrp_if_free (ei, INTERFACE_DOWN_BY_FINAL);
+ }
+
+ THREAD_OFF (eigrp->t_write);
+ THREAD_OFF (eigrp->t_read);
+ close (eigrp->fd);
+
+ list_delete(eigrp->eiflist);
+ list_delete(eigrp->oi_write_q);
+ list_delete(eigrp->topology_changes_externalIPV4);
+ list_delete(eigrp->topology_changes_internalIPV4);
+
+ eigrp_topology_cleanup(eigrp->topology_table);
+ eigrp_topology_free(eigrp->topology_table);
+
+ eigrp_nbr_delete(eigrp->neighbor_self);
+
+ eigrp_delete(eigrp);
+
+ XFREE(MTYPE_EIGRP_TOP,eigrp);
+}
+
+/*Look for existing eigrp process*/
+struct eigrp *
+eigrp_lookup (void)
+{
+ if (listcount(eigrp_om->eigrp) == 0)
+ return NULL;
+
+ return listgetdata(listhead(eigrp_om->eigrp));
+}
diff --git a/eigrpd/eigrpd.conf.sample b/eigrpd/eigrpd.conf.sample
new file mode 100644
index 0000000000..662e667d3f
--- /dev/null
+++ b/eigrpd/eigrpd.conf.sample
@@ -0,0 +1,13 @@
+! -*- eigrpd -*-
+!
+! EIGRPDd sample configuration file
+!
+!
+hostname eigrpd
+password zebra
+!enable password please-set-at-here
+!
+!router eigrp 4453
+! network 192.168.1.0/24
+!
+log stdout
diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h
new file mode 100644
index 0000000000..b3f233c58b
--- /dev/null
+++ b/eigrpd/eigrpd.h
@@ -0,0 +1,54 @@
+/*
+ * EIGRP main header.
+ * Copyright (C) 2013-2014
+ * Authors:
+ * Donnie Savage
+ * Jan Janovic
+ * Matej Perina
+ * Peter Orsag
+ * Peter Paluch
+ *
+ * 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 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 _ZEBRA_EIGRPD_H
+#define _ZEBRA_EIGRPD_H
+
+#include <zebra.h>
+
+#include "filter.h"
+#include "log.h"
+
+/* Set EIGRP version is "classic" - wide metrics comes next */
+#define EIGRP_MAJOR_VERSION 1
+#define EIGRP_MINOR_VERSION 2
+
+/* Extern variables. */
+extern struct zclient *zclient;
+extern struct thread_master *master;
+extern struct eigrp_master *eigrp_om;
+
+/* Prototypes */
+ extern void eigrp_master_init (void);
+ extern void eigrp_terminate (void);
+ extern void eigrp_finish_final (struct eigrp *);
+ extern void eigrp_finish (struct eigrp *);
+ extern struct eigrp *eigrp_get (const char *);
+ extern struct eigrp *eigrp_lookup (void);
+ extern void eigrp_router_id_update (struct eigrp *);
+
+#endif /* _ZEBRA_EIGRPD_H */
diff --git a/fpm/fpm_pb.c b/fpm/fpm_pb.c
index ba18627ea1..5cd03a4d59 100644
--- a/fpm/fpm_pb.c
+++ b/fpm/fpm_pb.c
@@ -17,10 +17,9 @@
* 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.
+ * 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
*/
/*
diff --git a/fpm/fpm_pb.h b/fpm/fpm_pb.h
index 8f74ac06eb..2e5f3d0527 100644
--- a/fpm/fpm_pb.h
+++ b/fpm/fpm_pb.h
@@ -17,10 +17,9 @@
* 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.
+ * 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
*/
/*
diff --git a/isisd/Makefile.am b/isisd/Makefile.am
index c97385f87a..2973820eed 100644
--- a/isisd/Makefile.am
+++ b/isisd/Makefile.am
@@ -16,7 +16,7 @@ libisis_a_SOURCES = \
isis_tlv.c isisd.c isis_misc.c isis_zebra.c isis_dr.c \
isis_flags.c isis_dynhn.c iso_checksum.c isis_csm.c isis_events.c \
isis_spf.c isis_redist.c isis_route.c isis_routemap.c isis_te.c \
- isis_vty.c
+ isis_vty.c isis_mt.c
noinst_HEADERS = \
@@ -25,7 +25,7 @@ noinst_HEADERS = \
isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_redist.h \
- isis_route.h isis_routemap.h isis_te.h
+ isis_route.h isis_routemap.h isis_te.h isis_mt.h
isisd_SOURCES = \
isis_main.c $(libisis_a_SOURCES) \
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index f550924874..1869346f89 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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>
@@ -47,6 +47,7 @@
#include "isisd/isis_lsp.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_events.h"
+#include "isisd/isis_mt.h"
extern struct isis *isis;
@@ -148,6 +149,8 @@ isis_delete_adj (void *arg)
if (adj->ipv6_addrs)
list_delete (adj->ipv6_addrs);
+ adj_mt_finish(adj);
+
XFREE (MTYPE_ISIS_ADJACENCY, adj);
return;
}
@@ -412,6 +415,12 @@ isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty, char detail)
vty_out (vty, " Circuit type: %s", circuit_t2string (adj->circuit_t));
vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
vty_out (vty, "%s", VTY_NEWLINE);
+ if (adj->mt_count != 1 || adj->mt_set[0] != ISIS_MT_IPV4_UNICAST)
+ {
+ vty_out (vty, " Topologies:%s", VTY_NEWLINE);
+ for (unsigned int i = 0; i < adj->mt_count; i++)
+ vty_out (vty, " %s%s", isis_mtid2str(adj->mt_set[i]), VTY_NEWLINE);
+ }
vty_out (vty, " SNPA: %s", snpa_print (adj->snpa));
if (adj->circuit && (adj->circuit->circ_type == CIRCUIT_T_BROADCAST))
{
@@ -521,3 +530,20 @@ isis_adj_build_up_list (struct list *adjdb, struct list *list)
return;
}
+
+int
+isis_adj_usage2levels(enum isis_adj_usage usage)
+{
+ switch (usage)
+ {
+ case ISIS_ADJ_LEVEL1:
+ return IS_LEVEL_1;
+ case ISIS_ADJ_LEVEL2:
+ return IS_LEVEL_2;
+ case ISIS_ADJ_LEVEL1AND2:
+ return IS_LEVEL_1 | IS_LEVEL_2;
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h
index 8539b03d6b..a81797bb1e 100644
--- a/isisd/isis_adjacency.h
+++ b/isisd/isis_adjacency.h
@@ -16,10 +16,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_ADJACENCY_H
@@ -97,6 +97,8 @@ struct isis_adjacency
int flaps; /* number of adjacency flaps */
struct thread *t_expire; /* expire after hold_time */
struct isis_circuit *circuit; /* back pointer */
+ uint16_t *mt_set; /* Topologies this adjacency is valid for */
+ unsigned int mt_count; /* Number of entries in mt_set */
};
struct isis_adjacency *isis_adj_lookup (const u_char * sysid, struct list *adjdb);
@@ -112,5 +114,6 @@ int isis_adj_expire (struct thread *thread);
void isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty, char detail);
void isis_adj_build_neigh_list (struct list *adjdb, struct list *list);
void isis_adj_build_up_list (struct list *adjdb, struct list *list);
+int isis_adj_usage2levels(enum isis_adj_usage usage);
#endif /* ISIS_ADJACENCY_H */
diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c
index 3a5eaf5585..4ebaa4a1ee 100644
--- a/isisd/isis_bpf.c
+++ b/isisd/isis_bpf.c
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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>
@@ -212,16 +212,11 @@ isis_sock_init (struct isis_circuit *circuit)
goto end;
}
- if (circuit->circ_type == CIRCUIT_T_BROADCAST)
+ if (if_is_broadcast(circuit->interface))
{
circuit->tx = isis_send_pdu_bcast;
circuit->rx = isis_recv_pdu_bcast;
}
- else if (circuit->circ_type == CIRCUIT_T_P2P)
- {
- circuit->tx = isis_send_pdu_p2p;
- circuit->rx = isis_recv_pdu_p2p;
- }
else
{
zlog_warn ("isis_sock_init(): unknown circuit type");
@@ -284,23 +279,6 @@ isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
}
int
-isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
-{
- int bytesread;
-
- bytesread = stream_read (circuit->rcv_stream, circuit->fd,
- circuit->interface->mtu);
-
- if (bytesread < 0)
- {
- zlog_warn ("isis_recv_pdu_p2p(): read () failed: %s", safe_strerror (errno));
- return ISIS_WARNING;
- }
-
- return ISIS_OK;
-}
-
-int
isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
{
struct ether_header *eth;
@@ -327,7 +305,8 @@ isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
else
memcpy (eth->ether_dhost, ALL_L2_ISS, ETHER_ADDR_LEN);
memcpy (eth->ether_shost, circuit->u.bc.snpa, ETHER_ADDR_LEN);
- eth->ether_type = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
+ size_t frame_size = stream_get_endp(circuit->snd_stream) + LLC_LEN;
+ eth->ether_type = htons(isis_ethertype(frame_size));
/*
* Then the LLC
@@ -354,10 +333,4 @@ isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
return ISIS_OK;
}
-int
-isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
-{
- return ISIS_OK;
-}
-
#endif /* ISIS_METHOD == ISIS_METHOD_BPF */
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 6207ae189a..bafc37a755 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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>
#ifdef GNU_LINUX
@@ -60,6 +60,7 @@
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"
#include "isisd/isis_te.h"
+#include "isisd/isis_mt.h"
DEFINE_QOBJ_TYPE(isis_circuit)
@@ -102,6 +103,8 @@ isis_circuit_new ()
circuit->mtc = mpls_te_circuit_new();
+ circuit_mt_init(circuit);
+
QOBJ_REG (circuit, isis_circuit);
return circuit;
@@ -117,6 +120,8 @@ isis_circuit_del (struct isis_circuit *circuit)
isis_circuit_if_unbind (circuit, circuit->interface);
+ circuit_mt_finish(circuit);
+
/* and lastly the circuit itself */
XFREE (MTYPE_ISIS_CIRCUIT, circuit);
@@ -602,11 +607,12 @@ void
isis_circuit_prepare (struct isis_circuit *circuit)
{
#ifdef GNU_LINUX
- THREAD_READ_ON (master, circuit->t_read, isis_receive, circuit,
- circuit->fd);
+ thread_add_read(master, isis_receive, circuit, circuit->fd,
+ &circuit->t_read);
#else
- THREAD_TIMER_MSEC_ON (master, circuit->t_read, isis_receive, circuit,
- listcount (circuit->area->circuit_list) * 100);
+ thread_add_timer_msec(master, isis_receive, circuit,
+ listcount(circuit->area->circuit_list) * 100,
+ &circuit->t_read);
#endif
}
@@ -667,13 +673,13 @@ isis_circuit_up (struct isis_circuit *circuit)
if (circuit->is_type & IS_LEVEL_1)
{
- thread_add_event (master, send_lan_l1_hello, circuit, 0);
+ thread_add_event(master, send_lan_l1_hello, circuit, 0, NULL);
circuit->u.bc.lan_neighs[0] = list_new ();
}
if (circuit->is_type & IS_LEVEL_2)
{
- thread_add_event (master, send_lan_l2_hello, circuit, 0);
+ thread_add_event(master, send_lan_l2_hello, circuit, 0, NULL);
circuit->u.bc.lan_neighs[1] = list_new ();
}
@@ -683,11 +689,13 @@ isis_circuit_up (struct isis_circuit *circuit)
/* 8.4.1 d) */
/* dr election will commence in... */
if (circuit->is_type & IS_LEVEL_1)
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
- circuit, 2 * circuit->hello_interval[0]);
+ thread_add_timer(master, isis_run_dr_l1, circuit,
+ 2 * circuit->hello_interval[0],
+ &circuit->u.bc.t_run_dr[0]);
if (circuit->is_type & IS_LEVEL_2)
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
- circuit, 2 * circuit->hello_interval[1]);
+ thread_add_timer(master, isis_run_dr_l2, circuit,
+ 2 * circuit->hello_interval[1],
+ &circuit->u.bc.t_run_dr[1]);
}
else
{
@@ -695,17 +703,19 @@ isis_circuit_up (struct isis_circuit *circuit)
* for a ptp IF
*/
circuit->u.p2p.neighbor = NULL;
- thread_add_event (master, send_p2p_hello, circuit, 0);
+ thread_add_event(master, send_p2p_hello, circuit, 0, NULL);
}
/* initializing PSNP timers */
if (circuit->is_type & IS_LEVEL_1)
- THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
- isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
+ thread_add_timer(master, send_l1_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
+ &circuit->t_send_psnp[0]);
if (circuit->is_type & IS_LEVEL_2)
- THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
- isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
+ thread_add_timer(master, send_l2_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
+ &circuit->t_send_psnp[1]);
/* unified init for circuits; ignore warnings below this level */
retv = isis_sock_init (circuit);
@@ -1215,6 +1225,7 @@ isis_interface_config_write (struct vty *vty)
VTY_NEWLINE);
write++;
}
+ write += circuit_write_mt_settings(circuit, vty);
}
vty_out (vty, "!%s", VTY_NEWLINE);
}
@@ -1383,6 +1394,22 @@ isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type)
}
int
+isis_circuit_mt_enabled_set (struct isis_circuit *circuit, uint16_t mtid,
+ bool enabled)
+{
+ struct isis_circuit_mt_setting *setting;
+
+ setting = circuit_get_mt_setting(circuit, mtid);
+ if (setting->enabled != enabled)
+ {
+ setting->enabled = enabled;
+ lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0);
+ }
+
+ return CMD_SUCCESS;
+}
+
+int
isis_if_new_hook (struct interface *ifp)
{
return 0;
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index bb0dc0f983..82ca7ca0d9 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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 ISIS_CIRCUIT_H
@@ -123,6 +123,7 @@ struct isis_circuit
struct mpls_te_circuit *mtc; /* Support for MPLS-TE parameters - see isis_te.[c,h] */
int ip_router; /* Route IP ? */
int is_passive; /* Is Passive ? */
+ struct list *mt_settings; /* IS-IS MT Settings */
struct list *ip_addrs; /* our IP addresses */
int ipv6_router; /* Route IPv6 ? */
struct list *ipv6_link; /* our link local IPv6 addresses */
@@ -187,4 +188,6 @@ int isis_circuit_passwd_unset (struct isis_circuit *circuit);
int isis_circuit_passwd_cleartext_set (struct isis_circuit *circuit, const char *passwd);
int isis_circuit_passwd_hmac_md5_set (struct isis_circuit *circuit, const char *passwd);
+int isis_circuit_mt_enabled_set (struct isis_circuit *circuit, uint16_t mtid, bool enabled);
+
#endif /* _ZEBRA_ISIS_CIRCUIT_H */
diff --git a/isisd/isis_common.h b/isisd/isis_common.h
index d158961b99..6c827115b3 100644
--- a/isisd/isis_common.h
+++ b/isisd/isis_common.h
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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 ISIS_COMMON_H
diff --git a/isisd/isis_constants.h b/isisd/isis_constants.h
index 17616d671b..b59d77bf3f 100644
--- a/isisd/isis_constants.h
+++ b/isisd/isis_constants.h
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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 ISIS_CONSTANTS_H
@@ -171,4 +171,14 @@
#define ETH_ALEN 6
#endif
+#define MAX_LLC_LEN 0x5ff
+#define ETHERTYPE_EXT_LLC 0x8870
+
+static inline uint16_t isis_ethertype(size_t len)
+{
+ if (len > MAX_LLC_LEN)
+ return ETHERTYPE_EXT_LLC;
+ return len;
+}
+
#endif /* ISIS_CONSTANTS_H */
diff --git a/isisd/isis_csm.c b/isisd/isis_csm.c
index 0fbf47aea1..90272d68b2 100644
--- a/isisd/isis_csm.c
+++ b/isisd/isis_csm.c
@@ -15,9 +15,9 @@
* 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.
+ * 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>
diff --git a/isisd/isis_csm.h b/isisd/isis_csm.h
index d6b13ac695..a1e0f234f6 100644
--- a/isisd/isis_csm.h
+++ b/isisd/isis_csm.h
@@ -16,10 +16,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_CSM_H
#define _ZEBRA_ISIS_CSM_H
diff --git a/isisd/isis_dlpi.c b/isisd/isis_dlpi.c
index 98b18ac38d..afd8a14f94 100644
--- a/isisd/isis_dlpi.c
+++ b/isisd/isis_dlpi.c
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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>
diff --git a/isisd/isis_dr.c b/isisd/isis_dr.c
index bc6ec11962..96cf8488da 100644
--- a/isisd/isis_dr.c
+++ b/isisd/isis_dr.c
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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
*/
@@ -259,12 +259,13 @@ isis_dr_resign (struct isis_circuit *circuit, int level)
THREAD_TIMER_OFF (circuit->t_send_csnp[0]);
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
- circuit, 2 * circuit->hello_interval[0]);
+ thread_add_timer(master, isis_run_dr_l1, circuit,
+ 2 * circuit->hello_interval[0],
+ &circuit->u.bc.t_run_dr[0]);
- THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
- isis_jitter (circuit->psnp_interval[level - 1],
- PSNP_JITTER));
+ thread_add_timer(master, send_l1_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[level - 1], PSNP_JITTER),
+ &circuit->t_send_psnp[0]);
}
else
{
@@ -272,15 +273,16 @@ isis_dr_resign (struct isis_circuit *circuit, int level)
THREAD_TIMER_OFF (circuit->t_send_csnp[1]);
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
- circuit, 2 * circuit->hello_interval[1]);
+ thread_add_timer(master, isis_run_dr_l2, circuit,
+ 2 * circuit->hello_interval[1],
+ &circuit->u.bc.t_run_dr[1]);
- THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
- isis_jitter (circuit->psnp_interval[level - 1],
- PSNP_JITTER));
+ thread_add_timer(master, send_l2_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[level - 1], PSNP_JITTER),
+ &circuit->t_send_psnp[1]);
}
- thread_add_event (master, isis_event_dis_status_change, circuit, 0);
+ thread_add_event(master, isis_event_dis_status_change, circuit, 0, NULL);
return ISIS_OK;
}
@@ -296,11 +298,13 @@ isis_dr_commence (struct isis_circuit *circuit, int level)
/* Lets keep a pause in DR election */
circuit->u.bc.run_dr_elect[level - 1] = 0;
if (level == 1)
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
- circuit, 2 * circuit->hello_interval[0]);
+ thread_add_timer(master, isis_run_dr_l1, circuit,
+ 2 * circuit->hello_interval[0],
+ &circuit->u.bc.t_run_dr[0]);
else
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
- circuit, 2 * circuit->hello_interval[1]);
+ thread_add_timer(master, isis_run_dr_l2, circuit,
+ 2 * circuit->hello_interval[1],
+ &circuit->u.bc.t_run_dr[1]);
circuit->u.bc.is_dr[level - 1] = 1;
if (level == 1)
@@ -321,12 +325,13 @@ isis_dr_commence (struct isis_circuit *circuit, int level)
lsp_generate_pseudo (circuit, 1);
THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[0]);
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
- circuit, 2 * circuit->hello_interval[0]);
+ thread_add_timer(master, isis_run_dr_l1, circuit,
+ 2 * circuit->hello_interval[0],
+ &circuit->u.bc.t_run_dr[0]);
- THREAD_TIMER_ON (master, circuit->t_send_csnp[0], send_l1_csnp, circuit,
- isis_jitter (circuit->csnp_interval[level - 1],
- CSNP_JITTER));
+ thread_add_timer(master, send_l1_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[level - 1], CSNP_JITTER),
+ &circuit->t_send_csnp[0]);
}
else
@@ -347,15 +352,16 @@ isis_dr_commence (struct isis_circuit *circuit, int level)
lsp_generate_pseudo (circuit, 2);
THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[1]);
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
- circuit, 2 * circuit->hello_interval[1]);
+ thread_add_timer(master, isis_run_dr_l2, circuit,
+ 2 * circuit->hello_interval[1],
+ &circuit->u.bc.t_run_dr[1]);
- THREAD_TIMER_ON (master, circuit->t_send_csnp[1], send_l2_csnp, circuit,
- isis_jitter (circuit->csnp_interval[level - 1],
- CSNP_JITTER));
+ thread_add_timer(master, send_l2_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[level - 1], CSNP_JITTER),
+ &circuit->t_send_csnp[1]);
}
- thread_add_event (master, isis_event_dis_status_change, circuit, 0);
+ thread_add_event(master, isis_event_dis_status_change, circuit, 0, NULL);
return ISIS_OK;
}
diff --git a/isisd/isis_dr.h b/isisd/isis_dr.h
index bad6836141..801cd0e472 100644
--- a/isisd/isis_dr.h
+++ b/isisd/isis_dr.h
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_DR_H
diff --git a/isisd/isis_dynhn.c b/isisd/isis_dynhn.c
index 412f098a1b..0c702e6729 100644
--- a/isisd/isis_dynhn.c
+++ b/isisd/isis_dynhn.c
@@ -15,9 +15,9 @@
* 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.
+ * 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>
@@ -51,7 +51,7 @@ dyn_cache_init (void)
{
if (dyn_cache == NULL)
dyn_cache = list_new ();
- THREAD_TIMER_ON (master, isis->t_dync_clean, dyn_cache_cleanup, NULL, 120);
+ thread_add_timer(master, dyn_cache_cleanup, NULL, 120, &isis->t_dync_clean);
return;
}
@@ -73,7 +73,7 @@ dyn_cache_cleanup (struct thread *thread)
XFREE (MTYPE_ISIS_DYNHN, dyn);
}
- THREAD_TIMER_ON (master, isis->t_dync_clean, dyn_cache_cleanup, NULL, 120);
+ thread_add_timer(master, dyn_cache_cleanup, NULL, 120, &isis->t_dync_clean);
return ISIS_OK;
}
diff --git a/isisd/isis_dynhn.h b/isisd/isis_dynhn.h
index f06a067be1..c36d9a0093 100644
--- a/isisd/isis_dynhn.h
+++ b/isisd/isis_dynhn.h
@@ -16,9 +16,9 @@
* 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.
+ * 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 _ZEBRA_ISIS_DYNHN_H
#define _ZEBRA_ISIS_DYNHN_H
diff --git a/isisd/isis_events.c b/isisd/isis_events.c
index ab42a1e367..8011d2db9c 100644
--- a/isisd/isis_events.c
+++ b/isisd/isis_events.c
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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>
@@ -82,18 +82,19 @@ circuit_commence_level (struct isis_circuit *circuit, int level)
if (level == 1)
{
if (! circuit->is_passive)
- THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
- isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
+ thread_add_timer(master, send_l1_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
+ &circuit->t_send_psnp[0]);
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
{
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
- circuit, 2 * circuit->hello_interval[0]);
+ thread_add_timer(master, isis_run_dr_l1, circuit,
+ 2 * circuit->hello_interval[0],
+ &circuit->u.bc.t_run_dr[0]);
- THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[0],
- send_lan_l1_hello, circuit,
- isis_jitter (circuit->hello_interval[0],
- IIH_JITTER));
+ thread_add_timer(master, send_lan_l1_hello, circuit,
+ isis_jitter(circuit->hello_interval[0], IIH_JITTER),
+ &circuit->u.bc.t_send_lan_hello[0]);
circuit->u.bc.lan_neighs[0] = list_new ();
}
@@ -101,18 +102,19 @@ circuit_commence_level (struct isis_circuit *circuit, int level)
else
{
if (! circuit->is_passive)
- THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
- isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
+ thread_add_timer(master, send_l2_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
+ &circuit->t_send_psnp[1]);
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
{
- THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
- circuit, 2 * circuit->hello_interval[1]);
+ thread_add_timer(master, isis_run_dr_l2, circuit,
+ 2 * circuit->hello_interval[1],
+ &circuit->u.bc.t_run_dr[1]);
- THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[1],
- send_lan_l2_hello, circuit,
- isis_jitter (circuit->hello_interval[1],
- IIH_JITTER));
+ thread_add_timer(master, send_lan_l2_hello, circuit,
+ isis_jitter(circuit->hello_interval[1], IIH_JITTER),
+ &circuit->u.bc.t_send_lan_hello[1]);
circuit->u.bc.lan_neighs[1] = list_new ();
}
diff --git a/isisd/isis_events.h b/isisd/isis_events.h
index e7cfa3509e..e9aa05db77 100644
--- a/isisd/isis_events.h
+++ b/isisd/isis_events.h
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_EVENTS_H
#define _ZEBRA_ISIS_EVENTS_H
diff --git a/isisd/isis_flags.c b/isisd/isis_flags.c
index ec0eaa4f82..6c88cfeda5 100644
--- a/isisd/isis_flags.c
+++ b/isisd/isis_flags.c
@@ -16,9 +16,9 @@
* 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.
+ * 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>
diff --git a/isisd/isis_flags.h b/isisd/isis_flags.h
index e2e42adcc9..ba11cf42b5 100644
--- a/isisd/isis_flags.h
+++ b/isisd/isis_flags.h
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_FLAGS_H
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index f633a8fb78..29e5280ce3 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -16,10 +16,10 @@
* 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.
+ *
+ * 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>
@@ -53,6 +53,7 @@
#include "isisd/isis_adjacency.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_te.h"
+#include "isisd/isis_mt.h"
/* staticly assigned vars for printing purposes */
char lsp_bits_string[200]; /* FIXME: enough ? */
@@ -501,6 +502,7 @@ lsp_update_data (struct isis_lsp *lsp, struct stream *stream,
expected |= TLVFLAG_TE_IPV4_REACHABILITY;
expected |= TLVFLAG_TE_ROUTER_ID;
}
+ expected |= TLVFLAG_MT_ROUTER_INFORMATION;
expected |= TLVFLAG_IPV4_ADDR;
expected |= TLVFLAG_IPV4_INT_REACHABILITY;
expected |= TLVFLAG_IPV4_EXT_REACHABILITY;
@@ -826,6 +828,107 @@ lsp_print (struct isis_lsp *lsp, struct vty *vty, char dynhost)
lsp_bits2string (&lsp->lsp_header->lsp_bits), VTY_NEWLINE);
}
+static void
+lsp_print_mt_reach(struct list *list, struct vty *vty,
+ char dynhost, uint16_t mtid)
+{
+ struct listnode *node;
+ struct te_is_neigh *neigh;
+
+ for (ALL_LIST_ELEMENTS_RO (list, node, neigh))
+ {
+ u_char lspid[255];
+
+ lspid_print(neigh->neigh_id, lspid, dynhost, 0);
+ if (mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ vty_out(vty, " Metric : %-8d IS-Extended : %s%s",
+ GET_TE_METRIC(neigh), lspid, VTY_NEWLINE);
+ }
+ else
+ {
+ vty_out(vty, " Metric : %-8d MT-Reach : %s %s%s",
+ GET_TE_METRIC(neigh), lspid,
+ isis_mtid2str(mtid), VTY_NEWLINE);
+ }
+ if (IS_MPLS_TE(isisMplsTE))
+ mpls_te_print_detail(vty, neigh);
+ }
+}
+
+static void
+lsp_print_mt_ipv6_reach(struct list *list, struct vty *vty, uint16_t mtid)
+{
+ struct listnode *node;
+ struct ipv6_reachability *ipv6_reach;
+ struct in6_addr in6;
+ u_char buff[BUFSIZ];
+
+ for (ALL_LIST_ELEMENTS_RO (list, node, ipv6_reach))
+ {
+ memset (&in6, 0, sizeof (in6));
+ memcpy (in6.s6_addr, ipv6_reach->prefix,
+ PSIZE (ipv6_reach->prefix_len));
+ inet_ntop (AF_INET6, &in6, (char *)buff, BUFSIZ);
+ if (mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ if ((ipv6_reach->control_info &
+ CTRL_INFO_DISTRIBUTION) == DISTRIBUTION_INTERNAL)
+ vty_out (vty, " Metric : %-8d IPv6-Internal : %s/%d%s",
+ ntohl (ipv6_reach->metric),
+ buff, ipv6_reach->prefix_len, VTY_NEWLINE);
+ else
+ vty_out (vty, " Metric : %-8d IPv6-External : %s/%d%s",
+ ntohl (ipv6_reach->metric),
+ buff, ipv6_reach->prefix_len, VTY_NEWLINE);
+ }
+ else
+ {
+ if ((ipv6_reach->control_info &
+ CTRL_INFO_DISTRIBUTION) == DISTRIBUTION_INTERNAL)
+ vty_out (vty, " Metric : %-8d IPv6-MT-Int : %s/%d %s%s",
+ ntohl (ipv6_reach->metric),
+ buff, ipv6_reach->prefix_len,
+ isis_mtid2str(mtid), VTY_NEWLINE);
+ else
+ vty_out (vty, " Metric : %-8d IPv6-MT-Ext : %s/%d %s%s",
+ ntohl (ipv6_reach->metric),
+ buff, ipv6_reach->prefix_len,
+ isis_mtid2str(mtid), VTY_NEWLINE);
+ }
+ }
+}
+
+static void
+lsp_print_mt_ipv4_reach(struct list *list, struct vty *vty, uint16_t mtid)
+{
+ struct listnode *node;
+ struct te_ipv4_reachability *te_ipv4_reach;
+
+ for (ALL_LIST_ELEMENTS_RO (list, node, te_ipv4_reach))
+ {
+ if (mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ /* FIXME: There should be better way to output this stuff. */
+ vty_out (vty, " Metric : %-8d IPv4-Extended : %s/%d%s",
+ ntohl (te_ipv4_reach->te_metric),
+ inet_ntoa (newprefix2inaddr (&te_ipv4_reach->prefix_start,
+ te_ipv4_reach->control)),
+ te_ipv4_reach->control & 0x3F, VTY_NEWLINE);
+ }
+ else
+ {
+ /* FIXME: There should be better way to output this stuff. */
+ vty_out (vty, " Metric : %-8d IPv4-MT : %s/%d %s%s",
+ ntohl (te_ipv4_reach->te_metric),
+ inet_ntoa (newprefix2inaddr (&te_ipv4_reach->prefix_start,
+ te_ipv4_reach->control)),
+ te_ipv4_reach->control & 0x3F,
+ isis_mtid2str(mtid), VTY_NEWLINE);
+ }
+ }
+}
+
void
lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost)
{
@@ -833,13 +936,12 @@ lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost)
int i;
struct listnode *lnode;
struct is_neigh *is_neigh;
- struct te_is_neigh *te_is_neigh;
struct ipv4_reachability *ipv4_reach;
struct in_addr *ipv4_addr;
- struct te_ipv4_reachability *te_ipv4_reach;
- struct ipv6_reachability *ipv6_reach;
- struct in6_addr in6;
- u_char buff[BUFSIZ];
+ struct mt_router_info *mt_router_info;
+ struct tlv_mt_ipv6_reachs *mt_ipv6_reachs;
+ struct tlv_mt_neighbors *mt_is_neigh;
+ struct tlv_mt_ipv4_reachs *mt_ipv4_reachs;
u_char LSPid[255];
u_char hostname[255];
u_char ipv4_reach_prefix[20];
@@ -877,6 +979,14 @@ lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost)
}
}
+ for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_router_info, lnode, mt_router_info))
+ {
+ vty_out (vty, " MT : %s%s%s",
+ isis_mtid2str(mt_router_info->mtid),
+ mt_router_info->overload ? " (overload)" : "",
+ VTY_NEWLINE);
+ }
+
/* for the hostname tlv */
if (lsp->tlv_data.hostname)
{
@@ -946,49 +1056,31 @@ lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost)
ipv4_reach->metrics.metric_default, ipv4_reach_prefix,
ipv4_reach_mask, VTY_NEWLINE);
}
-
+
/* IPv6 tlv */
- if (lsp->tlv_data.ipv6_reachs)
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv6_reachs, lnode, ipv6_reach))
- {
- memset (&in6, 0, sizeof (in6));
- memcpy (in6.s6_addr, ipv6_reach->prefix,
- PSIZE (ipv6_reach->prefix_len));
- inet_ntop (AF_INET6, &in6, (char *)buff, BUFSIZ);
- if ((ipv6_reach->control_info &
- CTRL_INFO_DISTRIBUTION) == DISTRIBUTION_INTERNAL)
- vty_out (vty, " Metric : %-8d IPv6-Internal : %s/%d%s",
- ntohl (ipv6_reach->metric),
- buff, ipv6_reach->prefix_len, VTY_NEWLINE);
- else
- vty_out (vty, " Metric : %-8d IPv6-External : %s/%d%s",
- ntohl (ipv6_reach->metric),
- buff, ipv6_reach->prefix_len, VTY_NEWLINE);
- }
+ lsp_print_mt_ipv6_reach(lsp->tlv_data.ipv6_reachs, vty,
+ ISIS_MT_IPV4_UNICAST);
+
+ /* MT IPv6 reachability tlv */
+ for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.mt_ipv6_reachs, lnode, mt_ipv6_reachs))
+ lsp_print_mt_ipv6_reach(mt_ipv6_reachs->list, vty, mt_ipv6_reachs->mtid);
/* TE IS neighbor tlv */
- if (lsp->tlv_data.te_is_neighs)
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.te_is_neighs, lnode, te_is_neigh))
- {
- lspid_print (te_is_neigh->neigh_id, LSPid, dynhost, 0);
- vty_out (vty, " Metric : %-8d IS-Extended : %s%s",
- GET_TE_METRIC(te_is_neigh), LSPid, VTY_NEWLINE);
- if (IS_MPLS_TE(isisMplsTE))
- mpls_te_print_detail(vty, te_is_neigh);
- }
+ lsp_print_mt_reach(lsp->tlv_data.te_is_neighs, vty,
+ dynhost, ISIS_MT_IPV4_UNICAST);
+
+ /* MT IS neighbor tlv */
+ for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.mt_is_neighs, lnode, mt_is_neigh))
+ lsp_print_mt_reach(mt_is_neigh->list, vty, dynhost, mt_is_neigh->mtid);
/* TE IPv4 tlv */
- if (lsp->tlv_data.te_ipv4_reachs)
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.te_ipv4_reachs, lnode,
- te_ipv4_reach))
- {
- /* FIXME: There should be better way to output this stuff. */
- vty_out (vty, " Metric : %-8d IPv4-Extended : %s/%d%s",
- ntohl (te_ipv4_reach->te_metric),
- inet_ntoa (newprefix2inaddr (&te_ipv4_reach->prefix_start,
- te_ipv4_reach->control)),
- te_ipv4_reach->control & 0x3F, VTY_NEWLINE);
- }
+ lsp_print_mt_ipv4_reach(lsp->tlv_data.te_ipv4_reachs, vty,
+ ISIS_MT_IPV4_UNICAST);
+
+ /* MT IPv4 reachability tlv */
+ for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.mt_ipv4_reachs, lnode, mt_ipv4_reachs))
+ lsp_print_mt_ipv4_reach(mt_ipv4_reachs->list, vty, mt_ipv4_reachs->mtid);
+
vty_out (vty, "%s", VTY_NEWLINE);
return;
@@ -1028,6 +1120,42 @@ lsp_print_all (struct vty *vty, dict_t * lspdb, char detail, char dynhost)
return lsp_count;
}
+static void
+_lsp_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to,
+ int frag_thold,
+ unsigned int tlv_build_func (struct list *, struct stream *,
+ void *arg),
+ void *arg)
+{
+ while (*from && listcount(*from))
+ {
+ unsigned int count;
+
+ count = tlv_build_func(*from, lsp->pdu, arg);
+
+ if (listcount(*to) != 0 || count != listcount(*from))
+ {
+ struct listnode *node, *nnode;
+ void *elem;
+
+ for (ALL_LIST_ELEMENTS(*from, node, nnode, elem))
+ {
+ if (!count)
+ break;
+ listnode_add (*to, elem);
+ list_delete_node (*from, node);
+ --count;
+ }
+ }
+ else
+ {
+ list_free (*to);
+ *to = *from;
+ *from = NULL;
+ }
+ }
+}
+
#define FRAG_THOLD(S,T) \
((STREAM_SIZE(S)*T)/100)
@@ -1085,64 +1213,6 @@ lsp_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to,
return;
}
-/* Process IS_NEIGHBOURS TLV with TE subTLVs */
-void
-lsp_te_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to, int frag_thold)
-{
- int count, size = 0;
- struct listnode *node, *nextnode;
- struct te_is_neigh *elem;
-
- /* Start computing real size of TLVs */
- for (ALL_LIST_ELEMENTS (*from, node, nextnode, elem))
- size = size + elem->sub_tlvs_length + IS_NEIGHBOURS_LEN;
-
- /* can we fit all ? */
- if (!FRAG_NEEDED (lsp->pdu, frag_thold, size))
- {
- tlv_add_te_is_neighs (*from, lsp->pdu);
- if (listcount (*to) != 0)
- {
- for (ALL_LIST_ELEMENTS (*from, node, nextnode, elem))
- {
- listnode_add (*to, elem);
- list_delete_node (*from, node);
- }
- }
- else
- {
- list_free (*to);
- *to = *from;
- *from = NULL;
- }
- }
- else
- {
- /* fit all we can */
- /* Compute remaining place in LSP PDU */
- count = FRAG_THOLD (lsp->pdu, frag_thold) - 2 -
- (STREAM_SIZE (lsp->pdu) - STREAM_REMAIN (lsp->pdu));
- /* Determine size of TE SubTLVs */
- elem = (struct te_is_neigh *)listgetdata ((struct listnode *)listhead (*from));
- count = count - elem->sub_tlvs_length - IS_NEIGHBOURS_LEN;
- if (count > 0)
- {
- while (count > 0)
- {
- listnode_add (*to, listgetdata ((struct listnode *)listhead (*from)));
- listnode_delete (*from, listgetdata ((struct listnode *)listhead (*from)));
-
- elem = (struct te_is_neigh *)listgetdata ((struct listnode *)listhead (*from));
- count = count - elem->sub_tlvs_length - IS_NEIGHBOURS_LEN;
- }
-
- tlv_add_te_is_neighs (*to, lsp->pdu);
- }
- }
- lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu));
- return;
-}
-
static u_int16_t
lsp_rem_lifetime (struct isis_area *area, int level)
{
@@ -1278,6 +1348,24 @@ lsp_build_ext_reach_ipv4(struct isis_lsp *lsp, struct isis_area *area,
}
}
+static struct list *
+tlv_get_ipv6_reach_list(struct isis_area *area, struct tlvs *tlv_data)
+{
+ uint16_t mtid = isis_area_ipv6_topology(area);
+ if (mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ if (!tlv_data->ipv6_reachs)
+ {
+ tlv_data->ipv6_reachs = list_new();
+ tlv_data->ipv6_reachs->del = free_tlv;
+ }
+ return tlv_data->ipv6_reachs;
+ }
+
+ struct tlv_mt_ipv6_reachs *reachs = tlvs_get_mt_ipv6_reachs(tlv_data, mtid);
+ return reachs->list;
+}
+
static void
lsp_build_ext_reach_ipv6(struct isis_lsp *lsp, struct isis_area *area,
struct tlvs *tlv_data)
@@ -1287,6 +1375,7 @@ lsp_build_ext_reach_ipv6(struct isis_lsp *lsp, struct isis_area *area,
struct prefix_ipv6 *ipv6;
struct isis_ext_info *info;
struct ipv6_reachability *ip6reach;
+ struct list *reach_list = NULL;
er_table = get_ext_reach(area, AF_INET6, lsp->level);
if (!er_table)
@@ -1300,11 +1389,9 @@ lsp_build_ext_reach_ipv6(struct isis_lsp *lsp, struct isis_area *area,
ipv6 = (struct prefix_ipv6*)&rn->p;
info = rn->info;
- if (tlv_data->ipv6_reachs == NULL)
- {
- tlv_data->ipv6_reachs = list_new();
- tlv_data->ipv6_reachs->del = free_tlv;
- }
+ if (!reach_list)
+ reach_list = tlv_get_ipv6_reach_list(area, tlv_data);
+
ip6reach = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ip6reach));
if (info->metric > MAX_WIDE_PATH_METRIC)
ip6reach->metric = htonl(MAX_WIDE_PATH_METRIC);
@@ -1313,7 +1400,7 @@ lsp_build_ext_reach_ipv6(struct isis_lsp *lsp, struct isis_area *area,
ip6reach->control_info = DISTRIBUTION_EXTERNAL;
ip6reach->prefix_len = ipv6->prefixlen;
memcpy(ip6reach->prefix, ipv6->prefix.s6_addr, sizeof(ip6reach->prefix));
- listnode_add(tlv_data->ipv6_reachs, ip6reach);
+ listnode_add(reach_list, ip6reach);
}
}
@@ -1342,6 +1429,7 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
struct te_ipv4_reachability *te_ipreach;
struct isis_adjacency *nei;
struct prefix_ipv6 *ipv6, ip6prefix;
+ struct list *ipv6_reachs = NULL;
struct ipv6_reachability *ip6reach;
struct tlvs tlv_data;
struct isis_lsp *lsp0 = lsp;
@@ -1402,6 +1490,32 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
tlv_add_nlpid (lsp->tlv_data.nlpids, lsp->pdu);
}
+ if (area_is_mt(area))
+ {
+ lsp_debug("ISIS (%s): Adding MT router tlv...", area->area_tag);
+ lsp->tlv_data.mt_router_info = list_new();
+ lsp->tlv_data.mt_router_info->del = free_tlv;
+
+ struct isis_area_mt_setting **mt_settings;
+ unsigned int mt_count;
+
+ mt_settings = area_mt_settings(area, &mt_count);
+ for (unsigned int i = 0; i < mt_count; i++)
+ {
+ struct mt_router_info *info;
+
+ info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info));
+ info->mtid = mt_settings[i]->mtid;
+ info->overload = mt_settings[i]->overload;
+ listnode_add(lsp->tlv_data.mt_router_info, info);
+ lsp_debug("ISIS (%s): MT %s", area->area_tag, isis_mtid2str(info->mtid));
+ }
+ tlv_add_mt_router_info (lsp->tlv_data.mt_router_info, lsp->pdu);
+ }
+ else
+ {
+ lsp_debug("ISIS (%s): Not adding MT router tlv (disabled)", area->area_tag);
+ }
/* Dynamic Hostname */
if (area->dynhostname)
{
@@ -1551,12 +1665,9 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
if (circuit->ipv6_router && circuit->ipv6_non_link &&
circuit->ipv6_non_link->count > 0)
{
+ if (!ipv6_reachs)
+ ipv6_reachs = tlv_get_ipv6_reach_list(area, &tlv_data);
- if (tlv_data.ipv6_reachs == NULL)
- {
- tlv_data.ipv6_reachs = list_new ();
- tlv_data.ipv6_reachs->del = free_tlv;
- }
for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, ipnode, ipv6))
{
ip6reach =
@@ -1579,7 +1690,7 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
memcpy (ip6reach->prefix, ip6prefix.prefix.s6_addr,
sizeof (ip6reach->prefix));
- listnode_add (tlv_data.ipv6_reachs, ip6reach);
+ listnode_add (ipv6_reachs, ip6reach);
}
}
@@ -1658,10 +1769,8 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
/* Or keep only TE metric with no SubTLVs if MPLS_TE is off */
te_is_neigh->sub_tlvs_length = 0;
- listnode_add (tlv_data.te_is_neighs, te_is_neigh);
- lsp_debug("ISIS (%s): Adding DIS %s.%02x as te-style neighbor",
- area->area_tag, sysid_print(te_is_neigh->neigh_id),
- LSP_PSEUDO_ID(te_is_neigh->neigh_id));
+ tlvs_add_mt_bcast(&tlv_data, circuit, level, te_is_neigh);
+ XFREE(MTYPE_ISIS_TLV, te_is_neigh);
}
}
}
@@ -1718,9 +1827,9 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
else
/* Or keep only TE metric with no SubTLVs if MPLS_TE is off */
te_is_neigh->sub_tlvs_length = 0;
- listnode_add (tlv_data.te_is_neighs, te_is_neigh);
- lsp_debug("ISIS (%s): Adding te-style is reach for %s", area->area_tag,
- sysid_print(te_is_neigh->neigh_id));
+
+ tlvs_add_mt_p2p(&tlv_data, circuit, te_is_neigh);
+ XFREE(MTYPE_ISIS_TLV, te_is_neigh);
}
}
else
@@ -1766,35 +1875,62 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
lsp0, area, level);
}
- /* FIXME: We pass maximum te_ipv4_reachability length to the lsp_tlv_fit()
- * for now. lsp_tlv_fit() needs to be fixed to deal with variable length
- * TLVs (sub TLVs!). */
while (tlv_data.te_ipv4_reachs && listcount (tlv_data.te_ipv4_reachs))
{
if (lsp->tlv_data.te_ipv4_reachs == NULL)
lsp->tlv_data.te_ipv4_reachs = list_new ();
- lsp_tlv_fit (lsp, &tlv_data.te_ipv4_reachs,
- &lsp->tlv_data.te_ipv4_reachs,
- TE_IPV4_REACH_LEN, area->lsp_frag_threshold,
- tlv_add_te_ipv4_reachs);
+ _lsp_tlv_fit (lsp, &tlv_data.te_ipv4_reachs, &lsp->tlv_data.te_ipv4_reachs,
+ area->lsp_frag_threshold, tlv_add_te_ipv4_reachs, NULL);
if (tlv_data.te_ipv4_reachs && listcount (tlv_data.te_ipv4_reachs))
lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
lsp0, area, level);
}
+ struct tlv_mt_ipv4_reachs *mt_ipv4_reachs;
+ for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_ipv4_reachs, node, mt_ipv4_reachs))
+ {
+ while (mt_ipv4_reachs->list && listcount(mt_ipv4_reachs->list))
+ {
+ struct tlv_mt_ipv4_reachs *frag_mt_ipv4_reachs;
+
+ frag_mt_ipv4_reachs = tlvs_get_mt_ipv4_reachs(&lsp->tlv_data, mt_ipv4_reachs->mtid);
+ _lsp_tlv_fit (lsp, &mt_ipv4_reachs->list, &frag_mt_ipv4_reachs->list,
+ area->lsp_frag_threshold, tlv_add_te_ipv4_reachs,
+ &mt_ipv4_reachs->mtid);
+ if (mt_ipv4_reachs->list && listcount(mt_ipv4_reachs->list))
+ lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
+ lsp0, area, level);
+ }
+ }
+
while (tlv_data.ipv6_reachs && listcount (tlv_data.ipv6_reachs))
{
if (lsp->tlv_data.ipv6_reachs == NULL)
lsp->tlv_data.ipv6_reachs = list_new ();
- lsp_tlv_fit (lsp, &tlv_data.ipv6_reachs,
- &lsp->tlv_data.ipv6_reachs,
- IPV6_REACH_LEN, area->lsp_frag_threshold,
- tlv_add_ipv6_reachs);
+ _lsp_tlv_fit (lsp, &tlv_data.ipv6_reachs, &lsp->tlv_data.ipv6_reachs,
+ area->lsp_frag_threshold, tlv_add_ipv6_reachs, NULL);
if (tlv_data.ipv6_reachs && listcount (tlv_data.ipv6_reachs))
lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
lsp0, area, level);
}
+ struct tlv_mt_ipv6_reachs *mt_ipv6_reachs;
+ for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_ipv6_reachs, node, mt_ipv6_reachs))
+ {
+ while (mt_ipv6_reachs->list && listcount(mt_ipv6_reachs->list))
+ {
+ struct tlv_mt_ipv6_reachs *frag_mt_ipv6_reachs;
+
+ frag_mt_ipv6_reachs = tlvs_get_mt_ipv6_reachs(&lsp->tlv_data, mt_ipv6_reachs->mtid);
+ _lsp_tlv_fit (lsp, &mt_ipv6_reachs->list, &frag_mt_ipv6_reachs->list,
+ area->lsp_frag_threshold, tlv_add_ipv6_reachs,
+ &mt_ipv6_reachs->mtid);
+ if (mt_ipv6_reachs->list && listcount(mt_ipv6_reachs->list))
+ lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
+ lsp0, area, level);
+ }
+ }
+
while (tlv_data.is_neighs && listcount (tlv_data.is_neighs))
{
if (lsp->tlv_data.is_neighs == NULL)
@@ -1812,13 +1948,31 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
{
if (lsp->tlv_data.te_is_neighs == NULL)
lsp->tlv_data.te_is_neighs = list_new ();
- lsp_tlv_fit (lsp, &tlv_data.te_is_neighs, &lsp->tlv_data.te_is_neighs,
- IS_NEIGHBOURS_LEN, area->lsp_frag_threshold,
- tlv_add_te_is_neighs);
+ _lsp_tlv_fit (lsp, &tlv_data.te_is_neighs, &lsp->tlv_data.te_is_neighs,
+ area->lsp_frag_threshold, tlv_add_te_is_neighs, NULL);
if (tlv_data.te_is_neighs && listcount (tlv_data.te_is_neighs))
lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
lsp0, area, level);
}
+
+ struct tlv_mt_neighbors *mt_neighs;
+ for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_is_neighs, node, mt_neighs))
+ {
+ while (mt_neighs->list && listcount(mt_neighs->list))
+ {
+ struct tlv_mt_neighbors *frag_mt_neighs;
+
+ frag_mt_neighs = tlvs_get_mt_neighbors(&lsp->tlv_data, mt_neighs->mtid);
+ _lsp_tlv_fit (lsp, &mt_neighs->list, &frag_mt_neighs->list,
+ area->lsp_frag_threshold, tlv_add_te_is_neighs,
+ &mt_neighs->mtid);
+ if (mt_neighs->list && listcount(mt_neighs->list))
+ lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
+ lsp0, area, level);
+ }
+ }
+
+
lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu));
free_tlvs (&tlv_data);
@@ -1880,11 +2034,11 @@ lsp_generate (struct isis_area *area, int level)
THREAD_TIMER_OFF (area->t_lsp_refresh[level - 1]);
area->lsp_regenerate_pending[level - 1] = 0;
if (level == IS_LEVEL_1)
- THREAD_TIMER_ON (master, area->t_lsp_refresh[level - 1],
- lsp_l1_refresh, area, refresh_time);
+ thread_add_timer(master, lsp_l1_refresh, area, refresh_time,
+ &area->t_lsp_refresh[level - 1]);
else if (level == IS_LEVEL_2)
- THREAD_TIMER_ON (master, area->t_lsp_refresh[level - 1],
- lsp_l2_refresh, area, refresh_time);
+ thread_add_timer(master, lsp_l2_refresh, area, refresh_time,
+ &area->t_lsp_refresh[level - 1]);
if (isis->debugs & DEBUG_UPDATE_PACKETS)
{
@@ -1957,11 +2111,11 @@ lsp_regenerate (struct isis_area *area, int level)
refresh_time = lsp_refresh_time (lsp, rem_lifetime);
if (level == IS_LEVEL_1)
- THREAD_TIMER_ON (master, area->t_lsp_refresh[level - 1],
- lsp_l1_refresh, area, refresh_time);
+ thread_add_timer(master, lsp_l1_refresh, area, refresh_time,
+ &area->t_lsp_refresh[level - 1]);
else if (level == IS_LEVEL_2)
- THREAD_TIMER_ON (master, area->t_lsp_refresh[level - 1],
- lsp_l2_refresh, area, refresh_time);
+ thread_add_timer(master, lsp_l2_refresh, area, refresh_time,
+ &area->t_lsp_refresh[level - 1]);
area->lsp_regenerate_pending[level - 1] = 0;
if (isis->debugs & DEBUG_UPDATE_PACKETS)
@@ -2095,13 +2249,13 @@ lsp_regenerate_schedule (struct isis_area *area, int level, int all_pseudo)
area->lsp_regenerate_pending[lvl - 1] = 1;
if (lvl == IS_LEVEL_1)
{
- THREAD_TIMER_MSEC_ON(master, area->t_lsp_refresh[lvl - 1],
- lsp_l1_refresh, area, timeout);
+ thread_add_timer_msec(master, lsp_l1_refresh, area, timeout,
+ &area->t_lsp_refresh[lvl - 1]);
}
else if (lvl == IS_LEVEL_2)
{
- THREAD_TIMER_MSEC_ON(master, area->t_lsp_refresh[lvl - 1],
- lsp_l2_refresh, area, timeout);
+ thread_add_timer_msec(master, lsp_l2_refresh, area, timeout,
+ &area->t_lsp_refresh[lvl - 1]);
}
}
@@ -2255,7 +2409,7 @@ lsp_build_pseudo (struct isis_lsp *lsp, struct isis_circuit *circuit,
tlv_add_is_neighs (lsp->tlv_data.is_neighs, lsp->pdu);
if (lsp->tlv_data.te_is_neighs && listcount (lsp->tlv_data.te_is_neighs) > 0)
- tlv_add_te_is_neighs (lsp->tlv_data.te_is_neighs, lsp->pdu);
+ tlv_add_te_is_neighs (lsp->tlv_data.te_is_neighs, lsp->pdu, NULL);
if (lsp->tlv_data.es_neighs && listcount (lsp->tlv_data.es_neighs) > 0)
tlv_add_is_neighs (lsp->tlv_data.es_neighs, lsp->pdu);
@@ -2311,11 +2465,11 @@ lsp_generate_pseudo (struct isis_circuit *circuit, int level)
THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
circuit->lsp_regenerate_pending[level - 1] = 0;
if (level == IS_LEVEL_1)
- THREAD_TIMER_ON (master, circuit->u.bc.t_refresh_pseudo_lsp[level - 1],
- lsp_l1_refresh_pseudo, circuit, refresh_time);
+ thread_add_timer(master, lsp_l1_refresh_pseudo, circuit, refresh_time,
+ &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
else if (level == IS_LEVEL_2)
- THREAD_TIMER_ON (master, circuit->u.bc.t_refresh_pseudo_lsp[level - 1],
- lsp_l2_refresh_pseudo, circuit, refresh_time);
+ thread_add_timer(master, lsp_l2_refresh_pseudo, circuit, refresh_time,
+ &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
if (isis->debugs & DEBUG_UPDATE_PACKETS)
{
@@ -2374,11 +2528,11 @@ lsp_regenerate_pseudo (struct isis_circuit *circuit, int level)
refresh_time = lsp_refresh_time (lsp, rem_lifetime);
if (level == IS_LEVEL_1)
- THREAD_TIMER_ON (master, circuit->u.bc.t_refresh_pseudo_lsp[level - 1],
- lsp_l1_refresh_pseudo, circuit, refresh_time);
+ thread_add_timer(master, lsp_l1_refresh_pseudo, circuit, refresh_time,
+ &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
else if (level == IS_LEVEL_2)
- THREAD_TIMER_ON (master, circuit->u.bc.t_refresh_pseudo_lsp[level - 1],
- lsp_l2_refresh_pseudo, circuit, refresh_time);
+ thread_add_timer(master, lsp_l2_refresh_pseudo, circuit, refresh_time,
+ &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
if (isis->debugs & DEBUG_UPDATE_PACKETS)
{
@@ -2530,15 +2684,15 @@ lsp_regenerate_schedule_pseudo (struct isis_circuit *circuit, int level)
if (lvl == IS_LEVEL_1)
{
- THREAD_TIMER_MSEC_ON(master,
- circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1],
- lsp_l1_refresh_pseudo, circuit, timeout);
+ thread_add_timer_msec(master, lsp_l1_refresh_pseudo, circuit,
+ timeout,
+ &circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
}
else if (lvl == IS_LEVEL_2)
{
- THREAD_TIMER_MSEC_ON(master,
- circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1],
- lsp_l2_refresh_pseudo, circuit, timeout);
+ thread_add_timer_msec(master, lsp_l2_refresh_pseudo, circuit,
+ timeout,
+ &circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
}
}
@@ -2567,7 +2721,7 @@ lsp_tick (struct thread *thread)
area = THREAD_ARG (thread);
assert (area);
area->t_tick = NULL;
- THREAD_TIMER_ON (master, area->t_tick, lsp_tick, area, 1);
+ thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
/*
* Build a list of LSPs with (any) SRMflag set
@@ -2645,7 +2799,8 @@ lsp_tick (struct thread *thread)
if (! listnode_lookup (circuit->lsp_queue, lsp))
{
listnode_add (circuit->lsp_queue, lsp);
- thread_add_event (master, send_lsp, circuit, 0);
+ thread_add_event(master, send_lsp, circuit, 0,
+ NULL);
}
}
}
diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h
index 24fae57a7b..0d1dd6740f 100644
--- a/isisd/isis_lsp.h
+++ b/isisd/isis_lsp.h
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_LSP_H
@@ -108,8 +108,6 @@ void lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost);
int lsp_print_all (struct vty *vty, dict_t * lspdb, char detail,
char dynhost);
const char *lsp_bits2string (u_char *);
-void lsp_te_tlv_fit (struct isis_lsp *lsp, struct list **from,
- struct list **to, int frag_thold);
/* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags (struct isis_lsp *lsp);
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index 644b652d44..58070c7f2a 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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>
@@ -206,7 +206,7 @@ main (int argc, char **argv, char **envp)
* initializations
*/
access_list_init();
- vrf_init ();
+ vrf_init (NULL, NULL, NULL, NULL);
prefix_list_init();
isis_init ();
isis_circuit_init ();
diff --git a/isisd/isis_memory.c b/isisd/isis_memory.c
index f3ecc6cd7a..101fdcc69c 100644
--- a/isisd/isis_memory.c
+++ b/isisd/isis_memory.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
#ifdef HAVE_CONFIG_H
diff --git a/isisd/isis_memory.h b/isisd/isis_memory.h
index 9345229daa..7729ebac33 100644
--- a/isisd/isis_memory.h
+++ b/isisd/isis_memory.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_ISIS_MEMORY_H
diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c
index f19b44155a..3869159a02 100644
--- a/isisd/isis_misc.c
+++ b/isisd/isis_misc.c
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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>
diff --git a/isisd/isis_misc.h b/isisd/isis_misc.h
index 37eaea1549..a71edd8e69 100644
--- a/isisd/isis_misc.h
+++ b/isisd/isis_misc.h
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_MISC_H
diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c
new file mode 100644
index 0000000000..269802e9f8
--- /dev/null
+++ b/isisd/isis_mt.c
@@ -0,0 +1,743 @@
+/*
+ * IS-IS Rout(e)ing protocol - Multi Topology Support
+ *
+ * Copyright (C) 2017 Christian Franke
+ *
+ * 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 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 "isisd/isisd.h"
+#include "isisd/isis_memory.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isis_adjacency.h"
+#include "isisd/isis_tlv.h"
+#include "isisd/isis_misc.h"
+#include "isisd/isis_lsp.h"
+#include "isisd/isis_mt.h"
+
+DEFINE_MTYPE_STATIC(ISISD, MT_AREA_SETTING, "ISIS MT Area Setting")
+DEFINE_MTYPE_STATIC(ISISD, MT_CIRCUIT_SETTING, "ISIS MT Circuit Setting")
+DEFINE_MTYPE_STATIC(ISISD, MT_ADJ_INFO, "ISIS MT Adjacency Info")
+DEFINE_MTYPE_STATIC(ISISD, MT_NEIGHBORS, "ISIS MT Neighbors for TLV")
+DEFINE_MTYPE_STATIC(ISISD, MT_IPV4_REACHS, "ISIS MT IPv4 Reachabilities for TLV")
+DEFINE_MTYPE_STATIC(ISISD, MT_IPV6_REACHS, "ISIS MT IPv6 Reachabilities for TLV")
+
+uint16_t isis_area_ipv6_topology(struct isis_area *area)
+{
+ struct isis_area_mt_setting *area_mt_setting;
+ area_mt_setting = area_lookup_mt_setting(area, ISIS_MT_IPV6_UNICAST);
+
+ if (area_mt_setting && area_mt_setting->enabled)
+ return ISIS_MT_IPV6_UNICAST;
+ return ISIS_MT_IPV4_UNICAST;
+}
+
+/* MT naming api */
+const char *isis_mtid2str(uint16_t mtid)
+{
+ static char buf[sizeof("65535")];
+
+ switch(mtid)
+ {
+ case ISIS_MT_IPV4_UNICAST:
+ return "ipv4-unicast";
+ case ISIS_MT_IPV4_MGMT:
+ return "ipv4-mgmt";
+ case ISIS_MT_IPV6_UNICAST:
+ return "ipv6-unicast";
+ case ISIS_MT_IPV4_MULTICAST:
+ return "ipv4-multicast";
+ case ISIS_MT_IPV6_MULTICAST:
+ return "ipv6-multicast";
+ case ISIS_MT_IPV6_MGMT:
+ return "ipv6-mgmt";
+ default:
+ snprintf(buf, sizeof(buf), "%" PRIu16, mtid);
+ return buf;
+ }
+}
+
+uint16_t isis_str2mtid(const char *name)
+{
+ if (!strcmp(name,"ipv4-unicast"))
+ return ISIS_MT_IPV4_UNICAST;
+ if (!strcmp(name,"ipv4-mgmt"))
+ return ISIS_MT_IPV4_MGMT;
+ if (!strcmp(name,"ipv6-unicast"))
+ return ISIS_MT_IPV6_UNICAST;
+ if (!strcmp(name,"ipv4-multicast"))
+ return ISIS_MT_IPV4_MULTICAST;
+ if (!strcmp(name,"ipv6-multicast"))
+ return ISIS_MT_IPV6_MULTICAST;
+ if (!strcmp(name,"ipv6-mgmt"))
+ return ISIS_MT_IPV6_MGMT;
+ return -1;
+}
+
+/* General MT settings api */
+
+struct mt_setting {
+ ISIS_MT_INFO_FIELDS;
+};
+
+static void *
+lookup_mt_setting(struct list *mt_list, uint16_t mtid)
+{
+ struct listnode *node;
+ struct mt_setting *setting;
+
+ for (ALL_LIST_ELEMENTS_RO(mt_list, node, setting))
+ {
+ if (setting->mtid == mtid)
+ return setting;
+ }
+ return NULL;
+}
+
+static void
+add_mt_setting(struct list **mt_list, void *setting)
+{
+ if (!*mt_list)
+ *mt_list = list_new();
+ listnode_add(*mt_list, setting);
+}
+
+/* Area specific MT settings api */
+
+struct isis_area_mt_setting*
+area_lookup_mt_setting(struct isis_area *area, uint16_t mtid)
+{
+ return lookup_mt_setting(area->mt_settings, mtid);
+}
+
+struct isis_area_mt_setting*
+area_new_mt_setting(struct isis_area *area, uint16_t mtid)
+{
+ struct isis_area_mt_setting *setting;
+
+ setting = XCALLOC(MTYPE_MT_AREA_SETTING, sizeof(*setting));
+ setting->mtid = mtid;
+ return setting;
+}
+
+static void
+area_free_mt_setting(void *setting)
+{
+ XFREE(MTYPE_MT_AREA_SETTING, setting);
+}
+
+void
+area_add_mt_setting(struct isis_area *area, struct isis_area_mt_setting *setting)
+{
+ add_mt_setting(&area->mt_settings, setting);
+}
+
+void
+area_mt_init(struct isis_area *area)
+{
+ struct isis_area_mt_setting *v4_unicast_setting;
+
+ /* MTID 0 is always enabled */
+ v4_unicast_setting = area_new_mt_setting(area, ISIS_MT_IPV4_UNICAST);
+ v4_unicast_setting->enabled = true;
+ add_mt_setting(&area->mt_settings, v4_unicast_setting);
+ area->mt_settings->del = area_free_mt_setting;
+}
+
+void
+area_mt_finish(struct isis_area *area)
+{
+ list_delete(area->mt_settings);
+ area->mt_settings = NULL;
+}
+
+struct isis_area_mt_setting *
+area_get_mt_setting(struct isis_area *area, uint16_t mtid)
+{
+ struct isis_area_mt_setting *setting;
+
+ setting = area_lookup_mt_setting(area, mtid);
+ if (!setting)
+ {
+ setting = area_new_mt_setting(area, mtid);
+ area_add_mt_setting(area, setting);
+ }
+ return setting;
+}
+
+int
+area_write_mt_settings(struct isis_area *area, struct vty *vty)
+{
+ int written = 0;
+ struct listnode *node;
+ struct isis_area_mt_setting *setting;
+
+ for (ALL_LIST_ELEMENTS_RO(area->mt_settings, node, setting))
+ {
+ const char *name = isis_mtid2str(setting->mtid);
+ if (name && setting->enabled)
+ {
+ if (setting->mtid == ISIS_MT_IPV4_UNICAST)
+ continue; /* always enabled, no need to write out config */
+ vty_out (vty, " topology %s%s%s", name,
+ setting->overload ? " overload" : "",
+ VTY_NEWLINE);
+ written++;
+ }
+ }
+ return written;
+}
+
+bool area_is_mt(struct isis_area *area)
+{
+ struct listnode *node, *node2;
+ struct isis_area_mt_setting *setting;
+ struct isis_circuit *circuit;
+ struct isis_circuit_mt_setting *csetting;
+
+ for (ALL_LIST_ELEMENTS_RO(area->mt_settings, node, setting))
+ {
+ if (setting->enabled && setting->mtid != ISIS_MT_IPV4_UNICAST)
+ return true;
+ }
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
+ {
+ for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node2, csetting))
+ {
+ if (!csetting->enabled && csetting->mtid == ISIS_MT_IPV4_UNICAST)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+struct isis_area_mt_setting**
+area_mt_settings(struct isis_area *area, unsigned int *mt_count)
+{
+ static unsigned int size = 0;
+ static struct isis_area_mt_setting **rv = NULL;
+
+ unsigned int count = 0;
+ struct listnode *node;
+ struct isis_area_mt_setting *setting;
+
+ for (ALL_LIST_ELEMENTS_RO(area->mt_settings, node, setting))
+ {
+ if (!setting->enabled)
+ continue;
+
+ count++;
+ if (count > size)
+ {
+ rv = XREALLOC(MTYPE_TMP, rv, count * sizeof(*rv));
+ size = count;
+ }
+ rv[count-1] = setting;
+ }
+
+ *mt_count = count;
+ return rv;
+}
+
+/* Circuit specific MT settings api */
+
+struct isis_circuit_mt_setting*
+circuit_lookup_mt_setting(struct isis_circuit *circuit, uint16_t mtid)
+{
+ return lookup_mt_setting(circuit->mt_settings, mtid);
+}
+
+struct isis_circuit_mt_setting*
+circuit_new_mt_setting(struct isis_circuit *circuit, uint16_t mtid)
+{
+ struct isis_circuit_mt_setting *setting;
+
+ setting = XCALLOC(MTYPE_MT_CIRCUIT_SETTING, sizeof(*setting));
+ setting->mtid = mtid;
+ setting->enabled = true; /* Enabled is default for circuit */
+ return setting;
+}
+
+static void
+circuit_free_mt_setting(void *setting)
+{
+ XFREE(MTYPE_MT_CIRCUIT_SETTING, setting);
+}
+
+void
+circuit_add_mt_setting(struct isis_circuit *circuit,
+ struct isis_circuit_mt_setting *setting)
+{
+ add_mt_setting(&circuit->mt_settings, setting);
+}
+
+void
+circuit_mt_init(struct isis_circuit *circuit)
+{
+ circuit->mt_settings = list_new();
+ circuit->mt_settings->del = circuit_free_mt_setting;
+}
+
+void
+circuit_mt_finish(struct isis_circuit *circuit)
+{
+ list_delete(circuit->mt_settings);
+ circuit->mt_settings = NULL;
+}
+
+struct isis_circuit_mt_setting*
+circuit_get_mt_setting(struct isis_circuit *circuit, uint16_t mtid)
+{
+ struct isis_circuit_mt_setting *setting;
+
+ setting = circuit_lookup_mt_setting(circuit, mtid);
+ if (!setting)
+ {
+ setting = circuit_new_mt_setting(circuit, mtid);
+ circuit_add_mt_setting(circuit, setting);
+ }
+ return setting;
+}
+
+int
+circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty)
+{
+ int written = 0;
+ struct listnode *node;
+ struct isis_circuit_mt_setting *setting;
+
+ for (ALL_LIST_ELEMENTS_RO (circuit->mt_settings, node, setting))
+ {
+ const char *name = isis_mtid2str(setting->mtid);
+ if (name && !setting->enabled)
+ {
+ vty_out (vty, " no isis topology %s%s", name, VTY_NEWLINE);
+ written++;
+ }
+ }
+ return written;
+}
+
+struct isis_circuit_mt_setting**
+circuit_mt_settings(struct isis_circuit *circuit, unsigned int *mt_count)
+{
+ static unsigned int size = 0;
+ static struct isis_circuit_mt_setting **rv = NULL;
+
+ struct isis_area_mt_setting **area_settings;
+ unsigned int area_count;
+
+ unsigned int count = 0;
+
+ struct listnode *node;
+ struct isis_circuit_mt_setting *setting;
+
+ area_settings = area_mt_settings(circuit->area, &area_count);
+
+ for (unsigned int i = 0; i < area_count; i++)
+ {
+ for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node, setting))
+ {
+ if (setting->mtid != area_settings[i]->mtid)
+ continue;
+ break;
+ }
+ if (!setting)
+ setting = circuit_get_mt_setting(circuit, area_settings[i]->mtid);
+
+ if (!setting->enabled)
+ continue;
+
+ count++;
+ if (count > size)
+ {
+ rv = XREALLOC(MTYPE_TMP, rv, count * sizeof(*rv));
+ size = count;
+ }
+ rv[count-1] = setting;
+ }
+
+ *mt_count = count;
+ return rv;
+}
+
+/* ADJ specific MT API */
+static void adj_mt_set(struct isis_adjacency *adj, unsigned int index,
+ uint16_t mtid)
+{
+ if (adj->mt_count < index + 1)
+ {
+ adj->mt_set = XREALLOC(MTYPE_MT_ADJ_INFO, adj->mt_set,
+ (index + 1) * sizeof(*adj->mt_set));
+ adj->mt_count = index + 1;
+ }
+ adj->mt_set[index] = mtid;
+}
+
+bool
+tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable,
+ struct isis_adjacency *adj)
+{
+ struct isis_circuit_mt_setting **mt_settings;
+ unsigned int circuit_mt_count;
+
+ unsigned int intersect_count = 0;
+
+ uint16_t *old_mt_set = NULL;
+ unsigned int old_mt_count;
+
+ old_mt_count = adj->mt_count;
+ if (old_mt_count)
+ {
+ old_mt_set = XCALLOC(MTYPE_TMP, old_mt_count * sizeof(*old_mt_set));
+ memcpy(old_mt_set, adj->mt_set, old_mt_count * sizeof(*old_mt_set));
+ }
+
+ mt_settings = circuit_mt_settings(adj->circuit, &circuit_mt_count);
+ for (unsigned int i = 0; i < circuit_mt_count; i++)
+ {
+ if (!tlvs->mt_router_info)
+ {
+ /* Other end does not have MT enabled */
+ if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST && v4_usable)
+ adj_mt_set(adj, intersect_count++, ISIS_MT_IPV4_UNICAST);
+ }
+ else
+ {
+ struct listnode *node;
+ struct mt_router_info *info;
+ for (ALL_LIST_ELEMENTS_RO(tlvs->mt_router_info, node, info))
+ {
+ if (mt_settings[i]->mtid == info->mtid)
+ {
+ bool usable;
+ switch (info->mtid)
+ {
+ case ISIS_MT_IPV4_UNICAST:
+ case ISIS_MT_IPV4_MGMT:
+ case ISIS_MT_IPV4_MULTICAST:
+ usable = v4_usable;
+ break;
+ case ISIS_MT_IPV6_UNICAST:
+ case ISIS_MT_IPV6_MGMT:
+ case ISIS_MT_IPV6_MULTICAST:
+ usable = v6_usable;
+ break;
+ default:
+ usable = true;
+ break;
+ }
+ if (usable)
+ adj_mt_set(adj, intersect_count++, info->mtid);
+ }
+ }
+ }
+ }
+ adj->mt_count = intersect_count;
+
+ bool changed = false;
+
+ if (adj->mt_count != old_mt_count)
+ changed = true;
+
+ if (!changed && old_mt_count
+ && memcmp(adj->mt_set, old_mt_set,
+ old_mt_count * sizeof(*old_mt_set)))
+ changed = true;
+
+ if (old_mt_count)
+ XFREE(MTYPE_TMP, old_mt_set);
+
+ return changed;
+}
+
+bool
+adj_has_mt(struct isis_adjacency *adj, uint16_t mtid)
+{
+ for (unsigned int i = 0; i < adj->mt_count; i++)
+ if (adj->mt_set[i] == mtid)
+ return true;
+ return false;
+}
+
+void
+adj_mt_finish(struct isis_adjacency *adj)
+{
+ XFREE(MTYPE_MT_ADJ_INFO, adj->mt_set);
+ adj->mt_count = 0;
+}
+
+/* TLV Router info api */
+struct mt_router_info*
+tlvs_lookup_mt_router_info(struct tlvs *tlvs, uint16_t mtid)
+{
+ return lookup_mt_setting(tlvs->mt_router_info, mtid);
+}
+
+/* TLV MT Neighbors api */
+struct tlv_mt_neighbors*
+tlvs_lookup_mt_neighbors(struct tlvs *tlvs, uint16_t mtid)
+{
+ return lookup_mt_setting(tlvs->mt_is_neighs, mtid);
+}
+
+static struct tlv_mt_neighbors*
+tlvs_new_mt_neighbors(uint16_t mtid)
+{
+ struct tlv_mt_neighbors *rv;
+
+ rv = XCALLOC(MTYPE_MT_NEIGHBORS, sizeof(*rv));
+ rv->mtid = mtid;
+ rv->list = list_new();
+
+ return rv;
+};
+
+static void
+tlvs_free_mt_neighbors(void *arg)
+{
+ struct tlv_mt_neighbors *neighbors = arg;
+
+ if (neighbors && neighbors->list)
+ list_delete(neighbors->list);
+ XFREE(MTYPE_MT_NEIGHBORS, neighbors);
+}
+
+static void
+tlvs_add_mt_neighbors(struct tlvs *tlvs, struct tlv_mt_neighbors *neighbors)
+{
+ add_mt_setting(&tlvs->mt_is_neighs, neighbors);
+ tlvs->mt_is_neighs->del = tlvs_free_mt_neighbors;
+}
+
+struct tlv_mt_neighbors*
+tlvs_get_mt_neighbors(struct tlvs *tlvs, uint16_t mtid)
+{
+ struct tlv_mt_neighbors *neighbors;
+
+ neighbors = tlvs_lookup_mt_neighbors(tlvs, mtid);
+ if (!neighbors)
+ {
+ neighbors = tlvs_new_mt_neighbors(mtid);
+ tlvs_add_mt_neighbors(tlvs, neighbors);
+ }
+ return neighbors;
+}
+
+/* TLV MT IPv4 reach api */
+struct tlv_mt_ipv4_reachs*
+tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs, uint16_t mtid)
+{
+ return lookup_mt_setting(tlvs->mt_ipv4_reachs, mtid);
+}
+
+static struct tlv_mt_ipv4_reachs*
+tlvs_new_mt_ipv4_reachs(uint16_t mtid)
+{
+ struct tlv_mt_ipv4_reachs *rv;
+
+ rv = XCALLOC(MTYPE_MT_IPV4_REACHS, sizeof(*rv));
+ rv->mtid = mtid;
+ rv->list = list_new();
+
+ return rv;
+};
+
+static void
+tlvs_free_mt_ipv4_reachs(void *arg)
+{
+ struct tlv_mt_ipv4_reachs *reachs = arg;
+
+ if (reachs && reachs->list)
+ list_delete(reachs->list);
+ XFREE(MTYPE_MT_IPV4_REACHS, reachs);
+}
+
+static void
+tlvs_add_mt_ipv4_reachs(struct tlvs *tlvs, struct tlv_mt_ipv4_reachs *reachs)
+{
+ add_mt_setting(&tlvs->mt_ipv4_reachs, reachs);
+ tlvs->mt_ipv4_reachs->del = tlvs_free_mt_ipv4_reachs;
+}
+
+struct tlv_mt_ipv4_reachs*
+tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs, uint16_t mtid)
+{
+ struct tlv_mt_ipv4_reachs *reachs;
+
+ reachs = tlvs_lookup_mt_ipv4_reachs(tlvs, mtid);
+ if (!reachs)
+ {
+ reachs = tlvs_new_mt_ipv4_reachs(mtid);
+ tlvs_add_mt_ipv4_reachs(tlvs, reachs);
+ }
+ return reachs;
+}
+
+/* TLV MT IPv6 reach api */
+struct tlv_mt_ipv6_reachs*
+tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs, uint16_t mtid)
+{
+ return lookup_mt_setting(tlvs->mt_ipv6_reachs, mtid);
+}
+
+static struct tlv_mt_ipv6_reachs*
+tlvs_new_mt_ipv6_reachs(uint16_t mtid)
+{
+ struct tlv_mt_ipv6_reachs *rv;
+
+ rv = XCALLOC(MTYPE_MT_IPV6_REACHS, sizeof(*rv));
+ rv->mtid = mtid;
+ rv->list = list_new();
+
+ return rv;
+};
+
+static void
+tlvs_free_mt_ipv6_reachs(void *arg)
+{
+ struct tlv_mt_ipv6_reachs *reachs = arg;
+
+ if (reachs && reachs->list)
+ list_delete(reachs->list);
+ XFREE(MTYPE_MT_IPV6_REACHS, reachs);
+}
+
+static void
+tlvs_add_mt_ipv6_reachs(struct tlvs *tlvs, struct tlv_mt_ipv6_reachs *reachs)
+{
+ add_mt_setting(&tlvs->mt_ipv6_reachs, reachs);
+ tlvs->mt_ipv6_reachs->del = tlvs_free_mt_ipv6_reachs;
+}
+
+struct tlv_mt_ipv6_reachs*
+tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs, uint16_t mtid)
+{
+ struct tlv_mt_ipv6_reachs *reachs;
+
+ reachs = tlvs_lookup_mt_ipv6_reachs(tlvs, mtid);
+ if (!reachs)
+ {
+ reachs = tlvs_new_mt_ipv6_reachs(mtid);
+ tlvs_add_mt_ipv6_reachs(tlvs, reachs);
+ }
+ return reachs;
+}
+
+static void
+mt_set_add(uint16_t **mt_set, unsigned int *size,
+ unsigned int *index, uint16_t mtid)
+{
+ for (unsigned int i = 0; i < *index; i++)
+ {
+ if ((*mt_set)[i] == mtid)
+ return;
+ }
+
+ if (*index >= *size)
+ {
+ *mt_set = XREALLOC(MTYPE_TMP, *mt_set, sizeof(**mt_set) * ((*index) + 1));
+ *size = (*index) + 1;
+ }
+
+ (*mt_set)[*index] = mtid;
+ *index = (*index) + 1;
+}
+
+static uint16_t *
+circuit_bcast_mt_set(struct isis_circuit *circuit, int level,
+ unsigned int *mt_count)
+{
+ static uint16_t *rv;
+ static unsigned int size;
+ struct listnode *node;
+ struct isis_adjacency *adj;
+
+ unsigned int count = 0;
+
+ if (circuit->circ_type != CIRCUIT_T_BROADCAST)
+ {
+ *mt_count = 0;
+ return NULL;
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(circuit->u.bc.adjdb[level - 1], node, adj))
+ {
+ if (adj->adj_state != ISIS_ADJ_UP)
+ continue;
+ for (unsigned int i = 0; i < adj->mt_count; i++)
+ mt_set_add(&rv, &size, &count, adj->mt_set[i]);
+ }
+
+ *mt_count = count;
+ return rv;
+}
+
+static void
+tlvs_add_mt_set(struct isis_area *area,
+ struct tlvs *tlvs, unsigned int mt_count,
+ uint16_t *mt_set, struct te_is_neigh *neigh)
+{
+ for (unsigned int i = 0; i < mt_count; i++)
+ {
+ uint16_t mtid = mt_set[i];
+ struct te_is_neigh *ne_copy;
+
+ ne_copy = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ne_copy));
+ memcpy(ne_copy, neigh, sizeof(*ne_copy));
+
+ if (mt_set[i] == ISIS_MT_IPV4_UNICAST)
+ {
+ listnode_add(tlvs->te_is_neighs, ne_copy);
+ lsp_debug("ISIS (%s): Adding %s.%02x as te-style neighbor",
+ area->area_tag, sysid_print(ne_copy->neigh_id),
+ LSP_PSEUDO_ID(ne_copy->neigh_id));
+ }
+ else
+ {
+ struct tlv_mt_neighbors *neighbors;
+
+ neighbors = tlvs_get_mt_neighbors(tlvs, mtid);
+ neighbors->list->del = free_tlv;
+ listnode_add(neighbors->list, ne_copy);
+ lsp_debug("ISIS (%s): Adding %s.%02x as mt-style neighbor for %s",
+ area->area_tag, sysid_print(ne_copy->neigh_id),
+ LSP_PSEUDO_ID(ne_copy->neigh_id), isis_mtid2str(mtid));
+ }
+ }
+}
+
+void
+tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit,
+ int level, struct te_is_neigh *neigh)
+{
+ unsigned int mt_count;
+ uint16_t *mt_set = circuit_bcast_mt_set(circuit, level,
+ &mt_count);
+
+ tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, neigh);
+}
+
+void
+tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit,
+ struct te_is_neigh *neigh)
+{
+ struct isis_adjacency *adj = circuit->u.p2p.neighbor;
+
+ tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, neigh);
+}
diff --git a/isisd/isis_mt.h b/isisd/isis_mt.h
new file mode 100644
index 0000000000..e90f1756ff
--- /dev/null
+++ b/isisd/isis_mt.h
@@ -0,0 +1,145 @@
+/*
+ * IS-IS Rout(e)ing protocol - Multi Topology Support
+ *
+ * Copyright (C) 2017 Christian Franke
+ *
+ * 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 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 ISIS_MT_H
+#define ISIS_MT_H
+
+#define ISIS_MT_MASK 0x0fff
+#define ISIS_MT_OL_MASK 0x8000
+
+#define ISIS_MT_IPV4_UNICAST 0
+#define ISIS_MT_IPV4_MGMT 1
+#define ISIS_MT_IPV6_UNICAST 2
+#define ISIS_MT_IPV4_MULTICAST 3
+#define ISIS_MT_IPV6_MULTICAST 4
+#define ISIS_MT_IPV6_MGMT 5
+
+#define ISIS_MT_NAMES \
+ "<ipv4-unicast" \
+ "|ipv4-mgmt" \
+ "|ipv6-unicast" \
+ "|ipv4-multicast" \
+ "|ipv6-multicast" \
+ "|ipv6-mgmt" \
+ ">"
+
+#define ISIS_MT_DESCRIPTIONS \
+ "IPv4 unicast topology\n" \
+ "IPv4 management topology\n" \
+ "IPv6 unicast topology\n" \
+ "IPv4 multicast topology\n" \
+ "IPv6 multicast topology\n" \
+ "IPv6 management topology\n"
+
+#define ISIS_MT_INFO_FIELDS \
+ uint16_t mtid;
+
+struct list;
+
+struct isis_area_mt_setting {
+ ISIS_MT_INFO_FIELDS
+ bool enabled;
+ bool overload;
+};
+
+struct isis_circuit_mt_setting {
+ ISIS_MT_INFO_FIELDS
+ bool enabled;
+};
+
+struct tlv_mt_neighbors {
+ ISIS_MT_INFO_FIELDS
+ struct list *list;
+};
+
+struct tlv_mt_ipv4_reachs {
+ ISIS_MT_INFO_FIELDS
+ struct list *list;
+};
+
+struct tlv_mt_ipv6_reachs {
+ ISIS_MT_INFO_FIELDS
+ struct list *list;
+};
+
+const char *isis_mtid2str(uint16_t mtid);
+uint16_t isis_str2mtid(const char *name);
+
+struct isis_adjacency;
+struct isis_area;
+struct isis_circuit;
+struct tlvs;
+struct te_is_neigh;
+
+uint16_t isis_area_ipv6_topology(struct isis_area *area);
+
+struct mt_router_info* tlvs_lookup_mt_router_info(struct tlvs *tlvs, uint16_t mtid);
+
+struct tlv_mt_neighbors* tlvs_lookup_mt_neighbors(struct tlvs *tlvs, uint16_t mtid);
+struct tlv_mt_neighbors* tlvs_get_mt_neighbors(struct tlvs *tlvs, uint16_t mtid);
+
+struct tlv_mt_ipv4_reachs* tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs, uint16_t mtid);
+struct tlv_mt_ipv4_reachs* tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs, uint16_t mtid);
+
+struct tlv_mt_ipv6_reachs* tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs, uint16_t mtid);
+struct tlv_mt_ipv6_reachs* tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs, uint16_t mtid);
+
+struct isis_area_mt_setting* area_lookup_mt_setting(struct isis_area *area,
+ uint16_t mtid);
+struct isis_area_mt_setting* area_new_mt_setting(struct isis_area *area,
+ uint16_t mtid);
+void area_add_mt_setting(struct isis_area *area,
+ struct isis_area_mt_setting *setting);
+
+void area_mt_init(struct isis_area *area);
+void area_mt_finish(struct isis_area *area);
+struct isis_area_mt_setting* area_get_mt_setting(struct isis_area *area,
+ uint16_t mtid);
+int area_write_mt_settings(struct isis_area *area, struct vty *vty);
+bool area_is_mt(struct isis_area *area);
+struct isis_area_mt_setting** area_mt_settings(struct isis_area *area,
+ unsigned int *mt_count);
+
+struct isis_circuit_mt_setting* circuit_lookup_mt_setting(
+ struct isis_circuit *circuit,
+ uint16_t mtid);
+struct isis_circuit_mt_setting* circuit_new_mt_setting(
+ struct isis_circuit *circuit,
+ uint16_t mtid);
+void circuit_add_mt_setting(struct isis_circuit *circuit,
+ struct isis_circuit_mt_setting *setting);
+void circuit_mt_init(struct isis_circuit *circuit);
+void circuit_mt_finish(struct isis_circuit *circuit);
+struct isis_circuit_mt_setting* circuit_get_mt_setting(
+ struct isis_circuit *circuit,
+ uint16_t mtid);
+int circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty);
+struct isis_circuit_mt_setting** circuit_mt_settings(struct isis_circuit *circuit,
+ unsigned int *mt_count);
+bool tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable,
+ struct isis_adjacency *adj);
+bool adj_has_mt(struct isis_adjacency *adj, uint16_t mtid);
+void adj_mt_finish(struct isis_adjacency *adj);
+void tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit,
+ int level, struct te_is_neigh *neigh);
+void tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit,
+ struct te_is_neigh *neigh);
+#endif
diff --git a/isisd/isis_network.h b/isisd/isis_network.h
index e1e10dfdb8..41788e69fa 100644
--- a/isisd/isis_network.h
+++ b/isisd/isis_network.h
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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
*/
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index a41581ff02..69beade477 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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>
@@ -53,6 +53,7 @@
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"
#include "isisd/isis_te.h"
+#include "isisd/isis_mt.h"
#define ISIS_MINIMUM_FIXED_HDR_LEN 15
#define ISIS_MIN_PDU_LEN 13 /* partial seqnum pdu with id_len=2 */
@@ -61,11 +62,6 @@
#define PNBBY 8
#endif /* PNBBY */
-/* Utility mask array. */
-static const u_char maskbit[] = {
- 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
-};
-
/*
* HELPER FUNCS
*/
@@ -93,69 +89,6 @@ area_match (struct list *left, struct list *right)
}
/*
- * Check if ip2 is in the ip1's network (function like Prefix.h:prefix_match() )
- * param ip1 the IS interface ip address structure
- * param ip2 the IIH's ip address
- * return 0 the IIH's IP is not in the IS's subnetwork
- * 1 the IIH's IP is in the IS's subnetwork
- */
-static int
-ip_same_subnet (struct prefix_ipv4 *ip1, struct in_addr *ip2)
-{
- u_char *addr1, *addr2;
- int shift, offset, offsetloop;
- int len;
-
- addr1 = (u_char *) & ip1->prefix.s_addr;
- addr2 = (u_char *) & ip2->s_addr;
- len = ip1->prefixlen;
-
- shift = len % PNBBY;
- offsetloop = offset = len / PNBBY;
-
- while (offsetloop--)
- if (addr1[offsetloop] != addr2[offsetloop])
- return 0;
-
- if (shift)
- if (maskbit[shift] & (addr1[offset] ^ addr2[offset]))
- return 0;
-
- return 1; /* match */
-}
-
-/*
- * Compares two set of ip addresses
- * param left the local interface's ip addresses
- * param right the iih interface's ip address
- * return 0 no match;
- * 1 match;
- */
-static int
-ip_match (struct list *left, struct list *right)
-{
- struct prefix_ipv4 *ip1;
- struct in_addr *ip2;
- struct listnode *node1, *node2;
-
- if ((left == NULL) || (right == NULL))
- return 0;
-
- for (ALL_LIST_ELEMENTS_RO (left, node1, ip1))
- {
- for (ALL_LIST_ELEMENTS_RO (right, node2, ip2))
- {
- if (ip_same_subnet (ip1, ip2))
- {
- return 1; /* match */
- }
- }
-
- }
- return 0;
-}
-
-/*
* Checks whether we should accept a PDU of given level
*/
static int
@@ -471,6 +404,7 @@ process_p2p_hello (struct isis_circuit *circuit)
expected |= TLVFLAG_NLPID;
expected |= TLVFLAG_IPV4_ADDR;
expected |= TLVFLAG_IPV6_ADDR;
+ expected |= TLVFLAG_MT_ROUTER_INFORMATION;
auth_tlv_offset = stream_get_getp (circuit->rcv_stream);
retval = parse_tlvs (circuit->area->area_tag,
@@ -515,16 +449,14 @@ process_p2p_hello (struct isis_circuit *circuit)
}
/*
- * check if it's own interface ip match iih ip addrs
+ * check if both ends have an IPv4 address
*/
- if (found & TLVFLAG_IPV4_ADDR)
+ if (circuit->ip_addrs && listcount(circuit->ip_addrs)
+ && tlvs.ipv4_addrs && listcount(tlvs.ipv4_addrs))
{
- if (ip_match (circuit->ip_addrs, tlvs.ipv4_addrs))
- v4_usable = 1;
- else
- zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap "
- "in P2P IIH from %s\n", circuit->interface->name);
+ v4_usable = 1;
}
+
if (found & TLVFLAG_IPV6_ADDR)
{
/* TBA: check that we have a linklocal ourselves? */
@@ -633,10 +565,12 @@ process_p2p_hello (struct isis_circuit *circuit)
if (found & TLVFLAG_IPV6_ADDR)
tlvs_to_adj_ipv6_addrs (&tlvs, adj);
+ bool mt_set_changed = tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj);
+
/* lets take care of the expiry */
THREAD_TIMER_OFF (adj->t_expire);
- THREAD_TIMER_ON (master, adj->t_expire, isis_adj_expire, adj,
- (long) adj->hold_time);
+ thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
+ &adj->t_expire);
/* 8.2.5.2 a) a match was detected */
if (area_match (circuit->area->area_addrs, tlvs.area_addrs))
@@ -869,6 +803,13 @@ process_p2p_hello (struct isis_circuit *circuit)
/* down - area mismatch */
isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch");
}
+
+ if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed)
+ {
+ lsp_regenerate_schedule(adj->circuit->area,
+ isis_adj_usage2levels(adj->adj_usage), 0);
+ }
+
/* 8.2.5.2 c) if the action was up - comparing circuit IDs */
/* FIXME - Missing parts */
@@ -1021,6 +962,7 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
expected |= TLVFLAG_NLPID;
expected |= TLVFLAG_IPV4_ADDR;
expected |= TLVFLAG_IPV6_ADDR;
+ expected |= TLVFLAG_MT_ROUTER_INFORMATION;
auth_tlv_offset = stream_get_getp (circuit->rcv_stream);
retval = parse_tlvs (circuit->area->area_tag,
@@ -1104,16 +1046,14 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
}
/*
- * check if it's own interface ip match iih ip addrs
+ * check if both ends have an IPv4 address
*/
- if (found & TLVFLAG_IPV4_ADDR)
+ if (circuit->ip_addrs && listcount(circuit->ip_addrs)
+ && tlvs.ipv4_addrs && listcount(tlvs.ipv4_addrs))
{
- if (ip_match (circuit->ip_addrs, tlvs.ipv4_addrs))
- v4_usable = 1;
- else
- zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap "
- "in LAN IIH from %s\n", circuit->interface->name);
+ v4_usable = 1;
}
+
if (found & TLVFLAG_IPV6_ADDR)
{
/* TBA: check that we have a linklocal ourselves? */
@@ -1184,7 +1124,8 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
case 1:
if (memcmp (circuit->u.bc.l1_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1))
{
- thread_add_event (master, isis_event_dis_status_change, circuit, 0);
+ thread_add_event(master, isis_event_dis_status_change, circuit, 0,
+ NULL);
memcpy (&circuit->u.bc.l1_desig_is, hdr.lan_id,
ISIS_SYS_ID_LEN + 1);
}
@@ -1192,7 +1133,8 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
case 2:
if (memcmp (circuit->u.bc.l2_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1))
{
- thread_add_event (master, isis_event_dis_status_change, circuit, 0);
+ thread_add_event(master, isis_event_dis_status_change, circuit, 0,
+ NULL);
memcpy (&circuit->u.bc.l2_desig_is, hdr.lan_id,
ISIS_SYS_ID_LEN + 1);
}
@@ -1223,10 +1165,12 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
adj->circuit_t = hdr.circuit_t;
+ bool mt_set_changed = tlvs_to_adj_mt_set(&tlvs, v4_usable, v6_usable, adj);
+
/* lets take care of the expiry */
THREAD_TIMER_OFF (adj->t_expire);
- THREAD_TIMER_ON (master, adj->t_expire, isis_adj_expire, adj,
- (long) adj->hold_time);
+ thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
+ &adj->t_expire);
/*
* If the snpa for this circuit is found from LAN Neighbours TLV
@@ -1266,6 +1210,9 @@ process_lan_hello (int level, struct isis_circuit *circuit, const u_char *ssnpa)
"no LAN Neighbours TLV found");
}
+ if (adj->adj_state == ISIS_ADJ_UP && mt_set_changed)
+ lsp_regenerate_schedule(adj->circuit->area, level, 0);
+
out:
if (isis->debugs & DEBUG_ADJ_PACKETS)
{
@@ -2336,6 +2283,37 @@ send_hello (struct isis_circuit *circuit, int level)
if (tlv_add_ip_addrs (circuit->ip_addrs, circuit->snd_stream))
return ISIS_WARNING;
+ /*
+ * MT Supported TLV
+ *
+ * TLV gets included if no topology is enabled on the interface,
+ * if one topology other than #0 is enabled, or if multiple topologies
+ * are enabled.
+ */
+ struct isis_circuit_mt_setting **mt_settings;
+ unsigned int mt_count;
+
+ mt_settings = circuit_mt_settings(circuit, &mt_count);
+ if ((mt_count == 0 && area_is_mt(circuit->area))
+ || (mt_count == 1 && mt_settings[0]->mtid != ISIS_MT_IPV4_UNICAST)
+ || (mt_count > 1))
+ {
+ struct list *mt_info = list_new();
+ mt_info->del = free_tlv;
+
+ for (unsigned int i = 0; i < mt_count; i++)
+ {
+ struct mt_router_info *info;
+
+ info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info));
+ info->mtid = mt_settings[i]->mtid;
+ /* overload info is not valid in IIH, so it's not included here */
+ listnode_add(mt_info, info);
+ }
+ tlv_add_mt_router_info (mt_info, circuit->snd_stream);
+ list_free(mt_info);
+ }
+
/* IPv6 Interface Address TLV */
if (circuit->ipv6_router && circuit->ipv6_link &&
listcount (circuit->ipv6_link) > 0)
@@ -2412,9 +2390,9 @@ send_lan_l1_hello (struct thread *thread)
retval = send_hello (circuit, 1);
/* set next timer thread */
- THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[0],
- send_lan_l1_hello, circuit,
- isis_jitter (circuit->hello_interval[0], IIH_JITTER));
+ thread_add_timer(master, send_lan_l1_hello, circuit,
+ isis_jitter(circuit->hello_interval[0], IIH_JITTER),
+ &circuit->u.bc.t_send_lan_hello[0]);
return retval;
}
@@ -2442,9 +2420,9 @@ send_lan_l2_hello (struct thread *thread)
retval = send_hello (circuit, 2);
/* set next timer thread */
- THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[1],
- send_lan_l2_hello, circuit,
- isis_jitter (circuit->hello_interval[1], IIH_JITTER));
+ thread_add_timer(master, send_lan_l2_hello, circuit,
+ isis_jitter(circuit->hello_interval[1], IIH_JITTER),
+ &circuit->u.bc.t_send_lan_hello[1]);
return retval;
}
@@ -2461,9 +2439,9 @@ send_p2p_hello (struct thread *thread)
send_hello (circuit, 1);
/* set next timer thread */
- THREAD_TIMER_ON (master, circuit->u.p2p.t_send_p2p_hello, send_p2p_hello,
- circuit, isis_jitter (circuit->hello_interval[1],
- IIH_JITTER));
+ thread_add_timer(master, send_p2p_hello, circuit,
+ isis_jitter(circuit->hello_interval[1], IIH_JITTER),
+ &circuit->u.p2p.t_send_p2p_hello);
return ISIS_OK;
}
@@ -2763,8 +2741,9 @@ send_l1_csnp (struct thread *thread)
send_csnp (circuit, 1);
}
/* set next timer thread */
- THREAD_TIMER_ON (master, circuit->t_send_csnp[0], send_l1_csnp, circuit,
- isis_jitter (circuit->csnp_interval[0], CSNP_JITTER));
+ thread_add_timer(master, send_l1_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[0], CSNP_JITTER),
+ &circuit->t_send_csnp[0]);
return retval;
}
@@ -2785,8 +2764,9 @@ send_l2_csnp (struct thread *thread)
send_csnp (circuit, 2);
}
/* set next timer thread */
- THREAD_TIMER_ON (master, circuit->t_send_csnp[1], send_l2_csnp, circuit,
- isis_jitter (circuit->csnp_interval[1], CSNP_JITTER));
+ thread_add_timer(master, send_l2_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[1], CSNP_JITTER),
+ &circuit->t_send_csnp[1]);
return retval;
}
@@ -2988,8 +2968,9 @@ send_l1_psnp (struct thread *thread)
send_psnp (1, circuit);
/* set next timer thread */
- THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
- isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
+ thread_add_timer(master, send_l1_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
+ &circuit->t_send_psnp[0]);
return retval;
}
@@ -3012,8 +2993,9 @@ send_l2_psnp (struct thread *thread)
send_psnp (2, circuit);
/* set next timer thread */
- THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
- isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
+ thread_add_timer(master, send_l2_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
+ &circuit->t_send_psnp[1]);
return retval;
}
diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h
index 3eca731938..e512b6b1b9 100644
--- a/isisd/isis_pdu.h
+++ b/isisd/isis_pdu.h
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_PDU_H
diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c
index dd07a9c6f5..c5985dcd8d 100644
--- a/isisd/isis_pfpacket.c
+++ b/isisd/isis_pfpacket.c
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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>
@@ -371,7 +371,9 @@ isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
stream_set_getp (circuit->snd_stream, 0);
memset (&sa, 0, sizeof (struct sockaddr_ll));
sa.sll_family = AF_PACKET;
- sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
+
+ size_t frame_size = stream_get_endp(circuit->snd_stream) + LLC_LEN;
+ sa.sll_protocol = htons(isis_ethertype(frame_size));
sa.sll_ifindex = circuit->interface->ifindex;
sa.sll_halen = ETH_ALEN;
/* RFC5309 section 4.1 recommends ALL_ISS */
@@ -418,7 +420,6 @@ isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
stream_set_getp (circuit->snd_stream, 0);
memset (&sa, 0, sizeof (struct sockaddr_ll));
sa.sll_family = AF_PACKET;
- sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
sa.sll_ifindex = circuit->interface->ifindex;
sa.sll_halen = ETH_ALEN;
if (level == 1)
diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c
index bdf90aaa1e..b0c065bdf1 100644
--- a/isisd/isis_redist.c
+++ b/isisd/isis_redist.c
@@ -12,10 +12,10 @@
* 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.
+ *
+ * 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>
diff --git a/isisd/isis_redist.h b/isisd/isis_redist.h
index cc9c2e6345..11b3c31e24 100644
--- a/isisd/isis_redist.h
+++ b/isisd/isis_redist.h
@@ -12,10 +12,10 @@
* 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.
+ *
+ * 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 ISIS_REDIST_H
diff --git a/isisd/isis_route.c b/isisd/isis_route.c
index e3256f2d02..bceb70ce03 100644
--- a/isisd/isis_route.c
+++ b/isisd/isis_route.c
@@ -16,10 +16,10 @@
* 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.
+ *
+ * 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>
diff --git a/isisd/isis_route.h b/isisd/isis_route.h
index de23070aa8..24bd786fa7 100644
--- a/isisd/isis_route.h
+++ b/isisd/isis_route.h
@@ -17,10 +17,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_ROUTE_H
#define _ZEBRA_ISIS_ROUTE_H
diff --git a/isisd/isis_routemap.c b/isisd/isis_routemap.c
index 61f3315f08..cf4562dbcd 100644
--- a/isisd/isis_routemap.c
+++ b/isisd/isis_routemap.c
@@ -12,10 +12,10 @@
* 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.
+ *
+ * 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>
diff --git a/isisd/isis_routemap.h b/isisd/isis_routemap.h
index 1cb063feec..b0ff559ac1 100644
--- a/isisd/isis_routemap.h
+++ b/isisd/isis_routemap.h
@@ -12,10 +12,10 @@
* 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.
+ *
+ * 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 ISIS_ROUTEMAP_H
#define ISIS_ROUTEMAP_H
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 554fa563ad..ca268cec7e 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -5,6 +5,7 @@
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
+ * Copyright (C) 2017 Christian Franke <chris@opensourcerouting.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
@@ -15,10 +16,10 @@
* 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.
+ *
+ * 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>
@@ -50,6 +51,14 @@
#include "isis_spf.h"
#include "isis_route.h"
#include "isis_csm.h"
+#include "isis_mt.h"
+
+DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info");
+
+struct isis_spf_run {
+ struct isis_area *area;
+ int level;
+};
/* 7.2.7 */
static void
@@ -142,35 +151,24 @@ vtype2string (enum vertextype vtype)
default:
return "UNKNOWN";
}
- return NULL; /* Not reached */
+ return NULL; /* Not reached */
}
static const char *
vid2string (struct isis_vertex *vertex, char * buff, int size)
{
- switch (vertex->type)
+ if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type))
{
- case VTYPE_PSEUDO_IS:
- case VTYPE_PSEUDO_TE_IS:
- return print_sys_hostname (vertex->N.id);
- break;
- case VTYPE_NONPSEUDO_IS:
- case VTYPE_NONPSEUDO_TE_IS:
- case VTYPE_ES:
return print_sys_hostname (vertex->N.id);
- break;
- case VTYPE_IPREACH_INTERNAL:
- case VTYPE_IPREACH_EXTERNAL:
- case VTYPE_IPREACH_TE:
- case VTYPE_IP6REACH_INTERNAL:
- case VTYPE_IP6REACH_EXTERNAL:
+ }
+
+ if (VTYPE_IP(vertex->type))
+ {
prefix2str ((struct prefix *) &vertex->N.prefix, buff, size);
- break;
- default:
- return "UNKNOWN";
+ return buff;
}
- return (char *) buff;
+ return "UNKNOWN";
}
static struct isis_vertex *
@@ -181,26 +179,17 @@ isis_vertex_new (void *id, enum vertextype vtype)
vertex = XCALLOC (MTYPE_ISIS_VERTEX, sizeof (struct isis_vertex));
vertex->type = vtype;
- switch (vtype)
+
+ if (VTYPE_IS(vtype) || VTYPE_ES(vtype))
{
- case VTYPE_ES:
- case VTYPE_NONPSEUDO_IS:
- case VTYPE_NONPSEUDO_TE_IS:
- memcpy (vertex->N.id, (u_char *) id, ISIS_SYS_ID_LEN);
- break;
- case VTYPE_PSEUDO_IS:
- case VTYPE_PSEUDO_TE_IS:
memcpy (vertex->N.id, (u_char *) id, ISIS_SYS_ID_LEN + 1);
- break;
- case VTYPE_IPREACH_INTERNAL:
- case VTYPE_IPREACH_EXTERNAL:
- case VTYPE_IPREACH_TE:
- case VTYPE_IP6REACH_INTERNAL:
- case VTYPE_IP6REACH_EXTERNAL:
- memcpy (&vertex->N.prefix, (struct prefix *) id,
- sizeof (struct prefix));
- break;
- default:
+ }
+ else if (VTYPE_IP(vtype))
+ {
+ memcpy (&vertex->N.prefix, (struct prefix *) id, sizeof (struct prefix));
+ }
+ else
+ {
zlog_err ("WTF!");
}
@@ -280,7 +269,7 @@ isis_spftree_del (struct isis_spftree *spftree)
return;
}
-void
+static void
isis_spftree_adj_del (struct isis_spftree *spftree, struct isis_adjacency *adj)
{
struct listnode *node;
@@ -394,23 +383,24 @@ isis_root_system_lsp (struct isis_area *area, int level, u_char *sysid)
* Add this IS to the root of SPT
*/
static struct isis_vertex *
-isis_spf_add_root (struct isis_spftree *spftree, int level, u_char *sysid)
+isis_spf_add_root (struct isis_spftree *spftree, u_char *sysid)
{
struct isis_vertex *vertex;
struct isis_lsp *lsp;
#ifdef EXTREME_DEBUG
char buff[PREFIX2STR_BUFFER];
#endif /* EXTREME_DEBUG */
+ u_char id[ISIS_SYS_ID_LEN + 1];
- lsp = isis_root_system_lsp (spftree->area, level, sysid);
- if (lsp == NULL)
- zlog_warn ("ISIS-Spf: could not find own l%d LSP!", level);
+ memcpy(id, sysid, ISIS_SYS_ID_LEN);
+ LSP_PSEUDO_ID(id) = 0;
- if (!spftree->area->oldmetric)
- vertex = isis_vertex_new (sysid, VTYPE_NONPSEUDO_TE_IS);
- else
- vertex = isis_vertex_new (sysid, VTYPE_NONPSEUDO_IS);
+ lsp = isis_root_system_lsp (spftree->area, spftree->level, sysid);
+ if (lsp == NULL)
+ zlog_warn ("ISIS-Spf: could not find own l%d LSP!", spftree->level);
+ vertex = isis_vertex_new (id, spftree->area->oldmetric ? VTYPE_NONPSEUDO_IS
+ : VTYPE_NONPSEUDO_TE_IS);
listnode_add (spftree->paths, vertex);
#ifdef EXTREME_DEBUG
@@ -432,44 +422,51 @@ isis_find_vertex (struct list *list, void *id, enum vertextype vtype)
for (ALL_LIST_ELEMENTS_RO (list, node, vertex))
{
if (vertex->type != vtype)
- continue;
- switch (vtype)
- {
- case VTYPE_ES:
- case VTYPE_NONPSEUDO_IS:
- case VTYPE_NONPSEUDO_TE_IS:
- if (memcmp ((u_char *) id, vertex->N.id, ISIS_SYS_ID_LEN) == 0)
- return vertex;
- break;
- case VTYPE_PSEUDO_IS:
- case VTYPE_PSEUDO_TE_IS:
- if (memcmp ((u_char *) id, vertex->N.id, ISIS_SYS_ID_LEN + 1) == 0)
- return vertex;
- break;
- case VTYPE_IPREACH_INTERNAL:
- case VTYPE_IPREACH_EXTERNAL:
- case VTYPE_IPREACH_TE:
- case VTYPE_IP6REACH_INTERNAL:
- case VTYPE_IP6REACH_EXTERNAL:
- p1 = (struct prefix *) id;
- p2 = (struct prefix *) &vertex->N.id;
- if (p1->family == p2->family && p1->prefixlen == p2->prefixlen &&
- memcmp (&p1->u.prefix, &p2->u.prefix,
- PSIZE (p1->prefixlen)) == 0)
- return vertex;
- break;
- }
+ continue;
+ if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type))
+ {
+ if (memcmp ((u_char *) id, vertex->N.id, ISIS_SYS_ID_LEN + 1) == 0)
+ return vertex;
+ }
+ if (VTYPE_IP(vertex->type))
+ {
+ p1 = (struct prefix *) id;
+ p2 = (struct prefix *) &vertex->N.id;
+ if (p1->family == p2->family
+ && p1->prefixlen == p2->prefixlen
+ && !memcmp(&p1->u.prefix, &p2->u.prefix, PSIZE (p1->prefixlen)))
+ {
+ return vertex;
+ }
+ }
}
return NULL;
}
/*
+ * Compares vertizes for sorting in the TENT list. Returns true
+ * if candidate should be considered before current, false otherwise.
+ */
+static bool
+tent_cmp (struct isis_vertex *current, struct isis_vertex *candidate)
+{
+ if (current->d_N > candidate->d_N)
+ return true;
+
+ if (current->d_N == candidate->d_N
+ && current->type > candidate->type)
+ return true;
+
+ return false;
+}
+
+/*
* Add a vertex to TENT sorted by cost and by vertextype on tie break situation
*/
static struct isis_vertex *
isis_spf_add2tent (struct isis_spftree *spftree, enum vertextype vtype,
- void *id, uint32_t cost, int depth, int family,
+ void *id, uint32_t cost, int depth,
struct isis_adjacency *adj, struct isis_vertex *parent)
{
struct isis_vertex *vertex, *v;
@@ -515,17 +512,11 @@ isis_spf_add2tent (struct isis_spftree *spftree, enum vertextype vtype,
for (node = listhead (spftree->tents); node; node = listnextnode (node))
{
v = listgetdata (node);
- if (v->d_N > vertex->d_N)
- {
- listnode_add_before (spftree->tents, node, vertex);
- break;
- }
- else if (v->d_N == vertex->d_N && v->type > vertex->type)
- {
- /* Tie break, add according to type */
+ if (tent_cmp(v, vertex))
+ {
listnode_add_before (spftree->tents, node, vertex);
- break;
- }
+ break;
+ }
}
if (node == NULL)
@@ -537,7 +528,7 @@ isis_spf_add2tent (struct isis_spftree *spftree, enum vertextype vtype,
static void
isis_spf_add_local (struct isis_spftree *spftree, enum vertextype vtype,
void *id, struct isis_adjacency *adj, uint32_t cost,
- int family, struct isis_vertex *parent)
+ struct isis_vertex *parent)
{
struct isis_vertex *vertex;
@@ -576,13 +567,13 @@ isis_spf_add_local (struct isis_spftree *spftree, enum vertextype vtype,
}
}
- isis_spf_add2tent (spftree, vtype, id, cost, 1, family, adj, parent);
+ isis_spf_add2tent (spftree, vtype, id, cost, 1, adj, parent);
return;
}
static void
process_N (struct isis_spftree *spftree, enum vertextype vtype, void *id,
- uint32_t dist, uint16_t depth, int family,
+ uint32_t dist, uint16_t depth,
struct isis_vertex *parent)
{
struct isis_vertex *vertex;
@@ -670,7 +661,7 @@ process_N (struct isis_spftree *spftree, enum vertextype vtype, void *id,
(parent ? print_sys_hostname (parent->N.id) : "null"));
#endif /* EXTREME_DEBUG */
- isis_spf_add2tent (spftree, vtype, id, dist, depth, family, NULL, parent);
+ isis_spf_add2tent (spftree, vtype, id, dist, depth, NULL, parent);
return;
}
@@ -679,9 +670,10 @@ process_N (struct isis_spftree *spftree, enum vertextype vtype, void *id,
*/
static int
isis_spf_process_lsp (struct isis_spftree *spftree, struct isis_lsp *lsp,
- uint32_t cost, uint16_t depth, int family,
+ uint32_t cost, uint16_t depth,
u_char *root_sysid, struct isis_vertex *parent)
{
+ bool pseudo_lsp = LSP_PSEUDO_ID(lsp->lsp_header->lsp_id);
struct listnode *node, *fragnode = NULL;
uint32_t dist;
struct is_neigh *is_neigh;
@@ -692,8 +684,14 @@ isis_spf_process_lsp (struct isis_spftree *spftree, struct isis_lsp *lsp,
struct prefix prefix;
struct ipv6_reachability *ip6reach;
static const u_char null_sysid[ISIS_SYS_ID_LEN];
+ struct mt_router_info *mt_router_info = NULL;
- if (!speaks (lsp->tlv_data.nlpids, family))
+ if (spftree->mtid != ISIS_MT_IPV4_UNICAST)
+ mt_router_info = tlvs_lookup_mt_router_info(&lsp->tlv_data, spftree->mtid);
+
+ if (!pseudo_lsp
+ && (spftree->mtid == ISIS_MT_IPV4_UNICAST && !speaks(lsp->tlv_data.nlpids, spftree->family))
+ && !mt_router_info)
return ISIS_OK;
lspfragloop:
@@ -707,9 +705,13 @@ lspfragloop:
zlog_debug ("ISIS-Spf: process_lsp %s", print_sys_hostname(lsp->lsp_header->lsp_id));
#endif /* EXTREME_DEBUG */
- if (!ISIS_MASK_LSP_OL_BIT (lsp->lsp_header->lsp_bits))
+ /* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */
+ if (pseudo_lsp
+ || (spftree->mtid == ISIS_MT_IPV4_UNICAST && !ISIS_MASK_LSP_OL_BIT (lsp->lsp_header->lsp_bits))
+ || (mt_router_info && !mt_router_info->overload))
+
{
- if (lsp->tlv_data.is_neighs)
+ if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST)
{
for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.is_neighs, node, is_neigh))
{
@@ -717,95 +719,126 @@ lspfragloop:
/* Two way connectivity */
if (!memcmp (is_neigh->neigh_id, root_sysid, ISIS_SYS_ID_LEN))
continue;
- if (!memcmp (is_neigh->neigh_id, null_sysid, ISIS_SYS_ID_LEN))
+ if (!pseudo_lsp && !memcmp (is_neigh->neigh_id, null_sysid, ISIS_SYS_ID_LEN))
continue;
dist = cost + is_neigh->metrics.metric_default;
- vtype = LSP_PSEUDO_ID (is_neigh->neigh_id) ? VTYPE_PSEUDO_IS
- : VTYPE_NONPSEUDO_IS;
- process_N (spftree, vtype, (void *) is_neigh->neigh_id, dist,
- depth + 1, family, parent);
+ process_N (spftree, LSP_PSEUDO_ID(is_neigh->neigh_id) ? VTYPE_PSEUDO_IS
+ : VTYPE_NONPSEUDO_IS,
+ (void *) is_neigh->neigh_id, dist, depth + 1, parent);
}
}
- if (lsp->tlv_data.te_is_neighs)
- {
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.te_is_neighs, node,
- te_is_neigh))
+
+ struct list *te_is_neighs = NULL;
+ if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ te_is_neighs = lsp->tlv_data.te_is_neighs;
+ }
+ else
+ {
+ struct tlv_mt_neighbors *mt_neighbors;
+ mt_neighbors = tlvs_lookup_mt_neighbors(&lsp->tlv_data, spftree->mtid);
+ if (mt_neighbors)
+ te_is_neighs = mt_neighbors->list;
+ }
+ for (ALL_LIST_ELEMENTS_RO (te_is_neighs, node, te_is_neigh))
{
if (!memcmp (te_is_neigh->neigh_id, root_sysid, ISIS_SYS_ID_LEN))
continue;
- if (!memcmp (te_is_neigh->neigh_id, null_sysid, ISIS_SYS_ID_LEN))
+ if (!pseudo_lsp && !memcmp (te_is_neigh->neigh_id, null_sysid, ISIS_SYS_ID_LEN))
continue;
dist = cost + GET_TE_METRIC(te_is_neigh);
- vtype = LSP_PSEUDO_ID (te_is_neigh->neigh_id) ? VTYPE_PSEUDO_TE_IS
- : VTYPE_NONPSEUDO_TE_IS;
- process_N (spftree, vtype, (void *) te_is_neigh->neigh_id, dist,
- depth + 1, family, parent);
+ process_N (spftree, LSP_PSEUDO_ID(te_is_neigh->neigh_id) ? VTYPE_PSEUDO_TE_IS
+ : VTYPE_NONPSEUDO_TE_IS,
+ (void *) te_is_neigh->neigh_id, dist, depth + 1, parent);
}
- }
}
- if (family == AF_INET && lsp->tlv_data.ipv4_int_reachs)
- {
- prefix.family = AF_INET;
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv4_int_reachs, node, ipreach))
- {
- dist = cost + ipreach->metrics.metric_default;
- vtype = VTYPE_IPREACH_INTERNAL;
- prefix.u.prefix4 = ipreach->prefix;
- prefix.prefixlen = ip_masklen (ipreach->mask);
- apply_mask (&prefix);
- process_N (spftree, vtype, (void *) &prefix, dist, depth + 1,
- family, parent);
- }
- }
- if (family == AF_INET && lsp->tlv_data.ipv4_ext_reachs)
+ if (!pseudo_lsp
+ && spftree->family == AF_INET
+ && spftree->mtid == ISIS_MT_IPV4_UNICAST)
{
+ struct list *reachs[] = {lsp->tlv_data.ipv4_int_reachs,
+ lsp->tlv_data.ipv4_ext_reachs};
+
prefix.family = AF_INET;
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv4_ext_reachs, node, ipreach))
- {
- dist = cost + ipreach->metrics.metric_default;
- vtype = VTYPE_IPREACH_EXTERNAL;
- prefix.u.prefix4 = ipreach->prefix;
- prefix.prefixlen = ip_masklen (ipreach->mask);
- apply_mask (&prefix);
- process_N (spftree, vtype, (void *) &prefix, dist, depth + 1,
- family, parent);
- }
+ for (unsigned int i = 0; i < array_size(reachs); i++)
+ {
+ vtype = (reachs[i] == lsp->tlv_data.ipv4_int_reachs) ? VTYPE_IPREACH_INTERNAL
+ : VTYPE_IPREACH_EXTERNAL;
+ for (ALL_LIST_ELEMENTS_RO (reachs[i], node, ipreach))
+ {
+ dist = cost + ipreach->metrics.metric_default;
+ prefix.u.prefix4 = ipreach->prefix;
+ prefix.prefixlen = ip_masklen (ipreach->mask);
+ apply_mask (&prefix);
+ process_N (spftree, vtype, (void *) &prefix, dist, depth + 1,
+ parent);
+ }
+ }
}
- if (family == AF_INET && lsp->tlv_data.te_ipv4_reachs)
+
+ if (!pseudo_lsp && spftree->family == AF_INET)
{
+ struct list *ipv4reachs = NULL;
+
+ if (spftree->mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ ipv4reachs = lsp->tlv_data.te_ipv4_reachs;
+ }
+ else
+ {
+ struct tlv_mt_ipv4_reachs *mt_reachs;
+ mt_reachs = tlvs_lookup_mt_ipv4_reachs(&lsp->tlv_data, spftree->mtid);
+ if (mt_reachs)
+ ipv4reachs = mt_reachs->list;
+ }
+
prefix.family = AF_INET;
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.te_ipv4_reachs,
- node, te_ipv4_reach))
+ for (ALL_LIST_ELEMENTS_RO (ipv4reachs, node, te_ipv4_reach))
{
assert ((te_ipv4_reach->control & 0x3F) <= IPV4_MAX_BITLEN);
dist = cost + ntohl (te_ipv4_reach->te_metric);
- vtype = VTYPE_IPREACH_TE;
prefix.u.prefix4 = newprefix2inaddr (&te_ipv4_reach->prefix_start,
te_ipv4_reach->control);
prefix.prefixlen = (te_ipv4_reach->control & 0x3F);
apply_mask (&prefix);
- process_N (spftree, vtype, (void *) &prefix, dist, depth + 1,
- family, parent);
+ process_N (spftree, VTYPE_IPREACH_TE, (void *) &prefix, dist, depth + 1,
+ parent);
}
}
- if (family == AF_INET6 && lsp->tlv_data.ipv6_reachs)
+
+ if (!pseudo_lsp
+ && spftree->family == AF_INET6)
{
+ struct list *ipv6reachs = NULL;
+
+ if (spftree->mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ ipv6reachs = lsp->tlv_data.ipv6_reachs;
+ }
+ else
+ {
+ struct tlv_mt_ipv6_reachs *mt_reachs;
+ mt_reachs = tlvs_lookup_mt_ipv6_reachs(&lsp->tlv_data, spftree->mtid);
+ if (mt_reachs)
+ ipv6reachs = mt_reachs->list;
+ }
+
prefix.family = AF_INET6;
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv6_reachs, node, ip6reach))
+ for (ALL_LIST_ELEMENTS_RO (ipv6reachs, node, ip6reach))
{
assert (ip6reach->prefix_len <= IPV6_MAX_BITLEN);
dist = cost + ntohl(ip6reach->metric);
vtype = (ip6reach->control_info & CTRL_INFO_DISTRIBUTION) ?
- VTYPE_IP6REACH_EXTERNAL : VTYPE_IP6REACH_INTERNAL;
+ VTYPE_IP6REACH_EXTERNAL : VTYPE_IP6REACH_INTERNAL;
prefix.prefixlen = ip6reach->prefix_len;
memcpy (&prefix.u.prefix6.s6_addr, ip6reach->prefix,
PSIZE (ip6reach->prefix_len));
apply_mask (&prefix);
process_N (spftree, vtype, (void *) &prefix, dist, depth + 1,
- family, parent);
+ parent);
}
}
@@ -824,76 +857,8 @@ lspfragloop:
}
static int
-isis_spf_process_pseudo_lsp (struct isis_spftree *spftree,
- struct isis_lsp *lsp, uint32_t cost,
- uint16_t depth, int family,
- u_char *root_sysid,
- struct isis_vertex *parent)
-{
- struct listnode *node, *fragnode = NULL;
- struct is_neigh *is_neigh;
- struct te_is_neigh *te_is_neigh;
- enum vertextype vtype;
- uint32_t dist;
-
-pseudofragloop:
-
- if (lsp->lsp_header->seq_num == 0)
- {
- zlog_warn ("isis_spf_process_pseudo_lsp(): lsp with 0 seq_num"
- " - do not process");
- return ISIS_WARNING;
- }
-
-#ifdef EXTREME_DEBUG
- zlog_debug ("ISIS-Spf: process_pseudo_lsp %s",
- print_sys_hostname(lsp->lsp_header->lsp_id));
-#endif /* EXTREME_DEBUG */
-
- /* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */
-
- if (lsp->tlv_data.is_neighs)
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.is_neighs, node, is_neigh))
- {
- /* Two way connectivity */
- if (!memcmp (is_neigh->neigh_id, root_sysid, ISIS_SYS_ID_LEN))
- continue;
- dist = cost + is_neigh->metrics.metric_default;
- vtype = LSP_PSEUDO_ID (is_neigh->neigh_id) ? VTYPE_PSEUDO_IS
- : VTYPE_NONPSEUDO_IS;
- process_N (spftree, vtype, (void *) is_neigh->neigh_id, dist,
- depth + 1, family, parent);
- }
- if (lsp->tlv_data.te_is_neighs)
- for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.te_is_neighs, node, te_is_neigh))
- {
- /* Two way connectivity */
- if (!memcmp (te_is_neigh->neigh_id, root_sysid, ISIS_SYS_ID_LEN))
- continue;
- dist = cost + GET_TE_METRIC(te_is_neigh);
- vtype = LSP_PSEUDO_ID (te_is_neigh->neigh_id) ? VTYPE_PSEUDO_TE_IS
- : VTYPE_NONPSEUDO_TE_IS;
- process_N (spftree, vtype, (void *) te_is_neigh->neigh_id, dist,
- depth + 1, family, parent);
- }
-
- if (fragnode == NULL)
- fragnode = listhead (lsp->lspu.frags);
- else
- fragnode = listnextnode (fragnode);
-
- if (fragnode)
- {
- lsp = listgetdata (fragnode);
- goto pseudofragloop;
- }
-
- return ISIS_OK;
-}
-
-static int
-isis_spf_preload_tent (struct isis_spftree *spftree, int level,
- int family, u_char *root_sysid,
+isis_spf_preload_tent (struct isis_spftree *spftree,
+ u_char *root_sysid,
struct isis_vertex *parent)
{
struct isis_circuit *circuit;
@@ -908,21 +873,25 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
static u_char null_lsp_id[ISIS_SYS_ID_LEN + 2];
struct prefix_ipv6 *ipv6;
+ struct isis_circuit_mt_setting *circuit_mt;
for (ALL_LIST_ELEMENTS_RO (spftree->area->circuit_list, cnode, circuit))
{
+ circuit_mt = circuit_lookup_mt_setting(circuit, spftree->mtid);
+ if (circuit_mt && !circuit_mt->enabled)
+ continue;
if (circuit->state != C_STATE_UP)
continue;
- if (!(circuit->is_type & level))
+ if (!(circuit->is_type & spftree->level))
continue;
- if (family == AF_INET && !circuit->ip_router)
+ if (spftree->family == AF_INET && !circuit->ip_router)
continue;
- if (family == AF_INET6 && !circuit->ipv6_router)
+ if (spftree->family == AF_INET6 && !circuit->ipv6_router)
continue;
/*
* Add IP(v6) addresses of this circuit
*/
- if (family == AF_INET)
+ if (spftree->family == AF_INET)
{
prefix.family = AF_INET;
for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, ipnode, ipv4))
@@ -931,10 +900,10 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
prefix.prefixlen = ipv4->prefixlen;
apply_mask (&prefix);
isis_spf_add_local (spftree, VTYPE_IPREACH_INTERNAL, &prefix,
- NULL, 0, family, parent);
+ NULL, 0, parent);
}
}
- if (family == AF_INET6)
+ if (spftree->family == AF_INET6)
{
prefix.family = AF_INET6;
for (ALL_LIST_ELEMENTS_RO (circuit->ipv6_non_link, ipnode, ipv6))
@@ -943,7 +912,7 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
prefix.u.prefix6 = ipv6->prefix;
apply_mask (&prefix);
isis_spf_add_local (spftree, VTYPE_IP6REACH_INTERNAL,
- &prefix, NULL, 0, family, parent);
+ &prefix, NULL, 0, parent);
}
}
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
@@ -952,45 +921,48 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
* Add the adjacencies
*/
adj_list = list_new ();
- adjdb = circuit->u.bc.adjdb[level - 1];
+ adjdb = circuit->u.bc.adjdb[spftree->level - 1];
isis_adj_build_up_list (adjdb, adj_list);
if (listcount (adj_list) == 0)
{
list_delete (adj_list);
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug ("ISIS-Spf: no L%d adjacencies on circuit %s",
- level, circuit->interface->name);
+ spftree->level, circuit->interface->name);
continue;
}
for (ALL_LIST_ELEMENTS_RO (adj_list, anode, adj))
{
- if (!speaks (&adj->nlpids, family))
- continue;
+ if (!adj_has_mt(adj, spftree->mtid))
+ continue;
+ if (spftree->mtid == ISIS_MT_IPV4_UNICAST && !speaks (&adj->nlpids, spftree->family))
+ continue;
switch (adj->sys_type)
{
case ISIS_SYSTYPE_ES:
- isis_spf_add_local (spftree, VTYPE_ES, adj->sysid, adj,
- circuit->te_metric[level - 1],
- family, parent);
+ memcpy(lsp_id, adj->sysid, ISIS_SYS_ID_LEN);
+ LSP_PSEUDO_ID (lsp_id) = 0;
+ isis_spf_add_local (spftree, VTYPE_ES, lsp_id, adj,
+ circuit->te_metric[spftree->level - 1],
+ parent);
break;
case ISIS_SYSTYPE_IS:
case ISIS_SYSTYPE_L1_IS:
case ISIS_SYSTYPE_L2_IS:
- isis_spf_add_local (spftree,
- spftree->area->oldmetric ?
- VTYPE_NONPSEUDO_IS :
- VTYPE_NONPSEUDO_TE_IS,
- adj->sysid, adj,
- circuit->te_metric[level - 1],
- family, parent);
memcpy (lsp_id, adj->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID (lsp_id) = 0;
LSP_FRAGMENT (lsp_id) = 0;
- lsp = lsp_search (lsp_id, spftree->area->lspdb[level - 1]);
+ isis_spf_add_local (spftree,
+ spftree->area->oldmetric ? VTYPE_NONPSEUDO_IS
+ : VTYPE_NONPSEUDO_TE_IS,
+ lsp_id, adj,
+ circuit->te_metric[spftree->level - 1],
+ parent);
+ lsp = lsp_search (lsp_id, spftree->area->lspdb[spftree->level - 1]);
if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0)
zlog_warn ("ISIS-Spf: No LSP %s found for IS adjacency "
"L%d on %s (ID %u)",
- rawlspid_print (lsp_id), level,
+ rawlspid_print (lsp_id), spftree->level,
circuit->interface->name, circuit->circuit_id);
break;
case ISIS_SYSTYPE_UNKNOWN:
@@ -1002,7 +974,7 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
/*
* Add the pseudonode
*/
- if (level == 1)
+ if (spftree->level == 1)
memcpy (lsp_id, circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1);
else
memcpy (lsp_id, circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
@@ -1011,55 +983,61 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
{
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug ("ISIS-Spf: No L%d DR on %s (ID %d)",
- level, circuit->interface->name, circuit->circuit_id);
+ spftree->level, circuit->interface->name, circuit->circuit_id);
continue;
}
adj = isis_adj_lookup (lsp_id, adjdb);
/* if no adj, we are the dis or error */
- if (!adj && !circuit->u.bc.is_dr[level - 1])
+ if (!adj && !circuit->u.bc.is_dr[spftree->level - 1])
{
zlog_warn ("ISIS-Spf: No adjacency found from root "
"to L%d DR %s on %s (ID %d)",
- level, rawlspid_print (lsp_id),
+ spftree->level, rawlspid_print (lsp_id),
circuit->interface->name, circuit->circuit_id);
continue;
}
- lsp = lsp_search (lsp_id, spftree->area->lspdb[level - 1]);
+ lsp = lsp_search (lsp_id, spftree->area->lspdb[spftree->level - 1]);
if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0)
{
zlog_warn ("ISIS-Spf: No lsp (%p) found from root "
"to L%d DR %s on %s (ID %d)",
- (void *)lsp, level, rawlspid_print (lsp_id),
+ (void *)lsp, spftree->level, rawlspid_print (lsp_id),
circuit->interface->name, circuit->circuit_id);
continue;
}
- isis_spf_process_pseudo_lsp (spftree, lsp,
- circuit->te_metric[level - 1], 0,
- family, root_sysid, parent);
+ isis_spf_process_lsp (spftree, lsp,
+ circuit->te_metric[spftree->level - 1], 0,
+ root_sysid, parent);
}
else if (circuit->circ_type == CIRCUIT_T_P2P)
{
adj = circuit->u.p2p.neighbor;
if (!adj)
continue;
+ if (!adj_has_mt(adj, spftree->mtid))
+ continue;
switch (adj->sys_type)
{
case ISIS_SYSTYPE_ES:
- isis_spf_add_local (spftree, VTYPE_ES, adj->sysid, adj,
- circuit->te_metric[level - 1], family,
+ memcpy (lsp_id, adj->sysid, ISIS_SYS_ID_LEN);
+ LSP_PSEUDO_ID (lsp_id) = 0;
+ isis_spf_add_local (spftree, VTYPE_ES, lsp_id, adj,
+ circuit->te_metric[spftree->level - 1],
parent);
break;
case ISIS_SYSTYPE_IS:
case ISIS_SYSTYPE_L1_IS:
case ISIS_SYSTYPE_L2_IS:
- if (speaks (&adj->nlpids, family))
+ memcpy (lsp_id, adj->sysid, ISIS_SYS_ID_LEN);
+ LSP_PSEUDO_ID (lsp_id) = 0;
+ LSP_FRAGMENT (lsp_id) = 0;
+ if (spftree->mtid != ISIS_MT_IPV4_UNICAST || speaks (&adj->nlpids, spftree->family))
isis_spf_add_local (spftree,
- spftree->area->oldmetric ?
- VTYPE_NONPSEUDO_IS :
- VTYPE_NONPSEUDO_TE_IS,
- adj->sysid,
- adj, circuit->te_metric[level - 1],
- family, parent);
+ spftree->area->oldmetric ? VTYPE_NONPSEUDO_IS
+ : VTYPE_NONPSEUDO_TE_IS,
+ lsp_id,
+ adj, circuit->te_metric[spftree->level - 1],
+ parent);
break;
case ISIS_SYSTYPE_UNKNOWN:
default:
@@ -1086,8 +1064,7 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
* now we just put the child pointer(s) in place
*/
static void
-add_to_paths (struct isis_spftree *spftree, struct isis_vertex *vertex,
- int level)
+add_to_paths (struct isis_spftree *spftree, struct isis_vertex *vertex)
{
char buff[PREFIX2STR_BUFFER];
@@ -1102,11 +1079,11 @@ add_to_paths (struct isis_spftree *spftree, struct isis_vertex *vertex,
vertex->depth, vertex->d_N);
#endif /* EXTREME_DEBUG */
- if (vertex->type > VTYPE_ES)
+ if (VTYPE_IP(vertex->type))
{
if (listcount (vertex->Adj_N) > 0)
isis_route_create ((struct prefix *) &vertex->N.prefix, vertex->d_N,
- vertex->depth, vertex->Adj_N, spftree->area, level);
+ vertex->depth, vertex->Adj_N, spftree->area, spftree->level);
else if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug ("ISIS-Spf: no adjacencies do not install route for "
"%s depth %d dist %d", vid2string (vertex, buff, sizeof (buff)),
@@ -1117,12 +1094,16 @@ add_to_paths (struct isis_spftree *spftree, struct isis_vertex *vertex,
}
static void
-init_spt (struct isis_spftree *spftree)
+init_spt (struct isis_spftree *spftree, int mtid, int level, int family)
{
spftree->tents->del = spftree->paths->del = (void (*)(void *)) isis_vertex_del;
list_delete_all_node (spftree->tents);
list_delete_all_node (spftree->paths);
spftree->tents->del = spftree->paths->del = NULL;
+
+ spftree->mtid = mtid;
+ spftree->level = level;
+ spftree->family = family;
return;
}
@@ -1139,6 +1120,7 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
struct route_table *table = NULL;
struct timeval time_now;
unsigned long long start_time, end_time;
+ uint16_t mtid;
/* Get time that can't roll backwards. */
monotime(&time_now);
@@ -1160,14 +1142,20 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
isis_route_invalidate_table (area, table);
+ /* We only support ipv4-unicast and ipv6-unicast as topologies for now */
+ if (family == AF_INET6)
+ mtid = isis_area_ipv6_topology(area);
+ else
+ mtid = ISIS_MT_IPV4_UNICAST;
+
/*
* C.2.5 Step 0
*/
- init_spt (spftree);
+ init_spt (spftree, mtid, level, family);
/* a) */
- root_vertex = isis_spf_add_root (spftree, level, sysid);
+ root_vertex = isis_spf_add_root (spftree, sysid);
/* b) */
- retval = isis_spf_preload_tent (spftree, level, family, sysid, root_vertex);
+ retval = isis_spf_preload_tent (spftree, sysid, root_vertex);
if (retval != ISIS_OK)
{
zlog_warn ("ISIS-Spf: failed to load TENT SPF-root:%s", print_sys_hostname(sysid));
@@ -1196,37 +1184,22 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
/* Remove from tent list and add to paths list */
list_delete_node (spftree->tents, node);
- add_to_paths (spftree, vertex, level);
- switch (vertex->type)
+ add_to_paths (spftree, vertex);
+ if (VTYPE_IS(vertex->type))
{
- case VTYPE_PSEUDO_IS:
- case VTYPE_NONPSEUDO_IS:
- case VTYPE_PSEUDO_TE_IS:
- case VTYPE_NONPSEUDO_TE_IS:
memcpy (lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT (lsp_id) = 0;
lsp = lsp_search (lsp_id, area->lspdb[level - 1]);
if (lsp && lsp->lsp_header->rem_lifetime != 0)
{
- if (LSP_PSEUDO_ID (lsp_id))
- {
- isis_spf_process_pseudo_lsp (spftree, lsp, vertex->d_N,
- vertex->depth, family, sysid,
- vertex);
- }
- else
- {
- isis_spf_process_lsp (spftree, lsp, vertex->d_N,
- vertex->depth, family, sysid, vertex);
- }
+ isis_spf_process_lsp (spftree, lsp, vertex->d_N,
+ vertex->depth, sysid, vertex);
}
else
{
zlog_warn ("ISIS-Spf: No LSP found for %s",
rawlspid_print (lsp_id));
}
- break;
- default:;
}
}
@@ -1243,17 +1216,17 @@ out:
}
static int
-isis_run_spf_l1 (struct thread *thread)
+isis_run_spf_cb (struct thread *thread)
{
- struct isis_area *area;
+ struct isis_spf_run *run = THREAD_ARG (thread);
+ struct isis_area *area = run->area;
+ int level = run->level;
int retval = ISIS_OK;
- area = THREAD_ARG (thread);
- assert (area);
-
- area->spf_timer[0] = NULL;
+ XFREE(MTYPE_ISIS_SPF_RUN, run);
+ area->spf_timer[level - 1] = NULL;
- if (!(area->is_type & IS_LEVEL_1))
+ if (!(area->is_type & level))
{
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_warn ("ISIS-SPF (%s) area does not share level",
@@ -1262,43 +1235,26 @@ isis_run_spf_l1 (struct thread *thread)
}
if (isis->debugs & DEBUG_SPF_EVENTS)
- zlog_debug ("ISIS-Spf (%s) L1 SPF needed, periodic SPF", area->area_tag);
+ zlog_debug ("ISIS-Spf (%s) L%d SPF needed, periodic SPF",
+ area->area_tag, level);
if (area->ip_circuits)
- retval = isis_run_spf (area, 1, AF_INET, isis->sysid);
+ retval = isis_run_spf (area, level, AF_INET, isis->sysid);
if (area->ipv6_circuits)
- retval = isis_run_spf (area, 1, AF_INET6, isis->sysid);
+ retval = isis_run_spf (area, level, AF_INET6, isis->sysid);
return retval;
}
-static int
-isis_run_spf_l2 (struct thread *thread)
+static struct isis_spf_run*
+isis_run_spf_arg(struct isis_area *area, int level)
{
- struct isis_area *area;
- int retval = ISIS_OK;
+ struct isis_spf_run *run = XMALLOC(MTYPE_ISIS_SPF_RUN, sizeof(*run));
- area = THREAD_ARG (thread);
- assert (area);
+ run->area = area;
+ run->level = level;
- area->spf_timer[1] = NULL;
-
- if (!(area->is_type & IS_LEVEL_2))
- {
- if (isis->debugs & DEBUG_SPF_EVENTS)
- zlog_warn ("ISIS-SPF (%s) area does not share level", area->area_tag);
- return ISIS_WARNING;
- }
-
- if (isis->debugs & DEBUG_SPF_EVENTS)
- zlog_debug ("ISIS-Spf (%s) L2 SPF needed, periodic SPF", area->area_tag);
-
- if (area->ip_circuits)
- retval = isis_run_spf (area, 2, AF_INET, isis->sysid);
- if (area->ipv6_circuits)
- retval = isis_run_spf (area, 2, AF_INET6, isis->sysid);
-
- return retval;
+ return run;
}
int
@@ -1323,16 +1279,9 @@ isis_spf_schedule (struct isis_area *area, int level)
if (area->spf_timer[level - 1])
return ISIS_OK;
- if (level == 1)
- {
- THREAD_TIMER_MSEC_ON(master, area->spf_timer[0],
- isis_run_spf_l1, area, delay);
- }
- else
- {
- THREAD_TIMER_MSEC_ON(master, area->spf_timer[1],
- isis_run_spf_l2, area, delay);
- }
+ thread_add_timer_msec (master, isis_run_spf_cb,
+ isis_run_spf_arg(area, level),
+ delay, &area->spf_timer[level-1]);
return ISIS_OK;
}
@@ -1352,12 +1301,9 @@ isis_spf_schedule (struct isis_area *area, int level)
return retval;
}
- if (level == 1)
- THREAD_TIMER_ON (master, area->spf_timer[0], isis_run_spf_l1, area,
- area->min_spf_interval[0] - diff);
- else
- THREAD_TIMER_ON (master, area->spf_timer[1], isis_run_spf_l2, area,
- area->min_spf_interval[1] - diff);
+ thread_add_timer (master, isis_run_spf_cb, isis_run_spf_arg(area, level),
+ area->min_spf_interval[level-1] - diff,
+ &area->spf_timer[level-1]);
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug ("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",
@@ -1427,14 +1373,23 @@ isis_print_paths (struct vty *vty, struct list *paths, u_char *root_sysid)
DEFUN (show_isis_topology,
show_isis_topology_cmd,
- "show isis topology",
+ "show isis topology [<level-1|level-2>]",
SHOW_STR
"IS-IS information\n"
- "IS-IS paths to Intermediate Systems\n")
+ "IS-IS paths to Intermediate Systems\n"
+ "Paths to all level-1 routers in the area\n"
+ "Paths to all level-2 routers in the domain\n")
{
+ int levels;
struct listnode *node;
struct isis_area *area;
- int level;
+
+ if (argc < 4)
+ levels = ISIS_LEVEL1|ISIS_LEVEL2;
+ else if (!strcmp(argv[3]->arg, "level-1"))
+ levels = ISIS_LEVEL1;
+ else
+ levels = ISIS_LEVEL2;
if (!isis->area_list || isis->area_list->count == 0)
return CMD_SUCCESS;
@@ -1444,23 +1399,26 @@ DEFUN (show_isis_topology,
vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null",
VTY_NEWLINE);
- for (level = 0; level < ISIS_LEVELS; level++)
+ for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++)
{
- if (area->ip_circuits > 0 && area->spftree[level]
- && area->spftree[level]->paths->count > 0)
+ if ((level & levels) == 0)
+ continue;
+
+ if (area->ip_circuits > 0 && area->spftree[level-1]
+ && area->spftree[level-1]->paths->count > 0)
{
vty_out (vty, "IS-IS paths to level-%d routers that speak IP%s",
- level + 1, VTY_NEWLINE);
- isis_print_paths (vty, area->spftree[level]->paths, isis->sysid);
+ level, VTY_NEWLINE);
+ isis_print_paths (vty, area->spftree[level-1]->paths, isis->sysid);
vty_out (vty, "%s", VTY_NEWLINE);
}
- if (area->ipv6_circuits > 0 && area->spftree6[level]
- && area->spftree6[level]->paths->count > 0)
+ if (area->ipv6_circuits > 0 && area->spftree6[level-1]
+ && area->spftree6[level-1]->paths->count > 0)
{
vty_out (vty,
"IS-IS paths to level-%d routers that speak IPv6%s",
- level + 1, VTY_NEWLINE);
- isis_print_paths (vty, area->spftree6[level]->paths, isis->sysid);
+ level, VTY_NEWLINE);
+ isis_print_paths (vty, area->spftree6[level-1]->paths, isis->sysid);
vty_out (vty, "%s", VTY_NEWLINE);
}
}
@@ -1471,92 +1429,8 @@ DEFUN (show_isis_topology,
return CMD_SUCCESS;
}
-DEFUN (show_isis_topology_l1,
- show_isis_topology_l1_cmd,
- "show isis topology level-1",
- SHOW_STR
- "IS-IS information\n"
- "IS-IS paths to Intermediate Systems\n"
- "Paths to all level-1 routers in the area\n")
-{
- struct listnode *node;
- struct isis_area *area;
-
- if (!isis->area_list || isis->area_list->count == 0)
- return CMD_SUCCESS;
-
- for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
- {
- vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null",
- VTY_NEWLINE);
-
- if (area->ip_circuits > 0 && area->spftree[0]
- && area->spftree[0]->paths->count > 0)
- {
- vty_out (vty, "IS-IS paths to level-1 routers that speak IP%s",
- VTY_NEWLINE);
- isis_print_paths (vty, area->spftree[0]->paths, isis->sysid);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- if (area->ipv6_circuits > 0 && area->spftree6[0]
- && area->spftree6[0]->paths->count > 0)
- {
- vty_out (vty, "IS-IS paths to level-1 routers that speak IPv6%s",
- VTY_NEWLINE);
- isis_print_paths (vty, area->spftree6[0]->paths, isis->sysid);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN (show_isis_topology_l2,
- show_isis_topology_l2_cmd,
- "show isis topology level-2",
- SHOW_STR
- "IS-IS information\n"
- "IS-IS paths to Intermediate Systems\n"
- "Paths to all level-2 routers in the domain\n")
-{
- struct listnode *node;
- struct isis_area *area;
-
- if (!isis->area_list || isis->area_list->count == 0)
- return CMD_SUCCESS;
-
- for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
- {
- vty_out (vty, "Area %s:%s", area->area_tag ? area->area_tag : "null",
- VTY_NEWLINE);
-
- if (area->ip_circuits > 0 && area->spftree[1]
- && area->spftree[1]->paths->count > 0)
- {
- vty_out (vty, "IS-IS paths to level-2 routers that speak IP%s",
- VTY_NEWLINE);
- isis_print_paths (vty, area->spftree[1]->paths, isis->sysid);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- if (area->ipv6_circuits > 0 && area->spftree6[1]
- && area->spftree6[1]->paths->count > 0)
- {
- vty_out (vty, "IS-IS paths to level-2 routers that speak IPv6%s",
- VTY_NEWLINE);
- isis_print_paths (vty, area->spftree6[1]->paths, isis->sysid);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-
- return CMD_SUCCESS;
-}
-
void
isis_spf_cmds_init ()
{
install_element (VIEW_NODE, &show_isis_topology_cmd);
- install_element (VIEW_NODE, &show_isis_topology_l1_cmd);
- install_element (VIEW_NODE, &show_isis_topology_l2_cmd);
}
diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h
index fb534542d0..8c72f45c52 100644
--- a/isisd/isis_spf.h
+++ b/isisd/isis_spf.h
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_SPF_H
@@ -38,6 +38,10 @@ enum vertextype
VTYPE_IP6REACH_EXTERNAL
};
+#define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS)
+#define VTYPE_ES(t) ((t) == VTYPE_ES)
+#define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL)
+
/*
* Triple <N, d(N), {Adj(N)}>
*/
@@ -66,12 +70,14 @@ struct isis_spftree
unsigned int runcount; /* number of runs since uptime */
time_t last_run_timestamp; /* last run timestamp for scheduling */
time_t last_run_duration; /* last run duration in msec */
+
+ uint16_t mtid;
+ int family;
+ int level;
};
struct isis_spftree * isis_spftree_new (struct isis_area *area);
void isis_spftree_del (struct isis_spftree *spftree);
-void isis_spftree_adj_del (struct isis_spftree *spftree,
- struct isis_adjacency *adj);
void spftree_area_init (struct isis_area *area);
void spftree_area_del (struct isis_area *area);
void spftree_area_adj_del (struct isis_area *area,
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index b04d0db3ca..1f9c2b9637 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -18,10 +18,9 @@
* 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.
+ * 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>
diff --git a/isisd/isis_te.h b/isisd/isis_te.h
index 1578d37706..3c99c90855 100644
--- a/isisd/isis_te.h
+++ b/isisd/isis_te.h
@@ -18,10 +18,9 @@
* 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.
+ * 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 _ZEBRA_ISIS_MPLS_TE_H
diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c
index 4192fff9a8..7ffa7509c3 100644
--- a/isisd/isis_tlv.c
+++ b/isisd/isis_tlv.c
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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>
@@ -43,6 +43,7 @@
#include "isisd/isis_pdu.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_te.h"
+#include "isisd/isis_mt.h"
void
free_tlv (void *val)
@@ -61,10 +62,14 @@ free_tlvs (struct tlvs *tlvs)
{
if (tlvs->area_addrs)
list_delete (tlvs->area_addrs);
+ if (tlvs->mt_router_info)
+ list_delete (tlvs->mt_router_info);
if (tlvs->is_neighs)
list_delete (tlvs->is_neighs);
if (tlvs->te_is_neighs)
list_delete (tlvs->te_is_neighs);
+ if (tlvs->mt_is_neighs)
+ list_delete (tlvs->mt_is_neighs);
if (tlvs->es_neighs)
list_delete (tlvs->es_neighs);
if (tlvs->lsp_entries)
@@ -81,16 +86,293 @@ free_tlvs (struct tlvs *tlvs)
list_delete (tlvs->ipv4_ext_reachs);
if (tlvs->te_ipv4_reachs)
list_delete (tlvs->te_ipv4_reachs);
+ if (tlvs->mt_ipv4_reachs)
+ list_delete (tlvs->mt_ipv4_reachs);
if (tlvs->ipv6_addrs)
list_delete (tlvs->ipv6_addrs);
if (tlvs->ipv6_reachs)
list_delete (tlvs->ipv6_reachs);
+ if (tlvs->mt_ipv6_reachs)
+ list_delete (tlvs->mt_ipv6_reachs);
memset (tlvs, 0, sizeof (struct tlvs));
return;
}
+static int
+parse_mtid(uint16_t *mtid, bool read_mtid,
+ unsigned int *length, u_char **pnt)
+{
+ if (!read_mtid)
+ {
+ *mtid = ISIS_MT_IPV4_UNICAST;
+ return ISIS_OK;
+ }
+
+ uint16_t mtid_buf;
+
+ if (*length < sizeof(mtid_buf))
+ {
+ zlog_warn("ISIS-TLV: mt tlv too short to contain MT id");
+ return ISIS_WARNING;
+ }
+
+ memcpy(&mtid_buf, *pnt, sizeof(mtid_buf));
+ *pnt += sizeof(mtid_buf);
+ *length -= sizeof(mtid_buf);
+
+ *mtid = ntohs(mtid_buf) & ISIS_MT_MASK;
+ return ISIS_OK;
+}
+
+static int
+parse_mt_is_neighs(struct tlvs *tlvs, bool read_mtid,
+ unsigned int length, u_char *pnt)
+{
+ struct list *neigh_list;
+ uint16_t mtid;
+ int rv;
+
+ rv = parse_mtid(&mtid, read_mtid, &length, &pnt);
+ if (rv != ISIS_OK)
+ return rv;
+
+ if (mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ if (!tlvs->te_is_neighs)
+ {
+ tlvs->te_is_neighs = list_new();
+ tlvs->te_is_neighs->del = free_tlv;
+ }
+ neigh_list = tlvs->te_is_neighs;
+ }
+ else
+ {
+ struct tlv_mt_neighbors *neighbors;
+
+ neighbors = tlvs_get_mt_neighbors(tlvs, mtid);
+ neighbors->list->del = free_tlv;
+ neigh_list = neighbors->list;
+ }
+
+ while (length >= IS_NEIGHBOURS_LEN)
+ {
+ struct te_is_neigh *neigh = XCALLOC(MTYPE_ISIS_TLV, sizeof(*neigh));
+
+ memcpy(neigh, pnt, IS_NEIGHBOURS_LEN);
+ pnt += IS_NEIGHBOURS_LEN;
+ length -= IS_NEIGHBOURS_LEN;
+
+ if (neigh->sub_tlvs_length > length)
+ {
+ zlog_warn("ISIS-TLV: neighbor subtlv length exceeds TLV size");
+ XFREE(MTYPE_ISIS_TLV, neigh);
+ return ISIS_WARNING;
+ }
+
+ memcpy(neigh->sub_tlvs, pnt, neigh->sub_tlvs_length);
+ pnt += neigh->sub_tlvs_length;
+ length -= neigh->sub_tlvs_length;
+
+ listnode_add(neigh_list, neigh);
+ }
+
+ if (length)
+ {
+ zlog_warn("ISIS-TLV: TE/MT neighor TLV has trailing data");
+ return ISIS_WARNING;
+ }
+
+ return ISIS_OK;
+}
+
+static int
+parse_mt_ipv4_reachs(struct tlvs *tlvs, bool read_mtid,
+ unsigned int length, u_char *pnt)
+{
+ struct list *reach_list;
+ uint16_t mtid;
+ int rv;
+
+ rv = parse_mtid(&mtid, read_mtid, &length, &pnt);
+ if (rv != ISIS_OK)
+ return rv;
+
+ if (mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ if (!tlvs->te_ipv4_reachs)
+ {
+ tlvs->te_ipv4_reachs = list_new();
+ tlvs->te_ipv4_reachs->del = free_tlv;
+ }
+ reach_list = tlvs->te_ipv4_reachs;
+ }
+ else
+ {
+ struct tlv_mt_ipv4_reachs *reachs;
+
+ reachs = tlvs_get_mt_ipv4_reachs(tlvs, mtid);
+ reachs->list->del = free_tlv;
+ reach_list = reachs->list;
+ }
+
+ while (length >= 5) /* Metric + Control */
+ {
+ struct te_ipv4_reachability *reach = XCALLOC(MTYPE_ISIS_TLV, TE_IPV4_REACH_LEN);
+
+ memcpy(reach, pnt, 5); /* Metric + Control */
+ pnt += 5;
+ length -= 5;
+
+ unsigned char prefixlen = reach->control & 0x3F;
+
+ if (prefixlen > IPV4_MAX_BITLEN)
+ {
+ zlog_warn("ISIS-TLV: invalid IPv4 extended reachability prefix length %d", prefixlen);
+ XFREE(MTYPE_ISIS_TLV, reach);
+ return ISIS_WARNING;
+ }
+
+ if (length < (unsigned int)PSIZE(prefixlen))
+ {
+ zlog_warn("ISIS-TLV: invalid IPv4 extended reachability prefix too long for tlv");
+ XFREE(MTYPE_ISIS_TLV, reach);
+ return ISIS_WARNING;
+ }
+
+ memcpy(&reach->prefix_start, pnt, PSIZE(prefixlen));
+ pnt += PSIZE(prefixlen);
+ length -= PSIZE(prefixlen);
+
+ if (reach->control & TE_IPV4_HAS_SUBTLV)
+ {
+ if (length < 1)
+ {
+ zlog_warn("ISIS-TLV: invalid IPv4 extended reachability SubTLV missing");
+ XFREE(MTYPE_ISIS_TLV, reach);
+ return ISIS_WARNING;
+ }
+
+ u_char subtlv_len = *pnt;
+ pnt++;
+ length--;
+
+ if (length < subtlv_len)
+ {
+ zlog_warn("ISIS-TLV: invalid IPv4 extended reachability SubTLVs have oversize");
+ XFREE(MTYPE_ISIS_TLV, reach);
+ return ISIS_WARNING;
+ }
+
+ /* Skip Sub-TLVs for now */
+ pnt += subtlv_len;
+ length -= subtlv_len;
+ }
+ listnode_add(reach_list, reach);
+ }
+
+ if (length)
+ {
+ zlog_warn("ISIS-TLV: TE/MT ipv4 reachability TLV has trailing data");
+ return ISIS_WARNING;
+ }
+
+ return ISIS_OK;
+}
+
+static int
+parse_mt_ipv6_reachs(struct tlvs *tlvs, bool read_mtid,
+ unsigned int length, u_char *pnt)
+{
+ struct list *reach_list;
+ uint16_t mtid;
+ int rv;
+
+ rv = parse_mtid(&mtid, read_mtid, &length, &pnt);
+ if (rv != ISIS_OK)
+ return rv;
+
+ if (mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ if (!tlvs->ipv6_reachs)
+ {
+ tlvs->ipv6_reachs = list_new();
+ tlvs->ipv6_reachs->del = free_tlv;
+ }
+ reach_list = tlvs->ipv6_reachs;
+ }
+ else
+ {
+ struct tlv_mt_ipv6_reachs *reachs;
+
+ reachs = tlvs_get_mt_ipv6_reachs(tlvs, mtid);
+ reachs->list->del = free_tlv;
+ reach_list = reachs->list;
+ }
+
+ while (length >= 6) /* Metric + Control + Prefixlen */
+ {
+ struct ipv6_reachability *reach = XCALLOC(MTYPE_ISIS_TLV, sizeof(*reach));
+
+ memcpy(reach, pnt, 6); /* Metric + Control + Prefixlen */
+ pnt += 6;
+ length -= 6;
+
+ if (reach->prefix_len > IPV6_MAX_BITLEN)
+ {
+ zlog_warn("ISIS-TLV: invalid IPv6 reachability prefix length %d", reach->prefix_len);
+ XFREE(MTYPE_ISIS_TLV, reach);
+ return ISIS_WARNING;
+ }
+
+ if (length < (unsigned int)PSIZE(reach->prefix_len))
+ {
+ zlog_warn("ISIS-TLV: invalid IPv6 reachability prefix too long for tlv");
+ XFREE(MTYPE_ISIS_TLV, reach);
+ return ISIS_WARNING;
+ }
+
+ memcpy(&reach->prefix, pnt, PSIZE(reach->prefix_len));
+ pnt += PSIZE(reach->prefix_len);
+ length -= PSIZE(reach->prefix_len);
+
+ if (reach->control_info & CTRL_INFO_SUBTLVS)
+ {
+ if (length < 1)
+ {
+ zlog_warn("ISIS-TLV: invalid IPv6 reachability SubTLV missing");
+ XFREE(MTYPE_ISIS_TLV, reach);
+ return ISIS_WARNING;
+ }
+
+ u_char subtlv_len = *pnt;
+ pnt++;
+ length--;
+
+ if (length < subtlv_len)
+ {
+ zlog_warn("ISIS-TLV: invalid IPv6 reachability SubTLVs have oversize");
+ XFREE(MTYPE_ISIS_TLV, reach);
+ return ISIS_WARNING;
+ }
+
+ /* Skip Sub-TLVs for now */
+ pnt += subtlv_len;
+ length -= subtlv_len;
+ }
+ listnode_add(reach_list, reach);
+ }
+
+ if (length)
+ {
+ zlog_warn("ISIS-TLV: (MT) IPv6 reachability TLV has trailing data");
+ return ISIS_WARNING;
+ }
+
+ return ISIS_OK;
+}
+
/*
* Parses the tlvs found in the variant length part of the PDU.
* Caller tells with flags in "expected" which TLV's it is interested in.
@@ -103,17 +385,13 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
struct lan_neigh *lan_nei;
struct area_addr *area_addr;
struct is_neigh *is_nei;
- struct te_is_neigh *te_is_nei;
struct es_neigh *es_nei;
struct lsp_entry *lsp_entry;
struct in_addr *ipv4_addr;
struct ipv4_reachability *ipv4_reach;
- struct te_ipv4_reachability *te_ipv4_reach;
struct in6_addr *ipv6_addr;
- struct ipv6_reachability *ipv6_reach;
- int prefix_octets;
int value_len, retval = ISIS_OK;
- u_char *start = stream, *pnt = stream, *endpnt;
+ u_char *start = stream, *pnt = stream;
*found = 0;
memset (tlvs, 0, sizeof (struct tlvs));
@@ -207,54 +485,25 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
break;
case TE_IS_NEIGHBOURS:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Neighbour ID | 7
- * +---------------------------------------------------------------+
- * | TE Metric | 3
- * +---------------------------------------------------------------+
- * | SubTLVs Length | 1
- * +---------------------------------------------------------------+
- * : :
- */
*found |= TLVFLAG_TE_IS_NEIGHS;
#ifdef EXTREME_TLV_DEBUG
zlog_debug ("ISIS-TLV (%s): Extended IS Neighbours length %d",
areatag, length);
#endif /* EXTREME_TLV_DEBUG */
if (TLVFLAG_TE_IS_NEIGHS & *expected)
- {
- while (length > value_len)
- {
- te_is_nei = (struct te_is_neigh *) pnt;
- value_len += IS_NEIGHBOURS_LEN;
- pnt += IS_NEIGHBOURS_LEN;
- /* FIXME - subtlvs are handled here, for now we skip */
- /* FIXME: All TE SubTLVs are not necessary present in LSP PDU. */
- /* So, it must be copied in a new te_is_neigh structure */
- /* rather than just initialize pointer to the original LSP PDU */
- /* to avoid consider the rest of lspdu as subTLVs or buffer overflow */
- if (IS_MPLS_TE(isisMplsTE))
- {
- struct te_is_neigh *new = XCALLOC(MTYPE_ISIS_TLV, sizeof(struct te_is_neigh));
- memcpy(new->neigh_id, te_is_nei->neigh_id, ISIS_SYS_ID_LEN + 1);
- memcpy(new->te_metric, te_is_nei->te_metric, 3);
- new->sub_tlvs_length = te_is_nei->sub_tlvs_length;
- memcpy(new->sub_tlvs, pnt, te_is_nei->sub_tlvs_length);
- te_is_nei = new;
- }
- /* Skip SUB TLVs payload */
- value_len += te_is_nei->sub_tlvs_length;
- pnt += te_is_nei->sub_tlvs_length;
-
- if (!tlvs->te_is_neighs)
- tlvs->te_is_neighs = list_new ();
- listnode_add (tlvs->te_is_neighs, te_is_nei);
- }
- }
- else
- {
- pnt += length;
- }
+ retval = parse_mt_is_neighs(tlvs, false, length, pnt);
+ pnt += length;
+ break;
+
+ case MT_IS_NEIGHBOURS:
+ *found |= TLVFLAG_TE_IS_NEIGHS;
+#ifdef EXTREME_TLV_DEBUG
+ zlog_debug ("ISIS-TLV (%s): MT IS Neighbours length %d",
+ areatag, length);
+#endif
+ if (TLVFLAG_TE_IS_NEIGHS & *expected)
+ retval = parse_mt_is_neighs(tlvs, true, length, pnt);
+ pnt += length;
break;
case ES_NEIGHBOURS:
@@ -577,71 +826,25 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
break;
case TE_IPV4_REACHABILITY:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | TE Metric | 4
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | U/D | sTLV? | Prefix Mask Len | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Prefix | 0-4
- * +---------------------------------------------------------------+
- * | sub tlvs |
- * +---------------------------------------------------------------+
- * : :
- */
*found |= TLVFLAG_TE_IPV4_REACHABILITY;
#ifdef EXTREME_TLV_DEBUG
zlog_debug ("ISIS-TLV (%s): IPv4 extended Reachability length %d",
- areatag, length);
+ areatag, length);
#endif /* EXTREME_TLV_DEBUG */
- endpnt = pnt + length;
if (*expected & TLVFLAG_TE_IPV4_REACHABILITY)
- {
- while (length > value_len)
- {
- te_ipv4_reach = (struct te_ipv4_reachability *) pnt;
- if ((te_ipv4_reach->control & 0x3F) > IPV4_MAX_BITLEN)
- {
- zlog_warn ("ISIS-TLV (%s): invalid IPv4 extended reach"
- "ability prefix length %d", areatag,
- te_ipv4_reach->control & 0x3F);
- retval = ISIS_WARNING;
- break;
- }
- if (!tlvs->te_ipv4_reachs)
- tlvs->te_ipv4_reachs = list_new ();
- listnode_add (tlvs->te_ipv4_reachs, te_ipv4_reach);
-
- /* Metric + Control-Byte + Prefix */
- unsigned int entry_len = 5 + PSIZE(te_ipv4_reach->control & 0x3F);
- value_len += entry_len;
- pnt += entry_len;
-
- if (te_ipv4_reach->control & TE_IPV4_HAS_SUBTLV)
- {
- if (length <= value_len)
- {
- zlog_warn("ISIS-TLV (%s): invalid IPv4 extended reachability SubTLV missing",
- areatag);
- retval = ISIS_WARNING;
- break;
- }
- u_char subtlv_len = *pnt;
- value_len += subtlv_len + 1;
- pnt += subtlv_len + 1;
- if (length < value_len)
- {
- zlog_warn("ISIS-TLV (%s): invalid IPv4 extended reachability SubTLVs have oversize",
- areatag);
- retval = ISIS_WARNING;
- break;
- }
- }
- }
- }
-
- pnt = endpnt;
+ retval = parse_mt_ipv4_reachs(tlvs, false, length, pnt);
+ pnt += length;
+ break;
+ case MT_IPV4_REACHABILITY:
+ *found |= TLVFLAG_TE_IPV4_REACHABILITY;
+#ifdef EXTREME_TLV_DEBUG
+ zlog_debug ("ISIS-TLV (%s): IPv4 MT Reachability length %d",
+ areatag, length);
+#endif /* EXTREME_TLV_DEBUG */
+ if (*expected & TLVFLAG_TE_IPV4_REACHABILITY)
+ retval = parse_mt_ipv4_reachs(tlvs, true, length, pnt);
+ pnt += length;
break;
-
case IPV6_ADDR:
/* +-------+-------+-------+-------+-------+-------+-------+-------+
* + IP version 6 address + 16
@@ -672,67 +875,25 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
break;
case IPV6_REACHABILITY:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Default Metric | 4
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Control Informantion |
- * +---------------------------------------------------------------+
- * | IPv6 Prefix Length |--+
- * +---------------------------------------------------------------+ |
- * | IPv6 Prefix |<-+
- * +---------------------------------------------------------------+
- */
*found |= TLVFLAG_IPV6_REACHABILITY;
- endpnt = pnt + length;
-
+#ifdef EXTREME_TLV_DEBUG
+ zlog_debug ("ISIS-TLV (%s): IPv6 Reachability length %d",
+ areatag, length);
+#endif /* EXTREME_TLV_DEBUG */
if (*expected & TLVFLAG_IPV6_REACHABILITY)
- {
- while (length > value_len)
- {
- ipv6_reach = (struct ipv6_reachability *) pnt;
- if (ipv6_reach->prefix_len > IPV6_MAX_BITLEN)
- {
- zlog_warn ("ISIS-TLV (%s): invalid IPv6 extended reach"
- "ability prefix length %d", areatag,
- ipv6_reach->prefix_len);
- retval = ISIS_WARNING;
- break;
- }
-
- prefix_octets = ((ipv6_reach->prefix_len + 7) / 8);
- value_len += prefix_octets + 6;
- pnt += prefix_octets + 6;
-
- if (ipv6_reach->control_info & CTRL_INFO_SUBTLVS)
- {
- if (length <= value_len)
- {
- zlog_warn("ISIS-TLV (%s): invalid IPv6 extended reachability SubTLV missing",
- areatag);
- retval = ISIS_WARNING;
- break;
- }
- u_char subtlv_len = *pnt;
- value_len += subtlv_len + 1;
- pnt += subtlv_len + 1;
- if (length < value_len)
- {
- zlog_warn("ISIS-TLV (%s): invalid IPv6 extended reachability SubTLVs have oversize",
- areatag);
- retval = ISIS_WARNING;
- break;
- }
- }
- /* FIXME: sub-tlvs */
- if (!tlvs->ipv6_reachs)
- tlvs->ipv6_reachs = list_new ();
- listnode_add (tlvs->ipv6_reachs, ipv6_reach);
- }
- }
-
- pnt = endpnt;
+ retval = parse_mt_ipv6_reachs(tlvs, false, length, pnt);
+ pnt += length;
+ break;
+ case MT_IPV6_REACHABILITY:
+ *found |= TLVFLAG_IPV6_REACHABILITY;
+#ifdef EXTREME_TLV_DEBUG
+ zlog_debug ("ISIS-TLV (%s): IPv6 Reachability length %d",
+ areatag, length);
+#endif /* EXTREME_TLV_DEBUG */
+ if (*expected & TLVFLAG_IPV6_REACHABILITY)
+ retval = parse_mt_ipv6_reachs(tlvs, true, length, pnt);
+ pnt += length;
break;
-
case WAY3_HELLO:
/* +---------------------------------------------------------------+
* | Adjacency state | 1
@@ -786,6 +947,42 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
pnt += length;
break;
+ case MT_ROUTER_INFORMATION:
+ *found |= TLVFLAG_MT_ROUTER_INFORMATION;
+ if (*expected & TLVFLAG_MT_ROUTER_INFORMATION)
+ {
+ if (!tlvs->mt_router_info)
+ {
+ tlvs->mt_router_info = list_new();
+ tlvs->mt_router_info->del = free_tlv;
+ }
+ while (length > value_len)
+ {
+ uint16_t mt_info;
+ struct mt_router_info *info;
+
+ if (value_len + sizeof(mt_info) > length) {
+ zlog_warn("ISIS-TLV (%s): TLV 229 is truncated.", areatag);
+ pnt += length - value_len;
+ break;
+ }
+
+ memcpy(&mt_info, pnt, sizeof(mt_info));
+ pnt += sizeof(mt_info);
+ value_len += sizeof(mt_info);
+
+ mt_info = ntohs(mt_info);
+ info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info));
+ info->mtid = mt_info & ISIS_MT_MASK;
+ info->overload = mt_info & ISIS_MT_OL_MASK;
+ listnode_add(tlvs->mt_router_info, info);
+ }
+ }
+ else
+ {
+ pnt += length;
+ }
+ break;
default:
zlog_warn ("ISIS-TLV (%s): unsupported TLV type %d, length %d",
areatag, type, length);
@@ -826,6 +1023,31 @@ add_tlv (u_char tag, u_char len, u_char * value, struct stream *stream)
}
int
+tlv_add_mt_router_info (struct list *mt_router_info, struct stream *stream)
+{
+ struct listnode *node;
+ struct mt_router_info *info;
+
+ uint16_t value[127];
+ uint16_t *pos = value;
+
+ for (ALL_LIST_ELEMENTS_RO(mt_router_info, node, info))
+ {
+ uint16_t mt_info;
+
+ mt_info = info->mtid;
+ if (info->overload)
+ mt_info |= ISIS_MT_OL_MASK;
+
+ *pos = htons(mt_info);
+ pos++;
+ }
+
+ return add_tlv(MT_ROUTER_INFORMATION, (pos - value) * sizeof(*pos),
+ (u_char*)value, stream);
+}
+
+int
tlv_add_area_addrs (struct list *area_addrs, struct stream *stream)
{
struct listnode *node;
@@ -887,26 +1109,44 @@ tlv_add_is_neighs (struct list *is_neighs, struct stream *stream)
return add_tlv (IS_NEIGHBOURS, pos - value, value, stream);
}
-int
-tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream)
+static size_t
+max_tlv_size(struct stream *stream)
+{
+ size_t avail = stream_get_size (stream) - stream_get_endp(stream);
+
+ if (avail < 2)
+ return 0;
+
+ if (avail < 257)
+ return avail - 2;
+
+ return 255;
+}
+
+unsigned int
+tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream, void *arg)
{
struct listnode *node;
struct te_is_neigh *te_is_neigh;
u_char value[255];
u_char *pos = value;
- int retval;
+ uint16_t mtid = arg ? *(uint16_t*)arg : ISIS_MT_IPV4_UNICAST;
+ unsigned int consumed = 0;
+ size_t max_size = max_tlv_size(stream);
+
+ if (mtid != ISIS_MT_IPV4_UNICAST)
+ {
+ uint16_t mtid_conversion = ntohs(mtid);
+ memcpy(pos, &mtid_conversion, sizeof(mtid_conversion));
+ pos += sizeof(mtid_conversion);
+ }
for (ALL_LIST_ELEMENTS_RO (te_is_neighs, node, te_is_neigh))
{
/* FIXME: Check if Total SubTLVs size doesn't exceed 255 */
- if (pos - value + IS_NEIGHBOURS_LEN + te_is_neigh->sub_tlvs_length > 255)
- {
- retval = add_tlv (TE_IS_NEIGHBOURS, pos - value, value, stream);
- if (retval != ISIS_OK)
- return retval;
- pos = value;
- }
-
+ if ((size_t)(pos - value) + IS_NEIGHBOURS_LEN + te_is_neigh->sub_tlvs_length > max_size)
+ break;
+
memcpy (pos, te_is_neigh->neigh_id, ISIS_SYS_ID_LEN + 1);
pos += ISIS_SYS_ID_LEN + 1;
memcpy (pos, te_is_neigh->te_metric, 3);
@@ -920,9 +1160,17 @@ tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream)
memcpy (pos, te_is_neigh->sub_tlvs, te_is_neigh->sub_tlvs_length);
pos += te_is_neigh->sub_tlvs_length;
}
+ consumed++;
}
- return add_tlv (TE_IS_NEIGHBOURS, pos - value, value, stream);
+ if (consumed)
+ {
+ int rv = add_tlv ((mtid != ISIS_MT_IPV4_UNICAST) ? MT_IS_NEIGHBOURS
+ : TE_IS_NEIGHBOURS,
+ pos - value, value, stream);
+ assert(rv == ISIS_OK);
+ }
+ return consumed;
}
int
@@ -1100,37 +1348,49 @@ 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)
+unsigned int
+tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, struct stream *stream, void *arg)
{
struct listnode *node;
struct te_ipv4_reachability *te_reach;
u_char value[255];
u_char *pos = value;
- u_char prefix_size;
- int retval;
+ uint16_t mtid = arg ? *(uint16_t*)arg : ISIS_MT_IPV4_UNICAST;
+ unsigned int consumed = 0;
+ size_t max_size = max_tlv_size(stream);
+
+ if (mtid != ISIS_MT_IPV4_UNICAST)
+ {
+ uint16_t mtid_conversion = ntohs(mtid);
+ memcpy(pos, &mtid_conversion, sizeof(mtid_conversion));
+ pos += sizeof(mtid_conversion);
+ }
for (ALL_LIST_ELEMENTS_RO (te_ipv4_reachs, node, te_reach))
{
- prefix_size = ((((te_reach->control & 0x3F) - 1) >> 3) + 1);
+ unsigned char prefixlen = te_reach->control & 0x3F;
+
+ if ((size_t)(pos - value) + 5 + PSIZE(prefixlen) > max_size)
+ break;
- if (pos - value + (5 + prefix_size) > 255)
- {
- retval =
- add_tlv (TE_IPV4_REACHABILITY, pos - value, value, stream);
- if (retval != ISIS_OK)
- return retval;
- pos = value;
- }
*(u_int32_t *) pos = te_reach->te_metric;
pos += 4;
*pos = te_reach->control;
pos++;
- memcpy (pos, &te_reach->prefix_start, prefix_size);
- pos += prefix_size;
+ memcpy (pos, &te_reach->prefix_start, PSIZE(prefixlen));
+ pos += PSIZE(prefixlen);
+ consumed++;
+ }
+
+ if (consumed)
+ {
+ int rv = add_tlv ((mtid != ISIS_MT_IPV4_UNICAST) ? MT_IPV4_REACHABILITY
+ : TE_IPV4_REACHABILITY,
+ pos - value, value, stream);
+ assert(rv == ISIS_OK);
}
- return add_tlv (TE_IPV4_REACHABILITY, pos - value, value, stream);
+ return consumed;
}
int
@@ -1158,36 +1418,49 @@ tlv_add_ipv6_addrs (struct list *ipv6_addrs, struct stream *stream)
return add_tlv (IPV6_ADDR, pos - value, value, stream);
}
-int
-tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream)
+unsigned int
+tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream, void *arg)
{
struct listnode *node;
struct ipv6_reachability *ip6reach;
u_char value[255];
u_char *pos = value;
- int retval, prefix_octets;
+ uint16_t mtid = arg ? *(uint16_t*)arg : ISIS_MT_IPV4_UNICAST;
+ unsigned int consumed = 0;
+ size_t max_size = max_tlv_size(stream);
+
+ if (mtid != ISIS_MT_IPV4_UNICAST)
+ {
+ uint16_t mtid_conversion = ntohs(mtid);
+ memcpy(pos, &mtid_conversion, sizeof(mtid_conversion));
+ pos += sizeof(mtid_conversion);
+ }
for (ALL_LIST_ELEMENTS_RO (ipv6_reachs, node, ip6reach))
{
- if (pos - value + IPV6_MAX_BYTELEN + 6 > 255)
- {
- retval = add_tlv (IPV6_REACHABILITY, pos - value, value, stream);
- if (retval != ISIS_OK)
- return retval;
- pos = value;
- }
- *(uint32_t *) pos = ip6reach->metric;
+ if ((size_t)(pos - value) + 6 + PSIZE(ip6reach->prefix_len) > max_size)
+ break;
+
+ *(uint32_t *)pos = ip6reach->metric;
pos += 4;
*pos = ip6reach->control_info;
pos++;
- prefix_octets = ((ip6reach->prefix_len + 7) / 8);
*pos = ip6reach->prefix_len;
pos++;
- memcpy (pos, ip6reach->prefix, prefix_octets);
- pos += prefix_octets;
+ memcpy (pos, ip6reach->prefix, PSIZE(ip6reach->prefix_len));
+ pos += PSIZE(ip6reach->prefix_len);
+ consumed++;
+ }
+
+ if (consumed)
+ {
+ int rv = add_tlv ((mtid != ISIS_MT_IPV4_UNICAST) ? MT_IPV6_REACHABILITY
+ : IPV6_REACHABILITY,
+ pos - value, value, stream);
+ assert(rv == ISIS_OK);
}
- return add_tlv (IPV6_REACHABILITY, pos - value, value, stream);
+ return consumed;
}
int
diff --git a/isisd/isis_tlv.h b/isisd/isis_tlv.h
index f899b9e9db..e55e81bce1 100644
--- a/isisd/isis_tlv.h
+++ b/isisd/isis_tlv.h
@@ -16,14 +16,16 @@
* 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.
+ * 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 _ZEBRA_ISIS_TLV_H
#define _ZEBRA_ISIS_TLV_H
+#include "isisd/isis_mt.h"
+
/*
* The list of TLVs we (should) support.
* ____________________________________________________________________________
@@ -109,8 +111,12 @@
#define TE_IPV4_REACHABILITY 135
#define DYNAMIC_HOSTNAME 137
#define GRACEFUL_RESTART 211
+#define MT_IS_NEIGHBOURS 222
+#define MT_ROUTER_INFORMATION 229
#define IPV6_ADDR 232
+#define MT_IPV4_REACHABILITY 235
#define IPV6_REACHABILITY 236
+#define MT_IPV6_REACHABILITY 237
#define WAY3_HELLO 240
#define ROUTER_INFORMATION 242
@@ -250,6 +256,12 @@ struct ipv6_reachability
#define CTRL_INFO_SUBTLVS 0x20
+struct mt_router_info
+{
+ ISIS_MT_INFO_FIELDS
+ bool overload;
+};
+
/*
* Pointer to each tlv type, filled by parse_tlvs()
*/
@@ -260,8 +272,10 @@ struct tlvs
struct nlpids *nlpids;
struct te_router_id *router_id;
struct list *area_addrs;
+ struct list *mt_router_info;
struct list *is_neighs;
struct list *te_is_neighs;
+ struct list *mt_is_neighs;
struct list *es_neighs;
struct list *lsp_entries;
struct list *prefix_neighs;
@@ -270,8 +284,10 @@ struct tlvs
struct list *ipv4_int_reachs;
struct list *ipv4_ext_reachs;
struct list *te_ipv4_reachs;
+ struct list *mt_ipv4_reachs;
struct list *ipv6_addrs;
struct list *ipv6_reachs;
+ struct list *mt_ipv6_reachs;
struct isis_passwd auth_info;
};
@@ -301,6 +317,7 @@ struct tlvs
#define TLVFLAG_TE_ROUTER_ID (1<<19)
#define TLVFLAG_CHECKSUM (1<<20)
#define TLVFLAG_GRACEFUL_RESTART (1<<21)
+#define TLVFLAG_MT_ROUTER_INFORMATION (1<<22)
void init_tlvs (struct tlvs *tlvs, uint32_t expected);
void free_tlvs (struct tlvs *tlvs);
@@ -310,9 +327,10 @@ int parse_tlvs (char *areatag, u_char * stream, int size,
int add_tlv (u_char, u_char, u_char *, struct stream *);
void free_tlv (void *val);
+int tlv_add_mt_router_info (struct list *mt_router_info, struct stream *stream);
int tlv_add_area_addrs (struct list *area_addrs, struct stream *stream);
int tlv_add_is_neighs (struct list *is_neighs, struct stream *stream);
-int tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream);
+unsigned int tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream, void *arg);
int tlv_add_lan_neighs (struct list *lan_neighs, struct stream *stream);
int tlv_add_nlpid (struct nlpids *nlpids, struct stream *stream);
int tlv_add_checksum (struct checksum *checksum, struct stream *stream);
@@ -325,9 +343,9 @@ int tlv_add_dynamic_hostname (struct hostname *hostname,
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);
+unsigned int tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, struct stream *stream, void *arg);
int tlv_add_ipv6_addrs (struct list *ipv6_addrs, struct stream *stream);
-int tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream);
+unsigned int tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream, void *arg);
int tlv_add_padding (struct stream *stream);
diff --git a/isisd/isis_vty.c b/isisd/isis_vty.c
index 721959859a..4d758315e2 100644
--- a/isisd/isis_vty.c
+++ b/isisd/isis_vty.c
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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>
@@ -29,6 +29,7 @@
#include "isis_circuit.h"
#include "isis_csm.h"
#include "isis_misc.h"
+#include "isis_mt.h"
#include "isisd.h"
static struct isis_circuit *
@@ -1271,6 +1272,62 @@ DEFUN (no_psnp_interval_l2,
return CMD_SUCCESS;
}
+DEFUN (circuit_topology,
+ circuit_topology_cmd,
+ "isis topology " ISIS_MT_NAMES,
+ "IS-IS commands\n"
+ "Configure interface IS-IS topologies\n"
+ ISIS_MT_DESCRIPTIONS)
+{
+ struct isis_circuit *circuit = isis_circuit_lookup (vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+ const char *arg = argv[2]->arg;
+ uint16_t mtid = isis_str2mtid(arg);
+
+ if (circuit->area && circuit->area->oldmetric)
+ {
+ vty_out (vty, "Multi topology IS-IS can only be used with wide metrics%s", VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
+ if (mtid == (uint16_t)-1)
+ {
+ vty_out (vty, "Don't know topology '%s'%s", arg, VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
+ return isis_circuit_mt_enabled_set(circuit, mtid, true);
+}
+
+DEFUN (no_circuit_topology,
+ no_circuit_topology_cmd,
+ "no isis topology " ISIS_MT_NAMES,
+ NO_STR
+ "IS-IS commands\n"
+ "Configure interface IS-IS topologies\n"
+ ISIS_MT_DESCRIPTIONS)
+{
+ struct isis_circuit *circuit = isis_circuit_lookup (vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+ const char *arg = argv[3]->arg;
+ uint16_t mtid = isis_str2mtid(arg);
+
+ if (circuit->area && circuit->area->oldmetric)
+ {
+ vty_out (vty, "Multi topology IS-IS can only be used with wide metrics%s", VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
+ if (mtid == (uint16_t)-1)
+ {
+ vty_out (vty, "Don't know topology '%s'%s", arg, VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
+ return isis_circuit_mt_enabled_set(circuit, mtid, false);
+}
static int
validate_metric_style_narrow (struct vty *vty, struct isis_area *area)
@@ -1328,6 +1385,12 @@ DEFUN (metric_style,
return CMD_SUCCESS;
}
+ if (area_is_mt(area))
+ {
+ vty_out (vty, "Narrow metrics cannot be used while multi topology IS-IS is active%s", VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
ret = validate_metric_style_narrow (vty, area);
if (ret != CMD_SUCCESS)
return ret;
@@ -1350,6 +1413,12 @@ DEFUN (no_metric_style,
VTY_DECLVAR_CONTEXT (isis_area, area);
int ret;
+ if (area_is_mt(area))
+ {
+ vty_out (vty, "Narrow metrics cannot be used while multi topology IS-IS is active%s", VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
ret = validate_metric_style_narrow (vty, area);
if (ret != CMD_SUCCESS)
return ret;
@@ -2116,6 +2185,9 @@ isis_vty_init (void)
install_element (INTERFACE_NODE, &psnp_interval_l2_cmd);
install_element (INTERFACE_NODE, &no_psnp_interval_l2_cmd);
+ install_element (INTERFACE_NODE, &circuit_topology_cmd);
+ install_element (INTERFACE_NODE, &no_circuit_topology_cmd);
+
install_element (ISIS_NODE, &metric_style_cmd);
install_element (ISIS_NODE, &no_metric_style_cmd);
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index e7bd99c3e8..4dd7ec5c3e 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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>
@@ -300,8 +300,9 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
/* FIXME: can it be ? */
if (nexthop->ip.s_addr != INADDR_ANY)
{
- stream_putc (stream, NEXTHOP_TYPE_IPV4);
+ stream_putc (stream, NEXTHOP_TYPE_IPV4_IFINDEX);
stream_put_in_addr (stream, &nexthop->ip);
+ stream_putl (stream, nexthop->ifindex);
}
else
{
diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h
index 217e3d48cd..aeead3c3b2 100644
--- a/isisd/isis_zebra.h
+++ b/isisd/isis_zebra.h
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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 _ZEBRA_ISIS_ZEBRA_H
#define _ZEBRA_ISIS_ZEBRA_H
diff --git a/isisd/isisd.c b/isisd/isisd.c
index f226c4a1f3..c1968918ed 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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>
@@ -56,6 +56,7 @@
#include "isisd/isis_zebra.h"
#include "isisd/isis_events.h"
#include "isisd/isis_te.h"
+#include "isisd/isis_mt.h"
struct isis *isis = NULL;
@@ -136,7 +137,7 @@ isis_area_create (const char *area_tag)
area->circuit_list = list_new ();
area->area_addrs = list_new ();
- THREAD_TIMER_ON (master, area->t_tick, lsp_tick, area, 1);
+ thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
flags_initialize (&area->flags);
/*
@@ -156,6 +157,8 @@ isis_area_create (const char *area_tag)
area->lsp_frag_threshold = 90;
area->lsp_mtu = DEFAULT_LSP_MTU;
+ area_mt_init(area);
+
area->area_tag = strdup (area_tag);
listnode_add (isis->area_list, area);
area->isis = isis;
@@ -296,6 +299,8 @@ isis_area_destroy (struct vty *vty, const char *area_tag)
free (area->area_tag);
+ area_mt_finish(area);
+
XFREE (MTYPE_ISIS_AREA, area);
if (listcount (isis->area_list) == 0)
@@ -307,6 +312,33 @@ isis_area_destroy (struct vty *vty, const char *area_tag)
return CMD_SUCCESS;
}
+static void
+area_set_mt_enabled(struct isis_area *area, uint16_t mtid, bool enabled)
+{
+ struct isis_area_mt_setting *setting;
+
+ setting = area_get_mt_setting(area, mtid);
+ if (setting->enabled != enabled)
+ {
+ setting->enabled = enabled;
+ lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0);
+ }
+}
+
+static void
+area_set_mt_overload(struct isis_area *area, uint16_t mtid, bool overload)
+{
+ struct isis_area_mt_setting *setting;
+
+ setting = area_get_mt_setting(area, mtid);
+ if (setting->overload != overload)
+ {
+ setting->overload = overload;
+ if (setting->enabled)
+ lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0);
+ }
+}
+
int
area_net_title (struct vty *vty, const char *net_title)
{
@@ -1626,6 +1658,75 @@ DEFUN (no_net,
return area_clear_net_title (vty, argv[idx_word]->arg);
}
+DEFUN (isis_topology,
+ isis_topology_cmd,
+ "topology " ISIS_MT_NAMES " [overload]",
+ "Configure IS-IS topologies\n"
+ ISIS_MT_DESCRIPTIONS
+ "Set overload bit for topology\n")
+{
+ VTY_DECLVAR_CONTEXT (isis_area, area);
+
+ const char *arg = argv[1]->arg;
+ uint16_t mtid = isis_str2mtid(arg);
+
+ if (area->oldmetric)
+ {
+ vty_out (vty, "Multi topology IS-IS can only be used with wide metrics%s", VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
+ if (mtid == (uint16_t)-1)
+ {
+ vty_out (vty, "Don't know topology '%s'%s", arg, VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+ if (mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ vty_out (vty, "Cannot configure IPv4 unicast topology%s", VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
+ area_set_mt_enabled(area, mtid, true);
+ area_set_mt_overload(area, mtid, (argc == 3));
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_topology,
+ no_isis_topology_cmd,
+ "no topology " ISIS_MT_NAMES " [overload]",
+ NO_STR
+ "Configure IS-IS topologies\n"
+ ISIS_MT_DESCRIPTIONS
+ "Set overload bit for topology\n")
+{
+ VTY_DECLVAR_CONTEXT (isis_area, area);
+
+ const char *arg = argv[2]->arg;
+ uint16_t mtid = isis_str2mtid(arg);
+
+ if (area->oldmetric)
+ {
+ vty_out (vty, "Multi topology IS-IS can only be used with wide metrics%s", VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
+ if (mtid == (uint16_t)-1)
+ {
+ vty_out (vty, "Don't know topology '%s'%s", arg, VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+ if (mtid == ISIS_MT_IPV4_UNICAST)
+ {
+ vty_out (vty, "Cannot configure IPv4 unicast topology%s", VTY_NEWLINE);
+ return CMD_ERR_AMBIGUOUS;
+ }
+
+ area_set_mt_enabled(area, mtid, false);
+ area_set_mt_overload(area, mtid, false);
+ return CMD_SUCCESS;
+}
+
void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu)
{
area->lsp_mtu = lsp_mtu;
@@ -2148,6 +2249,7 @@ isis_config_write (struct vty *vty)
write++;
}
+ write += area_write_mt_settings(area, vty);
}
isis_mpls_te_config_write_router(vty);
}
@@ -2254,6 +2356,9 @@ isis_init ()
install_element (ISIS_NODE, &net_cmd);
install_element (ISIS_NODE, &no_net_cmd);
+ install_element (ISIS_NODE, &isis_topology_cmd);
+ install_element (ISIS_NODE, &no_isis_topology_cmd);
+
install_element (ISIS_NODE, &log_adj_changes_cmd);
install_element (ISIS_NODE, &no_log_adj_changes_cmd);
diff --git a/isisd/isisd.h b/isisd/isisd.h
index e1d3a69f8d..9b6281866c 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -14,10 +14,10 @@
* 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.
+ *
+ * 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 ISISD_H
@@ -120,6 +120,8 @@ struct isis_area
int ip_circuits;
/* logging adjacency changes? */
u_char log_adj_changes;
+ /* multi topology settings */
+ struct list *mt_settings;
int ipv6_circuits;
/* Counters */
u_int32_t circuit_state_changes;
diff --git a/isisd/iso_checksum.c b/isisd/iso_checksum.c
index 294fe9942d..d036c0ba76 100644
--- a/isisd/iso_checksum.c
+++ b/isisd/iso_checksum.c
@@ -15,10 +15,10 @@
* 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.
+ *
+ * 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>
diff --git a/isisd/iso_checksum.h b/isisd/iso_checksum.h
index 5f8d41f9e4..cca6ee24a4 100644
--- a/isisd/iso_checksum.h
+++ b/isisd/iso_checksum.h
@@ -16,9 +16,9 @@
* 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.
+ * 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 _ZEBRA_ISO_CSUM_H
#define _ZEBRA_ISO_CSUM_H
diff --git a/ldpd/Makefile.am b/ldpd/Makefile.am
index 19f819ae36..b760b44573 100644
--- a/ldpd/Makefile.am
+++ b/ldpd/Makefile.am
@@ -16,7 +16,7 @@ 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 \
- ldpe.c log.c neighbor.c notification.c packet.c pfkey.c \
+ ldpe.c log.c logmsg.c neighbor.c notification.c packet.c pfkey.c \
socket.c util.c ldp_vty_cmds.c ldp_vty_conf.c ldp_vty_exec.c \
ldp_debug.c ldp_zebra.c
diff --git a/ldpd/accept.c b/ldpd/accept.c
index 4cb461b908..323558d7fd 100644
--- a/ldpd/accept.c
+++ b/ldpd/accept.c
@@ -58,7 +58,8 @@ accept_add(int fd, int (*cb)(struct thread *), void *arg)
av->arg = arg;
LIST_INSERT_HEAD(&accept_queue.queue, av, entry);
- av->ev = thread_add_read(master, accept_cb, av, av->fd);
+ av->ev = NULL;
+ thread_add_read(master, accept_cb, av, av->fd, &av->ev);
log_debug("%s: accepting on fd %d", __func__, fd);
@@ -85,7 +86,8 @@ accept_pause(void)
{
log_debug(__func__);
accept_unarm();
- accept_queue.evt = thread_add_timer(master, accept_timeout, NULL, 1);
+ accept_queue.evt = NULL;
+ thread_add_timer(master, accept_timeout, NULL, 1, &accept_queue.evt);
}
void
@@ -102,8 +104,10 @@ static void
accept_arm(void)
{
struct accept_ev *av;
- LIST_FOREACH(av, &accept_queue.queue, entry)
- av->ev = thread_add_read(master, accept_cb, av, av->fd);
+ LIST_FOREACH(av, &accept_queue.queue, entry) {
+ av->ev = NULL;
+ thread_add_read(master, accept_cb, av, av->fd, &av->ev);
+ }
}
static void
@@ -118,7 +122,8 @@ static int
accept_cb(struct thread *thread)
{
struct accept_ev *av = THREAD_ARG(thread);
- av->ev = thread_add_read(master, accept_cb, av, av->fd);
+ av->ev = NULL;
+ thread_add_read(master, accept_cb, av, av->fd, &av->ev);
av->accept_cb(thread);
return (0);
diff --git a/ldpd/adjacency.c b/ldpd/adjacency.c
index 8659202ee4..52e2776654 100644
--- a/ldpd/adjacency.c
+++ b/ldpd/adjacency.c
@@ -29,6 +29,8 @@ static __inline int adj_compare(struct adj *, struct adj *);
static int adj_itimer(struct thread *);
static __inline int tnbr_compare(struct tnbr *, struct tnbr *);
static void tnbr_del(struct ldpd_conf *, struct tnbr *);
+static void tnbr_start(struct tnbr *);
+static void tnbr_stop(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 *);
@@ -204,8 +206,9 @@ void
adj_start_itimer(struct adj *adj)
{
THREAD_TIMER_OFF(adj->inactivity_timer);
- adj->inactivity_timer = thread_add_timer(master, adj_itimer, adj,
- adj->holdtime);
+ adj->inactivity_timer = NULL;
+ thread_add_timer(master, adj_itimer, adj, adj->holdtime,
+ &adj->inactivity_timer);
}
void
@@ -245,9 +248,7 @@ tnbr_new(int af, union ldpd_addr *addr)
static void
tnbr_del(struct ldpd_conf *xconf, struct tnbr *tnbr)
{
- tnbr_stop_hello_timer(tnbr);
- if (tnbr->adj)
- adj_del(tnbr->adj, S_SHUTDOWN);
+ tnbr_stop(tnbr);
RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
free(tnbr);
}
@@ -273,6 +274,23 @@ tnbr_check(struct ldpd_conf *xconf, struct tnbr *tnbr)
return (tnbr);
}
+static void
+tnbr_start(struct tnbr *tnbr)
+{
+ send_hello(HELLO_TARGETED, NULL, tnbr);
+ tnbr_start_hello_timer(tnbr);
+ tnbr->state = TNBR_STA_ACTIVE;
+}
+
+static void
+tnbr_stop(struct tnbr *tnbr)
+{
+ tnbr_stop_hello_timer(tnbr);
+ if (tnbr->adj)
+ adj_del(tnbr->adj, S_SHUTDOWN);
+ tnbr->state = TNBR_STA_DOWN;
+}
+
void
tnbr_update(struct tnbr *tnbr)
{
@@ -292,16 +310,12 @@ tnbr_update(struct tnbr *tnbr)
if (!socket_ok || !rtr_id_ok)
return;
- tnbr->state = TNBR_STA_ACTIVE;
- send_hello(HELLO_TARGETED, NULL, tnbr);
-
- tnbr_start_hello_timer(tnbr);
+ tnbr_start(tnbr);
} else if (tnbr->state == TNBR_STA_ACTIVE) {
if (socket_ok && rtr_id_ok)
return;
- tnbr->state = TNBR_STA_DOWN;
- tnbr_stop_hello_timer(tnbr);
+ tnbr_stop(tnbr);
}
}
@@ -353,8 +367,9 @@ static void
tnbr_start_hello_timer(struct tnbr *tnbr)
{
THREAD_TIMER_OFF(tnbr->hello_timer);
- tnbr->hello_timer = thread_add_timer(master, tnbr_hello_timer, tnbr,
- tnbr_get_hello_interval(tnbr));
+ tnbr->hello_timer = NULL;
+ thread_add_timer(master, tnbr_hello_timer, tnbr, tnbr_get_hello_interval(tnbr),
+ &tnbr->hello_timer);
}
static void
diff --git a/ldpd/control.c b/ldpd/control.c
index 5c530e1b70..cde99dc8a9 100644
--- a/ldpd/control.c
+++ b/ldpd/control.c
@@ -37,7 +37,7 @@ struct ctl_conns ctl_conns;
static int control_fd;
int
-control_init(void)
+control_init(char *path)
{
struct sockaddr_un s_un;
int fd;
@@ -51,28 +51,28 @@ control_init(void)
memset(&s_un, 0, sizeof(s_un));
s_un.sun_family = AF_UNIX;
- strlcpy(s_un.sun_path, ctl_sock_path, sizeof(s_un.sun_path));
+ strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path));
- if (unlink(ctl_sock_path) == -1)
+ if (unlink(path) == -1)
if (errno != ENOENT) {
- log_warn("%s: unlink %s", __func__, ctl_sock_path);
+ log_warn("%s: unlink %s", __func__, path);
close(fd);
return (-1);
}
old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
if (bind(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
- log_warn("%s: bind: %s", __func__, ctl_sock_path);
+ log_warn("%s: bind: %s", __func__, path);
close(fd);
umask(old_umask);
return (-1);
}
umask(old_umask);
- if (chmod(ctl_sock_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
+ if (chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
log_warn("%s: chmod", __func__);
close(fd);
- (void)unlink(ctl_sock_path);
+ (void)unlink(path);
return (-1);
}
@@ -93,11 +93,11 @@ control_listen(void)
}
void
-control_cleanup(void)
+control_cleanup(char *path)
{
accept_del(control_fd);
close(control_fd);
- unlink(ctl_sock_path);
+ unlink(path);
}
/* ARGSUSED */
@@ -133,8 +133,9 @@ control_accept(struct thread *thread)
imsg_init(&c->iev.ibuf, connfd);
c->iev.handler_read = control_dispatch_imsg;
- c->iev.ev_read = thread_add_read(master, c->iev.handler_read,
- &c->iev, c->iev.ibuf.fd);
+ c->iev.ev_read = NULL;
+ thread_add_read(master, c->iev.handler_read, &c->iev, c->iev.ibuf.fd,
+ &c->iev.ev_read);
c->iev.handler_write = ldp_write_handler;
c->iev.ev_write = NULL;
diff --git a/ldpd/control.h b/ldpd/control.h
index 32c49fdf87..0e66a1636a 100644
--- a/ldpd/control.h
+++ b/ldpd/control.h
@@ -29,9 +29,9 @@ TAILQ_HEAD(ctl_conns, ctl_conn);
extern struct ctl_conns ctl_conns;
-int control_init(void);
+int control_init(char *);
int control_listen(void);
-void control_cleanup(void);
+void control_cleanup(char *);
int control_imsg_relay(struct imsg *);
#endif /* _CONTROL_H_ */
diff --git a/ldpd/interface.c b/ldpd/interface.c
index 7be8be755e..a064a58b2e 100644
--- a/ldpd/interface.c
+++ b/ldpd/interface.c
@@ -287,8 +287,9 @@ if_start(struct iface *iface, int af)
}
send_hello(HELLO_LINK, ia, NULL);
-
if_start_hello_timer(ia);
+ ia->state = IF_STA_ACTIVE;
+
return (0);
}
@@ -318,9 +319,11 @@ if_reset(struct iface *iface, int af)
if_leave_ipv6_group(iface, &global.mcast_addr_v6);
break;
default:
- fatalx("if_start: unknown af");
+ fatalx("if_reset: unknown af");
}
+ ia->state = IF_STA_DOWN;
+
return (0);
}
@@ -367,14 +370,12 @@ if_update_af(struct iface_af *ia)
!socket_ok || !rtr_id_ok)
return;
- ia->state = IF_STA_ACTIVE;
if_start(ia->iface, ia->af);
} else if (ia->state == IF_STA_ACTIVE) {
if (ia->enabled && ia->iface->operative && addr_ok &&
socket_ok && rtr_id_ok)
return;
- ia->state = IF_STA_DOWN;
if_reset(ia->iface, ia->af);
}
}
@@ -439,8 +440,9 @@ static void
if_start_hello_timer(struct iface_af *ia)
{
THREAD_TIMER_OFF(ia->hello_timer);
- ia->hello_timer = thread_add_timer(master, if_hello_timer, ia,
- if_get_hello_interval(ia));
+ ia->hello_timer = NULL;
+ thread_add_timer(master, if_hello_timer, ia, if_get_hello_interval(ia),
+ &ia->hello_timer);
}
static void
diff --git a/ldpd/lde.c b/ldpd/lde.c
index d8a2924b31..bef35f3194 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -54,9 +54,9 @@ 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 *);
-static void zclient_sync_init (u_short instance);
+static void zclient_sync_init(u_short instance);
static void lde_label_list_init(void);
-static int lde_get_label_chunk (void);
+static int lde_get_label_chunk(void);
static void on_get_label_chunk_response(uint32_t start, uint32_t end);
static uint32_t lde_get_next_label(void);
@@ -80,10 +80,6 @@ static zebra_capabilities_t _caps_p [] =
static struct zebra_privs_t lde_privs =
{
-#if defined(FRR_USER) && defined(FRR_GROUP)
- .user = FRR_USER,
- .group = FRR_GROUP,
-#endif
#if defined(VTY_GROUP)
.vty_group = VTY_GROUP,
#endif
@@ -93,8 +89,11 @@ static struct zebra_privs_t lde_privs =
};
/* List of chunks of labels externally assigned by Zebra */
-struct list *label_chunk_list;
-struct listnode *current_label_chunk;
+static struct list *label_chunk_list;
+static struct listnode *current_label_chunk;
+
+/* Synchronous zclient to request labels */
+static struct zclient *zclient_sync;
/* SIGINT / SIGTERM handler. */
static void
@@ -119,60 +118,17 @@ static struct quagga_signal_t lde_signals[] =
},
};
-static void
-lde_sleep (void)
-{
- sleep(1);
- if (lde_signals[0].caught || lde_signals[1].caught)
- lde_shutdown();
-}
-struct zclient *zclient_sync = NULL;
-static void
-zclient_sync_init(u_short instance)
-{
- /* Initialize special zclient for synchronous message exchanges. */
- log_debug("Initializing synchronous zclient for label manager");
- zclient_sync = zclient_new(master);
- zclient_sync->sock = -1;
- zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
- zclient_sync->instance = instance;
- while (zclient_socket_connect (zclient_sync) < 0) {
- fprintf(stderr, "Error connecting synchronous zclient!\n");
- lde_sleep();
- }
-
- /* Connect to label manager */
- while (lm_label_manager_connect (zclient_sync) != 0) {
- fprintf(stderr, "Error connecting to label manager!\n");
- lde_sleep();
- }
-}
-
/* label decision engine */
void
-lde(const char *user, const char *group, u_short instance)
+lde(void)
{
struct thread thread;
- struct timeval now;
-
- ldeconf = config_new_empty();
#ifdef HAVE_SETPROCTITLE
setproctitle("label decision engine");
#endif
ldpd_process = PROC_LDE_ENGINE;
-
- /* drop privileges */
- if (user)
- lde_privs.user = user;
- if (group)
- lde_privs.group = group;
- zprivs_init(&lde_privs);
-
-#ifdef HAVE_PLEDGE
- if (pledge("stdio recvfd unix", NULL) == -1)
- fatal("pledge");
-#endif
+ log_procname = log_procnames[PROC_LDE_ENGINE];
master = thread_master_create();
@@ -184,35 +140,53 @@ lde(const char *user, const char *group, u_short instance)
fatal(NULL);
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->ev_read = NULL;
+ thread_add_read(master, iev_main->handler_read, iev_main, iev_main->ibuf.fd,
+ &iev_main->ev_read);
iev_main->handler_write = ldp_write_handler;
if ((iev_main_sync = calloc(1, sizeof(struct imsgev))) == NULL)
fatal(NULL);
imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
+ /* create base configuration */
+ ldeconf = config_new_empty();
+
+ /* Fetch next active thread. */
+ while (thread_fetch(master, &thread))
+ thread_call(&thread);
+}
+
+void
+lde_init(struct ldpd_init *init)
+{
+ /* drop privileges */
+ lde_privs.user = init->user;
+ lde_privs.group = init->group;
+ zprivs_init(&lde_privs);
+
+#ifdef HAVE_PLEDGE
+ if (pledge("stdio recvfd unix", NULL) == -1)
+ fatal("pledge");
+#endif
+
/* start the LIB garbage collector */
lde_gc_start_timer();
- gettimeofday(&now, NULL);
- global.uptime = now.tv_sec;
-
/* Init synchronous zclient and label list */
- zclient_sync_init(instance);
+ zclient_serv_path_set(init->zclient_serv_path);
+ zclient_sync_init(init->instance);
lde_label_list_init();
-
- /* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
}
static void
lde_shutdown(void)
{
/* close pipes */
- msgbuf_clear(&iev_ldpe->ibuf.w);
- close(iev_ldpe->ibuf.fd);
+ if (iev_ldpe) {
+ msgbuf_clear(&iev_ldpe->ibuf.w);
+ close(iev_ldpe->ibuf.fd);
+ }
msgbuf_clear(&iev_main->ibuf.w);
close(iev_main->ibuf.fd);
msgbuf_clear(&iev_main_sync->ibuf.w);
@@ -224,7 +198,8 @@ lde_shutdown(void)
config_clear(ldeconf);
- free(iev_ldpe);
+ if (iev_ldpe)
+ free(iev_ldpe);
free(iev_main);
free(iev_main_sync);
@@ -239,6 +214,13 @@ lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
}
+void
+lde_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
+{
+ imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
+ imsg_flush(&iev_main_sync->ibuf);
+}
+
int
lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data,
uint16_t datalen)
@@ -545,11 +527,20 @@ lde_dispatch_parent(struct thread *thread)
fatal(NULL);
imsg_init(&iev_ldpe->ibuf, fd);
iev_ldpe->handler_read = lde_dispatch_imsg;
- iev_ldpe->ev_read = thread_add_read(master,
- iev_ldpe->handler_read, iev_ldpe, iev_ldpe->ibuf.fd);
+ iev_ldpe->ev_read = NULL;
+ thread_add_read(master, iev_ldpe->handler_read, iev_ldpe, iev_ldpe->ibuf.fd,
+ &iev_ldpe->ev_read);
iev_ldpe->handler_write = ldp_write_handler;
iev_ldpe->ev_write = NULL;
break;
+ case IMSG_INIT:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
+ sizeof(struct ldpd_init))
+ fatalx("INIT imsg with wrong len");
+
+ memcpy(&init, imsg.data, sizeof(init));
+ lde_init(&init);
+ break;
case IMSG_RECONF_CONF:
if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
NULL)
@@ -719,7 +710,7 @@ lde_update_label(struct fec_node *fn)
fn->local_label > MPLS_LABEL_RESERVED_MAX)
return (fn->local_label);
- return lde_get_next_label ();
+ return (lde_get_next_label());
}
void
@@ -901,10 +892,23 @@ lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec)
void
lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
{
- struct lde_req *lre;
- struct lde_map *me;
- struct map map;
- struct l2vpn_pw *pw;
+ struct lde_wdraw *lw;
+ struct lde_map *me;
+ struct lde_req *lre;
+ struct map map;
+ struct l2vpn_pw *pw;
+
+ /*
+ * We shouldn't send a new label mapping if we have a pending
+ * label release to receive. In this case, schedule to send a
+ * label mapping as soon as a label release is received.
+ */
+ lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
+ if (lw) {
+ if (!fec_find(&ln->sent_map_pending, &fn->fec))
+ lde_map_pending_add(ln, fn);
+ return;
+ }
/*
* This function skips SL.1 - 3 and SL.9 - 14 because the label
@@ -1210,6 +1214,7 @@ lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
ln->peerid = peerid;
fec_init(&ln->recv_map);
fec_init(&ln->sent_map);
+ fec_init(&ln->sent_map_pending);
fec_init(&ln->recv_req);
fec_init(&ln->sent_req);
fec_init(&ln->sent_wdraw);
@@ -1265,6 +1270,7 @@ lde_nbr_del(struct lde_nbr *ln)
fec_clear(&ln->recv_map, lde_map_free);
fec_clear(&ln->sent_map, lde_map_free);
+ fec_clear(&ln->sent_map_pending, free);
fec_clear(&ln->recv_req, free);
fec_clear(&ln->sent_req, free);
fec_clear(&ln->sent_wdraw, free);
@@ -1415,6 +1421,30 @@ lde_map_free(void *ptr)
free(map);
}
+struct fec *
+lde_map_pending_add(struct lde_nbr *ln, struct fec_node *fn)
+{
+ struct fec *map;
+
+ map = calloc(1, sizeof(*map));
+ if (map == NULL)
+ fatal(__func__);
+
+ *map = fn->fec;
+ if (fec_insert(&ln->sent_map_pending, map))
+ log_warnx("failed to add %s to sent map (pending)",
+ log_fec(map));
+
+ return (map);
+}
+
+void
+lde_map_pending_del(struct lde_nbr *ln, struct fec *map)
+{
+ fec_remove(&ln->sent_map_pending, map);
+ free(map);
+}
+
struct lde_req *
lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
{
@@ -1581,20 +1611,41 @@ lde_address_list_free(struct lde_nbr *ln)
}
static void
+zclient_sync_init(u_short instance)
+{
+ /* Initialize special zclient for synchronous message exchanges. */
+ log_debug("Initializing synchronous zclient for label manager");
+ zclient_sync = zclient_new(master);
+ zclient_sync->sock = -1;
+ zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
+ zclient_sync->instance = instance;
+ while (zclient_socket_connect(zclient_sync) < 0) {
+ log_warnx("Error connecting synchronous zclient!");
+ sleep(1);
+ }
+
+ /* Connect to label manager */
+ while (lm_label_manager_connect(zclient_sync) != 0) {
+ log_warnx("Error connecting to label manager!");
+ sleep(1);
+ }
+}
+
+static void
lde_del_label_chunk(void *val)
{
free(val);
}
+
static int
lde_get_label_chunk(void)
{
- int ret;
- uint32_t start, end;
+ int ret;
+ uint32_t start, end;
log_debug("Getting label chunk");
ret = lm_get_label_chunk(zclient_sync, 0, CHUNK_SIZE, &start, &end);
- if (ret < 0)
- {
+ if (ret < 0) {
log_warnx("Error getting label chunk!");
close(zclient_sync->sock);
zclient_sync->sock = -1;
@@ -1603,8 +1654,9 @@ lde_get_label_chunk(void)
on_get_label_chunk_response(start, end);
- return 0;
+ return (0);
}
+
static void
lde_label_list_init(void)
{
@@ -1613,8 +1665,8 @@ lde_label_list_init(void)
/* get first chunk */
while (lde_get_label_chunk () != 0) {
- fprintf(stderr, "Error getting first label chunk!\n");
- lde_sleep();
+ log_warnx("Error getting first label chunk!");
+ sleep(1);
}
}
@@ -1645,9 +1697,9 @@ on_get_label_chunk_response(uint32_t start, uint32_t end)
static uint32_t
lde_get_next_label(void)
{
- struct label_chunk *label_chunk;
- uint32_t i, pos, size;
- uint32_t label = NO_LABEL;
+ struct label_chunk *label_chunk;
+ uint32_t i, pos, size;
+ uint32_t label = NO_LABEL;
while (current_label_chunk) {
label_chunk = listgetdata(current_label_chunk);
@@ -1669,12 +1721,13 @@ lde_get_next_label(void)
end:
/* we moved till the last chunk, or were not able to find a label,
so let's ask for another one */
- if (!current_label_chunk || current_label_chunk == listtail(label_chunk_list)
- || label == NO_LABEL) {
+ if (!current_label_chunk ||
+ current_label_chunk == listtail(label_chunk_list) ||
+ label == NO_LABEL) {
if (lde_get_label_chunk() != 0)
log_warn("%s: Error getting label chunk!", __func__);
}
- return label;
+ return (label);
}
diff --git a/ldpd/lde.h b/ldpd/lde.h
index 57791cd1b0..1cce483832 100644
--- a/ldpd/lde.h
+++ b/ldpd/lde.h
@@ -95,6 +95,7 @@ struct lde_nbr {
struct fec_tree sent_req;
struct fec_tree recv_map;
struct fec_tree sent_map;
+ struct fec_tree sent_map_pending;
struct fec_tree sent_wdraw;
TAILQ_HEAD(, lde_addr) addr_list;
};
@@ -139,8 +140,10 @@ extern struct nbr_tree lde_nbrs;
extern struct thread *gc_timer;
/* lde.c */
-void lde(const char *, const char *, u_short instance);
+void lde(void);
+void lde_init(struct ldpd_init *);
int lde_imsg_compose_parent(int, pid_t, void *, uint16_t);
+void lde_imsg_compose_parent_sync(int, pid_t, void *, uint16_t);
int lde_imsg_compose_ldpe(int, uint32_t, pid_t, void *, uint16_t);
int lde_acl_check(char *, int, union ldpd_addr *, uint8_t);
uint32_t lde_update_label(struct fec_node *);
@@ -169,6 +172,8 @@ struct lde_nbr *lde_nbr_find_by_lsrid(struct in_addr);
struct lde_nbr *lde_nbr_find_by_addr(int, union ldpd_addr *);
struct lde_map *lde_map_add(struct lde_nbr *, struct fec_node *, int);
void lde_map_del(struct lde_nbr *, struct lde_map *, int);
+struct fec *lde_map_pending_add(struct lde_nbr *, struct fec_node *);
+void lde_map_pending_del(struct lde_nbr *, struct fec *);
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 *);
diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c
index db2682a173..89aa6d4201 100644
--- a/ldpd/lde_lib.c
+++ b/ldpd/lde_lib.c
@@ -383,20 +383,23 @@ lde_kernel_update(struct fec *fec)
if (LIST_EMPTY(&fn->nexthops)) {
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
lde_send_labelwithdraw(ln, fn, NULL, NULL);
- fn->local_label = NO_LABEL;
fn->data = NULL;
- } else {
- uint32_t previous_label;
- previous_label = fn->local_label;
+ /*
+ * Do not deallocate the local label now, do that only in the
+ * LIB garbage collector. This will prevent ldpd from changing
+ * the input label of some prefixes too often when running on
+ * an unstable network. Also, restart the garbage collector
+ * timer so that labels are deallocated only when the network
+ * is stabilized.
+ */
+ lde_gc_start_timer();
+ } else {
fn->local_label = lde_update_label(fn);
-
- if (fn->local_label != NO_LABEL &&
- fn->local_label != previous_label) {
+ if (fn->local_label != NO_LABEL && RB_EMPTY(&fn->upstream))
/* 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) {
@@ -659,6 +662,7 @@ lde_check_release(struct map *map, struct lde_nbr *ln)
struct fec_node *fn;
struct lde_wdraw *lw;
struct lde_map *me;
+ struct fec *pending_map;
/* wildcard label release */
if (map->type == MAP_TYPE_WILDCARD ||
@@ -674,17 +678,24 @@ lde_check_release(struct map *map, struct lde_nbr *ln)
if (fn == NULL)
return;
+ /* LRl.6: check sent map list and remove it if available */
+ me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
+ if (me && (map->label == NO_LABEL || map->label == me->map.label))
+ lde_map_del(ln, me, 1);
+
/* LRl.3: first check if we have a pending withdraw running */
lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
if (lw && (map->label == NO_LABEL || map->label == lw->label)) {
/* LRl.4: delete record of outstanding label withdraw */
lde_wdraw_del(ln, lw);
- }
- /* LRl.6: check sent map list and remove it if available */
- me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
- if (me && (map->label == NO_LABEL || map->label == me->map.label))
- lde_map_del(ln, me, 1);
+ /* send pending label mapping if any */
+ pending_map = fec_find(&ln->sent_map_pending, &fn->fec);
+ if (pending_map) {
+ lde_send_labelmapping(ln, fn, 1);
+ lde_map_pending_del(ln, pending_map);
+ }
+ }
/*
* LRl.11 - 13 are unnecessary since we remove the label from
@@ -699,6 +710,7 @@ lde_check_release_wcard(struct map *map, struct lde_nbr *ln)
struct fec_node *fn;
struct lde_wdraw *lw;
struct lde_map *me;
+ struct fec *pending_map;
RB_FOREACH(f, fec_tree, &ft) {
fn = (struct fec_node *)f;
@@ -708,17 +720,24 @@ lde_check_release_wcard(struct map *map, struct lde_nbr *ln)
if (lde_wildcard_apply(map, &fn->fec, me) == 0)
continue;
+ /* LRl.6: check sent map list and remove it if available */
+ if (me &&
+ (map->label == NO_LABEL || map->label == me->map.label))
+ lde_map_del(ln, me, 1);
+
/* LRl.3: first check if we have a pending withdraw running */
lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
if (lw && (map->label == NO_LABEL || map->label == lw->label)) {
/* LRl.4: delete record of outstanding lbl withdraw */
lde_wdraw_del(ln, lw);
- }
- /* LRl.6: check sent map list and remove it if available */
- if (me &&
- (map->label == NO_LABEL || map->label == me->map.label))
- lde_map_del(ln, me, 1);
+ /* send pending label mapping if any */
+ pending_map = fec_find(&ln->sent_map_pending, &fn->fec);
+ if (pending_map) {
+ lde_send_labelmapping(ln, fn, 1);
+ lde_map_pending_del(ln, pending_map);
+ }
+ }
/*
* LRl.11 - 13 are unnecessary since we remove the label from
@@ -913,8 +932,9 @@ void
lde_gc_start_timer(void)
{
THREAD_TIMER_OFF(gc_timer);
- gc_timer = thread_add_timer(master, lde_gc_timer, NULL,
- LDE_GC_INTERVAL);
+ gc_timer = NULL;
+ thread_add_timer(master, lde_gc_timer, NULL, LDE_GC_INTERVAL,
+ &gc_timer);
}
void
diff --git a/ldpd/ldp_debug.c b/ldpd/ldp_debug.c
index 86b679d8aa..4419f853b4 100644
--- a/ldpd/ldp_debug.c
+++ b/ldpd/ldp_debug.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ldpd/ldp_debug.h b/ldpd/ldp_debug.h
index f944851b6e..6366d3f6ac 100644
--- a/ldpd/ldp_debug.h
+++ b/ldpd/ldp_debug.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _LDP_DEBUG_H_
diff --git a/ldpd/ldp_vty.h b/ldpd/ldp_vty.h
index 8510a394ec..21a486ff65 100644
--- a/ldpd/ldp_vty.h
+++ b/ldpd/ldp_vty.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _LDP_VTY_H_
diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c
index e4fc7b0054..37288f4c00 100644
--- a/ldpd/ldp_vty_conf.c
+++ b/ldpd/ldp_vty_conf.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -1641,7 +1640,7 @@ iface_new_api(struct ldpd_conf *conf, const char *name)
struct iface *iface;
if (ldp_iface_is_configured(conf, ifname))
- return NULL;
+ return (NULL);
iface = if_new(name);
RB_INSERT(iface_head, &conf->iface_tree, iface);
diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c
index a149b7fe35..3463fb6c63 100644
--- a/ldpd/ldp_vty_exec.c
+++ b/ldpd/ldp_vty_exec.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -517,8 +516,7 @@ show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
nbr_state_name(nbr->nbr_state), addr);
if (strlen(addr) > 15)
vty_out(vty, "%s%48s", VTY_NEWLINE, " ");
- vty_out(vty, " %8s%s", nbr->uptime == 0 ? "-" :
- log_time(nbr->uptime), VTY_NEWLINE);
+ vty_out(vty, " %8s%s", log_time(nbr->uptime), VTY_NEWLINE);
break;
case IMSG_CTL_END:
return (1);
@@ -909,6 +907,7 @@ show_nbr_capabilities_msg(struct vty *vty, struct imsg *imsg, struct show_params
vty_out(vty, "Peer LDP Identifier: %s:0%s", inet_ntoa(nbr->id),
VTY_NEWLINE);
show_nbr_capabilities(vty, nbr);
+ vty_out(vty, "%s", VTY_NEWLINE);
break;
case IMSG_CTL_END:
vty_out(vty, "%s", VTY_NEWLINE);
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index fde6e56c64..1a93f5a86f 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -360,6 +359,7 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
struct kroute kr;
int nhnum = 0, nhlen;
size_t nhmark;
+ int add = 0;
memset(&kr, 0, sizeof(kr));
s = zclient->ibuf;
@@ -426,21 +426,14 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
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");
- }
- }
+ if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD ||
+ command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
+ add = 1;
+
+ if (nhnum == 0)
+ debug_zebra_in("route %s %s/%d (%s)", (add) ? "add" : "delete",
+ log_addr(kr.af, &kr.prefix), kr.prefixlen,
+ zebra_route_string(type));
/* loop through all the nexthops */
for (; nhnum > 0; nhnum--) {
@@ -457,19 +450,14 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
stream_getc(s); /* ifindex_num, unused. */
kr.ifindex = stream_getl(s);
- switch (command) {
- case ZEBRA_REDISTRIBUTE_IPV4_ADD:
- case ZEBRA_REDISTRIBUTE_IPV6_ADD:
- 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));
+ debug_zebra_in("route %s %s/%d nexthop %s ifindex %u (%s)",
+ (add) ? "add" : "delete", log_addr(kr.af, &kr.prefix),
+ kr.prefixlen, log_addr(kr.af, &kr.nexthop), kr.ifindex,
+ zebra_route_string(type));
+
+ if (add)
main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
sizeof(kr));
- break;
- default:
- break;
- }
}
main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index def3d2e2f3..710dcd15f4 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -44,8 +44,7 @@
#include "libfrr.h"
static void ldpd_shutdown(void);
-static pid_t start_child(enum ldpd_process, char *, int, int,
- const char *, const char *, const char *, const char *);
+static pid_t start_child(enum ldpd_process, char *, int, int);
static int main_dispatch_ldpe(struct thread *);
static int main_dispatch_lde(struct thread *);
static int main_imsg_send_ipc_sockets(struct imsgbuf *,
@@ -77,6 +76,7 @@ DEFINE_QOBJ_TYPE(l2vpn)
DEFINE_QOBJ_TYPE(ldpd_conf)
struct ldpd_global global;
+struct ldpd_init init;
struct ldpd_conf *ldpd_conf, *vty_conf;
static struct imsgev *iev_ldpe, *iev_ldpe_sync;
@@ -200,14 +200,10 @@ main(int argc, char *argv[])
int lflag = 0, eflag = 0;
int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
int pipe_parent2lde[2], pipe_parent2lde_sync[2];
- char *ctl_sock_custom_path = NULL;
char *ctl_sock_name;
- const char *user = NULL;
- const char *group = NULL;
- u_short instance = 0;
- const char *instance_char = NULL;
ldpd_process = PROC_MAIN;
+ log_procname = log_procnames[ldpd_process];
saved_argv0 = argv[0];
if (saved_argv0 == NULL)
@@ -241,17 +237,14 @@ main(int argc, char *argv[])
* sensible config
*/
ctl_sock_name = (char *)LDPD_SOCKET;
- ctl_sock_custom_path = optarg;
- strlcpy(ctl_sock_path, ctl_sock_custom_path,
- sizeof(ctl_sock_path));
+ strlcpy(ctl_sock_path, optarg, sizeof(ctl_sock_path));
strlcat(ctl_sock_path, "/", sizeof(ctl_sock_path));
strlcat(ctl_sock_path, ctl_sock_name,
sizeof(ctl_sock_path));
break;
case 'n':
- instance = atoi(optarg);
- instance_char = optarg;
- if (instance < 1)
+ init.instance = atoi(optarg);
+ if (init.instance < 1)
exit(0);
break;
case 'L':
@@ -266,8 +259,11 @@ main(int argc, char *argv[])
}
}
- user = ldpd_privs.user;
- group = ldpd_privs.group;
+ strlcpy(init.user, ldpd_privs.user, sizeof(init.user));
+ strlcpy(init.group, ldpd_privs.group, sizeof(init.group));
+ strlcpy(init.ctl_sock_path, ctl_sock_path, sizeof(init.ctl_sock_path));
+ strlcpy(init.zclient_serv_path, zclient_serv_path_get(),
+ sizeof(init.zclient_serv_path));
argc -= optind;
argv += optind;
@@ -281,14 +277,14 @@ main(int argc, char *argv[])
exit(1);
}
- if (lflag)
- lde(user, group, instance);
- else if (eflag)
- ldpe(user, group, ctl_sock_path);
-
openzlog(ldpd_di.progname, "LDP", 0,
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
+ if (lflag)
+ lde();
+ else if (eflag)
+ ldpe();
+
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1)
fatal("socketpair");
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC,
@@ -316,11 +312,9 @@ main(int argc, char *argv[])
/* start children */
lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
- pipe_parent2lde[1], pipe_parent2lde_sync[1],
- user, group, ctl_sock_custom_path, instance_char);
+ pipe_parent2lde[1], pipe_parent2lde_sync[1]);
ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
- pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1],
- user, group, ctl_sock_custom_path, instance_char);
+ pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1]);
/* drop privileges */
zprivs_init(&ldpd_privs);
@@ -335,7 +329,7 @@ main(int argc, char *argv[])
cmd_init(1);
vty_config_lockless();
vty_init(master);
- vrf_init();
+ vrf_init(NULL, NULL, NULL, NULL);
access_list_init();
ldp_vty_init();
ldp_zebra_init(master);
@@ -364,30 +358,35 @@ main(int argc, char *argv[])
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->ev_read = NULL;
+ thread_add_read(master, iev_ldpe->handler_read, iev_ldpe, iev_ldpe->ibuf.fd,
+ &iev_ldpe->ev_read);
iev_ldpe->handler_write = ldp_write_handler;
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->ev_read = NULL;
+ thread_add_read(master, iev_ldpe_sync->handler_read, iev_ldpe_sync, iev_ldpe_sync->ibuf.fd,
+ &iev_ldpe_sync->ev_read);
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->ev_read = NULL;
+ thread_add_read(master, iev_lde->handler_read, iev_lde, iev_lde->ibuf.fd,
+ &iev_lde->ev_read);
iev_lde->handler_write = ldp_write_handler;
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->ev_read = NULL;
+ thread_add_read(master, iev_lde_sync->handler_read, iev_lde_sync, iev_lde_sync->ibuf.fd,
+ &iev_lde_sync->ev_read);
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");
+ main_imsg_compose_both(IMSG_INIT, &init, sizeof(init));
main_imsg_compose_both(IMSG_DEBUG_UPDATE, &ldp_debug,
sizeof(ldp_debug));
main_imsg_send_config(ldpd_conf);
@@ -452,11 +451,9 @@ ldpd_shutdown(void)
}
static pid_t
-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,
- const char *instance)
+start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync)
{
- char *argv[13];
+ char *argv[3];
int argc = 0;
pid_t pid;
@@ -487,29 +484,6 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync,
argv[argc++] = (char *)"-E";
break;
}
- if (user) {
- argv[argc++] = (char *)"-u";
- argv[argc++] = (char *)user;
- }
- if (group) {
- argv[argc++] = (char *)"-g";
- argv[argc++] = (char *)group;
- }
- if (ctl_sock_custom_path) {
- argv[argc++] = (char *)"--ctl_socket";
- argv[argc++] = (char *)ctl_sock_custom_path;
- }
- /* zclient serv path */
-#ifdef HAVE_TCP_ZEBRA
-#else
- argv[argc++] = (char *)"-z";
- argv[argc++] = (char *)zclient_serv_path_get();
-#endif
- /* instance */
- if (instance) {
- argv[argc++] = (char *)"-n";
- argv[argc++] = (char *)instance;
- }
argv[argc++] = NULL;
execvp(argv0, argv);
@@ -720,12 +694,12 @@ void
imsg_event_add(struct imsgev *iev)
{
if (iev->handler_read)
- THREAD_READ_ON(master, iev->ev_read, iev->handler_read, iev,
- iev->ibuf.fd);
+ thread_add_read(master, iev->handler_read, iev, iev->ibuf.fd,
+ &iev->ev_read);
if (iev->handler_write && iev->ibuf.w.queued)
- THREAD_WRITE_ON(master, iev->ev_write, iev->handler_write, iev,
- iev->ibuf.fd);
+ thread_add_write(master, iev->handler_write, iev,
+ iev->ibuf.fd, &iev->ev_write);
}
int
@@ -751,8 +725,8 @@ void
evbuf_event_add(struct evbuf *eb)
{
if (eb->wbuf.queued)
- THREAD_WRITE_ON(master, eb->ev, eb->handler, eb->arg,
- eb->wbuf.fd);
+ thread_add_write(master, eb->handler, eb->arg, eb->wbuf.fd,
+ &eb->ev);
}
void
diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h
index 10742cf0dc..3acc4fbe2d 100644
--- a/ldpd/ldpd.h
+++ b/ldpd/ldpd.h
@@ -146,8 +146,15 @@ enum imsg_type {
IMSG_DEBUG_UPDATE,
IMSG_LOG,
IMSG_ACL_CHECK,
- IMSG_GET_LABEL_CHUNK,
- IMSG_RELEASE_LABEL_CHUNK
+ IMSG_INIT
+};
+
+struct ldpd_init {
+ char user[256];
+ char group[256];
+ char ctl_sock_path[MAXPATHLEN];
+ char zclient_serv_path[MAXPATHLEN];
+ u_short instance;
};
union ldpd_addr {
@@ -439,6 +446,12 @@ enum ldpd_process {
PROC_LDE_ENGINE
} ldpd_process;
+static const char * const log_procnames[] = {
+ "parent",
+ "ldpe",
+ "lde"
+};
+
enum socket_type {
LDP_SOCKET_DISC,
LDP_SOCKET_EDISC,
@@ -504,7 +517,6 @@ struct ldpd_af_global {
struct ldpd_global {
int cmd_opts;
int sighup;
- time_t uptime;
struct in_addr rtr_id;
struct ldpd_af_global ipv4;
struct ldpd_af_global ipv6;
@@ -649,6 +661,7 @@ struct ctl_pw {
extern struct ldpd_conf *ldpd_conf, *vty_conf;
extern struct ldpd_global global;
+extern struct ldpd_init init;
/* parse.y */
struct ldpd_conf *parse_config(char *);
@@ -762,6 +775,30 @@ int sock_set_ipv6_mcast_hops(int, int);
int sock_set_ipv6_mcast(struct iface *);
int sock_set_ipv6_mcast_loop(int);
+/* logmsg.h */
+struct in6_addr;
+union ldpd_addr;
+struct hello_source;
+struct fec;
+
+const char *log_sockaddr(void *);
+const char *log_in6addr(const struct in6_addr *);
+const char *log_in6addr_scope(const struct in6_addr *, unsigned int);
+const char *log_addr(int, const union ldpd_addr *);
+char *log_label(uint32_t);
+const char *log_time(time_t);
+char *log_hello_src(const struct hello_source *);
+const char *log_map(const struct map *);
+const char *log_fec(const struct fec *);
+const char *af_name(int);
+const char *socket_name(int);
+const char *nbr_state_name(int);
+const char *if_state_name(int);
+const char *if_type_name(enum iface_type);
+const char *msg_name(uint16_t);
+const char *status_code_name(uint32_t);
+const char *pw_type_name(uint16_t);
+
/* quagga */
extern struct thread_master *master;
extern char ctl_sock_path[MAXPATHLEN];
diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c
index 1bec3d2a95..ce2441ca2f 100644
--- a/ldpd/ldpe.c
+++ b/ldpd/ldpe.c
@@ -66,10 +66,6 @@ static zebra_capabilities_t _caps_p [] =
struct zebra_privs_t ldpe_privs =
{
-#if defined(FRR_USER) && defined(FRR_GROUP)
- .user = FRR_USER,
- .group = FRR_GROUP,
-#endif
#if defined(VTY_GROUP)
.vty_group = VTY_GROUP,
#endif
@@ -103,46 +99,17 @@ static struct quagga_signal_t ldpe_signals[] =
/* label distribution protocol engine */
void
-ldpe(const char *user, const char *group, const char *ctl_path)
+ldpe(void)
{
struct thread thread;
- leconf = config_new_empty();
-
#ifdef HAVE_SETPROCTITLE
setproctitle("ldp engine");
#endif
ldpd_process = PROC_LDP_ENGINE;
-
- LIST_INIT(&global.addr_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");
- if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
- fatal("inet_pton");
-#ifdef __OpenBSD__
- global.pfkeysock = pfkey_init();
-#endif
-
- /* drop privileges */
- if (user)
- ldpe_privs.user = user;
- if (group)
- ldpe_privs.group = group;
- zprivs_init(&ldpe_privs);
-
- strlcpy(ctl_sock_path, ctl_path, sizeof(ctl_sock_path));
- if (control_init() == -1)
- fatalx("control socket setup failed");
-
-#ifdef HAVE_PLEDGE
- if (pledge("stdio cpath inet mcast recvfd", NULL) == -1)
- fatal("pledge");
-#endif
+ log_procname = log_procnames[ldpd_process];
master = thread_master_create();
- accept_init();
/* setup signal handler */
signal_init(master, array_size(ldpe_signals), ldpe_signals);
@@ -152,18 +119,57 @@ ldpe(const char *user, const char *group, const char *ctl_path)
fatal(NULL);
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->ev_read = NULL;
+ thread_add_read(master, iev_main->handler_read, iev_main, iev_main->ibuf.fd,
+ &iev_main->ev_read);
iev_main->handler_write = ldp_write_handler;
if ((iev_main_sync = calloc(1, sizeof(struct imsgev))) == NULL)
fatal(NULL);
imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
+ /* create base configuration */
+ leconf = config_new_empty();
+
+ /* Fetch next active thread. */
+ while (thread_fetch(master, &thread))
+ thread_call(&thread);
+}
+
+void
+ldpe_init(struct ldpd_init *init)
+{
+ /* drop privileges */
+ ldpe_privs.user = init->user;
+ ldpe_privs.group = init->group;
+ zprivs_init(&ldpe_privs);
+
+ /* listen on ldpd control socket */
+ strlcpy(ctl_sock_path, init->ctl_sock_path, sizeof(ctl_sock_path));
+ if (control_init(ctl_sock_path) == -1)
+ fatalx("control socket setup failed");
+ TAILQ_INIT(&ctl_conns);
+ control_listen();
+
+#ifdef HAVE_PLEDGE
+ if (pledge("stdio cpath inet mcast recvfd", NULL) == -1)
+ fatal("pledge");
+#endif
+
+ LIST_INIT(&global.addr_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");
+ if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
+ fatal("inet_pton");
#ifdef __OpenBSD__
- if (sysdep.no_pfkey == 0)
- pfkey_ev = thread_add_read(master, ldpe_dispatch_pfkey,
- NULL, global.pfkeysock);
+ global.pfkeysock = pfkey_init();
+ if (sysdep.no_pfkey == 0) {
+ pfkey_ev = NULL;
+ thread_add_read(master, ldpe_dispatch_pfkey, NULL, global.pfkeysock,
+ &pfkey_ev);
+ }
#endif
/* mark sockets as closed */
@@ -174,16 +180,10 @@ ldpe(const char *user, const char *group, const char *ctl_path)
global.ipv6.ldp_edisc_socket = -1;
global.ipv6.ldp_session_socket = -1;
- /* listen on ldpd control socket */
- TAILQ_INIT(&ctl_conns);
- control_listen();
-
if ((pkt_ptr = calloc(1, IBUF_READ_SIZE)) == NULL)
fatal(__func__);
- /* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ accept_init();
}
static void
@@ -193,16 +193,18 @@ ldpe_shutdown(void)
struct adj *adj;
/* close pipes */
- msgbuf_write(&iev_lde->ibuf.w);
- msgbuf_clear(&iev_lde->ibuf.w);
- close(iev_lde->ibuf.fd);
+ if (iev_lde) {
+ msgbuf_write(&iev_lde->ibuf.w);
+ msgbuf_clear(&iev_lde->ibuf.w);
+ close(iev_lde->ibuf.fd);
+ }
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();
+ control_cleanup(ctl_sock_path);
config_clear(leconf);
#ifdef __OpenBSD__
@@ -223,7 +225,8 @@ ldpe_shutdown(void)
adj_del(adj, S_SHUTDOWN);
/* clean up */
- free(iev_lde);
+ if (iev_lde)
+ free(iev_lde);
free(iev_main);
free(iev_main_sync);
free(pkt_ptr);
@@ -239,6 +242,13 @@ ldpe_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
}
+void
+ldpe_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
+{
+ imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
+ imsg_flush(&iev_main_sync->ibuf);
+}
+
int
ldpe_imsg_compose_lde(int type, uint32_t peerid, pid_t pid, void *data,
uint16_t datalen)
@@ -346,11 +356,20 @@ ldpe_dispatch_main(struct thread *thread)
fatal(NULL);
imsg_init(&iev_lde->ibuf, fd);
iev_lde->handler_read = ldpe_dispatch_lde;
- iev_lde->ev_read = thread_add_read(master,
- iev_lde->handler_read, iev_lde, iev_lde->ibuf.fd);
+ iev_lde->ev_read = NULL;
+ thread_add_read(master, iev_lde->handler_read, iev_lde, iev_lde->ibuf.fd,
+ &iev_lde->ev_read);
iev_lde->handler_write = ldp_write_handler;
iev_lde->ev_write = NULL;
break;
+ case IMSG_INIT:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
+ sizeof(struct ldpd_init))
+ fatalx("INIT imsg with wrong len");
+
+ memcpy(&init, imsg.data, sizeof(init));
+ ldpe_init(&init);
+ break;
case IMSG_CLOSE_SOCKETS:
af = imsg.hdr.peerid;
@@ -679,8 +698,9 @@ ldpe_dispatch_pfkey(struct thread *thread)
{
int fd = THREAD_FD(thread);
- pfkey_ev = thread_add_read(master, ldpe_dispatch_pfkey,
- NULL, global.pfkeysock);
+ pfkey_ev = NULL;
+ thread_add_read(master, ldpe_dispatch_pfkey, NULL, global.pfkeysock,
+ &pfkey_ev);
if (pfkey_read(fd, NULL) == -1)
fatal("pfkey_read failed, exiting...");
@@ -699,13 +719,15 @@ ldpe_setup_sockets(int af, int disc_socket, int edisc_socket,
/* discovery socket */
af_global->ldp_disc_socket = disc_socket;
- af_global->disc_ev = thread_add_read(master, disc_recv_packet,
- &af_global->disc_ev, af_global->ldp_disc_socket);
+ af_global->disc_ev = NULL;
+ thread_add_read(master, disc_recv_packet, &af_global->disc_ev, af_global->ldp_disc_socket,
+ &af_global->disc_ev);
/* extended discovery socket */
af_global->ldp_edisc_socket = edisc_socket;
- af_global->edisc_ev = thread_add_read(master, disc_recv_packet,
- &af_global->edisc_ev, af_global->ldp_edisc_socket);
+ af_global->edisc_ev = NULL;
+ thread_add_read(master, disc_recv_packet, &af_global->edisc_ev, af_global->ldp_edisc_socket,
+ &af_global->edisc_ev);
/* session socket */
af_global->ldp_session_socket = session_socket;
diff --git a/ldpd/ldpe.h b/ldpd/ldpe.h
index a3f41a8b9f..d34ca4dc24 100644
--- a/ldpd/ldpe.h
+++ b/ldpd/ldpe.h
@@ -195,9 +195,11 @@ int tlv_decode_fec_elm(struct nbr *, struct ldp_msg *, char *,
uint16_t, struct map *);
/* ldpe.c */
-void ldpe(const char *, const char *, const char *);
+void ldpe(void);
+void ldpe_init(struct ldpd_init *);
int ldpe_imsg_compose_parent(int, pid_t, void *,
uint16_t);
+void ldpe_imsg_compose_parent_sync(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);
diff --git a/ldpd/log.c b/ldpd/log.c
index 407668bb03..b138e5754a 100644
--- a/ldpd/log.c
+++ b/ldpd/log.c
@@ -25,15 +25,8 @@
#include <lib/log.h>
#include <lib/log_int.h>
-#include "mpls.h"
-static const char * const procnames[] = {
- "parent",
- "ldpe",
- "lde"
-};
-
-void vlog(int, const char *, va_list);
+const char *log_procname;
void
logit(int pri, const char *fmt, ...)
@@ -53,11 +46,13 @@ vlog(int pri, const char *fmt, va_list ap)
switch (ldpd_process) {
case PROC_LDE_ENGINE:
vsnprintf(buf, sizeof(buf), fmt, ap);
- lde_imsg_compose_parent(IMSG_LOG, pri, buf, strlen(buf) + 1);
+ lde_imsg_compose_parent_sync(IMSG_LOG, pri, buf,
+ strlen(buf) + 1);
break;
case PROC_LDP_ENGINE:
vsnprintf(buf, sizeof(buf), fmt, ap);
- ldpe_imsg_compose_parent(IMSG_LOG, pri, buf, strlen(buf) + 1);
+ ldpe_imsg_compose_parent_sync(IMSG_LOG, pri, buf,
+ strlen(buf) + 1);
break;
case PROC_MAIN:
vzlog(pri, fmt, ap);
@@ -73,16 +68,16 @@ log_warn(const char *emsg, ...)
/* best effort to even work in out of memory situations */
if (emsg == NULL)
- logit(LOG_CRIT, "%s", strerror(errno));
+ logit(LOG_ERR, "%s", strerror(errno));
else {
va_start(ap, emsg);
if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
/* we tried it... */
- vlog(LOG_CRIT, emsg, ap);
- logit(LOG_CRIT, "%s", strerror(errno));
+ vlog(LOG_ERR, emsg, ap);
+ logit(LOG_ERR, "%s", strerror(errno));
} else {
- vlog(LOG_CRIT, nfmt, ap);
+ vlog(LOG_ERR, nfmt, ap);
free(nfmt);
}
va_end(ap);
@@ -95,7 +90,7 @@ log_warnx(const char *emsg, ...)
va_list ap;
va_start(ap, emsg);
- vlog(LOG_CRIT, emsg, ap);
+ vlog(LOG_ERR, emsg, ap);
va_end(ap);
}
@@ -133,15 +128,15 @@ void
fatal(const char *emsg)
{
if (emsg == NULL)
- logit(LOG_CRIT, "fatal in %s: %s", procnames[ldpd_process],
+ logit(LOG_CRIT, "fatal in %s: %s", log_procname,
strerror(errno));
else
if (errno)
logit(LOG_CRIT, "fatal in %s: %s: %s",
- procnames[ldpd_process], emsg, strerror(errno));
+ log_procname, emsg, strerror(errno));
else
logit(LOG_CRIT, "fatal in %s: %s",
- procnames[ldpd_process], emsg);
+ log_procname, emsg);
exit(1);
}
@@ -152,465 +147,3 @@ fatalx(const char *emsg)
errno = 0;
fatal(emsg);
}
-
-#define NUM_LOGS 4
-const char *
-log_sockaddr(void *vp)
-{
- static char buf[NUM_LOGS][NI_MAXHOST];
- static int round = 0;
- struct sockaddr *sa = vp;
-
- round = (round + 1) % NUM_LOGS;
-
- if (getnameinfo(sa, sockaddr_len(sa), buf[round], NI_MAXHOST, NULL, 0,
- NI_NUMERICHOST))
- return ("(unknown)");
- else
- return (buf[round]);
-}
-
-const char *
-log_in6addr(const struct in6_addr *addr)
-{
- struct sockaddr_in6 sa_in6;
-
- memset(&sa_in6, 0, sizeof(sa_in6));
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- sa_in6.sin6_len = sizeof(sa_in6);
-#endif
- sa_in6.sin6_family = AF_INET6;
- sa_in6.sin6_addr = *addr;
-
- recoverscope(&sa_in6);
-
- return (log_sockaddr(&sa_in6));
-}
-
-const char *
-log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
-{
- struct sockaddr_in6 sa_in6;
-
- memset(&sa_in6, 0, sizeof(sa_in6));
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- sa_in6.sin6_len = sizeof(sa_in6);
-#endif
- sa_in6.sin6_family = AF_INET6;
- sa_in6.sin6_addr = *addr;
-
- addscope(&sa_in6, ifindex);
-
- return (log_sockaddr(&sa_in6));
-}
-
-const char *
-log_addr(int af, const union ldpd_addr *addr)
-{
- static char buf[NUM_LOGS][INET6_ADDRSTRLEN];
- static int round = 0;
-
- switch (af) {
- case AF_INET:
- round = (round + 1) % NUM_LOGS;
- if (inet_ntop(AF_INET, &addr->v4, buf[round],
- sizeof(buf[round])) == NULL)
- return ("???");
- return (buf[round]);
- case AF_INET6:
- return (log_in6addr(&addr->v6));
- default:
- break;
- }
-
- return ("???");
-}
-
-#define TF_BUFS 4
-#define TF_LEN 32
-
-char *
-log_label(uint32_t label)
-{
- char *buf;
- static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
- static int idx = 0;
-
- buf = tfbuf[idx++];
- if (idx == TF_BUFS)
- idx = 0;
-
- switch (label) {
- case NO_LABEL:
- snprintf(buf, TF_LEN, "-");
- break;
- case MPLS_LABEL_IMPLNULL:
- snprintf(buf, TF_LEN, "imp-null");
- break;
- case MPLS_LABEL_IPV4NULL:
- case MPLS_LABEL_IPV6NULL:
- snprintf(buf, TF_LEN, "exp-null");
- break;
- default:
- snprintf(buf, TF_LEN, "%u", label);
- break;
- }
-
- return (buf);
-}
-
-const char *
-log_time(time_t t)
-{
- char *buf;
- static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
- static int idx = 0;
- unsigned int sec, min, hrs, day, week;
-
- buf = tfbuf[idx++];
- if (idx == TF_BUFS)
- idx = 0;
-
- week = t;
-
- sec = week % 60;
- week /= 60;
- min = week % 60;
- week /= 60;
- hrs = week % 24;
- week /= 24;
- day = week % 7;
- week /= 7;
-
- if (week > 0)
- snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs);
- else if (day > 0)
- snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
- else
- snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
-
- return (buf);
-}
-
-char *
-log_hello_src(const struct hello_source *src)
-{
- static char buf[64];
-
- switch (src->type) {
- case HELLO_LINK:
- snprintf(buf, sizeof(buf), "iface %s",
- src->link.ia->iface->name);
- break;
- case HELLO_TARGETED:
- snprintf(buf, sizeof(buf), "source %s",
- log_addr(src->target->af, &src->target->addr));
- break;
- }
-
- return (buf);
-}
-
-const char *
-log_map(const struct map *map)
-{
- static char buf[128];
-
- switch (map->type) {
- case MAP_TYPE_WILDCARD:
- if (snprintf(buf, sizeof(buf), "wildcard") < 0)
- return ("???");
- break;
- case MAP_TYPE_PREFIX:
- if (snprintf(buf, sizeof(buf), "%s/%u",
- log_addr(map->fec.prefix.af, &map->fec.prefix.prefix),
- map->fec.prefix.prefixlen) == -1)
- return ("???");
- break;
- case MAP_TYPE_PWID:
- if (snprintf(buf, sizeof(buf), "pw-id %u group-id %u (%s)",
- map->fec.pwid.pwid, map->fec.pwid.group_id,
- pw_type_name(map->fec.pwid.type)) == -1)
- return ("???");
- break;
- case MAP_TYPE_TYPED_WCARD:
- if (snprintf(buf, sizeof(buf), "typed wildcard") < 0)
- return ("???");
- switch (map->fec.twcard.type) {
- case MAP_TYPE_PREFIX:
- if (snprintf(buf + strlen(buf), sizeof(buf) -
- strlen(buf), " (prefix, address-family %s)",
- af_name(map->fec.twcard.u.prefix_af)) < 0)
- return ("???");
- break;
- case MAP_TYPE_PWID:
- if (snprintf(buf + strlen(buf), sizeof(buf) -
- strlen(buf), " (pwid, type %s)",
- pw_type_name(map->fec.twcard.u.pw_type)) < 0)
- return ("???");
- break;
- default:
- if (snprintf(buf + strlen(buf), sizeof(buf) -
- strlen(buf), " (unknown type)") < 0)
- return ("???");
- break;
- }
- break;
- default:
- return ("???");
- }
-
- return (buf);
-}
-
-const char *
-log_fec(const struct fec *fec)
-{
- static char buf[64];
- union ldpd_addr addr;
-
- switch (fec->type) {
- case FEC_TYPE_IPV4:
- addr.v4 = fec->u.ipv4.prefix;
- if (snprintf(buf, sizeof(buf), "ipv4 %s/%u",
- log_addr(AF_INET, &addr), fec->u.ipv4.prefixlen) == -1)
- return ("???");
- break;
- case FEC_TYPE_IPV6:
- addr.v6 = fec->u.ipv6.prefix;
- if (snprintf(buf, sizeof(buf), "ipv6 %s/%u",
- log_addr(AF_INET6, &addr), fec->u.ipv6.prefixlen) == -1)
- return ("???");
- break;
- case FEC_TYPE_PWID:
- if (snprintf(buf, sizeof(buf),
- "pwid %u (%s) - %s",
- fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
- inet_ntoa(fec->u.pwid.lsr_id)) == -1)
- return ("???");
- break;
- default:
- return ("???");
- }
-
- return (buf);
-}
-
-/* names */
-const char *
-af_name(int af)
-{
- switch (af) {
- case AF_INET:
- return ("ipv4");
- case AF_INET6:
- return ("ipv6");
-#ifdef AF_MPLS
- case AF_MPLS:
- return ("mpls");
-#endif
- default:
- return ("UNKNOWN");
- }
-}
-
-const char *
-socket_name(int type)
-{
- switch (type) {
- case LDP_SOCKET_DISC:
- return ("discovery");
- case LDP_SOCKET_EDISC:
- return ("extended discovery");
- case LDP_SOCKET_SESSION:
- return ("session");
- default:
- return ("UNKNOWN");
- }
-}
-
-const char *
-nbr_state_name(int state)
-{
- switch (state) {
- case NBR_STA_PRESENT:
- return ("PRESENT");
- case NBR_STA_INITIAL:
- return ("INITIALIZED");
- case NBR_STA_OPENREC:
- return ("OPENREC");
- case NBR_STA_OPENSENT:
- return ("OPENSENT");
- case NBR_STA_OPER:
- return ("OPERATIONAL");
- default:
- return ("UNKNOWN");
- }
-}
-
-const char *
-if_state_name(int state)
-{
- switch (state) {
- case IF_STA_DOWN:
- return ("DOWN");
- case IF_STA_ACTIVE:
- return ("ACTIVE");
- default:
- return ("UNKNOWN");
- }
-}
-
-const char *
-if_type_name(enum iface_type type)
-{
- switch (type) {
- case IF_TYPE_POINTOPOINT:
- return ("POINTOPOINT");
- case IF_TYPE_BROADCAST:
- return ("BROADCAST");
- }
- /* NOTREACHED */
- return ("UNKNOWN");
-}
-
-const char *
-msg_name(uint16_t msg)
-{
- static char buf[16];
-
- switch (msg) {
- case MSG_TYPE_NOTIFICATION:
- return ("notification");
- case MSG_TYPE_HELLO:
- return ("hello");
- case MSG_TYPE_INIT:
- return ("initialization");
- case MSG_TYPE_KEEPALIVE:
- return ("keepalive");
- case MSG_TYPE_CAPABILITY:
- return ("capability");
- case MSG_TYPE_ADDR:
- return ("address");
- case MSG_TYPE_ADDRWITHDRAW:
- return ("address withdraw");
- case MSG_TYPE_LABELMAPPING:
- return ("label mapping");
- case MSG_TYPE_LABELREQUEST:
- return ("label request");
- case MSG_TYPE_LABELWITHDRAW:
- return ("label withdraw");
- case MSG_TYPE_LABELRELEASE:
- return ("label release");
- case MSG_TYPE_LABELABORTREQ:
- default:
- snprintf(buf, sizeof(buf), "[%08x]", msg);
- return (buf);
- }
-}
-
-const char *
-status_code_name(uint32_t status)
-{
- static char buf[16];
-
- switch (status) {
- case S_SUCCESS:
- return ("Success");
- case S_BAD_LDP_ID:
- return ("Bad LDP Identifier");
- case S_BAD_PROTO_VER:
- return ("Bad Protocol Version");
- case S_BAD_PDU_LEN:
- return ("Bad PDU Length");
- case S_UNKNOWN_MSG:
- return ("Unknown Message Type");
- case S_BAD_MSG_LEN:
- return ("Bad Message Length");
- case S_UNKNOWN_TLV:
- return ("Unknown TLV");
- case S_BAD_TLV_LEN:
- return ("Bad TLV Length");
- case S_BAD_TLV_VAL:
- return ("Malformed TLV Value");
- case S_HOLDTIME_EXP:
- return ("Hold Timer Expired");
- case S_SHUTDOWN:
- return ("Shutdown");
- case S_LOOP_DETECTED:
- return ("Loop Detected");
- case S_UNKNOWN_FEC:
- return ("Unknown FEC");
- case S_NO_ROUTE:
- return ("No Route");
- case S_NO_LABEL_RES:
- return ("No Label Resources");
- case S_AVAILABLE:
- return ("Label Resources Available");
- case S_NO_HELLO:
- return ("Session Rejected, No Hello");
- case S_PARM_ADV_MODE:
- return ("Rejected Advertisement Mode Parameter");
- case S_MAX_PDU_LEN:
- return ("Rejected Max PDU Length Parameter");
- case S_PARM_L_RANGE:
- return ("Rejected Label Range Parameter");
- case S_KEEPALIVE_TMR:
- return ("KeepAlive Timer Expired");
- case S_LAB_REQ_ABRT:
- return ("Label Request Aborted");
- case S_MISS_MSG:
- return ("Missing Message Parameters");
- case S_UNSUP_ADDR:
- return ("Unsupported Address Family");
- case S_KEEPALIVE_BAD:
- return ("Bad KeepAlive Time");
- case S_INTERN_ERR:
- return ("Internal Error");
- case S_ILLEGAL_CBIT:
- return ("Illegal C-Bit");
- case S_WRONG_CBIT:
- return ("Wrong C-Bit");
- case S_INCPT_BITRATE:
- return ("Incompatible bit-rate");
- case S_CEP_MISCONF:
- return ("CEP-TDM mis-configuration");
- case S_PW_STATUS:
- return ("PW Status");
- case S_UNASSIGN_TAI:
- return ("Unassigned/Unrecognized TAI");
- case S_MISCONF_ERR:
- return ("Generic Misconfiguration Error");
- case S_WITHDRAW_MTHD:
- return ("Label Withdraw PW Status Method");
- case S_UNSSUPORTDCAP:
- return ("Unsupported Capability");
- case S_ENDOFLIB:
- return ("End-of-LIB");
- case S_TRANS_MISMTCH:
- return ("Transport Connection Mismatch");
- case S_DS_NONCMPLNCE:
- return ("Dual-Stack Noncompliance");
- default:
- snprintf(buf, sizeof(buf), "[%08x]", status);
- return (buf);
- }
-}
-
-const char *
-pw_type_name(uint16_t pw_type)
-{
- static char buf[64];
-
- switch (pw_type) {
- case PW_TYPE_ETHERNET_TAGGED:
- return ("Eth Tagged");
- case PW_TYPE_ETHERNET:
- return ("Ethernet");
- case PW_TYPE_WILDCARD:
- return ("Wildcard");
- default:
- snprintf(buf, sizeof(buf), "[%0x]", pw_type);
- return (buf);
- }
-}
diff --git a/ldpd/log.h b/ldpd/log.h
index 4d6da43cac..8c236ff5fe 100644
--- a/ldpd/log.h
+++ b/ldpd/log.h
@@ -16,50 +16,32 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef _LOG_H_
-#define _LOG_H_
+#ifndef LOG_H
+#define LOG_H
#include <stdarg.h>
-struct in6_addr;
-union ldpd_addr;
-struct hello_source;
-struct fec;
+extern const char *log_procname;
-void logit(int, const char *, ...)
- __attribute__((__format__ (printf, 2, 3)));
-void log_warn(const char *, ...)
- __attribute__((__format__ (printf, 1, 2)));
-void log_warnx(const char *, ...)
- __attribute__((__format__ (printf, 1, 2)));
-void log_info(const char *, ...)
- __attribute__((__format__ (printf, 1, 2)));
-void log_notice(const char *, ...)
- __attribute__((__format__ (printf, 1, 2)));
-void log_debug(const char *, ...)
- __attribute__((__format__ (printf, 1, 2)));
-void fatal(const char *)
- __attribute__ ((noreturn))
- __attribute__((__format__ (printf, 1, 0)));
-void fatalx(const char *)
- __attribute__ ((noreturn))
- __attribute__((__format__ (printf, 1, 0)));
-const char *log_sockaddr(void *);
-const char *log_in6addr(const struct in6_addr *);
-const char *log_in6addr_scope(const struct in6_addr *, unsigned int);
-const char *log_addr(int, const union ldpd_addr *);
-char *log_label(uint32_t);
-const char *log_time(time_t);
-char *log_hello_src(const struct hello_source *);
-const char *log_map(const struct map *);
-const char *log_fec(const struct fec *);
-const char *af_name(int);
-const char *socket_name(int);
-const char *nbr_state_name(int);
-const char *if_state_name(int);
-const char *if_type_name(enum iface_type);
-const char *msg_name(uint16_t);
-const char *status_code_name(uint32_t);
-const char *pw_type_name(uint16_t);
+void logit(int, const char *, ...)
+ __attribute__((__format__ (printf, 2, 3)));
+void vlog(int, const char *, va_list)
+ __attribute__((__format__ (printf, 2, 0)));
+void log_warn(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void log_warnx(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void log_info(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void log_notice(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void log_debug(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void fatal(const char *)
+ __attribute__ ((noreturn))
+ __attribute__((__format__ (printf, 1, 0)));
+void fatalx(const char *)
+ __attribute__ ((noreturn))
+ __attribute__((__format__ (printf, 1, 0)));
-#endif /* _LOG_H_ */
+#endif /* LOG_H */
diff --git a/ldpd/logmsg.c b/ldpd/logmsg.c
new file mode 100644
index 0000000000..c819b33b43
--- /dev/null
+++ b/ldpd/logmsg.c
@@ -0,0 +1,487 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
+ *
+ * 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.
+ */
+
+#include <zebra.h>
+
+#include "mpls.h"
+
+#include "ldpd.h"
+#include "ldpe.h"
+#include "lde.h"
+
+#define NUM_LOGS 4
+const char *
+log_sockaddr(void *vp)
+{
+ static char buf[NUM_LOGS][NI_MAXHOST];
+ static int round = 0;
+ struct sockaddr *sa = vp;
+
+ round = (round + 1) % NUM_LOGS;
+
+ if (getnameinfo(sa, sockaddr_len(sa), buf[round], NI_MAXHOST, NULL, 0,
+ NI_NUMERICHOST))
+ return ("(unknown)");
+ else
+ return (buf[round]);
+}
+
+const char *
+log_in6addr(const struct in6_addr *addr)
+{
+ struct sockaddr_in6 sa_in6;
+
+ memset(&sa_in6, 0, sizeof(sa_in6));
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+ sa_in6.sin6_len = sizeof(sa_in6);
+#endif
+ sa_in6.sin6_family = AF_INET6;
+ sa_in6.sin6_addr = *addr;
+
+ recoverscope(&sa_in6);
+
+ return (log_sockaddr(&sa_in6));
+}
+
+const char *
+log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
+{
+ struct sockaddr_in6 sa_in6;
+
+ memset(&sa_in6, 0, sizeof(sa_in6));
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+ sa_in6.sin6_len = sizeof(sa_in6);
+#endif
+ sa_in6.sin6_family = AF_INET6;
+ sa_in6.sin6_addr = *addr;
+
+ addscope(&sa_in6, ifindex);
+
+ return (log_sockaddr(&sa_in6));
+}
+
+const char *
+log_addr(int af, const union ldpd_addr *addr)
+{
+ static char buf[NUM_LOGS][INET6_ADDRSTRLEN];
+ static int round = 0;
+
+ switch (af) {
+ case AF_INET:
+ round = (round + 1) % NUM_LOGS;
+ if (inet_ntop(AF_INET, &addr->v4, buf[round],
+ sizeof(buf[round])) == NULL)
+ return ("???");
+ return (buf[round]);
+ case AF_INET6:
+ return (log_in6addr(&addr->v6));
+ default:
+ break;
+ }
+
+ return ("???");
+}
+
+#define TF_BUFS 4
+#define TF_LEN 32
+
+char *
+log_label(uint32_t label)
+{
+ char *buf;
+ static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
+ static int idx = 0;
+
+ buf = tfbuf[idx++];
+ if (idx == TF_BUFS)
+ idx = 0;
+
+ switch (label) {
+ case NO_LABEL:
+ snprintf(buf, TF_LEN, "-");
+ break;
+ case MPLS_LABEL_IMPLNULL:
+ snprintf(buf, TF_LEN, "imp-null");
+ break;
+ case MPLS_LABEL_IPV4NULL:
+ case MPLS_LABEL_IPV6NULL:
+ snprintf(buf, TF_LEN, "exp-null");
+ break;
+ default:
+ snprintf(buf, TF_LEN, "%u", label);
+ break;
+ }
+
+ return (buf);
+}
+
+const char *
+log_time(time_t t)
+{
+ char *buf;
+ static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
+ static int idx = 0;
+ unsigned int sec, min, hrs, day, week;
+
+ buf = tfbuf[idx++];
+ if (idx == TF_BUFS)
+ idx = 0;
+
+ week = t;
+
+ sec = week % 60;
+ week /= 60;
+ min = week % 60;
+ week /= 60;
+ hrs = week % 24;
+ week /= 24;
+ day = week % 7;
+ week /= 7;
+
+ if (week > 0)
+ snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs);
+ else if (day > 0)
+ snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
+ else
+ snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
+
+ return (buf);
+}
+
+char *
+log_hello_src(const struct hello_source *src)
+{
+ static char buf[64];
+
+ switch (src->type) {
+ case HELLO_LINK:
+ snprintf(buf, sizeof(buf), "iface %s",
+ src->link.ia->iface->name);
+ break;
+ case HELLO_TARGETED:
+ snprintf(buf, sizeof(buf), "source %s",
+ log_addr(src->target->af, &src->target->addr));
+ break;
+ }
+
+ return (buf);
+}
+
+const char *
+log_map(const struct map *map)
+{
+ static char buf[128];
+
+ switch (map->type) {
+ case MAP_TYPE_WILDCARD:
+ if (snprintf(buf, sizeof(buf), "wildcard") < 0)
+ return ("???");
+ break;
+ case MAP_TYPE_PREFIX:
+ if (snprintf(buf, sizeof(buf), "%s/%u",
+ log_addr(map->fec.prefix.af, &map->fec.prefix.prefix),
+ map->fec.prefix.prefixlen) == -1)
+ return ("???");
+ break;
+ case MAP_TYPE_PWID:
+ if (snprintf(buf, sizeof(buf), "pw-id %u group-id %u (%s)",
+ map->fec.pwid.pwid, map->fec.pwid.group_id,
+ pw_type_name(map->fec.pwid.type)) == -1)
+ return ("???");
+ break;
+ case MAP_TYPE_TYPED_WCARD:
+ if (snprintf(buf, sizeof(buf), "typed wildcard") < 0)
+ return ("???");
+ switch (map->fec.twcard.type) {
+ case MAP_TYPE_PREFIX:
+ if (snprintf(buf + strlen(buf), sizeof(buf) -
+ strlen(buf), " (prefix, address-family %s)",
+ af_name(map->fec.twcard.u.prefix_af)) < 0)
+ return ("???");
+ break;
+ case MAP_TYPE_PWID:
+ if (snprintf(buf + strlen(buf), sizeof(buf) -
+ strlen(buf), " (pwid, type %s)",
+ pw_type_name(map->fec.twcard.u.pw_type)) < 0)
+ return ("???");
+ break;
+ default:
+ if (snprintf(buf + strlen(buf), sizeof(buf) -
+ strlen(buf), " (unknown type)") < 0)
+ return ("???");
+ break;
+ }
+ break;
+ default:
+ return ("???");
+ }
+
+ return (buf);
+}
+
+const char *
+log_fec(const struct fec *fec)
+{
+ static char buf[64];
+ union ldpd_addr addr;
+
+ switch (fec->type) {
+ case FEC_TYPE_IPV4:
+ addr.v4 = fec->u.ipv4.prefix;
+ if (snprintf(buf, sizeof(buf), "ipv4 %s/%u",
+ log_addr(AF_INET, &addr), fec->u.ipv4.prefixlen) == -1)
+ return ("???");
+ break;
+ case FEC_TYPE_IPV6:
+ addr.v6 = fec->u.ipv6.prefix;
+ if (snprintf(buf, sizeof(buf), "ipv6 %s/%u",
+ log_addr(AF_INET6, &addr), fec->u.ipv6.prefixlen) == -1)
+ return ("???");
+ break;
+ case FEC_TYPE_PWID:
+ if (snprintf(buf, sizeof(buf),
+ "pwid %u (%s) - %s",
+ fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
+ inet_ntoa(fec->u.pwid.lsr_id)) == -1)
+ return ("???");
+ break;
+ default:
+ return ("???");
+ }
+
+ return (buf);
+}
+
+/* names */
+const char *
+af_name(int af)
+{
+ switch (af) {
+ case AF_INET:
+ return ("ipv4");
+ case AF_INET6:
+ return ("ipv6");
+#ifdef AF_MPLS
+ case AF_MPLS:
+ return ("mpls");
+#endif
+ default:
+ return ("UNKNOWN");
+ }
+}
+
+const char *
+socket_name(int type)
+{
+ switch (type) {
+ case LDP_SOCKET_DISC:
+ return ("discovery");
+ case LDP_SOCKET_EDISC:
+ return ("extended discovery");
+ case LDP_SOCKET_SESSION:
+ return ("session");
+ default:
+ return ("UNKNOWN");
+ }
+}
+
+const char *
+nbr_state_name(int state)
+{
+ switch (state) {
+ case NBR_STA_PRESENT:
+ return ("PRESENT");
+ case NBR_STA_INITIAL:
+ return ("INITIALIZED");
+ case NBR_STA_OPENREC:
+ return ("OPENREC");
+ case NBR_STA_OPENSENT:
+ return ("OPENSENT");
+ case NBR_STA_OPER:
+ return ("OPERATIONAL");
+ default:
+ return ("UNKNOWN");
+ }
+}
+
+const char *
+if_state_name(int state)
+{
+ switch (state) {
+ case IF_STA_DOWN:
+ return ("DOWN");
+ case IF_STA_ACTIVE:
+ return ("ACTIVE");
+ default:
+ return ("UNKNOWN");
+ }
+}
+
+const char *
+if_type_name(enum iface_type type)
+{
+ switch (type) {
+ case IF_TYPE_POINTOPOINT:
+ return ("POINTOPOINT");
+ case IF_TYPE_BROADCAST:
+ return ("BROADCAST");
+ }
+ /* NOTREACHED */
+ return ("UNKNOWN");
+}
+
+const char *
+msg_name(uint16_t msg)
+{
+ static char buf[16];
+
+ switch (msg) {
+ case MSG_TYPE_NOTIFICATION:
+ return ("notification");
+ case MSG_TYPE_HELLO:
+ return ("hello");
+ case MSG_TYPE_INIT:
+ return ("initialization");
+ case MSG_TYPE_KEEPALIVE:
+ return ("keepalive");
+ case MSG_TYPE_CAPABILITY:
+ return ("capability");
+ case MSG_TYPE_ADDR:
+ return ("address");
+ case MSG_TYPE_ADDRWITHDRAW:
+ return ("address withdraw");
+ case MSG_TYPE_LABELMAPPING:
+ return ("label mapping");
+ case MSG_TYPE_LABELREQUEST:
+ return ("label request");
+ case MSG_TYPE_LABELWITHDRAW:
+ return ("label withdraw");
+ case MSG_TYPE_LABELRELEASE:
+ return ("label release");
+ case MSG_TYPE_LABELABORTREQ:
+ default:
+ snprintf(buf, sizeof(buf), "[%08x]", msg);
+ return (buf);
+ }
+}
+
+const char *
+status_code_name(uint32_t status)
+{
+ static char buf[16];
+
+ switch (status) {
+ case S_SUCCESS:
+ return ("Success");
+ case S_BAD_LDP_ID:
+ return ("Bad LDP Identifier");
+ case S_BAD_PROTO_VER:
+ return ("Bad Protocol Version");
+ case S_BAD_PDU_LEN:
+ return ("Bad PDU Length");
+ case S_UNKNOWN_MSG:
+ return ("Unknown Message Type");
+ case S_BAD_MSG_LEN:
+ return ("Bad Message Length");
+ case S_UNKNOWN_TLV:
+ return ("Unknown TLV");
+ case S_BAD_TLV_LEN:
+ return ("Bad TLV Length");
+ case S_BAD_TLV_VAL:
+ return ("Malformed TLV Value");
+ case S_HOLDTIME_EXP:
+ return ("Hold Timer Expired");
+ case S_SHUTDOWN:
+ return ("Shutdown");
+ case S_LOOP_DETECTED:
+ return ("Loop Detected");
+ case S_UNKNOWN_FEC:
+ return ("Unknown FEC");
+ case S_NO_ROUTE:
+ return ("No Route");
+ case S_NO_LABEL_RES:
+ return ("No Label Resources");
+ case S_AVAILABLE:
+ return ("Label Resources Available");
+ case S_NO_HELLO:
+ return ("Session Rejected, No Hello");
+ case S_PARM_ADV_MODE:
+ return ("Rejected Advertisement Mode Parameter");
+ case S_MAX_PDU_LEN:
+ return ("Rejected Max PDU Length Parameter");
+ case S_PARM_L_RANGE:
+ return ("Rejected Label Range Parameter");
+ case S_KEEPALIVE_TMR:
+ return ("KeepAlive Timer Expired");
+ case S_LAB_REQ_ABRT:
+ return ("Label Request Aborted");
+ case S_MISS_MSG:
+ return ("Missing Message Parameters");
+ case S_UNSUP_ADDR:
+ return ("Unsupported Address Family");
+ case S_KEEPALIVE_BAD:
+ return ("Bad KeepAlive Time");
+ case S_INTERN_ERR:
+ return ("Internal Error");
+ case S_ILLEGAL_CBIT:
+ return ("Illegal C-Bit");
+ case S_WRONG_CBIT:
+ return ("Wrong C-Bit");
+ case S_INCPT_BITRATE:
+ return ("Incompatible bit-rate");
+ case S_CEP_MISCONF:
+ return ("CEP-TDM mis-configuration");
+ case S_PW_STATUS:
+ return ("PW Status");
+ case S_UNASSIGN_TAI:
+ return ("Unassigned/Unrecognized TAI");
+ case S_MISCONF_ERR:
+ return ("Generic Misconfiguration Error");
+ case S_WITHDRAW_MTHD:
+ return ("Label Withdraw PW Status Method");
+ case S_UNSSUPORTDCAP:
+ return ("Unsupported Capability");
+ case S_ENDOFLIB:
+ return ("End-of-LIB");
+ case S_TRANS_MISMTCH:
+ return ("Transport Connection Mismatch");
+ case S_DS_NONCMPLNCE:
+ return ("Dual-Stack Noncompliance");
+ default:
+ snprintf(buf, sizeof(buf), "[%08x]", status);
+ return (buf);
+ }
+}
+
+const char *
+pw_type_name(uint16_t pw_type)
+{
+ static char buf[64];
+
+ switch (pw_type) {
+ case PW_TYPE_ETHERNET_TAGGED:
+ return ("Eth Tagged");
+ case PW_TYPE_ETHERNET:
+ return ("Ethernet");
+ case PW_TYPE_WILDCARD:
+ return ("Wildcard");
+ default:
+ snprintf(buf, sizeof(buf), "[%0x]", pw_type);
+ return (buf);
+ }
+}
diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c
index 9a92a00d32..f867db228d 100644
--- a/ldpd/neighbor.c
+++ b/ldpd/neighbor.c
@@ -408,7 +408,8 @@ nbr_start_ktimer(struct nbr *nbr)
/* send three keepalives per period */
secs = nbr->keepalive / KEEPALIVE_PER_PERIOD;
THREAD_TIMER_OFF(nbr->keepalive_timer);
- nbr->keepalive_timer = thread_add_timer(master, nbr_ktimer, nbr, secs);
+ nbr->keepalive_timer = NULL;
+ thread_add_timer(master, nbr_ktimer, nbr, secs, &nbr->keepalive_timer);
}
void
@@ -437,8 +438,9 @@ static void
nbr_start_ktimeout(struct nbr *nbr)
{
THREAD_TIMER_OFF(nbr->keepalive_timeout);
- nbr->keepalive_timeout = thread_add_timer(master, nbr_ktimeout, nbr,
- nbr->keepalive);
+ nbr->keepalive_timeout = NULL;
+ thread_add_timer(master, nbr_ktimeout, nbr, nbr->keepalive,
+ &nbr->keepalive_timeout);
}
void
@@ -468,7 +470,8 @@ nbr_start_itimeout(struct nbr *nbr)
secs = INIT_FSM_TIMEOUT;
THREAD_TIMER_OFF(nbr->init_timeout);
- nbr->init_timeout = thread_add_timer(master, nbr_itimeout, nbr, secs);
+ nbr->init_timeout = NULL;
+ thread_add_timer(master, nbr_itimeout, nbr, secs, &nbr->init_timeout);
}
void
@@ -516,7 +519,9 @@ nbr_start_idtimer(struct nbr *nbr)
}
THREAD_TIMER_OFF(nbr->initdelay_timer);
- nbr->initdelay_timer = thread_add_timer(master, nbr_idtimer, nbr, secs);
+ nbr->initdelay_timer = NULL;
+ thread_add_timer(master, nbr_idtimer, nbr, secs,
+ &nbr->initdelay_timer);
}
void
@@ -633,8 +638,8 @@ nbr_establish_connection(struct nbr *nbr)
if (connect(nbr->fd, (struct sockaddr *)&remote_sa,
sockaddr_len((struct sockaddr *)&remote_sa)) == -1) {
if (errno == EINPROGRESS) {
- THREAD_WRITE_ON(master, nbr->ev_connect, nbr_connect_cb,
- nbr, nbr->fd);
+ thread_add_write(master, nbr_connect_cb, nbr, nbr->fd,
+ &nbr->ev_connect);
return (0);
}
log_warn("%s: error while connecting to %s", __func__,
diff --git a/ldpd/notification.c b/ldpd/notification.c
index f10faa4a54..4a5f3c8fa4 100644
--- a/ldpd/notification.c
+++ b/ldpd/notification.c
@@ -237,6 +237,16 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
if (nbr->state == NBR_STA_OPENSENT)
nbr_start_idtimer(nbr);
+ /*
+ * RFC 5036 - Section 3.5.1.1:
+ * "When an LSR receives a Shutdown message during session
+ * initialization, it SHOULD transmit a Shutdown message and
+ * then close the transport connection".
+ */
+ if (nbr->state != NBR_STA_OPER && nm.status_code == S_SHUTDOWN)
+ send_notification(nbr->tcp, S_SHUTDOWN,
+ msg.id, msg.type);
+
nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
return (-1);
}
diff --git a/ldpd/packet.c b/ldpd/packet.c
index 46893b992b..be7f2ba649 100644
--- a/ldpd/packet.c
+++ b/ldpd/packet.c
@@ -27,7 +27,7 @@
#include "sockopt.h"
static struct iface *disc_find_iface(unsigned int, int,
- union ldpd_addr *, int);
+ union ldpd_addr *);
static int session_read(struct thread *);
static int session_write(struct thread *);
static ssize_t session_get_pdu(struct ibuf_read *, char **);
@@ -134,7 +134,7 @@ disc_recv_packet(struct thread *thread)
int af;
union ldpd_addr src;
unsigned int ifindex = 0;
- struct iface *iface;
+ struct iface *iface = NULL;
uint16_t len;
struct ldp_hdr ldp_hdr;
uint16_t pdu_len;
@@ -143,7 +143,8 @@ disc_recv_packet(struct thread *thread)
struct in_addr lsr_id;
/* reschedule read */
- *threadp = thread_add_read(master, disc_recv_packet, threadp, fd);
+ *threadp = NULL;
+ thread_add_read(master, disc_recv_packet, threadp, fd, &*threadp);
/* setup buffer */
memset(&m, 0, sizeof(m));
@@ -212,9 +213,11 @@ disc_recv_packet(struct thread *thread)
ifindex = getsockopt_ifindex(af, &m);
/* find a matching interface */
- iface = disc_find_iface(ifindex, af, &src, multicast);
- if (iface == NULL)
- return (0);
+ if (multicast) {
+ iface = disc_find_iface(ifindex, af, &src);
+ if (iface == NULL)
+ return (0);
+ }
/* check packet size */
len = (uint16_t)r;
@@ -280,8 +283,7 @@ disc_recv_packet(struct thread *thread)
}
static struct iface *
-disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
- int multicast)
+disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src)
{
struct iface *iface;
struct iface_af *ia;
@@ -299,7 +301,7 @@ disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
* "Link-local IPv6 address MUST be used as the source IP address in
* IPv6 LDP Link Hellos".
*/
- if (multicast && af == AF_INET6 && !IN6_IS_ADDR_LINKLOCAL(&src->v6))
+ if (af == AF_INET6 && !IN6_IS_ADDR_LINKLOCAL(&src->v6))
return (NULL);
return (iface);
@@ -426,7 +428,8 @@ session_read(struct thread *thread)
uint16_t pdu_len, msg_len, msg_size, max_pdu_len;
int ret;
- tcp->rev = thread_add_read(master, session_read, nbr, fd);
+ tcp->rev = NULL;
+ thread_add_read(master, session_read, nbr, fd, &tcp->rev);
if ((n = read(fd, tcp->rbuf->buf + tcp->rbuf->wpos,
sizeof(tcp->rbuf->buf) - tcp->rbuf->wpos)) == -1) {
@@ -519,6 +522,8 @@ session_read(struct thread *thread)
return (0);
}
break;
+ case MSG_TYPE_NOTIFICATION:
+ break;
default:
if (nbr->state != NBR_STA_OPER) {
session_shutdown(nbr, S_SHUTDOWN,
@@ -661,8 +666,6 @@ session_shutdown(struct nbr *nbr, uint32_t status, uint32_t msg_id,
case NBR_STA_OPENREC:
case NBR_STA_OPENSENT:
case NBR_STA_OPER:
- log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
-
send_notification(nbr->tcp, status, msg_id, msg_type);
nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
@@ -730,7 +733,8 @@ tcp_new(int fd, struct nbr *nbr)
if ((tcp->rbuf = calloc(1, sizeof(struct ibuf_read))) == NULL)
fatal(__func__);
- tcp->rev = thread_add_read(master, session_read, nbr, tcp->fd);
+ tcp->rev = NULL;
+ thread_add_read(master, session_read, nbr, tcp->fd, &tcp->rev);
tcp->nbr = nbr;
}
@@ -776,8 +780,9 @@ pending_conn_new(int fd, int af, union ldpd_addr *addr)
pconn->af = af;
pconn->addr = *addr;
TAILQ_INSERT_TAIL(&global.pending_conns, pconn, entry);
- pconn->ev_timeout = thread_add_timer(master, pending_conn_timeout,
- pconn, PENDING_CONN_TIMEOUT);
+ pconn->ev_timeout = NULL;
+ thread_add_timer(master, pending_conn_timeout, pconn, PENDING_CONN_TIMEOUT,
+ &pconn->ev_timeout);
return (pconn);
}
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 14b7130c8a..a1b78d3c4d 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -17,6 +17,7 @@ libfrr_la_SOURCES = \
network.c pid_output.c getopt.c getopt1.c \
checksum.c vector.c linklist.c vty.c \
graph.c command_parse.y command_lex.l command_match.c \
+ command_graph.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 \
@@ -32,8 +33,10 @@ libfrr_la_SOURCES = \
libfrr.c \
strlcpy.c \
strlcat.c \
+ sha256.c \
module.c \
hook.c \
+ frr_pthread.c \
# end
BUILT_SOURCES = route_types.h gitversion.h command_parse.h command_lex.h
@@ -54,9 +57,11 @@ libfrrsnmp_la_SOURCES = \
#end
pkginclude_HEADERS = \
+ frratomic.h \
buffer.h checksum.h filter.h getopt.h hash.h \
if.h linklist.h log.h \
graph.h command_match.h \
+ command_graph.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 \
@@ -73,6 +78,9 @@ pkginclude_HEADERS = \
module.h \
hook.h \
libfrr.h \
+ sha256.h \
+ frr_pthread.h \
+ vrf_int.h \
# end
noinst_HEADERS = \
diff --git a/lib/agentx.c b/lib/agentx.c
index 11d5c9385d..fda634bb86 100644
--- a/lib/agentx.c
+++ b/lib/agentx.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -85,8 +84,11 @@ agentx_events_update(void)
FD_ZERO (&fds);
snmp_select_info (&maxfd, &fds, &timeout, &block);
- if (!block)
- timeout_thr = thread_add_timer_tv (agentx_tm, agentx_timeout, NULL, &timeout);
+ if (!block) {
+ timeout_thr = NULL;
+ thread_add_timer_tv(agentx_tm, agentx_timeout, NULL, &timeout,
+ &timeout_thr);
+ }
ln = listhead (events);
thr = ln ? listgetdata (ln) : NULL;
@@ -114,7 +116,8 @@ agentx_events_update(void)
else if (FD_ISSET (fd, &fds))
{
struct listnode *newln;
- thr = thread_add_read (agentx_tm, agentx_read, NULL, fd);
+ thr = NULL;
+ thread_add_read(agentx_tm, agentx_read, NULL, fd, &thr);
newln = listnode_add_before (events, ln, thr);
thr->arg = newln;
}
@@ -134,7 +137,8 @@ agentx_events_update(void)
static struct cmd_node agentx_node =
{
SMUX_NODE,
- "" /* AgentX has no interface. */
+ "", /* AgentX has no interface. */
+ 1
};
/* Logging NetSNMP messages */
@@ -165,7 +169,7 @@ config_write_agentx (struct vty *vty)
{
if (agentx_enabled)
vty_out (vty, "agentx%s", VTY_NEWLINE);
- return 0;
+ return 1;
}
DEFUN (agentx_enable,
@@ -183,7 +187,7 @@ DEFUN (agentx_enable,
return CMD_SUCCESS;
}
vty_out (vty, "SNMP AgentX already enabled%s", VTY_NEWLINE);
- return CMD_WARNING;
+ return CMD_SUCCESS;
}
DEFUN (no_agentx,
diff --git a/lib/bfd.c b/lib/bfd.c
index b651a05a09..217fc09722 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
diff --git a/lib/bfd.h b/lib/bfd.h
index e636e4426f..f23ff3bd8e 100644
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _ZEBRA_BFD_H
diff --git a/lib/bitfield.h b/lib/bitfield.h
index 7062796a99..4ff9c7fb2e 100644
--- a/lib/bitfield.h
+++ b/lib/bitfield.h
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/**
* A simple bit array implementation to allocate and free IDs. An example
diff --git a/lib/buffer.c b/lib/buffer.c
index 1dfcdb4732..649677fc93 100644
--- a/lib/buffer.c
+++ b/lib/buffer.c
@@ -8,16 +8,15 @@
* 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.
+ * 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>
diff --git a/lib/buffer.h b/lib/buffer.h
index 6c3dc76a1b..67ac71cad8 100644
--- a/lib/buffer.h
+++ b/lib/buffer.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_BUFFER_H
diff --git a/lib/command.c b/lib/command.c
index ff921ff402..84d59f076c 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -19,10 +19,9 @@
* 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.
+ * 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>
@@ -40,15 +39,13 @@
#include "workqueue.h"
#include "vrf.h"
#include "command_match.h"
+#include "command_graph.h"
#include "qobj.h"
#include "defaults.h"
DEFINE_MTYPE( LIB, HOST, "Host config")
DEFINE_MTYPE( LIB, STRVEC, "String vector")
-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")
+DEFINE_MTYPE( LIB, COMPLETION, "Completion item")
/* Command vector which includes some level of command lists. Normally
each daemon maintains each own cmdvec. */
@@ -234,8 +231,8 @@ install_node (struct cmd_node *node,
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);
+ struct cmd_token *token = cmd_token_new (START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ graph_new_node (node->cmdgraph, token, (void (*)(void *)) &cmd_token_del);
node->cmd_hash = hash_create (cmd_hash_key, cmd_hash_cmp);
}
@@ -306,272 +303,6 @@ cmd_prompt (enum node_type node)
return cnode->prompt;
}
-static bool
-cmd_nodes_link (struct graph_node *from, struct graph_node *to)
-{
- for (size_t i = 0; i < vector_active (from->to); i++)
- if (vector_slot (from->to, i) == to)
- return true;
- return false;
-}
-
-static bool cmd_nodes_equal (struct graph_node *ga, struct graph_node *gb);
-
-/* returns a single node to be excluded as "next" from iteration
- * - for JOIN_TKN, never continue back to the FORK_TKN
- * - in all other cases, don't try the node itself (in case of "...")
- */
-static inline struct graph_node *
-cmd_loopstop(struct graph_node *gn)
-{
- struct cmd_token *tok = gn->data;
- if (tok->type == JOIN_TKN)
- return tok->forkjoin;
- else
- return gn;
-}
-
-static bool
-cmd_subgraph_equal (struct graph_node *ga, struct graph_node *gb,
- struct graph_node *a_join)
-{
- size_t i, j;
- struct graph_node *a_fork, *b_fork;
- a_fork = cmd_loopstop (ga);
- b_fork = cmd_loopstop (gb);
-
- if (vector_active (ga->to) != vector_active (gb->to))
- return false;
- for (i = 0; i < vector_active (ga->to); i++)
- {
- struct graph_node *cga = vector_slot (ga->to, i);
-
- for (j = 0; j < vector_active (gb->to); j++)
- {
- struct graph_node *cgb = vector_slot (gb->to, i);
-
- if (cga == a_fork && cgb != b_fork)
- continue;
- if (cga == a_fork && cgb == b_fork)
- break;
-
- if (cmd_nodes_equal (cga, cgb))
- {
- if (cga == a_join)
- break;
- if (cmd_subgraph_equal (cga, cgb, a_join))
- break;
- }
- }
- if (j == vector_active (gb->to))
- return false;
- }
- return true;
-}
-
-/* deep compare -- for FORK_TKN, the entire subgraph is compared.
- * this is what's needed since we're not currently trying to partially
- * merge subgraphs */
-static bool
-cmd_nodes_equal (struct graph_node *ga, struct graph_node *gb)
-{
- struct cmd_token *a = ga->data, *b = gb->data;
-
- if (a->type != b->type || a->allowrepeat != b->allowrepeat)
- return false;
- if (a->type < SPECIAL_TKN && strcmp (a->text, b->text))
- return false;
- /* one a ..., the other not. */
- if (cmd_nodes_link (ga, ga) != cmd_nodes_link (gb, gb))
- return false;
-
- switch (a->type)
- {
- case RANGE_TKN:
- return a->min == b->min && a->max == b->max;
-
- case FORK_TKN:
- /* one is keywords, the other just option or selector ... */
- if (cmd_nodes_link (a->forkjoin, ga) != cmd_nodes_link (b->forkjoin, gb))
- return false;
- if (cmd_nodes_link (ga, a->forkjoin) != cmd_nodes_link (gb, b->forkjoin))
- return false;
- return cmd_subgraph_equal (ga, gb, a->forkjoin);
-
- default:
- return true;
- }
-}
-
-static void
-cmd_fork_bump_attr (struct graph_node *gn, struct graph_node *join,
- u_char attr)
-{
- size_t i;
- struct cmd_token *tok = gn->data;
- struct graph_node *stop = cmd_loopstop (gn);
-
- tok->attr = attr;
- for (i = 0; i < vector_active (gn->to); i++)
- {
- struct graph_node *next = vector_slot (gn->to, i);
- if (next == stop || next == join)
- continue;
- cmd_fork_bump_attr (next, join, attr);
- }
-}
-
-/* move an entire subtree from the temporary graph resulting from
- * parse() into the permanent graph for the command node.
- *
- * this touches rather deeply into the graph code unfortunately.
- */
-static void
-cmd_reparent_tree (struct graph *fromgraph, struct graph *tograph,
- struct graph_node *node)
-{
- struct graph_node *stop = cmd_loopstop (node);
- size_t i;
-
- for (i = 0; i < vector_active (fromgraph->nodes); i++)
- if (vector_slot (fromgraph->nodes, i) == node)
- {
- /* agressive iteration punching through subgraphs - may hit some
- * nodes twice. reparent only if found on old graph */
- vector_unset (fromgraph->nodes, i);
- vector_set (tograph->nodes, node);
- break;
- }
-
- for (i = 0; i < vector_active (node->to); i++)
- {
- struct graph_node *next = vector_slot (node->to, i);
- if (next != stop)
- cmd_reparent_tree (fromgraph, tograph, next);
- }
-}
-
-static void
-cmd_free_recur (struct graph *graph, struct graph_node *node,
- struct graph_node *stop)
-{
- struct graph_node *next, *nstop;
-
- for (size_t i = vector_active (node->to); i; i--)
- {
- next = vector_slot (node->to, i - 1);
- if (next == stop)
- continue;
- nstop = cmd_loopstop (next);
- if (nstop != next)
- cmd_free_recur (graph, next, nstop);
- cmd_free_recur (graph, nstop, stop);
- }
- graph_delete_node (graph, node);
-}
-
-static void
-cmd_free_node (struct graph *graph, struct graph_node *node)
-{
- struct cmd_token *tok = node->data;
- if (tok->type == JOIN_TKN)
- cmd_free_recur (graph, tok->forkjoin, node);
- graph_delete_node (graph, node);
-}
-
-/* recursive graph merge. call with
- * old ~= new
- * (which holds true for old == START_TKN, new == START_TKN)
- */
-static void
-cmd_merge_nodes (struct graph *oldgraph, struct graph *newgraph,
- struct graph_node *old, struct graph_node *new,
- int direction)
-{
- struct cmd_token *tok;
- struct graph_node *old_skip, *new_skip;
- old_skip = cmd_loopstop (old);
- new_skip = cmd_loopstop (new);
-
- assert (direction == 1 || direction == -1);
-
- tok = old->data;
- tok->refcnt += direction;
-
- size_t j, i;
- for (j = 0; j < vector_active (new->to); j++)
- {
- struct graph_node *cnew = vector_slot (new->to, j);
- if (cnew == new_skip)
- continue;
-
- for (i = 0; i < vector_active (old->to); i++)
- {
- struct graph_node *cold = vector_slot (old->to, i);
- if (cold == old_skip)
- continue;
-
- if (cmd_nodes_equal (cold, cnew))
- {
- struct cmd_token *told = cold->data, *tnew = cnew->data;
-
- if (told->type == END_TKN)
- {
- if (direction < 0)
- {
- graph_delete_node (oldgraph, vector_slot (cold->to, 0));
- graph_delete_node (oldgraph, cold);
- }
- else
- /* force no-match handling to install END_TKN */
- i = vector_active (old->to);
- break;
- }
-
- /* the entire fork compared as equal, we continue after it. */
- if (told->type == FORK_TKN)
- {
- if (tnew->attr < told->attr && direction > 0)
- cmd_fork_bump_attr (cold, told->forkjoin, tnew->attr);
- /* XXX: no reverse bump on uninstall */
- told = (cold = told->forkjoin)->data;
- tnew = (cnew = tnew->forkjoin)->data;
- }
- if (tnew->attr < told->attr)
- told->attr = tnew->attr;
-
- cmd_merge_nodes (oldgraph, newgraph, cold, cnew, direction);
- break;
- }
- }
- /* nothing found => add new to old */
- if (i == vector_active (old->to) && direction > 0)
- {
- assert (vector_count (cnew->from) ==
- cmd_nodes_link (cnew, cnew) ? 2 : 1);
- graph_remove_edge (new, cnew);
-
- cmd_reparent_tree (newgraph, oldgraph, cnew);
-
- graph_add_edge (old, cnew);
- }
- }
-
- if (!tok->refcnt)
- cmd_free_node (oldgraph, old);
-}
-
-void
-cmd_merge_graphs (struct graph *old, struct graph *new, int direction)
-{
- assert (vector_active (old->nodes) >= 1);
- assert (vector_active (new->nodes) >= 1);
-
- cmd_merge_nodes (old, new,
- vector_slot (old->nodes, 0), vector_slot (new->nodes, 0),
- direction);
-}
-
/* Install a command into a node. */
void
install_element (enum node_type ntype, struct cmd_element *cmd)
@@ -592,6 +323,7 @@ install_element (enum node_type ntype, struct cmd_element *cmd)
{
fprintf (stderr, "Command node %d doesn't exist, please check it\n",
ntype);
+ fprintf (stderr, "Have you called install_node before this install_element?\n");
exit (EXIT_FAILURE);
}
@@ -606,11 +338,12 @@ install_element (enum node_type ntype, struct cmd_element *cmd)
assert (hash_get (cnode->cmd_hash, cmd, hash_alloc_intern));
struct graph *graph = graph_new();
- struct cmd_token *token = new_cmd_token (START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
- graph_new_node (graph, token, (void (*)(void *)) &del_cmd_token);
+ struct cmd_token *token = cmd_token_new (START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ graph_new_node (graph, token, (void (*)(void *)) &cmd_token_del);
- command_parse_format (graph, cmd);
- cmd_merge_graphs (cnode->cmdgraph, graph, +1);
+ cmd_graph_parse (graph, cmd);
+ cmd_graph_names (graph);
+ cmd_graph_merge (cnode->cmdgraph, graph, +1);
graph_delete_graph (graph);
vector_set (cnode->cmd_vector, cmd);
@@ -638,6 +371,7 @@ uninstall_element (enum node_type ntype, struct cmd_element *cmd)
{
fprintf (stderr, "Command node %d doesn't exist, please check it\n",
ntype);
+ fprintf (stderr, "Have you called install_node before this install_element?\n");
exit (EXIT_FAILURE);
}
@@ -652,11 +386,12 @@ uninstall_element (enum node_type ntype, struct cmd_element *cmd)
vector_unset_value (cnode->cmd_vector, cmd);
struct graph *graph = graph_new();
- struct cmd_token *token = new_cmd_token (START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
- graph_new_node (graph, token, (void (*)(void *)) &del_cmd_token);
+ struct cmd_token *token = cmd_token_new (START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ graph_new_node (graph, token, (void (*)(void *)) &cmd_token_del);
- command_parse_format (graph, cmd);
- cmd_merge_graphs (cnode->cmdgraph, graph, -1);
+ cmd_graph_parse (graph, cmd);
+ cmd_graph_names (graph);
+ cmd_graph_merge (cnode->cmdgraph, graph, -1);
graph_delete_graph (graph);
if (ntype == VIEW_NODE)
@@ -945,6 +680,86 @@ cmd_describe_command (vector vline, struct vty *vty, int *status)
return cmd_complete_command_real (vline, vty, status);
}
+static struct list *varhandlers = NULL;
+
+void
+cmd_variable_complete (struct cmd_token *token, const char *arg, vector comps)
+{
+ struct listnode *ln;
+ const struct cmd_variable_handler *cvh;
+ size_t i, argsz;
+ vector tmpcomps;
+
+ tmpcomps = arg ? vector_init (VECTOR_MIN_SIZE) : comps;
+
+ for (ALL_LIST_ELEMENTS_RO(varhandlers, ln, cvh))
+ {
+ if (cvh->tokenname && strcmp(cvh->tokenname, token->text))
+ continue;
+ if (cvh->varname && (!token->varname || strcmp(cvh->varname, token->varname)))
+ continue;
+ cvh->completions(tmpcomps, token);
+ break;
+ }
+
+ if (!arg)
+ return;
+
+ argsz = strlen(arg);
+ for (i = vector_active(tmpcomps); i; i--)
+ {
+ char *item = vector_slot(tmpcomps, i - 1);
+ if (strlen(item) >= argsz
+ && !strncmp(item, arg, argsz))
+ vector_set(comps, item);
+ else
+ XFREE(MTYPE_COMPLETION, item);
+ }
+ vector_free(tmpcomps);
+}
+
+void
+cmd_variable_handler_register (const struct cmd_variable_handler *cvh)
+{
+ if (!varhandlers)
+ return;
+
+ for (; cvh->completions; cvh++)
+ listnode_add(varhandlers, (void *)cvh);
+}
+
+DEFUN_HIDDEN (autocomplete,
+ autocomplete_cmd,
+ "autocomplete TYPE TEXT VARNAME",
+ "Autocompletion handler (internal, for vtysh)\n"
+ "cmd_token->type\n"
+ "cmd_token->text\n"
+ "cmd_token->varname\n")
+{
+ struct cmd_token tok;
+ vector comps = vector_init(32);
+ size_t i;
+
+ memset(&tok, 0, sizeof(tok));
+ tok.type = atoi(argv[1]->arg);
+ tok.text = argv[2]->arg;
+ tok.varname = argv[3]->arg;
+ if (!strcmp(tok.varname, "-"))
+ tok.varname = NULL;
+
+ cmd_variable_complete(&tok, NULL, comps);
+
+ for (i = 0; i < vector_active(comps); i++)
+ {
+ char *text = vector_slot(comps, i);
+ vty_out(vty, "%s\n", text);
+ XFREE(MTYPE_COMPLETION, text);
+ }
+
+ vector_free(comps);
+ return CMD_SUCCESS;
+}
+
/**
* Generate possible tab-completions for the given input. This function only
* returns results that would result in a valid command if used as Readline
@@ -986,7 +801,12 @@ cmd_complete_command (vector vline, struct vty *vty, int *status)
{
struct cmd_token *token = vector_slot (initial_comps, i);
if (token->type == WORD_TKN)
- vector_set (comps, token);
+ vector_set (comps, XSTRDUP (MTYPE_COMPLETION, token->text));
+ else if (IS_VARYING_TOKEN(token->type))
+ {
+ const char *ref = vector_lookup(vline, vector_active (vline) - 1);
+ cmd_variable_complete (token, ref, comps);
+ }
}
vector_free (initial_comps);
@@ -1008,9 +828,7 @@ cmd_complete_command (vector vline, struct vty *vty, int *status)
unsigned int i;
for (i = 0; i < vector_active (comps); i++)
{
- struct cmd_token *token = vector_slot (comps, i);
- ret[i] = XSTRDUP (MTYPE_TMP, token->text);
- vector_unset (comps, i);
+ ret[i] = vector_slot (comps, i);
}
// set the last element to NULL, because this array is used in
// a Readline completion_generator function which expects NULL
@@ -1055,9 +873,11 @@ node_parent ( enum node_type node )
case BGP_VNC_L2_GROUP_NODE:
case BGP_IPV4_NODE:
case BGP_IPV4M_NODE:
+ case BGP_IPV4L_NODE:
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
case BGP_EVPN_NODE:
+ case BGP_IPV6L_NODE:
ret = BGP_NODE;
break;
case KEYCHAIN_KEY_NODE:
@@ -1399,6 +1219,7 @@ cmd_exit (struct vty *vty)
case ZEBRA_NODE:
case BGP_NODE:
case RIP_NODE:
+ case EIGRP_NODE:
case RIPNG_NODE:
case OSPF_NODE:
case OSPF6_NODE:
@@ -1414,6 +1235,7 @@ cmd_exit (struct vty *vty)
break;
case BGP_IPV4_NODE:
case BGP_IPV4M_NODE:
+ case BGP_IPV4L_NODE:
case BGP_VPNV4_NODE:
case BGP_VPNV6_NODE:
case BGP_ENCAP_NODE:
@@ -1425,6 +1247,7 @@ cmd_exit (struct vty *vty)
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
case BGP_EVPN_NODE:
+ case BGP_IPV6L_NODE:
vty->node = BGP_NODE;
break;
case LDP_IPV4_NODE:
@@ -1480,6 +1303,7 @@ DEFUN (config_end,
case ZEBRA_NODE:
case RIP_NODE:
case RIPNG_NODE:
+ case EIGRP_NODE:
case BGP_NODE:
case BGP_ENCAP_NODE:
case BGP_ENCAPV6_NODE:
@@ -1491,9 +1315,11 @@ DEFUN (config_end,
case BGP_VPNV6_NODE:
case BGP_IPV4_NODE:
case BGP_IPV4M_NODE:
+ case BGP_IPV4L_NODE:
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
case BGP_EVPN_NODE:
+ case BGP_IPV6L_NODE:
case RMAP_NODE:
case OSPF_NODE:
case OSPF6_NODE:
@@ -1546,11 +1372,6 @@ DEFUN (frr_version_defaults,
"set of configuration defaults used\n"
"version string\n")
{
- if (vty->type == VTY_TERM || vty->type == VTY_SHELL)
- /* only print this when the user tries to do run it */
- vty_out (vty, "%% NOTE: This command currently does nothing.%s"
- "%% It is written to the configuration for future reference.%s",
- VTY_NEWLINE, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -2109,16 +1930,8 @@ DEFUN (config_terminal_length,
"Number of lines on screen (0 for no pausing)\n")
{
int idx_number = 2;
- int lines;
- char *endptr = NULL;
- lines = strtol (argv[idx_number]->arg, &endptr, 10);
- if (lines < 0 || lines > 512 || *endptr != '\0')
- {
- vty_out (vty, "length is malformed%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- vty->lines = lines;
+ vty->lines = atoi (argv[idx_number]->arg);
return CMD_SUCCESS;
}
@@ -2142,16 +1955,8 @@ DEFUN (service_terminal_length,
"Number of lines of VTY (0 means no line control)\n")
{
int idx_number = 2;
- int lines;
- char *endptr = NULL;
- lines = strtol (argv[idx_number]->arg, &endptr, 10);
- if (lines < 0 || lines > 512 || *endptr != '\0')
- {
- vty_out (vty, "length is malformed%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- host.lines = lines;
+ host.lines = atoi (argv[idx_number]->arg);
return CMD_SUCCESS;
}
@@ -2657,6 +2462,8 @@ install_default (enum node_type node)
install_element (node, &config_write_cmd);
install_element (node, &show_running_config_cmd);
+
+ install_element (node, &autocomplete_cmd);
}
/* Initialize command interface. Install basic nodes and commands.
@@ -2669,6 +2476,8 @@ cmd_init (int terminal)
{
qobj_init ();
+ varhandlers = list_new ();
+
/* Allocate initial top vector of commands. */
cmdvec = vector_init (VECTOR_MIN_SIZE);
@@ -2704,6 +2513,7 @@ cmd_init (int terminal)
install_element (VIEW_NODE, &show_logging_cmd);
install_element (VIEW_NODE, &show_commandtree_cmd);
install_element (VIEW_NODE, &echo_cmd);
+ install_element (VIEW_NODE, &autocomplete_cmd);
}
if (terminal)
@@ -2768,50 +2578,6 @@ cmd_init (int terminal)
#endif
}
-struct cmd_token *
-new_cmd_token (enum cmd_token_type type, u_char attr,
- const char *text, const char *desc)
-{
- 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->refcnt = 1;
- token->arg = NULL;
- token->allowrepeat = false;
-
- return token;
-}
-
-void
-del_cmd_token (struct cmd_token *token)
-{
- if (!token) return;
-
- 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);
-}
-
-struct cmd_token *
-copy_cmd_token (struct cmd_token *token)
-{
- 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;
-
- return copy;
-}
-
void
cmd_terminate ()
{
diff --git a/lib/command.h b/lib/command.h
index d62f7655ee..35fb20f8b0 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_COMMAND_H
@@ -29,9 +28,10 @@
#include "graph.h"
#include "memory.h"
#include "hash.h"
+#include "command_graph.h"
DECLARE_MTYPE(HOST)
-DECLARE_MTYPE(CMD_ARG)
+DECLARE_MTYPE(COMPLETION)
/* for test-commands.c */
DECLARE_MTYPE(STRVEC)
@@ -91,13 +91,16 @@ enum node_type
TABLE_NODE, /* rtm_table selection node. */
RIP_NODE, /* RIP protocol mode node. */
RIPNG_NODE, /* RIPng protocol mode node. */
+ EIGRP_NODE, /* EIGRP 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_IPV4L_NODE, /* BGP IPv4 labeled unicast address family. */
BGP_IPV6_NODE, /* BGP IPv6 address family */
BGP_IPV6M_NODE, /* BGP IPv6 multicast address family. */
+ BGP_IPV6L_NODE, /* BGP IPv6 labeled unicast address family. */
BGP_ENCAP_NODE, /* BGP ENCAP SAFI */
BGP_ENCAPV6_NODE, /* BGP ENCAP SAFI */
BGP_VRF_POLICY_NODE, /* BGP VRF policy */
@@ -162,69 +165,6 @@ struct cmd_node
struct hash *cmd_hash;
};
-/**
- * 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
-{
- 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,
-};
-
-/* Command attributes */
-enum
-{
- CMD_ATTR_NORMAL,
- CMD_ATTR_DEPRECATED,
- CMD_ATTR_HIDDEN,
-};
-
-/* Comamand token struct. */
-struct cmd_token
-{
- enum cmd_token_type type; // token type
- u_char attr; // token attributes
- bool allowrepeat; // matcher allowed to match token repetively?
- uint32_t refcnt;
-
- char *text; // token text
- char *desc; // token description
- long long min, max; // for ranges
- char *arg; // user input that matches this token
-
- struct graph_node *forkjoin; // paired FORK/JOIN for JOIN/FORK
-};
-
-/* 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 */
-
- /* handler function for command */
- int (*func) (const struct cmd_element *, struct vty *, int, struct cmd_token *[]);
-
- const char *name; /* symbol name for debugging */
-};
-
/* Return value of the commands. */
#define CMD_SUCCESS 0
#define CMD_WARNING 1
@@ -356,6 +296,7 @@ struct cmd_element
#define REDIST_STR "Redistribute information from another routing protocol\n"
#define CLEAR_STR "Reset functions\n"
#define RIP_STR "RIP information\n"
+#define EIGRP_STR "EIGRP information\n"
#define BGP_STR "BGP information\n"
#define BGP_SOFT_STR "Soft reconfig inbound and outbound updates\n"
#define BGP_SOFT_IN_STR "Send route-refresh unless using 'soft-reconfiguration inbound'\n"
@@ -437,15 +378,7 @@ 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 cmd_merge_graphs (struct graph *old, struct graph *new, int direction);
-extern void command_parse_format (struct graph *graph, struct cmd_element *cmd);
/* Export typical functions. */
extern const char *host_config_get (void);
@@ -458,7 +391,12 @@ extern int cmd_banner_motd_file (const char *);
/* struct host global, ick */
extern struct host host;
-/* text for <cr> command */
-#define CMD_CR_TEXT "<cr>"
+struct cmd_variable_handler {
+ const char *tokenname, *varname;
+ void (*completions)(vector out, struct cmd_token *token);
+};
+
+extern void cmd_variable_complete (struct cmd_token *token, const char *arg, vector comps);
+extern void cmd_variable_handler_register (const struct cmd_variable_handler *cvh);
#endif /* _ZEBRA_COMMAND_H */
diff --git a/lib/command_graph.c b/lib/command_graph.c
new file mode 100644
index 0000000000..8cfb333575
--- /dev/null
+++ b/lib/command_graph.c
@@ -0,0 +1,478 @@
+/*
+ * CLI graph handling
+ *
+ * --
+ * 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 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 "command_graph.h"
+
+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")
+DEFINE_MTYPE_STATIC(LIB, CMD_VAR, "Command Argument Name")
+
+struct cmd_token *
+cmd_token_new (enum cmd_token_type type, u_char attr,
+ const char *text, const char *desc)
+{
+ 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->refcnt = 1;
+ token->arg = NULL;
+ token->allowrepeat = false;
+ token->varname = NULL;
+
+ return token;
+}
+
+void
+cmd_token_del (struct cmd_token *token)
+{
+ if (!token) return;
+
+ XFREE (MTYPE_CMD_TEXT, token->text);
+ XFREE (MTYPE_CMD_DESC, token->desc);
+ XFREE (MTYPE_CMD_ARG, token->arg);
+ XFREE (MTYPE_CMD_VAR, token->varname);
+
+ XFREE (MTYPE_CMD_TOKENS, token);
+}
+
+struct cmd_token *
+cmd_token_dup (struct cmd_token *token)
+{
+ struct cmd_token *copy = cmd_token_new (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;
+ copy->varname = token->varname ? XSTRDUP (MTYPE_CMD_VAR, token->varname) : NULL;
+
+ return copy;
+}
+
+void cmd_token_varname_set(struct cmd_token *token, const char *varname)
+{
+ XFREE (MTYPE_CMD_VAR, token->varname);
+ if (!varname)
+ {
+ token->varname = NULL;
+ return;
+ }
+
+ size_t len = strlen (varname), i;
+ token->varname = XMALLOC (MTYPE_CMD_VAR, len + 1);
+
+ for (i = 0; i < len; i++)
+ switch (varname[i])
+ {
+ case '-':
+ case '+':
+ case '*':
+ case ':':
+ token->varname[i] = '_';
+ break;
+ default:
+ token->varname[i] = tolower (varname[i]);
+ }
+ token->varname[len] = '\0';
+}
+
+static bool
+cmd_nodes_link (struct graph_node *from, struct graph_node *to)
+{
+ for (size_t i = 0; i < vector_active (from->to); i++)
+ if (vector_slot (from->to, i) == to)
+ return true;
+ return false;
+}
+
+static bool cmd_nodes_equal (struct graph_node *ga, struct graph_node *gb);
+
+/* returns a single node to be excluded as "next" from iteration
+ * - for JOIN_TKN, never continue back to the FORK_TKN
+ * - in all other cases, don't try the node itself (in case of "...")
+ */
+static inline struct graph_node *
+cmd_loopstop(struct graph_node *gn)
+{
+ struct cmd_token *tok = gn->data;
+ if (tok->type == JOIN_TKN)
+ return tok->forkjoin;
+ else
+ return gn;
+}
+
+static bool
+cmd_subgraph_equal (struct graph_node *ga, struct graph_node *gb,
+ struct graph_node *a_join)
+{
+ size_t i, j;
+ struct graph_node *a_fork, *b_fork;
+ a_fork = cmd_loopstop (ga);
+ b_fork = cmd_loopstop (gb);
+
+ if (vector_active (ga->to) != vector_active (gb->to))
+ return false;
+ for (i = 0; i < vector_active (ga->to); i++)
+ {
+ struct graph_node *cga = vector_slot (ga->to, i);
+
+ for (j = 0; j < vector_active (gb->to); j++)
+ {
+ struct graph_node *cgb = vector_slot (gb->to, i);
+
+ if (cga == a_fork && cgb != b_fork)
+ continue;
+ if (cga == a_fork && cgb == b_fork)
+ break;
+
+ if (cmd_nodes_equal (cga, cgb))
+ {
+ if (cga == a_join)
+ break;
+ if (cmd_subgraph_equal (cga, cgb, a_join))
+ break;
+ }
+ }
+ if (j == vector_active (gb->to))
+ return false;
+ }
+ return true;
+}
+
+/* deep compare -- for FORK_TKN, the entire subgraph is compared.
+ * this is what's needed since we're not currently trying to partially
+ * merge subgraphs */
+static bool
+cmd_nodes_equal (struct graph_node *ga, struct graph_node *gb)
+{
+ struct cmd_token *a = ga->data, *b = gb->data;
+
+ if (a->type != b->type || a->allowrepeat != b->allowrepeat)
+ return false;
+ if (a->type < SPECIAL_TKN && strcmp (a->text, b->text))
+ return false;
+ /* one a ..., the other not. */
+ if (cmd_nodes_link (ga, ga) != cmd_nodes_link (gb, gb))
+ return false;
+ if (!a->varname != !b->varname)
+ return false;
+ if (a->varname && strcmp (a->varname, b->varname))
+ return false;
+
+ switch (a->type)
+ {
+ case RANGE_TKN:
+ return a->min == b->min && a->max == b->max;
+
+ case FORK_TKN:
+ /* one is keywords, the other just option or selector ... */
+ if (cmd_nodes_link (a->forkjoin, ga) != cmd_nodes_link (b->forkjoin, gb))
+ return false;
+ if (cmd_nodes_link (ga, a->forkjoin) != cmd_nodes_link (gb, b->forkjoin))
+ return false;
+ return cmd_subgraph_equal (ga, gb, a->forkjoin);
+
+ default:
+ return true;
+ }
+}
+
+static void
+cmd_fork_bump_attr (struct graph_node *gn, struct graph_node *join,
+ u_char attr)
+{
+ size_t i;
+ struct cmd_token *tok = gn->data;
+ struct graph_node *stop = cmd_loopstop (gn);
+
+ tok->attr = attr;
+ for (i = 0; i < vector_active (gn->to); i++)
+ {
+ struct graph_node *next = vector_slot (gn->to, i);
+ if (next == stop || next == join)
+ continue;
+ cmd_fork_bump_attr (next, join, attr);
+ }
+}
+
+/* move an entire subtree from the temporary graph resulting from
+ * parse() into the permanent graph for the command node.
+ *
+ * this touches rather deeply into the graph code unfortunately.
+ */
+static void
+cmd_reparent_tree (struct graph *fromgraph, struct graph *tograph,
+ struct graph_node *node)
+{
+ struct graph_node *stop = cmd_loopstop (node);
+ size_t i;
+
+ for (i = 0; i < vector_active (fromgraph->nodes); i++)
+ if (vector_slot (fromgraph->nodes, i) == node)
+ {
+ /* agressive iteration punching through subgraphs - may hit some
+ * nodes twice. reparent only if found on old graph */
+ vector_unset (fromgraph->nodes, i);
+ vector_set (tograph->nodes, node);
+ break;
+ }
+
+ for (i = 0; i < vector_active (node->to); i++)
+ {
+ struct graph_node *next = vector_slot (node->to, i);
+ if (next != stop)
+ cmd_reparent_tree (fromgraph, tograph, next);
+ }
+}
+
+static void
+cmd_free_recur (struct graph *graph, struct graph_node *node,
+ struct graph_node *stop)
+{
+ struct graph_node *next, *nstop;
+
+ for (size_t i = vector_active (node->to); i; i--)
+ {
+ next = vector_slot (node->to, i - 1);
+ if (next == stop)
+ continue;
+ nstop = cmd_loopstop (next);
+ if (nstop != next)
+ cmd_free_recur (graph, next, nstop);
+ cmd_free_recur (graph, nstop, stop);
+ }
+ graph_delete_node (graph, node);
+}
+
+static void
+cmd_free_node (struct graph *graph, struct graph_node *node)
+{
+ struct cmd_token *tok = node->data;
+ if (tok->type == JOIN_TKN)
+ cmd_free_recur (graph, tok->forkjoin, node);
+ graph_delete_node (graph, node);
+}
+
+/* recursive graph merge. call with
+ * old ~= new
+ * (which holds true for old == START_TKN, new == START_TKN)
+ */
+static void
+cmd_merge_nodes (struct graph *oldgraph, struct graph *newgraph,
+ struct graph_node *old, struct graph_node *new,
+ int direction)
+{
+ struct cmd_token *tok;
+ struct graph_node *old_skip, *new_skip;
+ old_skip = cmd_loopstop (old);
+ new_skip = cmd_loopstop (new);
+
+ assert (direction == 1 || direction == -1);
+
+ tok = old->data;
+ tok->refcnt += direction;
+
+ size_t j, i;
+ for (j = 0; j < vector_active (new->to); j++)
+ {
+ struct graph_node *cnew = vector_slot (new->to, j);
+ if (cnew == new_skip)
+ continue;
+
+ for (i = 0; i < vector_active (old->to); i++)
+ {
+ struct graph_node *cold = vector_slot (old->to, i);
+ if (cold == old_skip)
+ continue;
+
+ if (cmd_nodes_equal (cold, cnew))
+ {
+ struct cmd_token *told = cold->data, *tnew = cnew->data;
+
+ if (told->type == END_TKN)
+ {
+ if (direction < 0)
+ {
+ graph_delete_node (oldgraph, vector_slot (cold->to, 0));
+ graph_delete_node (oldgraph, cold);
+ }
+ else
+ /* force no-match handling to install END_TKN */
+ i = vector_active (old->to);
+ break;
+ }
+
+ /* the entire fork compared as equal, we continue after it. */
+ if (told->type == FORK_TKN)
+ {
+ if (tnew->attr < told->attr && direction > 0)
+ cmd_fork_bump_attr (cold, told->forkjoin, tnew->attr);
+ /* XXX: no reverse bump on uninstall */
+ told = (cold = told->forkjoin)->data;
+ tnew = (cnew = tnew->forkjoin)->data;
+ }
+ if (tnew->attr < told->attr)
+ told->attr = tnew->attr;
+
+ cmd_merge_nodes (oldgraph, newgraph, cold, cnew, direction);
+ break;
+ }
+ }
+ /* nothing found => add new to old */
+ if (i == vector_active (old->to) && direction > 0)
+ {
+ assert (vector_count (cnew->from) ==
+ cmd_nodes_link (cnew, cnew) ? 2 : 1);
+ graph_remove_edge (new, cnew);
+
+ cmd_reparent_tree (newgraph, oldgraph, cnew);
+
+ graph_add_edge (old, cnew);
+ }
+ }
+
+ if (!tok->refcnt)
+ cmd_free_node (oldgraph, old);
+}
+
+void
+cmd_graph_merge (struct graph *old, struct graph *new, int direction)
+{
+ assert (vector_active (old->nodes) >= 1);
+ assert (vector_active (new->nodes) >= 1);
+
+ cmd_merge_nodes (old, new,
+ vector_slot (old->nodes, 0), vector_slot (new->nodes, 0),
+ direction);
+}
+
+static void
+cmd_node_names (struct graph_node *gn, struct graph_node *join,
+ const char *prevname)
+{
+ size_t i;
+ struct cmd_token *tok = gn->data, *jointok;
+ struct graph_node *stop = cmd_loopstop (gn);
+
+ switch (tok->type)
+ {
+ case WORD_TKN:
+ prevname = tok->text;
+ break;
+
+ case VARIABLE_TKN:
+ if (!tok->varname
+ && strcmp (tok->text, "WORD")
+ && strcmp (tok->text, "NAME"))
+ cmd_token_varname_set (tok, tok->text);
+ /* fallthrough */
+ case RANGE_TKN:
+ case IPV4_TKN:
+ case IPV4_PREFIX_TKN:
+ case IPV6_TKN:
+ case IPV6_PREFIX_TKN:
+ if (!tok->varname && prevname)
+ cmd_token_varname_set (tok, prevname);
+ prevname = NULL;
+ break;
+
+ case START_TKN:
+ case END_TKN:
+ case JOIN_TKN:
+ /* "<foo|bar> WORD" -> word is not "bar" or "foo" */
+ prevname = NULL;
+ break;
+
+ case FORK_TKN:
+ /* apply "<A.B.C.D|X:X::X:X>$name" */
+ jointok = tok->forkjoin->data;
+ if (!jointok->varname)
+ break;
+ for (i = 0; i < vector_active (tok->forkjoin->from); i++)
+ {
+ struct graph_node *tail = vector_slot (tok->forkjoin->from, i);
+ struct cmd_token *tailtok = tail->data;
+ if (tail == gn || tailtok->varname)
+ continue;
+ cmd_token_varname_set (tailtok, jointok->varname);
+ }
+ break;
+ }
+
+ for (i = 0; i < vector_active (gn->to); i++)
+ {
+ struct graph_node *next = vector_slot (gn->to, i);
+ if (next == stop || next == join)
+ continue;
+ cmd_node_names (next, join, prevname);
+ }
+
+ if (tok->type == FORK_TKN && tok->forkjoin != join)
+ cmd_node_names (tok->forkjoin, join, NULL);
+}
+
+void
+cmd_graph_names (struct graph *graph)
+{
+ struct graph_node *start;
+
+ assert (vector_active (graph->nodes) >= 1);
+ start = vector_slot (graph->nodes, 0);
+
+ /* apply varname on initial "[no]" */
+ do
+ {
+ if (vector_active (start->to) != 1)
+ break;
+
+ struct graph_node *first = vector_slot (start->to, 0);
+ struct cmd_token *tok = first->data;
+ /* looking for an option with 2 choices, nothing or "no" */
+ if (tok->type != FORK_TKN || vector_active (first->to) != 2)
+ break;
+
+ struct graph_node *next0 = vector_slot (first->to, 0);
+ struct graph_node *next1 = vector_slot (first->to, 1);
+ /* one needs to be empty */
+ if (next0 != tok->forkjoin && next1 != tok->forkjoin)
+ break;
+
+ struct cmd_token *tok0 = next0->data;
+ struct cmd_token *tok1 = next1->data;
+ /* the other one needs to be "no" (only one will match here) */
+ if ((tok0->type == WORD_TKN && !strcmp(tok0->text, "no")))
+ cmd_token_varname_set (tok0, "no");
+ if ((tok1->type == WORD_TKN && !strcmp(tok1->text, "no")))
+ cmd_token_varname_set (tok1, "no");
+ }
+ while (0);
+
+ cmd_node_names (start, NULL, NULL);
+}
diff --git a/lib/command_graph.h b/lib/command_graph.h
new file mode 100644
index 0000000000..a7a34a0598
--- /dev/null
+++ b/lib/command_graph.h
@@ -0,0 +1,119 @@
+/*
+ * CLI graph handling
+ *
+ * --
+ * 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 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 _FRR_COMMAND_GRAPH_H
+#define _FRR_COMMAND_GRAPH_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "memory.h"
+#include "vector.h"
+#include "graph.h"
+
+DECLARE_MTYPE(CMD_ARG)
+
+struct vty;
+
+/**
+ * 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
+{
+ 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,
+};
+
+#define IS_VARYING_TOKEN(x) ((x) >= VARIABLE_TKN && (x) < FORK_TKN)
+
+/* Command attributes */
+enum
+{
+ CMD_ATTR_NORMAL,
+ CMD_ATTR_DEPRECATED,
+ CMD_ATTR_HIDDEN,
+};
+
+/* Comamand token struct. */
+struct cmd_token
+{
+ enum cmd_token_type type; // token type
+ uint8_t attr; // token attributes
+ bool allowrepeat; // matcher allowed to match token repetively?
+ uint32_t refcnt;
+
+ char *text; // token text
+ char *desc; // token description
+ long long min, max; // for ranges
+ char *arg; // user input that matches this token
+ char *varname;
+
+ struct graph_node *forkjoin; // paired FORK/JOIN for JOIN/FORK
+};
+
+/* 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. */
+ uint8_t attr; /* Command attributes */
+
+ /* handler function for command */
+ int (*func) (const struct cmd_element *, struct vty *, int, struct cmd_token *[]);
+
+ const char *name; /* symbol name for debugging */
+};
+
+/* text for <cr> command */
+#define CMD_CR_TEXT "<cr>"
+
+/* memory management for cmd_token */
+extern struct cmd_token *cmd_token_new (enum cmd_token_type, uint8_t attr,
+ const char *text, const char *desc);
+extern struct cmd_token *cmd_token_dup (struct cmd_token *);
+extern void cmd_token_del (struct cmd_token *);
+extern void cmd_token_varname_set(struct cmd_token *token, const char *varname);
+
+extern void cmd_graph_parse (struct graph *graph, struct cmd_element *cmd);
+extern void cmd_graph_names (struct graph *graph);
+extern void cmd_graph_merge (struct graph *old, struct graph *new, int direction);
+
+#endif /* _FRR_COMMAND_GRAPH_H */
diff --git a/lib/command_lex.l b/lib/command_lex.l
index deec1757c2..c020d193a1 100644
--- a/lib/command_lex.l
+++ b/lib/command_lex.l
@@ -23,6 +23,9 @@
*/
%{
+/* ignore harmless bug in old versions of flex */
+#pragma GCC diagnostic ignored "-Wsign-compare"
+
#include "command_parse.h"
#define YY_USER_ACTION yylloc->last_column += yyleng;
diff --git a/lib/command_match.c b/lib/command_match.c
index bbd9cd091d..75d8fdc3d3 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -16,10 +16,9 @@
* 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.
+ * 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>
@@ -78,10 +77,7 @@ 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 *);
+match_ipv6_prefix (const char *, bool);
static enum match_type
match_range (struct cmd_token *, const char *);
@@ -117,7 +113,7 @@ command_match (struct graph *cmdgraph,
struct listnode *tail = listtail (*argv);
// delete dummy start node
- del_cmd_token ((struct cmd_token *) head->data);
+ cmd_token_del ((struct cmd_token *) head->data);
list_delete_node (*argv, head);
// get cmd_element out of list tail
@@ -281,7 +277,7 @@ command_match_r (struct graph_node *start, vector vline, unsigned int n,
// manually deleted
struct cmd_element *el = leaf->data;
listnode_add (currbest, el);
- currbest->del = (void (*)(void *)) &del_cmd_token;
+ currbest->del = (void (*)(void *)) &cmd_token_del;
// do not break immediately; continue walking through the follow set
// to ensure that there is exactly one END_TKN
}
@@ -320,7 +316,7 @@ command_match_r (struct graph_node *start, vector vline, unsigned int n,
{
// copy token, set arg and prepend to currbest
struct cmd_token *token = start->data;
- struct cmd_token *copy = copy_cmd_token (token);
+ struct cmd_token *copy = cmd_token_dup (token);
copy->arg = XSTRDUP (MTYPE_CMD_ARG, input_token);
listnode_add_before (currbest, currbest->head, copy);
matcher_rv = MATCHER_OK;
@@ -677,9 +673,9 @@ match_token (struct cmd_token *token, char *input_token)
case IPV4_PREFIX_TKN:
return match_ipv4_prefix (input_token);
case IPV6_TKN:
- return match_ipv6 (input_token);
+ return match_ipv6_prefix (input_token, false);
case IPV6_PREFIX_TKN:
- return match_ipv6_prefix (input_token);
+ return match_ipv6_prefix (input_token, true);
case RANGE_TKN:
return match_range (token, input_token);
case VARIABLE_TKN:
@@ -835,35 +831,18 @@ match_ipv4_prefix (const char *str)
#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)
+match_ipv6_prefix (const char *str, bool prefix)
{
int state = STATE_START;
int colons = 0, nums = 0, double_colon = 0;
int mask;
- const char *sp = NULL;
+ const char *sp = NULL, *start = str;
char *endptr = NULL;
if (str == NULL)
return partly_match;
- if (strspn (str, IPV6_PREFIX_STR) != strlen (str))
+ if (strspn (str, prefix ? IPV6_PREFIX_STR : IPV6_ADDR_STR) != strlen (str))
return no_match;
while (*str != '\0' && state != STATE_MASK)
@@ -966,6 +945,13 @@ match_ipv6_prefix (const char *str)
str++;
}
+ if (!prefix)
+ {
+ struct sockaddr_in6 sin6_dummy;
+ int ret = inet_pton(AF_INET6, start, &sin6_dummy.sin6_addr);
+ return ret == 1 ? exact_match : partly_match;
+ }
+
if (state < STATE_MASK)
return partly_match;
diff --git a/lib/command_match.h b/lib/command_match.h
index 9e18b8d905..a04f60f0d8 100644
--- a/lib/command_match.h
+++ b/lib/command_match.h
@@ -16,10 +16,9 @@
* 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.
+ * 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 _ZEBRA_COMMAND_MATCH_H
diff --git a/lib/command_parse.y b/lib/command_parse.y
index 0c415af3aa..466e3d3f1f 100644
--- a/lib/command_parse.y
+++ b/lib/command_parse.y
@@ -44,12 +44,12 @@
* 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 <stdlib.h>
+ #include <string.h>
+ #include <ctype.h>
+
+ #include "command_graph.h"
#include "log.h"
- #include "graph.h"
DECLARE_MTYPE(LEX)
@@ -104,12 +104,15 @@
%type <node> start
%type <node> literal_token
%type <node> placeholder_token
+%type <node> placeholder_token_real
%type <node> simple_token
%type <subgraph> selector
%type <subgraph> selector_token
%type <subgraph> selector_token_seq
%type <subgraph> selector_seq_seq
+%type <string> varname_token
+
%code {
/* bison declarations */
@@ -184,6 +187,16 @@ start:
}
;
+varname_token: '$' WORD
+{
+ $$ = XSTRDUP (MTYPE_LEX, $2);
+}
+| /* empty */
+{
+ $$ = NULL;
+}
+;
+
cmd_token_seq:
/* empty */
| cmd_token_seq cmd_token
@@ -207,14 +220,16 @@ simple_token:
| placeholder_token
;
-literal_token: WORD
+literal_token: WORD varname_token
{
$$ = new_token_node (ctx, WORD_TKN, $1, doc_next(ctx));
+ cmd_token_varname_set ($$->data, $2);
+ XFREE (MTYPE_LEX, $2);
XFREE (MTYPE_LEX, $1);
}
;
-placeholder_token:
+placeholder_token_real:
IPV4
{
$$ = new_token_node (ctx, IPV4_TKN, $1, doc_next(ctx));
@@ -257,10 +272,22 @@ placeholder_token:
XFREE (MTYPE_LEX, $1);
}
+placeholder_token:
+ placeholder_token_real varname_token
+{
+ struct cmd_token *token = $$->data;
+ $$ = $1;
+ cmd_token_varname_set (token, $2);
+ XFREE (MTYPE_LEX, $2);
+};
+
+
/* <selector|set> productions */
-selector: '<' selector_seq_seq '>'
+selector: '<' selector_seq_seq '>' varname_token
{
$$ = $2;
+ cmd_token_varname_set ($2.end->data, $4);
+ XFREE (MTYPE_LEX, $4);
};
selector_seq_seq:
@@ -283,7 +310,7 @@ selector_seq_seq:
;
/* {keyword} productions */
-selector: '{' selector_seq_seq '}'
+selector: '{' selector_seq_seq '}' varname_token
{
$$ = $2;
graph_add_edge ($$.end, $$.start);
@@ -293,6 +320,9 @@ selector: '{' selector_seq_seq '}'
* 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. */
+
+ cmd_token_varname_set ($2.end->data, $4);
+ XFREE (MTYPE_LEX, $4);
};
@@ -315,10 +345,12 @@ selector_token_seq:
;
/* [option] productions */
-selector: '[' selector_seq_seq ']'
+selector: '[' selector_seq_seq ']' varname_token
{
$$ = $2;
graph_add_edge ($$.start, $$.end);
+ cmd_token_varname_set ($2.end->data, $4);
+ XFREE (MTYPE_LEX, $4);
}
;
@@ -329,7 +361,7 @@ selector: '[' selector_seq_seq ']'
DEFINE_MTYPE(LIB, LEX, "Lexer token (temporary)")
void
-command_parse_format (struct graph *graph, struct cmd_element *cmd)
+cmd_graph_parse (struct graph *graph, struct cmd_element *cmd)
{
struct parser_ctx ctx = { .graph = graph, .el = cmd };
@@ -430,6 +462,6 @@ 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);
+ struct cmd_token *token = cmd_token_new (type, ctx->el->attr, text, doc);
+ return graph_new_node (ctx->graph, token, (void (*)(void *)) &cmd_token_del);
}
diff --git a/lib/csv.c b/lib/csv.c
index d614ac3066..bfe712bade 100644
--- a/lib/csv.c
+++ b/lib/csv.c
@@ -13,10 +13,9 @@
* 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.
+ * 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 <stdio.h>
#include <stdlib.h>
diff --git a/lib/csv.h b/lib/csv.h
index 3fb4453761..3ee568578c 100644
--- a/lib/csv.h
+++ b/lib/csv.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 __CSV_H__
diff --git a/lib/distribute.c b/lib/distribute.c
index f85994c9a8..7b7d49d1d6 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/distribute.h b/lib/distribute.h
index e9625a3548..23d7cac577 100644
--- a/lib/distribute.h
+++ b/lib/distribute.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_DISTRIBUTE_H
diff --git a/lib/event_counter.c b/lib/event_counter.c
index e94aa4c0f6..0acd0a1f7a 100644
--- a/lib/event_counter.c
+++ b/lib/event_counter.c
@@ -35,10 +35,9 @@
* 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.
+ * 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>
diff --git a/lib/event_counter.h b/lib/event_counter.h
index f40c6cde63..8c11e10287 100644
--- a/lib/event_counter.h
+++ b/lib/event_counter.h
@@ -35,10 +35,9 @@
* 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.
+ * 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 _ZEBRA_EVENT_COUNTER_H
diff --git a/lib/fifo.h b/lib/fifo.h
index 6be75b7611..631556e78e 100644
--- a/lib/fifo.h
+++ b/lib/fifo.h
@@ -1,22 +1,22 @@
/* FIFO common header.
- Copyright (C) 2015 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 2015 Kunihiro Ishiguro
+ *
+ * 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 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 __LIB_FIFO_H__
#define __LIB_FIFO_H__
diff --git a/lib/filter.c b/lib/filter.c
index fd73d4de73..93aac31b4f 100644
--- a/lib/filter.c
+++ b/lib/filter.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/filter.h b/lib/filter.h
index 6b5ccb52ec..2c70018112 100644
--- a/lib/filter.h
+++ b/lib/filter.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_FILTER_H
diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c
new file mode 100644
index 0000000000..17bc82f5da
--- /dev/null
+++ b/lib/frr_pthread.c
@@ -0,0 +1,183 @@
+/*
+ * Utilities and interfaces for managing POSIX threads
+ * Copyright (C) 2017 Cumulus Networks
+ *
+ * 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 <pthread.h>
+
+#include "frr_pthread.h"
+#include "memory.h"
+#include "hash.h"
+
+DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread");
+
+static unsigned int next_id = 0;
+
+/* Hash table of all frr_pthreads along with synchronization primitive(s) and
+ * hash table callbacks.
+ * ------------------------------------------------------------------------ */
+static struct hash *pthread_table;
+static pthread_mutex_t pthread_table_mtx = PTHREAD_MUTEX_INITIALIZER;
+
+/* pthread_table->hash_cmp */
+static int pthread_table_hash_cmp(const void *value1, const void *value2)
+{
+ const struct frr_pthread *tq1 = value1;
+ const struct frr_pthread *tq2 = value2;
+
+ return (tq1->id == tq2->id);
+}
+
+/* pthread_table->hash_key */
+static unsigned int pthread_table_hash_key(void *value)
+{
+ return ((struct frr_pthread *)value)->id;
+}
+/* ------------------------------------------------------------------------ */
+
+void frr_pthread_init()
+{
+ pthread_mutex_lock(&pthread_table_mtx);
+ {
+ pthread_table =
+ hash_create(pthread_table_hash_key, pthread_table_hash_cmp);
+ }
+ pthread_mutex_unlock(&pthread_table_mtx);
+}
+
+void frr_pthread_finish()
+{
+ pthread_mutex_lock(&pthread_table_mtx);
+ {
+ hash_clean(pthread_table, (void (*)(void *))frr_pthread_destroy);
+ hash_free(pthread_table);
+ }
+ pthread_mutex_unlock(&pthread_table_mtx);
+}
+
+struct frr_pthread *frr_pthread_new(const char *name, unsigned int id,
+ void *(*start_routine) (void *),
+ int (*stop_routine) (void **, struct frr_pthread *))
+{
+ static struct frr_pthread holder = { 0 };
+ struct frr_pthread *fpt = NULL;
+
+ pthread_mutex_lock(&pthread_table_mtx);
+ {
+ holder.id = id;
+
+ if (!hash_lookup(pthread_table, &holder)) {
+ struct frr_pthread *fpt =
+ XCALLOC(MTYPE_FRR_PTHREAD,
+ sizeof(struct frr_pthread));
+ fpt->id = id;
+ fpt->master = thread_master_create();
+ fpt->start_routine = start_routine;
+ fpt->stop_routine = stop_routine;
+ fpt->name = XSTRDUP(MTYPE_FRR_PTHREAD, name);
+
+ hash_get(pthread_table, fpt, hash_alloc_intern);
+ }
+ }
+ pthread_mutex_unlock(&pthread_table_mtx);
+
+ return fpt;
+}
+
+void frr_pthread_destroy(struct frr_pthread *fpt)
+{
+ thread_master_free(fpt->master);
+ XFREE(MTYPE_FRR_PTHREAD, fpt->name);
+ XFREE(MTYPE_FRR_PTHREAD, fpt);
+}
+
+struct frr_pthread *frr_pthread_get(unsigned int id)
+{
+ static struct frr_pthread holder = { 0 };
+ struct frr_pthread *fpt;
+
+ pthread_mutex_lock(&pthread_table_mtx);
+ {
+ holder.id = id;
+ fpt = hash_lookup(pthread_table, &holder);
+ }
+ pthread_mutex_unlock(&pthread_table_mtx);
+
+ return fpt;
+}
+
+int frr_pthread_run(unsigned int id, const pthread_attr_t * attr, void *arg)
+{
+ struct frr_pthread *fpt = frr_pthread_get(id);
+ int ret;
+
+ if (!fpt)
+ return -1;
+
+ ret = pthread_create(&fpt->thread, attr, fpt->start_routine, arg);
+
+ /* Per pthread_create(3), the contents of fpt->thread are undefined if
+ * pthread_create() did not succeed. Reset this value to zero. */
+ if (ret < 0)
+ memset(&fpt->thread, 0x00, sizeof(fpt->thread));
+
+ return ret;
+}
+
+/**
+ * Calls the stop routine for the frr_pthread and resets any relevant fields.
+ *
+ * @param fpt - the frr_pthread to stop
+ * @param result - pointer to result pointer
+ * @return the return code from the stop routine
+ */
+static int frr_pthread_stop_actual(struct frr_pthread *fpt, void **result)
+{
+ int ret = (*fpt->stop_routine) (result, fpt);
+ memset(&fpt->thread, 0x00, sizeof(fpt->thread));
+ return ret;
+}
+
+int frr_pthread_stop(unsigned int id, void **result)
+{
+ struct frr_pthread *fpt = frr_pthread_get(id);
+ return frr_pthread_stop_actual(fpt, result);
+}
+
+/**
+ * Callback for hash_iterate to stop all frr_pthread's.
+ */
+static void frr_pthread_stop_all_iter(struct hash_backet *hb, void *arg)
+{
+ struct frr_pthread *fpt = hb->data;
+ frr_pthread_stop_actual(fpt, NULL);
+}
+
+void frr_pthread_stop_all()
+{
+ pthread_mutex_lock(&pthread_table_mtx);
+ {
+ hash_iterate(pthread_table, frr_pthread_stop_all_iter, NULL);
+ }
+ pthread_mutex_unlock(&pthread_table_mtx);
+}
+
+unsigned int frr_pthread_get_id()
+{
+ return next_id++;
+}
diff --git a/lib/frr_pthread.h b/lib/frr_pthread.h
new file mode 100644
index 0000000000..1a390b1e45
--- /dev/null
+++ b/lib/frr_pthread.h
@@ -0,0 +1,144 @@
+/*
+ * Utilities and interfaces for managing POSIX threads
+ * Copyright (C) 2017 Cumulus Networks
+ *
+ * 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 _FRR_PTHREAD_H
+#define _FRR_PTHREAD_H
+
+#include <pthread.h>
+#include "thread.h"
+
+struct frr_pthread {
+
+ /* pthread id */
+ pthread_t thread;
+
+ /* frr thread identifier */
+ unsigned int id;
+
+ /* thread master for this pthread's thread.c event loop */
+ struct thread_master *master;
+
+ /* start routine */
+ void *(*start_routine) (void *);
+
+ /* stop routine */
+ int (*stop_routine) (void **, struct frr_pthread *);
+
+ /* the (hopefully descriptive) name of this thread */
+ char *name;
+};
+
+/* Initializes this module.
+ *
+ * Must be called before using any of the other functions.
+ */
+void frr_pthread_init(void);
+
+/* Uninitializes this module.
+ *
+ * Destroys all registered frr_pthread's and internal data structures.
+ *
+ * It is safe to call frr_pthread_init() after this function to reinitialize
+ * the module.
+ */
+void frr_pthread_finish(void);
+
+/* Creates a new frr_pthread.
+ *
+ * If the provided ID is already assigned to an existing frr_pthread, the
+ * return value will be NULL.
+ *
+ * @param name - the name of the thread. Doesn't have to be unique, but it
+ * probably should be. This value is copied and may be safely free'd upon
+ * return.
+ *
+ * @param id - the integral ID of the thread. MUST be unique. The caller may
+ * use this id to retrieve the thread.
+ *
+ * @param start_routine - start routine for the pthread, will be passed to
+ * pthread_create (see those docs for details)
+ *
+ * @param stop_routine - stop routine for the pthread, called to terminate the
+ * thread. This function should gracefully stop the pthread and clean up any
+ * thread-specific resources. The passed pointer is used to return a data
+ * result.
+ *
+ * @return the created frr_pthread upon success, or NULL upon failure
+ */
+struct frr_pthread *frr_pthread_new(const char *name, unsigned int id,
+ void *(*start_routine) (void *),
+ int (*stop_routine) (void **, struct frr_pthread *));
+
+/* Destroys an frr_pthread.
+ *
+ * Assumes that the associated pthread, if any, has already terminated.
+ *
+ * @param fpt - the frr_pthread to destroy
+ */
+void frr_pthread_destroy(struct frr_pthread *fpt);
+
+/* Gets an existing frr_pthread by its id.
+ *
+ * @return frr_thread associated with the provided id, or NULL on error
+ */
+struct frr_pthread *frr_pthread_get(unsigned int id);
+
+/* Creates a new pthread and binds it to a frr_pthread.
+ *
+ * This function is a wrapper for pthread_create. The first parameter is the
+ * frr_pthread to bind the created pthread to. All subsequent arguments are
+ * passed unmodified to pthread_create().
+ *
+ * This function returns the same code as pthread_create(). If the value is
+ * zero, the provided frr_pthread is bound to a running POSIX thread. If the
+ * value is less than zero, the provided frr_pthread is guaranteed to be a
+ * clean instance that may be susbsequently passed to frr_pthread_run().
+ *
+ * @param id - frr_pthread to bind the created pthread to
+ * @param attr - see pthread_create(3)
+ * @param arg - see pthread_create(3)
+ *
+ * @return see pthread_create(3)
+ */
+int frr_pthread_run(unsigned int id, const pthread_attr_t * attr, void *arg);
+
+/* Stops an frr_pthread with a result.
+ *
+ * @param id - frr_pthread to stop
+ * @param result - where to store the thread's result, if any. May be NULL if a
+ * result is not needed.
+ */
+int frr_pthread_stop(unsigned int id, void **result);
+
+/* Stops all frr_pthread's. */
+void frr_pthread_stop_all(void);
+
+/* Returns a unique identifier for use with frr_pthread_new().
+ *
+ * Internally, this is an integer that increments after each call to this
+ * function. Because the number of pthreads created should never exceed INT_MAX
+ * during the life of the program, there is no overflow protection. If by
+ * chance this function returns an ID which is already in use,
+ * frr_pthread_new() will fail when it is provided.
+ *
+ * @return unique identifier
+ */
+unsigned int frr_pthread_get_id(void);
+
+#endif /* _FRR_PTHREAD_H */
diff --git a/lib/frratomic.h b/lib/frratomic.h
new file mode 100644
index 0000000000..183790aeb0
--- /dev/null
+++ b/lib/frratomic.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015-16 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 _FRRATOMIC_H
+#define _FRRATOMIC_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef FRR_AUTOCONF_ATOMIC
+#error autoconf checks for atomic functions were not properly run
+#endif
+
+/* ISO C11 */
+#ifdef HAVE_STDATOMIC_H
+#include <stdatomic.h>
+
+/* gcc 4.7 and newer */
+#elif defined(HAVE___ATOMIC)
+
+#define _Atomic volatile
+
+#define memory_order_relaxed __ATOMIC_RELAXED
+#define memory_order_consume __ATOMIC_CONSUME
+#define memory_order_acquire __ATOMIC_ACQUIRE
+#define memory_order_release __ATOMIC_RELEASE
+#define memory_order_acq_rel __ATOMIC_ACQ_REL
+#define memory_order_seq_cst __ATOMIC_SEQ_CST
+
+#define atomic_load_explicit __atomic_load_n
+#define atomic_store_explicit __atomic_store_n
+#define atomic_exchange_explicit __atomic_exchange_n
+#define atomic_fetch_add_explicit __atomic_fetch_add
+#define atomic_fetch_sub_explicit __atomic_fetch_sub
+
+#define atomic_compare_exchange_weak_explicit(atom, expect, desire, mem1, mem2) \
+ __atomic_compare_exchange_n(atom, expect, desire, 1, mem1, mem2)
+
+/* gcc 4.1 and newer,
+ * clang 3.3 (possibly older)
+ *
+ * __sync_swap isn't in gcc's documentation, but clang has it
+ *
+ * note __sync_synchronize()
+ */
+#elif defined(HAVE___SYNC)
+
+#define _Atomic volatile
+
+#define memory_order_relaxed 0
+#define memory_order_consume 0
+#define memory_order_acquire 0
+#define memory_order_release 0
+#define memory_order_acq_rel 0
+#define memory_order_seq_cst 0
+
+#define atomic_load_explicit(ptr, mem) \
+ ({ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_fetch_and_add((ptr), 0); \
+ __sync_synchronize(); rval; })
+#define atomic_store_explicit(ptr, val, mem) \
+ ({ __sync_synchronize(); \
+ *(ptr) = (val); \
+ __sync_synchronize(); (void)0; })
+#ifdef HAVE___SYNC_SWAP
+#define atomic_exchange_explicit(ptr, val, mem) \
+ ({ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_swap((ptr, val), 0); \
+ __sync_synchronize(); rval; })
+#else /* !HAVE___SYNC_SWAP */
+#define atomic_exchange_explicit(ptr, val, mem) \
+ ({ typeof(ptr) _ptr = (ptr); typeof(val) _val = (val); \
+ __sync_synchronize(); \
+ typeof(*ptr) old1, old2 = __sync_fetch_and_add(_ptr, 0); \
+ do { \
+ old1 = old2; \
+ old2 = __sync_val_compare_and_swap (_ptr, old1, _val); \
+ } while (old1 != old2); \
+ __sync_synchronize(); \
+ old2; \
+ })
+#endif /* !HAVE___SYNC_SWAP */
+#define atomic_fetch_add_explicit(ptr, val, mem) \
+ ({ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_fetch_and_add((ptr), (val)); \
+ __sync_synchronize(); rval; })
+#define atomic_fetch_sub_explicit(ptr, val, mem) \
+ ({ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_fetch_and_sub((ptr), (val)); \
+ __sync_synchronize(); rval; })
+
+#define atomic_compare_exchange_weak_explicit(atom, expect, desire, mem1, mem2) \
+ ({ typeof(atom) _atom = (atom); typeof(expect) _expect = (expect); \
+ typeof(desire) _desire = (desire); \
+ __sync_synchronize(); \
+ typeof(*atom) rval = __sync_val_compare_and_swap(_atom, *_expect, _desire); \
+ __sync_synchronize(); \
+ bool ret = (rval == *_expect); *_expect = rval; ret; })
+
+#else /* !HAVE___ATOMIC && !HAVE_STDATOMIC_H */
+#error no atomic functions...
+#endif
+
+#endif /* _FRRATOMIC_H */
diff --git a/lib/getopt.c b/lib/getopt.c
index 7a58a8a8cc..d0ee43510b 100644
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -1,28 +1,28 @@
/* Getopt for GNU.
- NOTE: getopt is now part of the C library, so if you don't know what
- "Keep this file name-space clean" means, talk to drepper@gnu.org
- before changing it!
-
- Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
- Free Software Foundation, Inc.
-
- NOTE: The canonical source of this file is maintained with the GNU C Library.
- Bugs can be reported to bug-glibc@gnu.org.
-
- 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, 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. */
+ * NOTE: getopt is now part of the C library, so if you don't know what
+ * "Keep this file name-space clean" means, talk to drepper@gnu.org
+ * before changing it!
+ *
+ * Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
+ * Free Software Foundation, Inc.
+ *
+ * NOTE: The canonical source of this file is maintained with the GNU C Library.
+ * Bugs can be reported to bug-glibc@gnu.org.
+ *
+ * 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, 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
+ */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
diff --git a/lib/getopt.h b/lib/getopt.h
index b359a47beb..cc38a45c23 100644
--- a/lib/getopt.h
+++ b/lib/getopt.h
@@ -1,23 +1,23 @@
/* Declarations for getopt.
- Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
-
- NOTE: The canonical source of this file is maintained with the GNU C Library.
- Bugs can be reported to bug-glibc@gnu.org.
-
- 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, 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. */
+ * Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+ *
+ * NOTE: The canonical source of this file is maintained with the GNU C Library.
+ * Bugs can be reported to bug-glibc@gnu.org.
+ *
+ * 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, 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 _GETOPT_H
#define _GETOPT_H 1
diff --git a/lib/getopt1.c b/lib/getopt1.c
index bd3099e799..1873a197e1 100644
--- a/lib/getopt1.c
+++ b/lib/getopt1.c
@@ -1,24 +1,24 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
- Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
- Free Software Foundation, Inc.
-
- NOTE: The canonical source of this file is maintained with the GNU C Library.
- Bugs can be reported to bug-glibc@gnu.org.
-
- 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, 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. */
+ * Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+ * Free Software Foundation, Inc.
+ *
+ * NOTE: The canonical source of this file is maintained with the GNU C Library.
+ * Bugs can be reported to bug-glibc@gnu.org.
+ *
+ * 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, 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 "getopt.h"
diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c
index 0da7981fc1..cfc3fb7982 100644
--- a/lib/grammar_sandbox.c
+++ b/lib/grammar_sandbox.c
@@ -18,10 +18,9 @@
* 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.
+ * 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 "command.h"
@@ -70,11 +69,11 @@ DEFUN (grammar_test,
// parse the command and install it into the command graph
struct graph *graph = graph_new();
- struct cmd_token *token = new_cmd_token (START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
- graph_new_node (graph, token, (void (*)(void *)) &del_cmd_token);
+ struct cmd_token *token = cmd_token_new (START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ graph_new_node (graph, token, (void (*)(void *)) &cmd_token_del);
- command_parse_format (graph, cmd);
- cmd_merge_graphs (nodegraph, graph, +1);
+ cmd_graph_parse (graph, cmd);
+ cmd_graph_merge (nodegraph, graph, +1);
return CMD_SUCCESS;
}
@@ -123,7 +122,7 @@ DEFUN (grammar_test_complete,
}
for (i = 0; i < vector_active (comps); i++)
- del_cmd_token ((struct cmd_token *) vector_slot (comps, i));
+ cmd_token_del ((struct cmd_token *) vector_slot (comps, i));
vector_free (comps);
}
else
@@ -229,7 +228,7 @@ DEFUN (grammar_test_doc,
cmd->func = NULL;
// parse element
- command_parse_format (nodegraph, cmd);
+ cmd_graph_parse (nodegraph, cmd);
return CMD_SUCCESS;
}
@@ -526,6 +525,8 @@ pretty_print_graph (struct vty *vty, struct graph_node *start, int level,
vty_out(vty, "%s", LOOKUP_DEF(tokennames, tok->type, tokennum));
if (tok->text)
vty_out(vty, ":\"%s\"", tok->text);
+ if (tok->varname)
+ vty_out(vty, " => %s", tok->varname);
if (desc)
vty_out(vty, " ?'%s'", tok->desc);
vty_out(vty, " ");
@@ -647,8 +648,8 @@ 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);
+ struct cmd_token *token = cmd_token_new (START_TKN, 0, NULL, NULL);
+ graph_new_node (*graph, token, (void (*)(void *)) &cmd_token_del);
if (vty)
vty_out (vty, "initialized graph%s", VTY_NEWLINE);
}
diff --git a/lib/grammar_sandbox_main.c b/lib/grammar_sandbox_main.c
index 681d4da440..3bf0e268cf 100644
--- a/lib/grammar_sandbox_main.c
+++ b/lib/grammar_sandbox_main.c
@@ -19,8 +19,8 @@
* 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.
+ * 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 "command.h"
diff --git a/lib/graph.c b/lib/graph.c
index 0992059ef1..6173b2084b 100644
--- a/lib/graph.c
+++ b/lib/graph.c
@@ -16,10 +16,9 @@
* 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.
+ * 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 "graph.h"
diff --git a/lib/graph.h b/lib/graph.h
index 8d8aa3823b..d3973d4b02 100644
--- a/lib/graph.h
+++ b/lib/graph.h
@@ -16,10 +16,9 @@
* 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.
+ * 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 _ZEBRA_COMMAND_GRAPH_H
diff --git a/lib/hash.c b/lib/hash.c
index cb8531fccf..553a137eb6 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/hash.h b/lib/hash.h
index 11ecf75ec9..bafb35a2a3 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -1,22 +1,22 @@
/* Hash routine.
- Copyright (C) 1998 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ *
+ * 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 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 _ZEBRA_HASH_H
#define _ZEBRA_HASH_H
diff --git a/lib/if.c b/lib/if.c
index ecb7463168..dc417f8e3c 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -1,10 +1,9 @@
-
/*
* Interface functions.
* Copyright (C) 1997, 98 Kunihiro Ishiguro
*
* 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
@@ -15,10 +14,9 @@
* 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.
+ * 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>
@@ -1126,6 +1124,36 @@ ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex)
}
#endif /* ifaddr_ipv4_table */
+static void if_autocomplete(vector comps, struct cmd_token *token)
+{
+ struct interface *ifp;
+ struct listnode *ln;
+ struct vrf *vrf = NULL;
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+ {
+ for (ALL_LIST_ELEMENTS_RO(vrf->iflist, ln, ifp))
+ vector_set (comps, XSTRDUP (MTYPE_COMPLETION, ifp->name));
+ }
+
+}
+
+static const struct cmd_variable_handler if_var_handlers[] = {
+ {
+ /* "interface NAME" */
+ .varname = "interface",
+ .completions = if_autocomplete
+ }, {
+ .tokenname = "IFNAME",
+ .completions = if_autocomplete
+ }, {
+ .tokenname = "INTERFACE",
+ .completions = if_autocomplete
+ }, {
+ .completions = NULL
+ }
+};
+
/* Initialize interface list. */
void
if_init (struct list **intf_list)
@@ -1136,6 +1164,8 @@ if_init (struct list **intf_list)
#endif /* ifaddr_ipv4_table */
(*intf_list)->cmp = (int (*)(void *, void *))if_cmp_func;
+
+ cmd_variable_handler_register(if_var_handlers);
}
void
diff --git a/lib/if.h b/lib/if.h
index e8e84ffc88..fa95901a58 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -1,22 +1,22 @@
/* Interface related header.
- Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
+ *
+ * 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 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 _ZEBRA_IF_H
#define _ZEBRA_IF_H
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index 2afb08c7ca..fa9b17f2ae 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/if_rmap.h b/lib/if_rmap.h
index e6c2966ff8..e38b5f7f73 100644
--- a/lib/if_rmap.h
+++ b/lib/if_rmap.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_IF_RMAP_H
diff --git a/lib/json.c b/lib/json.c
index ccbecb726a..186efc9f48 100644
--- a/lib/json.c
+++ b/lib/json.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/json.h b/lib/json.h
index 7e98614280..5faaaa841a 100644
--- a/lib/json.h
+++ b/lib/json.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _QUAGGA_JSON_H
diff --git a/lib/keychain.c b/lib/keychain.c
index 95a2c8e599..1aa6edb4bd 100644
--- a/lib/keychain.c
+++ b/lib/keychain.c
@@ -1,22 +1,22 @@
/* key-chain for authentication.
- Copyright (C) 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 2000 Kunihiro Ishiguro
+ *
+ * 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 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>
diff --git a/lib/keychain.h b/lib/keychain.h
index d3f9168a0f..e6bdcc6f06 100644
--- a/lib/keychain.h
+++ b/lib/keychain.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_KEYCHAIN_H
diff --git a/lib/libfrr.c b/lib/libfrr.c
index de83e14f0e..16681fe578 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -13,9 +13,9 @@
* 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
+ * 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>
diff --git a/lib/libfrr.h b/lib/libfrr.h
index 0cc7ad564b..6bd92d8bea 100644
--- a/lib/libfrr.h
+++ b/lib/libfrr.h
@@ -13,9 +13,9 @@
* 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
+ * 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 _ZEBRA_FRR_H
diff --git a/lib/libospf.h b/lib/libospf.h
index a1ff9c24a2..c9483a4c65 100644
--- a/lib/libospf.h
+++ b/lib/libospf.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _LIBOSPFD_H
diff --git a/lib/linklist.c b/lib/linklist.c
index 6fe91c75fc..0aee54d44c 100644
--- a/lib/linklist.c
+++ b/lib/linklist.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/linklist.h b/lib/linklist.h
index cd6e2f13aa..37ba396a76 100644
--- a/lib/linklist.h
+++ b/lib/linklist.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_LINKLIST_H
diff --git a/lib/log.c b/lib/log.c
index c7d4ca2d97..111b98758d 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
#define FRR_DEFINE_DESC_TABLE
@@ -734,6 +733,17 @@ openzlog (const char *progname, const char *protoname, u_short instance,
openlog (progname, syslog_flags, zl->facility);
zlog_default = zl;
+
+#ifdef HAVE_GLIBC_BACKTRACE
+ /* work around backtrace() using lazily resolved dynamically linked
+ * symbols, which will otherwise cause funny breakage in the SEGV handler.
+ * (particularly, the dynamic linker can call malloc(), which uses locks
+ * in programs linked with -pthread, thus can deadlock.) */
+ void *bt[4];
+ backtrace (bt, array_size(bt));
+ free (backtrace_symbols (bt, 0));
+ backtrace_symbols_fd (bt, 0, 0);
+#endif
}
void
@@ -1047,6 +1057,8 @@ proto_redistnum(int afi, const char *s)
return ZEBRA_ROUTE_STATIC;
else if (strmatch (s, "rip"))
return ZEBRA_ROUTE_RIP;
+ else if (strmatch (s, "eigrp"))
+ return ZEBRA_ROUTE_EIGRP;
else if (strmatch (s, "ospf"))
return ZEBRA_ROUTE_OSPF;
else if (strmatch (s, "isis"))
diff --git a/lib/log.h b/lib/log.h
index cc419cc374..f6c94ba604 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -14,16 +14,16 @@
* 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.
+ * 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 _ZEBRA_LOG_H
#define _ZEBRA_LOG_H
#include <syslog.h>
+#include <stdint.h>
#include <stdio.h>
/* Here is some guidance on logging levels to use:
@@ -64,7 +64,7 @@ struct message
/* Open zlog function */
extern void openzlog (const char *progname, const char *protoname,
- u_short instance, int syslog_options, int syslog_facility);
+ uint16_t instance, int syslog_options, int syslog_facility);
/* Close zlog function. */
extern void closezlog (void);
diff --git a/lib/log_int.h b/lib/log_int.h
index c21d723ac6..7c93381cbc 100644
--- a/lib/log_int.h
+++ b/lib/log_int.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_LOG_PRIVATE_H
diff --git a/lib/memory.c b/lib/memory.c
index ad55366f64..c6207adb98 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -27,119 +27,107 @@ struct memgroup **mg_insert = &mg_first;
DEFINE_MGROUP(LIB, "libfrr")
DEFINE_MTYPE(LIB, TMP, "Temporary memory")
-static inline void
-mt_count_alloc (struct memtype *mt, size_t size)
+static inline void mt_count_alloc(struct memtype *mt, size_t size)
{
- mt->n_alloc++;
+ size_t oldsize;
- if (mt->size == 0)
- mt->size = size;
- else if (mt->size != size)
- mt->size = SIZE_VAR;
+ atomic_fetch_add_explicit(&mt->n_alloc, 1, memory_order_relaxed);
+
+ oldsize = atomic_load_explicit(&mt->size, memory_order_relaxed);
+ if (oldsize == 0)
+ oldsize = atomic_exchange_explicit(&mt->size, size, memory_order_relaxed);
+ if (oldsize != 0 && oldsize != size && oldsize != SIZE_VAR)
+ atomic_store_explicit(&mt->size, SIZE_VAR, memory_order_relaxed);
}
-static inline void
-mt_count_free (struct memtype *mt)
+static inline void mt_count_free(struct memtype *mt)
{
- assert(mt->n_alloc);
- mt->n_alloc--;
+ assert(mt->n_alloc);
+ atomic_fetch_sub_explicit(&mt->n_alloc, 1, memory_order_relaxed);
}
-static inline void *
-mt_checkalloc (struct memtype *mt, void *ptr, size_t size)
+static inline void *mt_checkalloc(struct memtype *mt, void *ptr, size_t size)
{
- if (__builtin_expect(ptr == NULL, 0))
- {
- memory_oom (size, mt->name);
- return NULL;
- }
- mt_count_alloc (mt, size);
- return ptr;
+ if (__builtin_expect(ptr == NULL, 0)) {
+ memory_oom(size, mt->name);
+ return NULL;
+ }
+ mt_count_alloc(mt, size);
+ return ptr;
}
-void *
-qmalloc (struct memtype *mt, size_t size)
+void *qmalloc(struct memtype *mt, size_t size)
{
- return mt_checkalloc (mt, malloc (size), size);
+ return mt_checkalloc(mt, malloc(size), size);
}
-void *
-qcalloc (struct memtype *mt, size_t size)
+void *qcalloc(struct memtype *mt, size_t size)
{
- return mt_checkalloc (mt, calloc (size, 1), size);
+ return mt_checkalloc(mt, calloc(size, 1), size);
}
-void *
-qrealloc (struct memtype *mt, void *ptr, size_t size)
+void *qrealloc(struct memtype *mt, void *ptr, size_t size)
{
- if (ptr)
- mt_count_free (mt);
- return mt_checkalloc (mt, ptr ? realloc (ptr, size) : malloc (size), size);
+ if (ptr)
+ mt_count_free(mt);
+ return mt_checkalloc(mt, ptr ? realloc(ptr, size) : malloc(size), size);
}
-void *
-qstrdup (struct memtype *mt, const char *str)
+void *qstrdup(struct memtype *mt, const char *str)
{
- return mt_checkalloc (mt, strdup (str), strlen (str) + 1);
+ return mt_checkalloc(mt, strdup(str), strlen(str) + 1);
}
-void
-qfree (struct memtype *mt, void *ptr)
+void qfree(struct memtype *mt, void *ptr)
{
- if (ptr)
- mt_count_free (mt);
- free (ptr);
+ if (ptr)
+ mt_count_free(mt);
+ free(ptr);
}
-int
-qmem_walk (qmem_walk_fn *func, void *arg)
+int qmem_walk(qmem_walk_fn *func, void *arg)
{
- struct memgroup *mg;
- struct memtype *mt;
- int rv;
-
- for (mg = mg_first; mg; mg = mg->next)
- {
- if ((rv = func (arg, mg, NULL)))
- return rv;
- for (mt = mg->types; mt; mt = mt->next)
- if ((rv = func (arg, mg, mt)))
- return rv;
- }
- return 0;
+ struct memgroup *mg;
+ struct memtype *mt;
+ int rv;
+
+ for (mg = mg_first; mg; mg = mg->next) {
+ if ((rv = func(arg, mg, NULL)))
+ return rv;
+ for (mt = mg->types; mt; mt = mt->next)
+ if ((rv = func(arg, mg, mt)))
+ return rv;
+ }
+ return 0;
}
-struct exit_dump_args
-{
- const char *prefix;
- int error;
+struct exit_dump_args {
+ const char *prefix;
+ int error;
};
-static int
-qmem_exit_walker (void *arg, struct memgroup *mg, struct memtype *mt)
+static int qmem_exit_walker(void *arg, struct memgroup *mg, struct memtype *mt)
{
- struct exit_dump_args *eda = arg;
-
- if (!mt)
- {
- fprintf (stderr, "%s: showing active allocations in memory group %s\n",
- eda->prefix, mg->name);
- }
- else if (mt->n_alloc)
- {
- char size[32];
- eda->error++;
- snprintf (size, sizeof (size), "%10zu", mt->size);
- fprintf (stderr, "%s: memstats: %-30s: %6zu * %s\n",
- eda->prefix, mt->name, mt->n_alloc,
- mt->size == SIZE_VAR ? "(variably sized)" : size);
- }
- return 0;
+ struct exit_dump_args *eda = arg;
+
+ if (!mt) {
+ fprintf(stderr, "%s: showing active allocations in "
+ "memory group %s\n",
+ eda->prefix, mg->name);
+
+ } else if (mt->n_alloc) {
+ char size[32];
+ eda->error++;
+ snprintf(size, sizeof(size), "%10zu", mt->size);
+ fprintf(stderr, "%s: memstats: %-30s: %6zu * %s\n",
+ eda->prefix, mt->name, mt->n_alloc,
+ mt->size == SIZE_VAR ? "(variably sized)" : size);
+ }
+ return 0;
}
-void
-log_memstats_stderr (const char *prefix)
+void log_memstats_stderr(const char *prefix)
{
- struct exit_dump_args eda = { .prefix = prefix, .error = 0 };
- qmem_walk (qmem_exit_walker, &eda);
+ struct exit_dump_args eda = { .prefix = prefix, .error = 0 };
+ qmem_walk(qmem_exit_walker, &eda);
}
diff --git a/lib/memory.h b/lib/memory.h
index 477a6162dc..9e8803a8b2 100644
--- a/lib/memory.h
+++ b/lib/memory.h
@@ -18,23 +18,22 @@
#define _QUAGGA_MEMORY_H
#include <stdlib.h>
+#include <frratomic.h>
#define array_size(ar) (sizeof(ar) / sizeof(ar[0]))
#define SIZE_VAR ~0UL
-struct memtype
-{
- struct memtype *next, **ref;
- const char *name;
- size_t n_alloc;
- size_t size;
+struct memtype {
+ struct memtype *next, **ref;
+ const char *name;
+ _Atomic size_t n_alloc;
+ _Atomic size_t size;
};
-struct memgroup
-{
- struct memgroup *next, **ref;
- struct memtype *types, **insert;
- const char *name;
+struct memgroup {
+ struct memgroup *next, **ref;
+ struct memtype *types, **insert;
+ const char *name;
};
#if defined(__clang__)
@@ -82,14 +81,14 @@ struct memgroup
* DEFINE_MGROUP(MYDAEMON, "my daemon memory")
* DEFINE_MTYPE(MYDAEMON, MYDAEMON_COMMON,
* "this mtype is used in multiple files in mydaemon")
- * foo = qmalloc (MTYPE_MYDAEMON_COMMON, sizeof (*foo))
+ * foo = qmalloc(MTYPE_MYDAEMON_COMMON, sizeof(*foo))
*
* mydaemon_io.c
- * bar = qmalloc (MTYPE_MYDAEMON_COMMON, sizeof (*bar))
+ * bar = qmalloc(MTYPE_MYDAEMON_COMMON, sizeof(*bar))
*
* DEFINE_MTYPE_STATIC(MYDAEMON, MYDAEMON_IO,
* "this mtype is used only in this file")
- * baz = qmalloc (MTYPE_MYDAEMON_IO, sizeof (*baz))
+ * baz = qmalloc(MTYPE_MYDAEMON_IO, sizeof(*baz))
*
* Note: Naming conventions (MGROUP_ and MTYPE_ prefixes are enforced
* by not having these as part of the macro arguments)
@@ -155,15 +154,15 @@ DECLARE_MGROUP(LIB)
DECLARE_MTYPE(TMP)
-extern void *qmalloc (struct memtype *mt, size_t size)
+extern void *qmalloc(struct memtype *mt, size_t size)
__attribute__ ((malloc, _ALLOC_SIZE(2), nonnull (1) _RET_NONNULL));
-extern void *qcalloc (struct memtype *mt, size_t size)
+extern void *qcalloc(struct memtype *mt, size_t size)
__attribute__ ((malloc, _ALLOC_SIZE(2), nonnull (1) _RET_NONNULL));
-extern void *qrealloc (struct memtype *mt, void *ptr, size_t size)
+extern void *qrealloc(struct memtype *mt, void *ptr, size_t size)
__attribute__ ((_ALLOC_SIZE(3), nonnull (1) _RET_NONNULL));
extern void *qstrdup (struct memtype *mt, const char *str)
__attribute__ ((malloc, nonnull (1) _RET_NONNULL));
-extern void qfree (struct memtype *mt, void *ptr)
+extern void qfree(struct memtype *mt, void *ptr)
__attribute__ ((nonnull (1)));
#define XMALLOC(mtype, size) qmalloc(mtype, size)
@@ -183,10 +182,10 @@ static inline size_t mtype_stats_alloc(struct memtype *mt)
*
* return value: 0: continue, !0: abort walk. qmem_walk will return the
* last value from qmem_walk_fn. */
-typedef int qmem_walk_fn (void *arg, struct memgroup *mg, struct memtype *mt);
-extern int qmem_walk (qmem_walk_fn *func, void *arg);
-extern void log_memstats_stderr (const char *);
+typedef int qmem_walk_fn(void *arg, struct memgroup *mg, struct memtype *mt);
+extern int qmem_walk(qmem_walk_fn *func, void *arg);
+extern void log_memstats_stderr(const char *);
-extern void memory_oom (size_t size, const char *name);
+extern void memory_oom(size_t size, const char *name);
#endif /* _QUAGGA_MEMORY_H */
diff --git a/lib/memory_vty.c b/lib/memory_vty.c
index 6d63bc2d53..27254cfa5b 100644
--- a/lib/memory_vty.c
+++ b/lib/memory_vty.c
@@ -14,9 +14,9 @@
* 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
+ * 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>
diff --git a/lib/memory_vty.h b/lib/memory_vty.h
index 565a75aa98..a47c5d51b8 100644
--- a/lib/memory_vty.h
+++ b/lib/memory_vty.h
@@ -1,22 +1,22 @@
/* Memory management routine
- Copyright (C) 1998 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ *
+ * 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 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 _ZEBRA_MEMORY_VTY_H
#define _ZEBRA_MEMORY_VTY_H
diff --git a/lib/mpls.h b/lib/mpls.h
index 13a46e1012..6cf0142755 100644
--- a/lib/mpls.h
+++ b/lib/mpls.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_MPLS_H
@@ -85,7 +84,8 @@ enum lsp_types_t
{
ZEBRA_LSP_NONE = 0, /* No LSP. */
ZEBRA_LSP_STATIC = 1, /* Static LSP. */
- ZEBRA_LSP_LDP = 2 /* LDP LSP. */
+ ZEBRA_LSP_LDP = 2, /* LDP LSP. */
+ ZEBRA_LSP_BGP = 3 /* BGP LSP. */
};
/* Functions for basic label operations. */
@@ -122,6 +122,11 @@ mpls_lse_decode (mpls_lse_t lse, mpls_label_t *label,
*ttl = MPLS_LABEL_TTL(local_lse);
}
+/* Invalid label index value (when used with BGP Prefix-SID). Should
+ * match the BGP definition.
+ */
+#define MPLS_INVALID_LABEL_INDEX 0xFFFFFFFF
+
/* Printable string for labels (with consideration for reserved values). */
static inline char *
diff --git a/lib/network.c b/lib/network.c
index 2b6f2fbab5..3d2c63c89d 100644
--- a/lib/network.c
+++ b/lib/network.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/lib/network.h b/lib/network.h
index a9126caf7f..a6b8ed1e17 100644
--- a/lib/network.h
+++ b/lib/network.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_NETWORK_H
diff --git a/lib/nexthop.c b/lib/nexthop.c
index 7b8ac95e83..725b52c052 100644
--- a/lib/nexthop.c
+++ b/lib/nexthop.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -92,6 +91,28 @@ nexthop_type_to_str (enum nexthop_types_t nh_type)
return desc[nh_type];
}
+/*
+ * Check if the labels match for the 2 nexthops specified.
+ */
+int
+nexthop_labels_match (struct nexthop *nh1, struct nexthop *nh2)
+{
+ struct nexthop_label *nhl1, *nhl2;
+
+ nhl1 = nh1->nh_label;
+ nhl2 = nh2->nh_label;
+ if ((nhl1 && !nhl2) || (!nhl1 && nhl2))
+ return 0;
+
+ if (nhl1->num_labels != nhl2->num_labels)
+ return 0;
+
+ if (memcmp (nhl1->label, nhl2->label, nhl1->num_labels))
+ return 0;
+
+ return 1;
+}
+
struct nexthop *
nexthop_new (void)
{
diff --git a/lib/nexthop.h b/lib/nexthop.h
index e66e0eee20..8c9c801c91 100644
--- a/lib/nexthop.h
+++ b/lib/nexthop.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _LIB_NEXTHOP_H
@@ -117,6 +116,7 @@ void nexthop_del_labels (struct nexthop *);
extern const char *nexthop_type_to_str (enum nexthop_types_t nh_type);
extern int nexthop_same_no_recurse (struct nexthop *next1, struct nexthop *next2);
+extern int nexthop_labels_match (struct nexthop *nh1, struct nexthop *nh2);
extern const char * nexthop2str (struct nexthop *nexthop, char *str, int size);
#endif /*_LIB_NEXTHOP_H */
diff --git a/lib/ns.c b/lib/ns.c
index ae0a24668e..8c489d68fd 100644
--- a/lib/ns.c
+++ b/lib/ns.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/lib/ns.h b/lib/ns.h
index 2a7be1ef8a..98fd3fa18c 100644
--- a/lib/ns.h
+++ b/lib/ns.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_NS_H
diff --git a/lib/pid_output.c b/lib/pid_output.c
index ba1f37476e..7369e23c20 100644
--- a/lib/pid_output.c
+++ b/lib/pid_output.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/lib/plist.c b/lib/plist.c
index 3714969696..8091429e31 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -3157,6 +3156,40 @@ config_write_prefix_ipv4 (struct vty *vty)
}
static void
+plist_autocomplete_afi (afi_t afi, vector comps, struct cmd_token *token)
+{
+ struct prefix_list *plist;
+ struct prefix_master *master;
+
+ master = prefix_master_get (afi, 0);
+ if (master == NULL)
+ return;
+
+ for (plist = master->str.head; plist; plist = plist->next)
+ vector_set (comps, XSTRDUP (MTYPE_COMPLETION, plist->name));
+ for (plist = master->num.head; plist; plist = plist->next)
+ vector_set (comps, XSTRDUP (MTYPE_COMPLETION, plist->name));
+}
+
+static void
+plist_autocomplete(vector comps, struct cmd_token *token)
+{
+ plist_autocomplete_afi (AFI_IP, comps, token);
+ plist_autocomplete_afi (AFI_IP6, comps, token);
+}
+
+static const struct cmd_variable_handler plist_var_handlers[] = {
+ {
+ /* "prefix-list WORD" */
+ .varname = "prefix_list",
+ .completions = plist_autocomplete
+ }, {
+ .completions = NULL
+ }
+};
+
+
+static void
prefix_list_init_ipv4 (void)
{
install_node (&prefix_node, config_write_prefix_ipv4);
@@ -3275,6 +3308,8 @@ prefix_list_init_ipv6 (void)
void
prefix_list_init ()
{
+ cmd_variable_handler_register(plist_var_handlers);
+
prefix_list_init_ipv4 ();
prefix_list_init_ipv6 ();
}
diff --git a/lib/plist.h b/lib/plist.h
index 89d9a874f0..0f397ff01a 100644
--- a/lib/plist.h
+++ b/lib/plist.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_PLIST_H
diff --git a/lib/plist_int.h b/lib/plist_int.h
index e6e5901dbf..e711d12564 100644
--- a/lib/plist_int.h
+++ b/lib/plist_int.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_PLIST_INT_H
diff --git a/lib/pqueue.c b/lib/pqueue.c
index 0f870564da..2d9127b88e 100644
--- a/lib/pqueue.c
+++ b/lib/pqueue.c
@@ -1,22 +1,22 @@
/* Priority queue functions.
- Copyright (C) 2003 Yasuhiro Ohara
-
-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. */
+ * Copyright (C) 2003 Yasuhiro Ohara
+ *
+ * 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 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>
@@ -188,3 +188,11 @@ pqueue_remove_at (int index, struct pqueue *queue)
trickle_down (index, queue);
}
}
+
+void
+pqueue_remove (void *data, struct pqueue *queue)
+{
+ for (int i = 0; i < queue->size; i++)
+ if (queue->array[i] == data)
+ pqueue_remove_at (i, queue);
+}
diff --git a/lib/pqueue.h b/lib/pqueue.h
index 8bb6961d86..d87d91fdc5 100644
--- a/lib/pqueue.h
+++ b/lib/pqueue.h
@@ -1,22 +1,22 @@
/* Priority queue functions.
- Copyright (C) 2003 Yasuhiro Ohara
-
-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. */
+ * Copyright (C) 2003 Yasuhiro Ohara
+ *
+ * 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 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 _ZEBRA_PQUEUE_H
#define _ZEBRA_PQUEUE_H
@@ -39,6 +39,7 @@ extern void pqueue_delete (struct pqueue *queue);
extern void pqueue_enqueue (void *data, struct pqueue *queue);
extern void *pqueue_dequeue (struct pqueue *queue);
extern void pqueue_remove_at (int index, struct pqueue *queue);
+extern void pqueue_remove (void *data, struct pqueue *queue);
extern void trickle_down (int index, struct pqueue *queue);
extern void trickle_up (int index, struct pqueue *queue);
diff --git a/lib/prefix.c b/lib/prefix.c
index 0cc759bb7c..9c228cf954 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -252,12 +251,14 @@ safi2str(safi_t safi)
return "unicast";
case SAFI_MULTICAST:
return "multicast";
- case SAFI_ENCAP:
- return "encap";
case SAFI_MPLS_VPN:
return "vpn";
+ case SAFI_ENCAP:
+ return "encap";
case SAFI_EVPN:
return "evpn";
+ case SAFI_LABELED_UNICAST:
+ return "labeled-unicast";
}
return NULL;
}
diff --git a/lib/prefix.h b/lib/prefix.h
index eb3ae3dafb..09cb0cab87 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_PREFIX_H
@@ -244,6 +243,8 @@ union prefixconstptr
/* Count prefix size from mask length */
#define PSIZE(a) (((a) + 7) / (8))
+#define BSIZE(a) ((a) * (8))
+
/* Prefix's family member. */
#define PREFIX_FAMILY(p) ((p)->family)
diff --git a/lib/privs.c b/lib/privs.c
index decd4bb7db..3a66382191 100644
--- a/lib/privs.c
+++ b/lib/privs.c
@@ -16,10 +16,9 @@
* 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.
+ * 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 "log.h"
@@ -769,6 +768,7 @@ zprivs_init(struct zebra_privs_t *zprivs)
}
}
+ zprivs_state.zsuid = geteuid(); /* initial uid */
/* add groups only if we changed uid - otherwise skip */
if ((ngroups) && (zprivs_state.zsuid != zprivs_state.zuid))
{
diff --git a/lib/privs.h b/lib/privs.h
index 46d614e008..9a5eb3bd6c 100644
--- a/lib/privs.h
+++ b/lib/privs.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _ZEBRA_PRIVS_H
diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c
index a93d7b8476..7181e2d89d 100644
--- a/lib/ptm_lib.c
+++ b/lib/ptm_lib.c
@@ -13,10 +13,9 @@
* 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.
+ * 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 <stdio.h>
#include <stdlib.h>
diff --git a/lib/ptm_lib.h b/lib/ptm_lib.h
index be4170bb37..747ce349ad 100644
--- a/lib/ptm_lib.h
+++ b/lib/ptm_lib.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 __PTM_LIB_H__
#define __PTM_LIB_H__
diff --git a/lib/qobj.c b/lib/qobj.c
index 8a386d2486..fd7b4c8c5b 100644
--- a/lib/qobj.c
+++ b/lib/qobj.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/route_types.txt b/lib/route_types.txt
index 5cb06ffb7f..7625d1f690 100644
--- a/lib/route_types.txt
+++ b/lib/route_types.txt
@@ -52,6 +52,7 @@ 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"
+ZEBRA_ROUTE_EIGRP, eigrp, eigrpd, 'E', 1, 0, "EIGRP"
ZEBRA_ROUTE_NHRP, nhrp, nhrpd, 'N', 1, 1, "NHRP"
# HSLS and OLSR both are AFI independent (so: 1, 1), however
# we want to disable for them for general Quagga distribution.
@@ -86,6 +87,7 @@ ZEBRA_ROUTE_OSPF6, "Open Shortest Path First (IPv6) (OSPFv3)"
ZEBRA_ROUTE_ISIS, "Intermediate System to Intermediate System (IS-IS)"
ZEBRA_ROUTE_BGP, "Border Gateway Protocol (BGP)"
ZEBRA_ROUTE_PIM, "Protocol Independent Multicast (PIM)"
+ZEBRA_ROUTE_EIGRP, "Enhanced Interior Gateway Routing Protocol (EIGRP)"
ZEBRA_ROUTE_NHRP, "Next Hop Resolution Protocol (NHRP)"
ZEBRA_ROUTE_HSLS, "Hazy-Sighted Link State Protocol (HSLS)"
ZEBRA_ROUTE_VNC, "Virtual Network Control (VNC)"
diff --git a/lib/routemap.c b/lib/routemap.c
index cd34ffaae5..44b3c2bf9f 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -1,22 +1,22 @@
/* Route map function.
- Copyright (C) 1998, 1999 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1998, 1999 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -2001,7 +2001,7 @@ DEFUN (match_interface,
DEFUN (no_match_interface,
no_match_interface_cmd,
- "no match interface [INTERFACE]",
+ "no match interface [WORD]",
NO_STR
MATCH_STR
"Match first hop interface of route\n"
@@ -2958,6 +2958,30 @@ route_map_finish (void)
route_map_master_hash = NULL;
}
+static void rmap_autocomplete(vector comps, struct cmd_token *token)
+{
+ struct route_map *map;
+
+ for (map = route_map_master.head; map; map = map->next)
+ vector_set (comps, XSTRDUP (MTYPE_COMPLETION, map->name));
+}
+
+static const struct cmd_variable_handler rmap_var_handlers[] = {
+ {
+ /* "route-map WORD" */
+ .varname = "route_map",
+ .completions = rmap_autocomplete
+ }, {
+ .tokenname = "ROUTEMAP_NAME",
+ .completions = rmap_autocomplete
+ }, {
+ .tokenname = "RMAP_NAME",
+ .completions = rmap_autocomplete
+ }, {
+ .completions = NULL
+ }
+};
+
/* Initialization of route map vector. */
void
route_map_init (void)
@@ -2973,6 +2997,8 @@ route_map_init (void)
route_map_dep_hash[i] = hash_create(route_map_dep_hash_make_key,
route_map_dep_hash_cmp);
+ cmd_variable_handler_register(rmap_var_handlers);
+
/* Install route map top node. */
install_node (&rmap_node, route_map_config_write);
diff --git a/lib/routemap.h b/lib/routemap.h
index b378c64eae..f1937ac403 100644
--- a/lib/routemap.h
+++ b/lib/routemap.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_ROUTEMAP_H
diff --git a/lib/sha256.c b/lib/sha256.c
new file mode 100644
index 0000000000..f98a758821
--- /dev/null
+++ b/lib/sha256.c
@@ -0,0 +1,433 @@
+/*-
+ * Copyright 2005,2007,2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <zebra.h>
+#include "sha256.h"
+
+#if !HAVE_DECL_BE32DEC
+static inline uint32_t
+be32dec(const void *pp)
+{
+ const uint8_t *p = (uint8_t const *)pp;
+
+ return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
+ ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
+}
+#else
+#include <sys/endian.h>
+#endif
+
+#if !HAVE_DECL_BE32ENC
+static inline void
+be32enc(void *pp, uint32_t x)
+{
+ uint8_t * p = (uint8_t *)pp;
+
+ p[3] = x & 0xff;
+ p[2] = (x >> 8) & 0xff;
+ p[1] = (x >> 16) & 0xff;
+ p[0] = (x >> 24) & 0xff;
+}
+#else
+#include <sys/endian.h>
+#endif
+
+/*
+ * Encode a length len/4 vector of (uint32_t) into a length len vector of
+ * (unsigned char) in big-endian form. Assumes len is a multiple of 4.
+ */
+static void
+be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len / 4; i++)
+ be32enc(dst + i * 4, src[i]);
+}
+
+/*
+ * Decode a big-endian length len vector of (unsigned char) into a length
+ * len/4 vector of (uint32_t). Assumes len is a multiple of 4.
+ */
+static void
+be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len / 4; i++)
+ dst[i] = be32dec(src + i * 4);
+}
+
+/* Elementary functions used by SHA256 */
+#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
+#define Maj(x, y, z) ((x & (y | z)) | (y & z))
+#define SHR(x, n) (x >> n)
+#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
+#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
+#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
+
+/* SHA256 round function */
+#define RND(a, b, c, d, e, f, g, h, k) \
+ t0 = h + S1(e) + Ch(e, f, g) + k; \
+ t1 = S0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1;
+
+/* Adjusted round function for rotating state */
+#define RNDr(S, W, i, k) \
+ RND(S[(64 - i) % 8], S[(65 - i) % 8], \
+ S[(66 - i) % 8], S[(67 - i) % 8], \
+ S[(68 - i) % 8], S[(69 - i) % 8], \
+ S[(70 - i) % 8], S[(71 - i) % 8], \
+ W[i] + k)
+
+/*
+ * SHA256 block compression function. The 256-bit state is transformed via
+ * the 512-bit input block to produce a new state.
+ */
+static void
+SHA256_Transform(uint32_t * state, const unsigned char block[64])
+{
+ uint32_t W[64];
+ uint32_t S[8];
+ uint32_t t0, t1;
+ int i;
+
+ /* 1. Prepare message schedule W. */
+ be32dec_vect(W, block, 64);
+ for (i = 16; i < 64; i++)
+ W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
+
+ /* 2. Initialize working variables. */
+ memcpy(S, state, 32);
+
+ /* 3. Mix. */
+ RNDr(S, W, 0, 0x428a2f98);
+ RNDr(S, W, 1, 0x71374491);
+ RNDr(S, W, 2, 0xb5c0fbcf);
+ RNDr(S, W, 3, 0xe9b5dba5);
+ RNDr(S, W, 4, 0x3956c25b);
+ RNDr(S, W, 5, 0x59f111f1);
+ RNDr(S, W, 6, 0x923f82a4);
+ RNDr(S, W, 7, 0xab1c5ed5);
+ RNDr(S, W, 8, 0xd807aa98);
+ RNDr(S, W, 9, 0x12835b01);
+ RNDr(S, W, 10, 0x243185be);
+ RNDr(S, W, 11, 0x550c7dc3);
+ RNDr(S, W, 12, 0x72be5d74);
+ RNDr(S, W, 13, 0x80deb1fe);
+ RNDr(S, W, 14, 0x9bdc06a7);
+ RNDr(S, W, 15, 0xc19bf174);
+ RNDr(S, W, 16, 0xe49b69c1);
+ RNDr(S, W, 17, 0xefbe4786);
+ RNDr(S, W, 18, 0x0fc19dc6);
+ RNDr(S, W, 19, 0x240ca1cc);
+ RNDr(S, W, 20, 0x2de92c6f);
+ RNDr(S, W, 21, 0x4a7484aa);
+ RNDr(S, W, 22, 0x5cb0a9dc);
+ RNDr(S, W, 23, 0x76f988da);
+ RNDr(S, W, 24, 0x983e5152);
+ RNDr(S, W, 25, 0xa831c66d);
+ RNDr(S, W, 26, 0xb00327c8);
+ RNDr(S, W, 27, 0xbf597fc7);
+ RNDr(S, W, 28, 0xc6e00bf3);
+ RNDr(S, W, 29, 0xd5a79147);
+ RNDr(S, W, 30, 0x06ca6351);
+ RNDr(S, W, 31, 0x14292967);
+ RNDr(S, W, 32, 0x27b70a85);
+ RNDr(S, W, 33, 0x2e1b2138);
+ RNDr(S, W, 34, 0x4d2c6dfc);
+ RNDr(S, W, 35, 0x53380d13);
+ RNDr(S, W, 36, 0x650a7354);
+ RNDr(S, W, 37, 0x766a0abb);
+ RNDr(S, W, 38, 0x81c2c92e);
+ RNDr(S, W, 39, 0x92722c85);
+ RNDr(S, W, 40, 0xa2bfe8a1);
+ RNDr(S, W, 41, 0xa81a664b);
+ RNDr(S, W, 42, 0xc24b8b70);
+ RNDr(S, W, 43, 0xc76c51a3);
+ RNDr(S, W, 44, 0xd192e819);
+ RNDr(S, W, 45, 0xd6990624);
+ RNDr(S, W, 46, 0xf40e3585);
+ RNDr(S, W, 47, 0x106aa070);
+ RNDr(S, W, 48, 0x19a4c116);
+ RNDr(S, W, 49, 0x1e376c08);
+ RNDr(S, W, 50, 0x2748774c);
+ RNDr(S, W, 51, 0x34b0bcb5);
+ RNDr(S, W, 52, 0x391c0cb3);
+ RNDr(S, W, 53, 0x4ed8aa4a);
+ RNDr(S, W, 54, 0x5b9cca4f);
+ RNDr(S, W, 55, 0x682e6ff3);
+ RNDr(S, W, 56, 0x748f82ee);
+ RNDr(S, W, 57, 0x78a5636f);
+ RNDr(S, W, 58, 0x84c87814);
+ RNDr(S, W, 59, 0x8cc70208);
+ RNDr(S, W, 60, 0x90befffa);
+ RNDr(S, W, 61, 0xa4506ceb);
+ RNDr(S, W, 62, 0xbef9a3f7);
+ RNDr(S, W, 63, 0xc67178f2);
+
+ /* 4. Mix local working variables into global state */
+ for (i = 0; i < 8; i++)
+ state[i] += S[i];
+
+ /* Clean the stack. */
+ memset(W, 0, 256);
+ memset(S, 0, 32);
+ t0 = t1 = 0;
+}
+
+static unsigned char PAD[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* Add padding and terminating bit-count. */
+static void
+SHA256_Pad(SHA256_CTX * ctx)
+{
+ unsigned char len[8];
+ uint32_t r, plen;
+
+ /*
+ * Convert length to a vector of bytes -- we do this now rather
+ * than later because the length will change after we pad.
+ */
+ be32enc_vect(len, ctx->count, 8);
+
+ /* Add 1--64 bytes so that the resulting length is 56 mod 64 */
+ r = (ctx->count[1] >> 3) & 0x3f;
+ plen = (r < 56) ? (56 - r) : (120 - r);
+ SHA256_Update(ctx, PAD, (size_t)plen);
+
+ /* Add the terminating bit-count */
+ SHA256_Update(ctx, len, 8);
+}
+
+/* SHA-256 initialization. Begins a SHA-256 operation. */
+void
+SHA256_Init(SHA256_CTX * ctx)
+{
+
+ /* Zero bits processed so far */
+ ctx->count[0] = ctx->count[1] = 0;
+
+ /* Magic initialization constants */
+ ctx->state[0] = 0x6A09E667;
+ ctx->state[1] = 0xBB67AE85;
+ ctx->state[2] = 0x3C6EF372;
+ ctx->state[3] = 0xA54FF53A;
+ ctx->state[4] = 0x510E527F;
+ ctx->state[5] = 0x9B05688C;
+ ctx->state[6] = 0x1F83D9AB;
+ ctx->state[7] = 0x5BE0CD19;
+}
+
+/* Add bytes into the hash */
+void
+SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
+{
+ uint32_t bitlen[2];
+ uint32_t r;
+ const unsigned char *src = in;
+
+ /* Number of bytes left in the buffer from previous updates */
+ r = (ctx->count[1] >> 3) & 0x3f;
+
+ /* Convert the length into a number of bits */
+ bitlen[1] = ((uint32_t)len) << 3;
+ bitlen[0] = (uint32_t)(len >> 29);
+
+ /* Update number of bits */
+ if ((ctx->count[1] += bitlen[1]) < bitlen[1])
+ ctx->count[0]++;
+ ctx->count[0] += bitlen[0];
+
+ /* Handle the case where we don't need to perform any transforms */
+ if (len < 64 - r) {
+ memcpy(&ctx->buf[r], src, len);
+ return;
+ }
+
+ /* Finish the current block */
+ memcpy(&ctx->buf[r], src, 64 - r);
+ SHA256_Transform(ctx->state, ctx->buf);
+ src += 64 - r;
+ len -= 64 - r;
+
+ /* Perform complete blocks */
+ while (len >= 64) {
+ SHA256_Transform(ctx->state, src);
+ src += 64;
+ len -= 64;
+ }
+
+ /* Copy left over data into buffer */
+ memcpy(ctx->buf, src, len);
+}
+
+/*
+ * SHA-256 finalization. Pads the input data, exports the hash value,
+ * and clears the context state.
+ */
+void
+SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
+{
+
+ /* Add padding */
+ SHA256_Pad(ctx);
+
+ /* Write the hash */
+ be32enc_vect(digest, ctx->state, 32);
+
+ /* Clear the context state */
+ memset((void *)ctx, 0, sizeof(*ctx));
+}
+
+/* Initialize an HMAC-SHA256 operation with the given key. */
+void
+HMAC__SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
+{
+ unsigned char pad[64];
+ unsigned char khash[32];
+ const unsigned char * K = _K;
+ size_t i;
+
+ /* If Klen > 64, the key is really SHA256(K). */
+ if (Klen > 64) {
+ SHA256_Init(&ctx->ictx);
+ SHA256_Update(&ctx->ictx, K, Klen);
+ SHA256_Final(khash, &ctx->ictx);
+ K = khash;
+ Klen = 32;
+ }
+
+ /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
+ SHA256_Init(&ctx->ictx);
+ memset(pad, 0x36, 64);
+ for (i = 0; i < Klen; i++)
+ pad[i] ^= K[i];
+ SHA256_Update(&ctx->ictx, pad, 64);
+
+ /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
+ SHA256_Init(&ctx->octx);
+ memset(pad, 0x5c, 64);
+ for (i = 0; i < Klen; i++)
+ pad[i] ^= K[i];
+ SHA256_Update(&ctx->octx, pad, 64);
+
+ /* Clean the stack. */
+ memset(khash, 0, 32);
+}
+
+/* Add bytes to the HMAC-SHA256 operation. */
+void
+HMAC__SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
+{
+
+ /* Feed data to the inner SHA256 operation. */
+ SHA256_Update(&ctx->ictx, in, len);
+}
+
+/* Finish an HMAC-SHA256 operation. */
+void
+HMAC__SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
+{
+ unsigned char ihash[32];
+
+ /* Finish the inner SHA256 operation. */
+ SHA256_Final(ihash, &ctx->ictx);
+
+ /* Feed the inner hash to the outer SHA256 operation. */
+ SHA256_Update(&ctx->octx, ihash, 32);
+
+ /* Finish the outer SHA256 operation. */
+ SHA256_Final(digest, &ctx->octx);
+
+ /* Clean the stack. */
+ memset(ihash, 0, 32);
+}
+
+/**
+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
+ * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
+ */
+void
+PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
+ size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
+{
+ HMAC_SHA256_CTX PShctx, hctx;
+ size_t i;
+ uint8_t ivec[4];
+ uint8_t U[32];
+ uint8_t T[32];
+ uint64_t j;
+ int k;
+ size_t clen;
+
+ /* Compute HMAC state after processing P and S. */
+ HMAC__SHA256_Init(&PShctx, passwd, passwdlen);
+ HMAC__SHA256_Update(&PShctx, salt, saltlen);
+
+ /* Iterate through the blocks. */
+ for (i = 0; i * 32 < dkLen; i++) {
+ /* Generate INT(i + 1). */
+ be32enc(ivec, (uint32_t)(i + 1));
+
+ /* Compute U_1 = PRF(P, S || INT(i)). */
+ memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
+ HMAC__SHA256_Update(&hctx, ivec, 4);
+ HMAC__SHA256_Final(U, &hctx);
+
+ /* T_i = U_1 ... */
+ memcpy(T, U, 32);
+
+ for (j = 2; j <= c; j++) {
+ /* Compute U_j. */
+ HMAC__SHA256_Init(&hctx, passwd, passwdlen);
+ HMAC__SHA256_Update(&hctx, U, 32);
+ HMAC__SHA256_Final(U, &hctx);
+
+ /* ... xor U_j ... */
+ for (k = 0; k < 32; k++)
+ T[k] ^= U[k];
+ }
+
+ /* Copy as many bytes as necessary into buf. */
+ clen = dkLen - i * 32;
+ if (clen > 32)
+ clen = 32;
+ memcpy(&buf[i * 32], T, clen);
+ }
+
+ /* Clean PShctx, since we never called _Final on it. */
+ memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
+}
diff --git a/lib/sha256.h b/lib/sha256.h
new file mode 100644
index 0000000000..502f3fc224
--- /dev/null
+++ b/lib/sha256.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright 2005,2007,2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $
+ */
+
+#ifndef _SHA256_H_
+#define _SHA256_H_
+
+typedef struct SHA256Context {
+ uint32_t state[8];
+ uint32_t count[2];
+ unsigned char buf[64];
+} SHA256_CTX;
+
+typedef struct HMAC_SHA256Context {
+ SHA256_CTX ictx;
+ SHA256_CTX octx;
+} HMAC_SHA256_CTX;
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX *, const void *, size_t);
+void SHA256_Final(unsigned char [32], SHA256_CTX *);
+void HMAC__SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
+void HMAC__SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
+void HMAC__SHA256_Final(unsigned char [32], HMAC_SHA256_CTX *);
+
+/**
+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
+ * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
+ */
+void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
+ uint64_t, uint8_t *, size_t);
+
+#endif /* !_SHA256_H_ */
diff --git a/lib/sigevent.c b/lib/sigevent.c
index 09f07180ce..e8c722b987 100644
--- a/lib/sigevent.c
+++ b/lib/sigevent.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -132,8 +131,9 @@ quagga_signal_timer (struct thread *t)
int i;
sigm = THREAD_ARG (t);
- sigm->t = thread_add_timer (sigm->t->master, quagga_signal_timer, &sigmaster,
- QUAGGA_SIGNAL_TIMER_INTERVAL);
+ sigm->t = NULL;
+ thread_add_timer(sigm->t->master, quagga_signal_timer, &sigmaster, QUAGGA_SIGNAL_TIMER_INTERVAL,
+ &sigm->t);
return quagga_sigevent_process ();
}
#endif /* SIGEVENT_SCHEDULE_THREAD */
@@ -233,6 +233,18 @@ core_handler(int signo
#endif
)
{
+ /* make sure we don't hang in here. default for SIGALRM is terminate.
+ * - if we're in backtrace for more than a second, abort. */
+ struct sigaction sa_default = { .sa_handler = SIG_DFL };
+ sigaction (SIGALRM, &sa_default, NULL);
+
+ sigset_t sigset;
+ sigemptyset (&sigset);
+ sigaddset (&sigset, SIGALRM);
+ sigprocmask (SIG_UNBLOCK, &sigset, NULL);
+
+ alarm (1);
+
zlog_signal(signo, "aborting..."
#ifdef SA_SIGINFO
, siginfo, program_counter(context)
@@ -327,6 +339,11 @@ trap_default_signals(void)
act.sa_handler = sigmap[i].handler;
act.sa_flags = 0;
#endif
+#ifdef SA_RESETHAND
+ /* don't try to print backtraces recursively */
+ if (sigmap[i].handler == core_handler)
+ act.sa_flags |= SA_RESETHAND;
+#endif
}
if (sigaction(sigmap[i].sigs[j],&act,NULL) < 0)
zlog_warn("Unable to set signal handler for signal %d: %s",
@@ -361,8 +378,8 @@ signal_init (struct thread_master *m, int sigc,
sigmaster.signals = signals;
#ifdef SIGEVENT_SCHEDULE_THREAD
- sigmaster.t =
- thread_add_timer (m, quagga_signal_timer, &sigmaster,
- QUAGGA_SIGNAL_TIMER_INTERVAL);
+ sigmaster.t = NULL;
+ thread_add_timer(m, quagga_signal_timer, &sigmaster, QUAGGA_SIGNAL_TIMER_INTERVAL,
+ &sigmaster.t);
#endif /* SIGEVENT_SCHEDULE_THREAD */
}
diff --git a/lib/sigevent.h b/lib/sigevent.h
index 248fa2c058..08eb1ca412 100644
--- a/lib/sigevent.h
+++ b/lib/sigevent.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _QUAGGA_SIGNAL_H
diff --git a/lib/smux.c b/lib/smux.c
index 370b8f138e..032801f6df 100644
--- a/lib/smux.c
+++ b/lib/smux.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -1197,13 +1196,18 @@ smux_event (enum smux_event event, int sock)
switch (event)
{
case SMUX_SCHEDULE:
- smux_connect_thread = thread_add_event (smux_master, smux_connect, NULL, 0);
+ smux_connect_thread = NULL;
+ thread_add_event(smux_master, smux_connect, NULL, 0,
+ &smux_connect_thread);
break;
case SMUX_CONNECT:
- smux_connect_thread = thread_add_timer (smux_master, smux_connect, NULL, 10);
+ smux_connect_thread = NULL;
+ thread_add_timer(smux_master, smux_connect, NULL, 10,
+ &smux_connect_thread);
break;
case SMUX_READ:
- smux_read_thread = thread_add_read (smux_master, smux_read, NULL, sock);
+ smux_read_thread = NULL;
+ thread_add_read(smux_master, smux_read, NULL, sock, &smux_read_thread);
break;
default:
break;
diff --git a/lib/smux.h b/lib/smux.h
index dc91cac71a..e94a7a9cc9 100644
--- a/lib/smux.h
+++ b/lib/smux.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_SNMP_H
diff --git a/lib/snmp.c b/lib/snmp.c
index 1cbd41c720..7eb86e9412 100644
--- a/lib/snmp.c
+++ b/lib/snmp.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/sockopt.c b/lib/sockopt.c
index 2a9f907cb3..83ea574833 100644
--- a/lib/sockopt.c
+++ b/lib/sockopt.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/sockopt.h b/lib/sockopt.h
index 1b7be1e49f..d31fcaa411 100644
--- a/lib/sockopt.h
+++ b/lib/sockopt.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_SOCKOPT_H
diff --git a/lib/sockunion.c b/lib/sockunion.c
index 9ba2ce82f6..423ad20441 100644
--- a/lib/sockunion.c
+++ b/lib/sockunion.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/sockunion.h b/lib/sockunion.h
index bed68e1ee1..98c3e0adef 100644
--- a/lib/sockunion.h
+++ b/lib/sockunion.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_SOCKUNION_H
diff --git a/lib/spf_backoff.c b/lib/spf_backoff.c
index e923f232b8..7e34947344 100644
--- a/lib/spf_backoff.c
+++ b/lib/spf_backoff.c
@@ -19,10 +19,9 @@
* 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.
+ * 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>
@@ -169,21 +168,19 @@ long spf_backoff_schedule(struct spf_backoff *backoff)
{
case SPF_BACKOFF_QUIET:
backoff->state = SPF_BACKOFF_SHORT_WAIT;
- THREAD_TIMER_MSEC_ON(backoff->m, backoff->t_timetolearn,
- spf_backoff_timetolearn_elapsed, backoff,
- backoff->timetolearn);
- THREAD_TIMER_MSEC_ON(backoff->m, backoff->t_holddown,
- spf_backoff_holddown_elapsed, backoff,
- backoff->holddown);
+ thread_add_timer_msec(backoff->m, spf_backoff_timetolearn_elapsed,
+ backoff, backoff->timetolearn,
+ &backoff->t_timetolearn);
+ thread_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed, backoff,
+ backoff->holddown, &backoff->t_holddown);
backoff->first_event_time = now;
rv = backoff->init_delay;
break;
case SPF_BACKOFF_SHORT_WAIT:
case SPF_BACKOFF_LONG_WAIT:
THREAD_TIMER_OFF(backoff->t_holddown);
- THREAD_TIMER_MSEC_ON(backoff->m, backoff->t_holddown,
- spf_backoff_holddown_elapsed, backoff,
- backoff->holddown);
+ thread_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed, backoff,
+ backoff->holddown, &backoff->t_holddown);
if (backoff->state == SPF_BACKOFF_SHORT_WAIT)
rv = backoff->short_delay;
else
diff --git a/lib/spf_backoff.h b/lib/spf_backoff.h
index 552ca4ae41..92bd46506a 100644
--- a/lib/spf_backoff.h
+++ b/lib/spf_backoff.h
@@ -19,10 +19,9 @@
* 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.
+ * 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 _ZEBRA_SPF_BACKOFF_H
#define _ZEBRA_SPF_BACKOFF_H
diff --git a/lib/srcdest_table.c b/lib/srcdest_table.c
index 04c9eff79a..383cf00d4f 100644
--- a/lib/srcdest_table.c
+++ b/lib/srcdest_table.c
@@ -16,10 +16,9 @@
* 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.
+ * 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>
diff --git a/lib/srcdest_table.h b/lib/srcdest_table.h
index 207f5d121d..0d858d11ab 100644
--- a/lib/srcdest_table.h
+++ b/lib/srcdest_table.h
@@ -16,10 +16,9 @@
* 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.
+ * 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 _ZEBRA_SRC_DEST_TABLE_H
diff --git a/lib/stream.c b/lib/stream.c
index 301ebc6275..e8320a8fa1 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -1,4 +1,4 @@
- /*
+/*
* Packet interface
* Copyright (C) 1999 Kunihiro Ishiguro
*
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -919,6 +918,31 @@ stream_put_prefix (struct stream *s, struct prefix *p)
return stream_put_prefix_addpath (s, p, 0, 0);
}
+/* Put NLRI with label */
+int
+stream_put_labeled_prefix (struct stream *s, struct prefix *p, u_char *label)
+{
+ size_t psize;
+
+ STREAM_VERIFY_SANE(s);
+
+ psize = PSIZE (p->prefixlen);
+
+ if (STREAM_WRITEABLE (s) < (psize + 3))
+ {
+ STREAM_BOUND_WARN (s, "put");
+ return 0;
+ }
+
+ stream_putc (s, (p->prefixlen + 24));
+ stream_putc(s, label[0]);
+ stream_putc(s, label[1]);
+ stream_putc(s, label[2]);
+ memcpy (s->data + s->endp, &p->u.prefix, psize);
+ s->endp += psize;
+
+ return (psize + 3);
+}
/* Read size from fd. */
int
diff --git a/lib/stream.h b/lib/stream.h
index 1e2bc89b32..dd6aae677d 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_STREAM_H
@@ -181,7 +180,8 @@ extern int stream_put_prefix_addpath (struct stream *, struct prefix *,
int addpath_encode,
u_int32_t addpath_tx_id);
extern int stream_put_prefix (struct stream *, struct prefix *);
-
+extern int stream_put_labeled_prefix (struct stream *, struct prefix *,
+ u_char *);
extern void stream_get (void *, struct stream *, size_t);
extern void stream_get_from (void *, struct stream *, size_t, size_t);
extern u_char stream_getc (struct stream *);
diff --git a/lib/strlcat.c b/lib/strlcat.c
index 1d04b43d95..6fdb2a4a37 100644
--- a/lib/strlcat.c
+++ b/lib/strlcat.c
@@ -1,20 +1,21 @@
/* Append a null-terminated string to another string, with length checking.
- Copyright (C) 2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
+ * Copyright (C) 2016 Free Software Foundation, Inc.
+ * This file is part of the GNU C Library.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * The GNU C Library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the GNU C Library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
/* adapted for Quagga from glibc patch submission originally from
* Florian Weimer <fweimer@redhat.com>, 2016-05-18 */
diff --git a/lib/strlcpy.c b/lib/strlcpy.c
index 41bab97ea7..112c8180b9 100644
--- a/lib/strlcpy.c
+++ b/lib/strlcpy.c
@@ -1,20 +1,21 @@
/* Copy a null-terminated string to a fixed-size buffer, with length checking.
- Copyright (C) 2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
+ * Copyright (C) 2016 Free Software Foundation, Inc.
+ * This file is part of the GNU C Library.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * The GNU C Library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the GNU C Library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
/* adapted for Quagga from glibc patch submission originally from
* Florian Weimer <fweimer@redhat.com>, 2016-05-18 */
diff --git a/lib/systemd.c b/lib/systemd.c
index 4c78cf328c..341de9eabe 100644
--- a/lib/systemd.c
+++ b/lib/systemd.c
@@ -1,23 +1,23 @@
/* lib/systemd 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 Quagga; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * 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 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>
@@ -104,7 +104,7 @@ systemd_send_watchdog (struct thread *t)
{
systemd_send_information ("WATCHDOG=1");
- thread_add_timer (systemd_master, systemd_send_watchdog, NULL, wsecs);
+ thread_add_timer(systemd_master, systemd_send_watchdog, NULL, wsecs, NULL);
return 1;
}
@@ -119,5 +119,5 @@ systemd_send_started (struct thread_master *m, int the_process)
systemd_send_information ("READY=1");
if (wsecs != 0)
- thread_add_timer (m, systemd_send_watchdog, m, wsecs);
+ thread_add_timer(m, systemd_send_watchdog, m, wsecs, NULL);
}
diff --git a/lib/systemd.h b/lib/systemd.h
index 685f3d9a77..c048797cf2 100644
--- a/lib/systemd.h
+++ b/lib/systemd.h
@@ -1,23 +1,23 @@
/* lib/systemd 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 Quagga; see the file COPYING. If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ * 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 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
+ */
/*
* Wrapper functions to systemd calls.
diff --git a/lib/table.c b/lib/table.c
index 7f789dd3cd..1461bb81a4 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/lib/table.h b/lib/table.h
index 1691a8e20a..00131b29c6 100644
--- a/lib/table.h
+++ b/lib/table.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_TABLE_H
diff --git a/lib/thread.c b/lib/thread.c
index dbdd91dd24..2843a9211e 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/* #define DEBUG */
@@ -41,7 +40,7 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats")
#include <mach/mach_time.h>
#endif
-/* Relative time, since startup */
+static pthread_mutex_t cpu_record_mtx = PTHREAD_MUTEX_INITIALIZER;
static struct hash *cpu_record = NULL;
static unsigned long
@@ -137,9 +136,14 @@ cpu_record_print(struct vty *vty, thread_type filter)
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,
- (void(*)(struct hash_backet*,void*))cpu_record_hash_print,
- args);
+
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ hash_iterate(cpu_record,
+ (void(*)(struct hash_backet*,void*))cpu_record_hash_print,
+ args);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
if (tmp.total_calls > 0)
vty_out_cpu_thread_history(vty, &tmp);
@@ -216,16 +220,25 @@ cpu_record_hash_clear (struct hash_backet *bucket,
if ( !(a->types & *filter) )
return;
- hash_release (cpu_record, bucket->data);
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ hash_release (cpu_record, bucket->data);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
}
static void
cpu_record_clear (thread_type filter)
{
thread_type *tmp = &filter;
- hash_iterate (cpu_record,
- (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
- tmp);
+
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ hash_iterate (cpu_record,
+ (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
+ tmp);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
}
DEFUN (clear_thread_cpu,
@@ -326,16 +339,20 @@ thread_master_create (void)
getrlimit(RLIMIT_NOFILE, &limit);
- if (cpu_record == NULL)
- cpu_record
- = hash_create ((unsigned int (*) (void *))cpu_record_hash_key,
- (int (*) (const void *, const void *))cpu_record_hash_cmp);
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ if (cpu_record == NULL)
+ cpu_record = hash_create ((unsigned int (*) (void *))cpu_record_hash_key,
+ (int (*) (const void *, const void *))
+ cpu_record_hash_cmp);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
rv = XCALLOC (MTYPE_THREAD_MASTER, sizeof (struct thread_master));
if (rv == NULL)
- {
- return NULL;
- }
+ return NULL;
+
+ pthread_mutex_init (&rv->mtx, NULL);
rv->fd_limit = (int)limit.rlim_cur;
rv->read = XCALLOC (MTYPE_THREAD, sizeof (struct thread *) * rv->fd_limit);
@@ -358,6 +375,8 @@ thread_master_create (void)
rv->background = pqueue_create();
rv->timer->cmp = rv->background->cmp = thread_timer_cmp;
rv->timer->update = rv->background->update = thread_timer_update;
+ rv->spin = true;
+ rv->handle_signals = true;
#if defined(HAVE_POLL_CALL)
rv->handler.pfdsize = rv->fd_limit;
@@ -434,6 +453,7 @@ thread_add_unuse (struct thread_master *m, struct thread *thread)
assert (m != NULL && thread != NULL);
assert (thread->next == NULL);
assert (thread->prev == NULL);
+ thread->ref = NULL;
thread->type = THREAD_UNUSED;
thread->hist->total_active--;
@@ -498,11 +518,16 @@ thread_queue_free (struct thread_master *m, struct pqueue *queue)
void
thread_master_free_unused (struct thread_master *m)
{
- struct thread *t;
- while ((t = thread_trim_head(&m->unuse)) != NULL)
- {
- XFREE(MTYPE_THREAD, t);
- }
+ pthread_mutex_lock (&m->mtx);
+ {
+ struct thread *t;
+ while ((t = thread_trim_head(&m->unuse)) != NULL)
+ {
+ pthread_mutex_destroy (&t->mtx);
+ XFREE(MTYPE_THREAD, t);
+ }
+ }
+ pthread_mutex_unlock (&m->mtx);
}
/* Stop thread scheduler. */
@@ -516,25 +541,37 @@ thread_master_free (struct thread_master *m)
thread_list_free (m, &m->ready);
thread_list_free (m, &m->unuse);
thread_queue_free (m, m->background);
+ pthread_mutex_destroy (&m->mtx);
#if defined(HAVE_POLL_CALL)
XFREE (MTYPE_THREAD_MASTER, m->handler.pfds);
#endif
XFREE (MTYPE_THREAD_MASTER, m);
- if (cpu_record)
- {
- hash_clean (cpu_record, cpu_record_hash_free);
- hash_free (cpu_record);
- cpu_record = NULL;
- }
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ if (cpu_record)
+ {
+ hash_clean (cpu_record, cpu_record_hash_free);
+ hash_free (cpu_record);
+ cpu_record = NULL;
+ }
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
}
/* Return remain time in second. */
unsigned long
thread_timer_remain_second (struct thread *thread)
{
- int64_t remain = monotime_until(&thread->u.sands, NULL) / 1000000LL;
+ int64_t remain;
+
+ pthread_mutex_lock (&thread->mtx);
+ {
+ remain = monotime_until(&thread->u.sands, NULL) / 1000000LL;
+ }
+ pthread_mutex_unlock (&thread->mtx);
+
return remain < 0 ? 0 : remain;
}
@@ -545,7 +582,11 @@ struct timeval
thread_timer_remain(struct thread *thread)
{
struct timeval remain;
- monotime_until(&thread->u.sands, &remain);
+ pthread_mutex_lock (&thread->mtx);
+ {
+ monotime_until(&thread->u.sands, &remain);
+ }
+ pthread_mutex_unlock (&thread->mtx);
return remain;
}
@@ -560,14 +601,18 @@ thread_get (struct thread_master *m, u_char type,
if (! thread)
{
thread = XCALLOC (MTYPE_THREAD, sizeof (struct thread));
+ /* mutex only needs to be initialized at struct creation. */
+ pthread_mutex_init (&thread->mtx, NULL);
m->alloc++;
}
+
thread->type = type;
thread->add_type = type;
thread->master = m;
thread->arg = arg;
thread->index = -1;
thread->yield = THREAD_YIELD_TIME_SLOT; /* default */
+ thread->ref = NULL;
/*
* So if the passed in funcname is not what we have
@@ -584,8 +629,12 @@ thread_get (struct thread_master *m, u_char type,
{
tmp.func = func;
tmp.funcname = funcname;
- thread->hist = hash_get (cpu_record, &tmp,
- (void * (*) (void *))cpu_record_hash_alloc);
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ thread->hist = hash_get (cpu_record, &tmp,
+ (void * (*) (void *))cpu_record_hash_alloc);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
}
thread->hist->total_active++;
thread->func = func;
@@ -650,15 +699,46 @@ static int
fd_select (struct thread_master *m, int size, thread_fd_set *read, thread_fd_set *write, thread_fd_set *except, struct timeval *timer_wait)
{
int num;
+
+ /* If timer_wait is null here, that means either select() or poll() should
+ * block indefinitely, unless the thread_master has overriden it. select()
+ * and poll() differ in the timeout values they interpret as an indefinite
+ * block; select() requires a null pointer, while poll takes a millisecond
+ * value of -1.
+ *
+ * The thread_master owner has the option of overriding the default behavior
+ * by setting ->selectpoll_timeout. If the value is positive, it specifies
+ * the maximum number of milliseconds to wait. If the timeout is -1, it
+ * specifies that we should never wait and always return immediately even if
+ * no event is detected. If the value is zero, the behavior is default.
+ */
+
#if defined(HAVE_POLL_CALL)
- /* recalc timeout for poll. Attention NULL pointer is no timeout with
- select, where with poll no timeount is -1 */
int timeout = -1;
- if (timer_wait != NULL)
+
+ if (timer_wait != NULL && m->selectpoll_timeout == 0) // use the default value
timeout = (timer_wait->tv_sec*1000) + (timer_wait->tv_usec/1000);
+ else if (m->selectpoll_timeout > 0) // use the user's timeout
+ timeout = m->selectpoll_timeout;
+ else if (m->selectpoll_timeout < 0) // effect a poll (return immediately)
+ timeout = 0;
num = poll (m->handler.pfds, m->handler.pfdcount + m->handler.pfdcountsnmp, timeout);
#else
+ struct timeval timeout;
+
+ if (m->selectpoll_timeout > 0) // use the user's timeout
+ {
+ timeout.tv_sec = m->selectpoll_timeout / 1000;
+ timeout.tv_usec = (m->selectpoll_timeout % 1000) * 1000;
+ timer_wait = &timeout;
+ }
+ else if (m->selectpoll_timeout < 0) // effect a poll (return immediately)
+ {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ timer_wait = &timeout;
+ }
num = select (size, read, write, except, timer_wait);
#endif
@@ -698,52 +778,74 @@ fd_clear_read_write (struct thread *thread)
/* Add new read thread. */
struct thread *
funcname_thread_add_read_write (int dir, struct thread_master *m,
- int (*func) (struct thread *), void *arg, int fd,
- debugargdef)
+ int (*func) (struct thread *), void *arg, int fd, struct thread **t_ptr,
+ debugargdef)
{
struct thread *thread = NULL;
-#if !defined(HAVE_POLL_CALL)
- thread_fd_set *fdset = NULL;
- if (dir == THREAD_READ)
- fdset = &m->handler.readfd;
- else
- fdset = &m->handler.writefd;
-#endif
+ pthread_mutex_lock (&m->mtx);
+ {
+ if (t_ptr && *t_ptr) // thread is already scheduled; don't reschedule
+ {
+ pthread_mutex_unlock (&m->mtx);
+ return NULL;
+ }
#if defined (HAVE_POLL_CALL)
- thread = generic_thread_add(m, func, arg, fd, dir, debugargpass);
-
- if (thread == NULL)
- return NULL;
+ thread = generic_thread_add(m, func, arg, fd, dir, debugargpass);
#else
- if (FD_ISSET (fd, fdset))
- {
- zlog_warn ("There is already %s fd [%d]",
- (dir == THREAD_READ) ? "read" : "write", fd);
- return NULL;
- }
+ if (fd >= FD_SETSIZE)
+ {
+ zlog_err ("File descriptor %d is >= FD_SETSIZE (%d). Please recompile"
+ "with --enable-poll=yes", fd, FD_SETSIZE);
+ assert (fd < FD_SETSIZE && !"fd >= FD_SETSIZE");
+ }
+ thread_fd_set *fdset = NULL;
+ if (dir == THREAD_READ)
+ fdset = &m->handler.readfd;
+ else
+ fdset = &m->handler.writefd;
- FD_SET (fd, fdset);
- thread = thread_get (m, dir, func, arg, debugargpass);
+ if (FD_ISSET (fd, fdset))
+ {
+ zlog_warn ("There is already %s fd [%d]",
+ (dir == THREAD_READ) ? "read" : "write", fd);
+ }
+ else
+ {
+ FD_SET (fd, fdset);
+ thread = thread_get (m, dir, func, arg, debugargpass);
+ }
#endif
- thread->u.fd = fd;
- if (dir == THREAD_READ)
- thread_add_fd (m->read, thread);
- else
- thread_add_fd (m->write, thread);
+ if (thread)
+ {
+ pthread_mutex_lock (&thread->mtx);
+ {
+ thread->u.fd = fd;
+ if (dir == THREAD_READ)
+ thread_add_fd (m->read, thread);
+ else
+ thread_add_fd (m->write, thread);
+ }
+ pthread_mutex_unlock (&thread->mtx);
+
+ if (t_ptr)
+ {
+ *t_ptr = thread;
+ thread->ref = t_ptr;
+ }
+ }
+ }
+ pthread_mutex_unlock (&m->mtx);
return thread;
}
static struct thread *
funcname_thread_add_timer_timeval (struct thread_master *m,
- int (*func) (struct thread *),
- int type,
- void *arg,
- struct timeval *time_relative,
- debugargdef)
+ int (*func) (struct thread *), int type, void *arg,
+ struct timeval *time_relative, struct thread **t_ptr, debugargdef)
{
struct thread *thread;
struct pqueue *queue;
@@ -753,13 +855,32 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
assert (type == THREAD_TIMER || type == THREAD_BACKGROUND);
assert (time_relative);
- queue = ((type == THREAD_TIMER) ? m->timer : m->background);
- thread = thread_get (m, type, func, arg, debugargpass);
+ pthread_mutex_lock (&m->mtx);
+ {
+ if (t_ptr && *t_ptr) // thread is already scheduled; don't reschedule
+ {
+ pthread_mutex_unlock (&m->mtx);
+ return NULL;
+ }
- monotime(&thread->u.sands);
- timeradd(&thread->u.sands, time_relative, &thread->u.sands);
+ queue = ((type == THREAD_TIMER) ? m->timer : m->background);
+ thread = thread_get (m, type, func, arg, debugargpass);
+
+ pthread_mutex_lock (&thread->mtx);
+ {
+ monotime(&thread->u.sands);
+ timeradd(&thread->u.sands, time_relative, &thread->u.sands);
+ pqueue_enqueue(thread, queue);
+ if (t_ptr)
+ {
+ *t_ptr = thread;
+ thread->ref = t_ptr;
+ }
+ }
+ pthread_mutex_unlock (&thread->mtx);
+ }
+ pthread_mutex_unlock (&m->mtx);
- pqueue_enqueue(thread, queue);
return thread;
}
@@ -767,9 +888,8 @@ funcname_thread_add_timer_timeval (struct thread_master *m,
/* Add timer event thread. */
struct thread *
funcname_thread_add_timer (struct thread_master *m,
- int (*func) (struct thread *),
- void *arg, long timer,
- debugargdef)
+ int (*func) (struct thread *), void *arg, long timer,
+ struct thread **t_ptr, debugargdef)
{
struct timeval trel;
@@ -778,16 +898,15 @@ funcname_thread_add_timer (struct thread_master *m,
trel.tv_sec = timer;
trel.tv_usec = 0;
- return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg,
- &trel, debugargpass);
+ return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, &trel,
+ t_ptr, debugargpass);
}
/* Add timer event thread with "millisecond" resolution */
struct thread *
funcname_thread_add_timer_msec (struct thread_master *m,
- int (*func) (struct thread *),
- void *arg, long timer,
- debugargdef)
+ int (*func) (struct thread *), void *arg, long timer,
+ struct thread **t_ptr, debugargdef)
{
struct timeval trel;
@@ -796,27 +915,25 @@ funcname_thread_add_timer_msec (struct thread_master *m,
trel.tv_sec = timer / 1000;
trel.tv_usec = 1000*(timer % 1000);
- return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER,
- arg, &trel, debugargpass);
+ return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, &trel,
+ t_ptr, debugargpass);
}
/* Add timer event thread with "millisecond" resolution */
struct thread *
funcname_thread_add_timer_tv (struct thread_master *m,
- int (*func) (struct thread *),
- void *arg, struct timeval *tv,
- debugargdef)
+ int (*func) (struct thread *), void *arg, struct timeval *tv,
+ struct thread **t_ptr, debugargdef)
{
- return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER,
- arg, tv, debugargpass);
+ return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, tv,
+ t_ptr, debugargpass);
}
/* Add a background thread, with an optional millisec delay */
struct thread *
funcname_thread_add_background (struct thread_master *m,
- int (*func) (struct thread *),
- void *arg, long delay,
- debugargdef)
+ int (*func) (struct thread *), void *arg, long delay,
+ struct thread **t_ptr, debugargdef)
{
struct timeval trel;
@@ -833,23 +950,43 @@ funcname_thread_add_background (struct thread_master *m,
trel.tv_usec = 0;
}
- return funcname_thread_add_timer_timeval (m, func, THREAD_BACKGROUND,
- arg, &trel, debugargpass);
+ return funcname_thread_add_timer_timeval (m, func, THREAD_BACKGROUND, arg, &trel,
+ t_ptr, debugargpass);
}
/* Add simple event thread. */
struct thread *
funcname_thread_add_event (struct thread_master *m,
- int (*func) (struct thread *), void *arg, int val,
- debugargdef)
+ int (*func) (struct thread *), void *arg, int val,
+ struct thread **t_ptr, debugargdef)
{
struct thread *thread;
assert (m != NULL);
- thread = thread_get (m, THREAD_EVENT, func, arg, debugargpass);
- thread->u.val = val;
- thread_list_add (&m->event, thread);
+ pthread_mutex_lock (&m->mtx);
+ {
+ if (t_ptr && *t_ptr) // thread is already scheduled; don't reschedule
+ {
+ pthread_mutex_unlock (&m->mtx);
+ return NULL;
+ }
+
+ thread = thread_get (m, THREAD_EVENT, func, arg, debugargpass);
+ pthread_mutex_lock (&thread->mtx);
+ {
+ thread->u.val = val;
+ thread_list_add (&m->event, thread);
+ }
+ pthread_mutex_unlock (&thread->mtx);
+
+ if (t_ptr)
+ {
+ *t_ptr = thread;
+ thread->ref = t_ptr;
+ }
+ }
+ pthread_mutex_unlock (&m->mtx);
return thread;
}
@@ -880,14 +1017,22 @@ thread_cancel_read_or_write (struct thread *thread, short int state)
fd_clear_read_write (thread);
}
-/* Cancel thread from scheduler. */
+/**
+ * Cancel thread from scheduler.
+ *
+ * This function is *NOT* MT-safe. DO NOT call it from any other pthread except
+ * the one which owns thread->master.
+ */
void
thread_cancel (struct thread *thread)
{
struct thread_list *list = NULL;
struct pqueue *queue = NULL;
struct thread **thread_array = NULL;
-
+
+ pthread_mutex_lock (&thread->master->mtx);
+ pthread_mutex_lock (&thread->mtx);
+
switch (thread->type)
{
case THREAD_READ:
@@ -919,15 +1064,14 @@ thread_cancel (struct thread *thread)
queue = thread->master->background;
break;
default:
- return;
+ goto done;
break;
}
if (queue)
{
assert(thread->index >= 0);
- assert(thread == queue->array[thread->index]);
- pqueue_remove_at(thread->index, queue);
+ pqueue_remove (thread, queue);
}
else if (list)
{
@@ -942,7 +1086,14 @@ thread_cancel (struct thread *thread)
assert(!"Thread should be either in queue or list or array!");
}
+ if (thread->ref)
+ *thread->ref = NULL;
+
thread_add_unuse (thread->master, thread);
+
+done:
+ pthread_mutex_unlock (&thread->mtx);
+ pthread_mutex_unlock (&thread->master->mtx);
}
/* Delete all events which has argument value arg. */
@@ -951,39 +1102,52 @@ thread_cancel_event (struct thread_master *m, void *arg)
{
unsigned int ret = 0;
struct thread *thread;
+ struct thread *t;
- thread = m->event.head;
- while (thread)
- {
- struct thread *t;
-
- t = thread;
- thread = t->next;
-
- if (t->arg == arg)
+ pthread_mutex_lock (&m->mtx);
+ {
+ thread = m->event.head;
+ while (thread)
+ {
+ t = thread;
+ pthread_mutex_lock (&t->mtx);
{
- ret++;
- thread_list_delete (&m->event, t);
- thread_add_unuse (m, t);
+ thread = t->next;
+
+ if (t->arg == arg)
+ {
+ ret++;
+ thread_list_delete (&m->event, t);
+ if (t->ref)
+ *t->ref = NULL;
+ thread_add_unuse (m, t);
+ }
}
- }
-
- /* thread can be on the ready list too */
- thread = m->ready.head;
- while (thread)
- {
- struct thread *t;
-
- t = thread;
- thread = t->next;
+ pthread_mutex_unlock (&t->mtx);
+ }
- if (t->arg == arg)
+ /* thread can be on the ready list too */
+ thread = m->ready.head;
+ while (thread)
+ {
+ t = thread;
+ pthread_mutex_lock (&t->mtx);
{
- ret++;
- thread_list_delete (&m->ready, t);
- thread_add_unuse (m, t);
+ thread = t->next;
+
+ if (t->arg == arg)
+ {
+ ret++;
+ thread_list_delete (&m->ready, t);
+ if (t->ref)
+ *t->ref = NULL;
+ thread_add_unuse (m, t);
+ }
}
- }
+ pthread_mutex_unlock (&t->mtx);
+ }
+ }
+ pthread_mutex_unlock (&m->mtx);
return ret;
}
@@ -1142,18 +1306,26 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
struct timeval *timer_wait = &timer_val;
struct timeval *timer_wait_bg;
- while (1)
+ do
{
int num = 0;
/* Signals pre-empt everything */
- quagga_sigevent_process ();
+ if (m->handle_signals)
+ quagga_sigevent_process ();
+ pthread_mutex_lock (&m->mtx);
/* Drain the ready queue of already scheduled jobs, before scheduling
* more.
*/
if ((thread = thread_trim_head (&m->ready)) != NULL)
- return thread_run (m, thread, fetch);
+ {
+ fetch = thread_run (m, thread, fetch);
+ if (fetch->ref)
+ *fetch->ref = NULL;
+ pthread_mutex_unlock (&m->mtx);
+ return fetch;
+ }
/* To be fair to all kinds of threads, and avoid starvation, we
* need to be careful to consider all thread types for scheduling
@@ -1193,8 +1365,12 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
if (num < 0)
{
if (errno == EINTR)
- continue; /* signal received - process it */
+ {
+ pthread_mutex_unlock (&m->mtx);
+ continue; /* signal received - process it */
+ }
zlog_warn ("select() error: %s", safe_strerror (errno));
+ pthread_mutex_unlock (&m->mtx);
return NULL;
}
@@ -1214,15 +1390,32 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
list at this time. If this is code is uncommented, then background
timer threads will not run unless there is nothing else to do. */
if ((thread = thread_trim_head (&m->ready)) != NULL)
- return thread_run (m, thread, fetch);
+ {
+ fetch = thread_run (m, thread, fetch);
+ if (fetch->ref)
+ *fetch->ref = NULL;
+ pthread_mutex_unlock (&m->mtx);
+ return fetch;
+ }
#endif
/* Background timer/events, lowest priority */
thread_timer_process (m->background, &now);
if ((thread = thread_trim_head (&m->ready)) != NULL)
- return thread_run (m, thread, fetch);
- }
+ {
+ fetch = thread_run (m, thread, fetch);
+ if (fetch->ref)
+ *fetch->ref = NULL;
+ pthread_mutex_unlock (&m->mtx);
+ return fetch;
+ }
+
+ pthread_mutex_unlock (&m->mtx);
+
+ } while (m->spin);
+
+ return NULL;
}
unsigned long
@@ -1247,13 +1440,23 @@ thread_consumed_time (RUSAGE_T *now, RUSAGE_T *start, unsigned long *cputime)
int
thread_should_yield (struct thread *thread)
{
- return monotime_since(&thread->real, NULL) > (int64_t)thread->yield;
+ int result;
+ pthread_mutex_lock (&thread->mtx);
+ {
+ result = monotime_since(&thread->real, NULL) > (int64_t)thread->yield;
+ }
+ pthread_mutex_unlock (&thread->mtx);
+ return result;
}
void
thread_set_yield_time (struct thread *thread, unsigned long yield_time)
{
- thread->yield = yield_time;
+ pthread_mutex_lock (&thread->mtx);
+ {
+ thread->yield = yield_time;
+ }
+ pthread_mutex_unlock (&thread->mtx);
}
void
@@ -1311,7 +1514,7 @@ thread_call (struct thread *thread)
}
/* Execute thread */
-struct thread *
+void
funcname_thread_execute (struct thread_master *m,
int (*func)(struct thread *),
void *arg,
@@ -1323,6 +1526,7 @@ funcname_thread_execute (struct thread_master *m,
memset (&dummy, 0, sizeof (struct thread));
+ pthread_mutex_init (&dummy.mtx, NULL);
dummy.type = THREAD_EVENT;
dummy.add_type = THREAD_EXECUTE;
dummy.master = NULL;
@@ -1331,13 +1535,15 @@ funcname_thread_execute (struct thread_master *m,
tmp.func = dummy.func = func;
tmp.funcname = dummy.funcname = funcname;
- dummy.hist = hash_get (cpu_record, &tmp,
- (void * (*) (void *))cpu_record_hash_alloc);
+ pthread_mutex_lock (&cpu_record_mtx);
+ {
+ dummy.hist = hash_get (cpu_record, &tmp,
+ (void * (*) (void *))cpu_record_hash_alloc);
+ }
+ pthread_mutex_unlock (&cpu_record_mtx);
dummy.schedfrom = schedfrom;
dummy.schedfrom_line = fromln;
thread_call (&dummy);
-
- return NULL;
}
diff --git a/lib/thread.h b/lib/thread.h
index 6cb7896e7d..218672c7bf 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_THREAD_H
@@ -24,6 +23,7 @@
#include <zebra.h>
#include "monotime.h"
+#include <pthread.h>
struct rusage_t
{
@@ -84,6 +84,10 @@ struct thread_master
int fd_limit;
struct fd_handler handler;
unsigned long alloc;
+ long selectpoll_timeout;
+ bool spin;
+ bool handle_signals;
+ pthread_mutex_t mtx;
};
typedef unsigned char thread_type;
@@ -91,25 +95,27 @@ typedef unsigned char thread_type;
/* Thread itself. */
struct thread
{
- thread_type type; /* thread type */
- thread_type add_type; /* thread type */
- struct thread *next; /* next pointer of the thread */
- struct thread *prev; /* previous pointer of the thread */
- struct thread_master *master; /* pointer to the struct thread_master. */
- int (*func) (struct thread *); /* event function */
- void *arg; /* event argument */
+ thread_type type; /* thread type */
+ thread_type add_type; /* thread type */
+ struct thread *next; /* next pointer of the thread */
+ struct thread *prev; /* previous pointer of the thread */
+ struct thread **ref; /* external reference (if given) */
+ struct thread_master *master; /* pointer to the struct thread_master */
+ int (*func) (struct thread *); /* event function */
+ void *arg; /* event argument */
union {
- int val; /* second argument of the event. */
- int fd; /* file descriptor in case of read/write. */
- struct timeval sands; /* rest of time sands value. */
+ int val; /* second argument of the event. */
+ int fd; /* file descriptor in case of r/w */
+ struct timeval sands; /* rest of time sands value. */
} u;
- int index; /* used for timers to store position in queue */
+ int index; /* queue position for timers */
struct timeval real;
- struct cpu_thread_history *hist; /* cache pointer to cpu_history */
- unsigned long yield; /* yield time in us */
- const char *funcname;
- const char *schedfrom;
- int schedfrom_line;
+ struct cpu_thread_history *hist; /* cache pointer to cpu_history */
+ unsigned long yield; /* yield time in microseconds */
+ const char *funcname; /* name of thread function */
+ const char *schedfrom; /* source file thread was scheduled from */
+ int schedfrom_line; /* line number of source file */
+ pthread_mutex_t mtx; /* mutex for thread.c functions */
};
struct cpu_thread_history
@@ -147,30 +153,6 @@ struct cpu_thread_history
#define THREAD_FD(X) ((X)->u.fd)
#define THREAD_VAL(X) ((X)->u.val)
-#define THREAD_READ_ON(master,thread,func,arg,sock) \
- do { \
- if (! thread) \
- thread = thread_add_read (master, func, arg, sock); \
- } while (0)
-
-#define THREAD_WRITE_ON(master,thread,func,arg,sock) \
- do { \
- if (! thread) \
- thread = thread_add_write (master, func, arg, sock); \
- } while (0)
-
-#define THREAD_TIMER_ON(master,thread,func,arg,time) \
- do { \
- if (! thread) \
- thread = thread_add_timer (master, func, arg, time); \
- } while (0)
-
-#define THREAD_TIMER_MSEC_ON(master,thread,func,arg,time) \
- do { \
- if (! thread) \
- thread = thread_add_timer_msec (master, func, arg, time); \
- } while (0)
-
#define THREAD_OFF(thread) \
do { \
if (thread) \
@@ -186,46 +168,42 @@ struct cpu_thread_history
#define debugargdef const char *funcname, const char *schedfrom, int fromln
-#define thread_add_read(m,f,a,v) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,#f,__FILE__,__LINE__)
-#define thread_add_write(m,f,a,v) funcname_thread_add_read_write(THREAD_WRITE,m,f,a,v,#f,__FILE__,__LINE__)
-#define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f,__FILE__,__LINE__)
-#define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f,__FILE__,__LINE__)
-#define thread_add_timer_tv(m,f,a,v) funcname_thread_add_timer_tv(m,f,a,v,#f,__FILE__,__LINE__)
-#define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f,__FILE__,__LINE__)
+#define thread_add_read(m,f,a,v,t) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,t,#f,__FILE__,__LINE__)
+#define thread_add_write(m,f,a,v,t) funcname_thread_add_read_write(THREAD_WRITE,m,f,a,v,t,#f,__FILE__,__LINE__)
+#define thread_add_timer(m,f,a,v,t) funcname_thread_add_timer(m,f,a,v,t,#f,__FILE__,__LINE__)
+#define thread_add_timer_msec(m,f,a,v,t) funcname_thread_add_timer_msec(m,f,a,v,t,#f,__FILE__,__LINE__)
+#define thread_add_timer_tv(m,f,a,v,t) funcname_thread_add_timer_tv(m,f,a,v,t,#f,__FILE__,__LINE__)
+#define thread_add_event(m,f,a,v,t) funcname_thread_add_event(m,f,a,v,t,#f,__FILE__,__LINE__)
#define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__)
/* The 4th arg to thread_add_background is the # of milliseconds to delay. */
-#define thread_add_background(m,f,a,v) funcname_thread_add_background(m,f,a,v,#f,__FILE__,__LINE__)
+#define thread_add_background(m,f,a,v,t) funcname_thread_add_background(m,f,a,v,t,#f,__FILE__,__LINE__)
/* Prototypes. */
extern struct thread_master *thread_master_create (void);
extern void thread_master_free (struct thread_master *);
extern void thread_master_free_unused(struct thread_master *);
-extern struct thread *funcname_thread_add_read_write (int dir, struct thread_master *,
- int (*)(struct thread *),
- void *, int, debugargdef);
-extern struct thread *funcname_thread_add_timer (struct thread_master *,
- int (*)(struct thread *),
- void *, long, debugargdef);
-extern struct thread *funcname_thread_add_timer_msec (struct thread_master *,
- int (*)(struct thread *),
- void *, long, debugargdef);
-extern struct thread *funcname_thread_add_timer_tv (struct thread_master *,
- int (*)(struct thread *),
- void *, struct timeval *,
- debugargdef);
-extern struct thread *funcname_thread_add_event (struct thread_master *,
- int (*)(struct thread *),
- void *, int, debugargdef);
-extern struct thread *funcname_thread_add_background (struct thread_master *,
- int (*func)(struct thread *),
- void *arg,
- long milliseconds_to_delay,
- debugargdef);
-extern struct thread *funcname_thread_execute (struct thread_master *,
- int (*)(struct thread *),
- void *, int, debugargdef);
+extern struct thread * funcname_thread_add_read_write (int dir, struct thread_master *,
+ int (*)(struct thread *), void *, int, struct thread **, debugargdef);
+
+extern struct thread * funcname_thread_add_timer (struct thread_master *,
+ int (*)(struct thread *), void *, long, struct thread **, debugargdef);
+
+extern struct thread * funcname_thread_add_timer_msec (struct thread_master *,
+ int (*)(struct thread *), void *, long, struct thread **, debugargdef);
+
+extern struct thread * funcname_thread_add_timer_tv (struct thread_master *,
+ int (*)(struct thread *), void *, struct timeval *, struct thread **, debugargdef);
+
+extern struct thread * funcname_thread_add_event (struct thread_master *,
+ int (*)(struct thread *), void *, int, struct thread **, debugargdef);
+
+extern struct thread * funcname_thread_add_background (struct thread_master *,
+ int (*)(struct thread *), void *, long, struct thread **, debugargdef);
+
+extern void funcname_thread_execute (struct thread_master *,
+ int (*)(struct thread *), void *, int, debugargdef);
#undef debugargdef
extern void thread_cancel (struct thread *);
diff --git a/lib/vector.c b/lib/vector.c
index e16fcf5315..110cd2915c 100644
--- a/lib/vector.c
+++ b/lib/vector.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/lib/vector.h b/lib/vector.h
index f57f28bbd0..ab1d1e6aac 100644
--- a/lib/vector.h
+++ b/lib/vector.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_VECTOR_H
diff --git a/lib/vrf.c b/lib/vrf.c
index ce57bb6e7a..c4e527db5b 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -14,16 +14,16 @@
* 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.
+ * 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 "if.h"
#include "vrf.h"
+#include "vrf_int.h"
#include "prefix.h"
#include "table.h"
#include "log.h"
@@ -237,33 +237,6 @@ vrf_disable (struct vrf *vrf)
(*vrf_master.vrf_disable_hook) (vrf);
}
-
-/* Add a VRF hook. Please add hooks before calling vrf_init(). */
-void
-vrf_add_hook (int type, int (*func)(struct vrf *))
-{
- if (debug_vrf)
- zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__,
- type, func);
-
- switch (type) {
- case VRF_NEW_HOOK:
- vrf_master.vrf_new_hook = func;
- break;
- case VRF_DELETE_HOOK:
- vrf_master.vrf_delete_hook = func;
- break;
- case VRF_ENABLE_HOOK:
- vrf_master.vrf_enable_hook = func;
- break;
- case VRF_DISABLE_HOOK:
- vrf_master.vrf_disable_hook = func;
- break;
- default:
- break;
- }
-}
-
vrf_id_t
vrf_name_to_id (const char *name)
{
@@ -309,24 +282,6 @@ vrf_iflist_get (vrf_id_t vrf_id)
return vrf->iflist;
}
-/* Create the interface list for the specified VRF, if needed. */
-void
-vrf_iflist_create (vrf_id_t vrf_id)
-{
- struct vrf * vrf = vrf_lookup_by_id (vrf_id);
- if (vrf && !vrf->iflist)
- if_init (&vrf->iflist);
-}
-
-/* Free the interface list of the specified VRF. */
-void
-vrf_iflist_terminate (vrf_id_t vrf_id)
-{
- struct vrf * vrf = vrf_lookup_by_id (vrf_id);
- if (vrf && vrf->iflist)
- if_terminate (&vrf->iflist);
-}
-
/*
* VRF bit-map
*/
@@ -424,13 +379,21 @@ vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
/* Initialize VRF module. */
void
-vrf_init (void)
+vrf_init (int (*create)(struct vrf *),
+ int (*enable)(struct vrf *),
+ int (*disable)(struct vrf *),
+ int (*delete)(struct vrf *))
{
struct vrf *default_vrf;
if (debug_vrf)
zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__);
+ vrf_master.vrf_new_hook = create;
+ vrf_master.vrf_enable_hook = enable;
+ vrf_master.vrf_disable_hook = disable;
+ vrf_master.vrf_delete_hook = delete;
+
/* The default VRF always exists. */
default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
if (!default_vrf)
diff --git a/lib/vrf.h b/lib/vrf.h
index f8bb07ef48..fe2b4842b0 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_VRF_H
@@ -57,15 +56,6 @@ enum {
#define VRF_CMD_HELP_STR "Specify the VRF\nThe VRF name\n"
#define VRF_ALL_CMD_HELP_STR "Specify the VRF\nAll VRFs\n"
-/*
- * VRF hooks
- */
-
-#define VRF_NEW_HOOK 0 /* a new VRF is just created */
-#define VRF_DELETE_HOOK 1 /* a VRF is to be deleted */
-#define VRF_ENABLE_HOOK 2 /* a VRF is ready to use */
-#define VRF_DISABLE_HOOK 3 /* a VRF is to be unusable */
-
struct vrf
{
RB_ENTRY(vrf) id_entry, name_entry;
@@ -98,21 +88,9 @@ DECLARE_QOBJ_TYPE(vrf)
extern struct vrf_id_head vrfs_by_id;
extern struct vrf_name_head vrfs_by_name;
-/*
- * Add a specific hook to VRF module.
- * @param1: hook type
- * @param2: the callback function
- * - param 1: the VRF ID
- * - param 2: the address of the user data pointer (the user data
- * can be stored in or freed from there)
- */
-extern void vrf_add_hook (int, int (*)(struct vrf *));
-
extern struct vrf *vrf_lookup_by_id (vrf_id_t);
extern struct vrf *vrf_lookup_by_name (const char *);
extern struct vrf *vrf_get (vrf_id_t, const char *);
-extern void vrf_delete (struct vrf *);
-extern int vrf_enable (struct vrf *);
extern vrf_id_t vrf_name_to_id (const char *);
#define VRF_GET_ID(V,NAME) \
@@ -148,10 +126,6 @@ extern void *vrf_info_lookup (vrf_id_t);
extern struct list *vrf_iflist (vrf_id_t);
/* Get the interface list of the specified VRF. Create one if not find. */
extern struct list *vrf_iflist_get (vrf_id_t);
-/* Create the interface list for the specified VRF, if needed. */
-extern void vrf_iflist_create (vrf_id_t vrf_id);
-/* Free the interface list of the specified VRF. */
-extern void vrf_iflist_terminate (vrf_id_t vrf_id);
/*
* VRF bit-map: maintaining flags, one bit per VRF ID
@@ -168,9 +142,31 @@ extern int vrf_bitmap_check (vrf_bitmap_t, vrf_id_t);
/*
* VRF initializer/destructor
+ *
+ * create -> Called back when a new VRF is created. This
+ * can be either through these 3 options:
+ * 1) CLI mentions a vrf before OS knows about it
+ * 2) OS calls zebra and we create the vrf from OS
+ * callback
+ * 3) zebra calls individual protocols to notify
+ * about the new vrf
+ *
+ * enable -> Called back when a VRF is actually usable from
+ * an OS perspective ( 2 and 3 above )
+ *
+ * disable -> Called back when a VRF is being deleted from
+ * the system ( 2 and 3 ) above
+ *
+ * delete -> Called back when a vrf is being deleted from
+ * the system ( 2 and 3 ) above.
+ */
+extern void vrf_init (int (*create)(struct vrf *),
+ int (*enable)(struct vrf *),
+ int (*disable)(struct vrf *),
+ int (*delete)(struct vrf *));
+/*
+ * Call vrf_terminate when the protocol is being shutdown
*/
-/* Please add hooks before calling vrf_init(). */
-extern void vrf_init (void);
extern void vrf_terminate (void);
extern void vrf_cmd_init (int (*writefunc)(struct vty *vty));
diff --git a/lib/vrf_int.h b/lib/vrf_int.h
new file mode 100644
index 0000000000..f0301b7670
--- /dev/null
+++ b/lib/vrf_int.h
@@ -0,0 +1,56 @@
+/*
+ * VRF Internal Header
+ * Copyright (C) 2017 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of 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 __LIB_VRF_PRIVATE_H__
+#define __LIB_VRF_PRIVATE_H__
+
+#include "vrf.h"
+
+/*
+ * These functions should only be called by:
+ * zebra/if_netlink.c -> The interface from OS into Zebra
+ * lib/zclient.c -> The interface from Zebra to each daemon
+ *
+ * Why you ask? Well because these are the turn on/off
+ * functions and the only place we can really turn a
+ * vrf on properly is in the call up from the os -> zebra
+ * and the pass through of this informatoin from zebra -> protocols
+ */
+
+/*
+ * vrf_enable
+ *
+ * Given a newly running vrf enable it to be used
+ * by interested routing protocols
+ */
+extern int vrf_enable (struct vrf *);
+
+/*
+ * vrf_delete
+ *
+ * Given a vrf that is being deleted, delete it
+ * from interested parties
+ */
+extern void vrf_delete (struct vrf *);
+
+#endif
+
diff --git a/lib/vty.c b/lib/vty.c
index 36755b1d95..51e56fc1ae 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -734,6 +733,7 @@ vty_end_config (struct vty *vty)
case ZEBRA_NODE:
case RIP_NODE:
case RIPNG_NODE:
+ case EIGRP_NODE:
case BGP_NODE:
case BGP_VPNV4_NODE:
case BGP_VPNV6_NODE:
@@ -745,9 +745,11 @@ vty_end_config (struct vty *vty)
case BGP_VNC_L2_GROUP_NODE:
case BGP_IPV4_NODE:
case BGP_IPV4M_NODE:
+ case BGP_IPV4L_NODE:
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
case BGP_EVPN_NODE:
+ case BGP_IPV6L_NODE:
case RMAP_NODE:
case OSPF_NODE:
case OSPF6_NODE:
@@ -952,14 +954,14 @@ vty_complete_command (struct vty *vty)
vty_backward_pure_word (vty);
vty_insert_word_overwrite (vty, matched[0]);
vty_self_insert (vty, ' ');
- XFREE (MTYPE_TMP, matched[0]);
+ XFREE (MTYPE_COMPLETION, matched[0]);
break;
case CMD_COMPLETE_MATCH:
vty_prompt (vty);
vty_redraw_line (vty);
vty_backward_pure_word (vty);
vty_insert_word_overwrite (vty, matched[0]);
- XFREE (MTYPE_TMP, matched[0]);
+ XFREE (MTYPE_COMPLETION, matched[0]);
break;
case CMD_COMPLETE_LIST_MATCH:
for (i = 0; matched[i] != NULL; i++)
@@ -967,7 +969,7 @@ vty_complete_command (struct vty *vty)
if (i != 0 && ((i % 6) == 0))
vty_out (vty, "%s", VTY_NEWLINE);
vty_out (vty, "%-10s ", matched[i]);
- XFREE (MTYPE_TMP, matched[i]);
+ XFREE (MTYPE_COMPLETION, matched[i]);
}
vty_out (vty, "%s", VTY_NEWLINE);
@@ -1106,6 +1108,26 @@ vty_describe_command (struct vty *vty)
else
vty_describe_fold (vty, width, desc_width, token);
+ if (IS_VARYING_TOKEN(token->type))
+ {
+ const char *ref = vector_slot(vline, vector_active(vline) - 1);
+
+ vector varcomps = vector_init (VECTOR_MIN_SIZE);
+ cmd_variable_complete (token, ref, varcomps);
+
+ if (vector_active(varcomps) > 0)
+ {
+ vty_out(vty, " ");
+ for (size_t j = 0; j < vector_active (varcomps); j++)
+ {
+ char *item = vector_slot (varcomps, j);
+ vty_out(vty, " %s", item);
+ XFREE(MTYPE_COMPLETION, item);
+ }
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+ vector_free(varcomps);
+ }
#if 0
vty_out (vty, " %-*s %s%s", width
desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
@@ -1161,6 +1183,7 @@ vty_stop_input (struct vty *vty)
case ZEBRA_NODE:
case RIP_NODE:
case RIPNG_NODE:
+ case EIGRP_NODE:
case BGP_NODE:
case RMAP_NODE:
case OSPF_NODE:
@@ -2609,41 +2632,44 @@ static struct thread_master *vty_master;
static void
vty_event (enum event event, int sock, struct vty *vty)
{
- struct thread *vty_serv_thread;
+ struct thread *vty_serv_thread = NULL;
switch (event)
{
case VTY_SERV:
- vty_serv_thread = thread_add_read (vty_master, vty_accept, vty, sock);
+ vty_serv_thread = thread_add_read(vty_master, vty_accept, vty, sock, NULL);
vector_set_index (Vvty_serv_thread, sock, vty_serv_thread);
break;
#ifdef VTYSH
case VTYSH_SERV:
- vty_serv_thread = thread_add_read (vty_master, vtysh_accept, vty, sock);
+ vty_serv_thread = thread_add_read(vty_master, vtysh_accept, vty, sock, NULL);
vector_set_index (Vvty_serv_thread, sock, vty_serv_thread);
break;
case VTYSH_READ:
- vty->t_read = thread_add_read (vty_master, vtysh_read, vty, sock);
+ vty->t_read = NULL;
+ thread_add_read(vty_master, vtysh_read, vty, sock, &vty->t_read);
break;
case VTYSH_WRITE:
- vty->t_write = thread_add_write (vty_master, vtysh_write, vty, sock);
+ vty->t_write = NULL;
+ thread_add_write(vty_master, vtysh_write, vty, sock, &vty->t_write);
break;
#endif /* VTYSH */
case VTY_READ:
- vty->t_read = thread_add_read (vty_master, vty_read, vty, sock);
+ vty->t_read = NULL;
+ thread_add_read(vty_master, vty_read, vty, sock, &vty->t_read);
/* 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);
+ vty->t_timeout = NULL;
+ thread_add_timer(vty_master, vty_timeout, vty, vty->v_timeout,
+ &vty->t_timeout);
}
break;
case VTY_WRITE:
- if (! vty->t_write)
- vty->t_write = thread_add_write (vty_master, vty_flush, vty, sock);
+ thread_add_write(vty_master, vty_flush, vty, sock, &vty->t_write);
break;
case VTY_TIMEOUT_RESET:
if (vty->t_timeout)
@@ -2653,8 +2679,9 @@ vty_event (enum event event, int sock, struct vty *vty)
}
if (vty->v_timeout)
{
- vty->t_timeout =
- thread_add_timer (vty_master, vty_timeout, vty, vty->v_timeout);
+ vty->t_timeout = NULL;
+ thread_add_timer(vty_master, vty_timeout, vty, vty->v_timeout,
+ &vty->t_timeout);
}
break;
}
diff --git a/lib/vty.h b/lib/vty.h
index 0ac73d95be..77edc7173a 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -1,22 +1,22 @@
/* Virtual terminal [aka TeletYpe] interface routine
- Copyright (C) 1997 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1997 Kunihiro Ishiguro
+ *
+ * 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 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 _ZEBRA_VTY_H
#define _ZEBRA_VTY_H
diff --git a/lib/wheel.c b/lib/wheel.c
index fe53dea299..f273a29262 100644
--- a/lib/wheel.c
+++ b/lib/wheel.c
@@ -13,10 +13,9 @@
* 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
+ * 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"
@@ -60,9 +59,8 @@ wheel_timer_thread (struct thread *t)
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);
+ thread_add_timer_msec(wheel->master, wheel_timer_thread, wheel,
+ wheel->nexttime * slots_to_skip, &wheel->timer);
return 0;
}
@@ -91,9 +89,8 @@ wheel_init (struct thread_master *master, int period, size_t slots,
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);
+ thread_add_timer_msec(wheel->master, wheel_timer_thread, wheel,
+ wheel->nexttime, &wheel->timer);
return wheel;
}
@@ -124,9 +121,8 @@ int
wheel_start (struct timer_wheel *wheel)
{
if (!wheel->timer)
- THREAD_TIMER_MSEC_ON (wheel->master, wheel->timer,
- wheel_timer_thread, wheel,
- wheel->nexttime);
+ thread_add_timer_msec(wheel->master, wheel_timer_thread, wheel,
+ wheel->nexttime, &wheel->timer);
return 0;
}
diff --git a/lib/wheel.h b/lib/wheel.h
index 79d21e124b..07be79bf26 100644
--- a/lib/wheel.h
+++ b/lib/wheel.h
@@ -13,10 +13,9 @@
* 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
+ * 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__
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 51017b34ea..f992588399 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
@@ -126,8 +125,9 @@ work_queue_schedule (struct work_queue *wq, unsigned int delay)
&& (wq->thread == NULL)
&& (listcount (wq->items) > 0) )
{
- wq->thread = thread_add_background (wq->master, work_queue_run,
- wq, delay);
+ wq->thread = NULL;
+ thread_add_background(wq->master, work_queue_run, wq, delay,
+ &wq->thread);
/* set thread yield time, if needed */
if (wq->thread && wq->spec.yield != THREAD_YIELD_TIME_SLOT)
thread_set_yield_time (wq->thread, wq->spec.yield);
diff --git a/lib/workqueue.h b/lib/workqueue.h
index 548f96d8b0..45f02afc63 100644
--- a/lib/workqueue.h
+++ b/lib/workqueue.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _QUAGGA_WORK_QUEUE_H
diff --git a/lib/zassert.h b/lib/zassert.h
index bf0a851ba8..082ad67897 100644
--- a/lib/zassert.h
+++ b/lib/zassert.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _QUAGGA_ASSERT_H
diff --git a/lib/zclient.c b/lib/zclient.c
index d2a5186315..9823bc8d99 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -26,6 +25,8 @@
#include "stream.h"
#include "buffer.h"
#include "network.h"
+#include "vrf.h"
+#include "vrf_int.h"
#include "if.h"
#include "log.h"
#include "thread.h"
@@ -310,8 +311,9 @@ zclient_flush_data(struct thread *thread)
return zclient_failed(zclient);
break;
case BUFFER_PENDING:
- zclient->t_write = thread_add_write(zclient->master, zclient_flush_data,
- zclient, zclient->sock);
+ zclient->t_write = NULL;
+ thread_add_write(zclient->master, zclient_flush_data, zclient, zclient->sock,
+ &zclient->t_write);
break;
case BUFFER_EMPTY:
break;
@@ -336,8 +338,8 @@ zclient_send_message(struct zclient *zclient)
THREAD_OFF(zclient->t_write);
break;
case BUFFER_PENDING:
- THREAD_WRITE_ON(zclient->master, zclient->t_write,
- zclient_flush_data, zclient, zclient->sock);
+ thread_add_write(zclient->master, zclient_flush_data, zclient,
+ zclient->sock, &zclient->t_write);
break;
}
return 0;
@@ -733,6 +735,18 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
s = zclient->obuf;
stream_reset (s);
+ /* Some checks for labeled-unicast. The current expectation is that each
+ * nexthop is accompanied by a label in the case of labeled-unicast.
+ */
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL) &&
+ CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
+ {
+ /* We expect prefixes installed with labels and the number to match
+ * the number of nexthops.
+ */
+ assert (api->label_num == api->nexthop_num);
+ }
+
zclient_create_header (s, cmd, api->vrf_id);
/* Put type and nexthop. */
@@ -749,7 +763,7 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
/* Nexthop, ifindex, distance and metric information. */
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
- {
+ {
/* traditional 32-bit data units */
if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
{
@@ -765,6 +779,9 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
{
stream_putc (s, NEXTHOP_TYPE_IPV4);
stream_put_in_addr (s, api->nexthop[i]);
+ /* For labeled-unicast, each nexthop is followed by label. */
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL))
+ stream_putl (s, api->label[i]);
}
for (i = 0; i < api->ifindex_num; i++)
{
@@ -800,6 +817,18 @@ zapi_ipv4_route_ipv6_nexthop (u_char cmd, struct zclient *zclient,
s = zclient->obuf;
stream_reset (s);
+ /* Some checks for labeled-unicast. The current expectation is that each
+ * nexthop is accompanied by a label in the case of labeled-unicast.
+ */
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL) &&
+ CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
+ {
+ /* We expect prefixes installed with labels and the number to match
+ * the number of nexthops.
+ */
+ assert (api->label_num == api->nexthop_num);
+ }
+
zclient_create_header (s, cmd, api->vrf_id);
/* Put type and nexthop. */
@@ -831,6 +860,9 @@ zapi_ipv4_route_ipv6_nexthop (u_char cmd, struct zclient *zclient,
{
stream_putc (s, NEXTHOP_TYPE_IPV6);
stream_write (s, (u_char *)api->nexthop[i], 16);
+ /* For labeled-unicast, each nexthop is followed by label. */
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL))
+ stream_putl (s, api->label[i]);
}
for (i = 0; i < api->ifindex_num; i++)
{
@@ -869,6 +901,18 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
s = zclient->obuf;
stream_reset (s);
+ /* Some checks for labeled-unicast. The current expectation is that each
+ * nexthop is accompanied by a label in the case of labeled-unicast.
+ */
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL) &&
+ CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
+ {
+ /* We expect prefixes installed with labels and the number to match
+ * the number of nexthops.
+ */
+ assert (api->label_num == api->nexthop_num);
+ }
+
zclient_create_header (s, cmd, api->vrf_id);
/* Put type and nexthop. */
@@ -907,6 +951,9 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
{
stream_putc (s, NEXTHOP_TYPE_IPV6);
stream_write (s, (u_char *)api->nexthop[i], 16);
+ /* For labeled-unicast, each nexthop is followed by label. */
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL))
+ stream_putl (s, api->label[i]);
}
for (i = 0; i < api->ifindex_num; i++)
{
@@ -1879,6 +1926,12 @@ zclient_read (struct thread *thread)
if (zclient->interface_link_params)
(*zclient->interface_link_params) (command, zclient, length);
break;
+ case ZEBRA_FEC_UPDATE:
+ if (zclient_debug)
+ zlog_debug("zclient rcvd fec update\n");
+ if (zclient->fec_update)
+ (*zclient->fec_update) (command, zclient, length);
+ break;
default:
break;
}
@@ -1961,22 +2014,20 @@ zclient_event (enum event event, struct zclient *zclient)
switch (event)
{
case ZCLIENT_SCHEDULE:
- if (! zclient->t_connect)
- zclient->t_connect =
- thread_add_event (zclient->master, zclient_connect, zclient, 0);
+ thread_add_event(zclient->master, zclient_connect, zclient, 0,
+ &zclient->t_connect);
break;
case ZCLIENT_CONNECT:
if (zclient_debug)
zlog_debug ("zclient connect failures: %d schedule interval is now %d",
zclient->fail, zclient->fail < 3 ? 10 : 60);
- if (! zclient->t_connect)
- zclient->t_connect =
- thread_add_timer (zclient->master, zclient_connect, zclient,
- zclient->fail < 3 ? 10 : 60);
+ thread_add_timer(zclient->master, zclient_connect, zclient,
+ zclient->fail < 3 ? 10 : 60, &zclient->t_connect);
break;
case ZCLIENT_READ:
- zclient->t_read =
- thread_add_read (zclient->master, zclient_read, zclient, zclient->sock);
+ zclient->t_read = NULL;
+ thread_add_read(zclient->master, zclient_read, zclient, zclient->sock,
+ &zclient->t_read);
break;
}
}
diff --git a/lib/zclient.h b/lib/zclient.h
index d3d0a202c5..847ac3b671 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -7,16 +7,15 @@
* 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.
+ *
+ * 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 _ZEBRA_ZCLIENT_H
@@ -94,6 +93,9 @@ typedef enum {
ZEBRA_LABEL_MANAGER_CONNECT,
ZEBRA_GET_LABEL_CHUNK,
ZEBRA_RELEASE_LABEL_CHUNK,
+ ZEBRA_FEC_REGISTER,
+ ZEBRA_FEC_UNREGISTER,
+ ZEBRA_FEC_UPDATE,
} zebra_message_types_t;
struct redist_proto
@@ -164,6 +166,7 @@ struct zclient
int (*redistribute_route_ipv4_del) (int, struct zclient *, uint16_t, vrf_id_t);
int (*redistribute_route_ipv6_add) (int, struct zclient *, uint16_t, vrf_id_t);
int (*redistribute_route_ipv6_del) (int, struct zclient *, uint16_t, vrf_id_t);
+ int (*fec_update) (int, struct zclient *, uint16_t);
};
/* Zebra API message flag. */
@@ -174,6 +177,7 @@ struct zclient
#define ZAPI_MESSAGE_TAG 0x10
#define ZAPI_MESSAGE_MTU 0x20
#define ZAPI_MESSAGE_SRCPFX 0x40
+#define ZAPI_MESSAGE_LABEL 0x80
/* Zserv protocol message header */
struct zserv_header
@@ -206,6 +210,9 @@ struct zapi_ipv4
u_char ifindex_num;
ifindex_t *ifindex;
+ u_char label_num;
+ unsigned int *label;
+
u_char distance;
u_int32_t metric;
@@ -297,6 +304,9 @@ struct zapi_ipv6
u_char ifindex_num;
ifindex_t *ifindex;
+ u_char label_num;
+ unsigned int *label;
+
u_char distance;
u_int32_t metric;
diff --git a/lib/zebra.h b/lib/zebra.h
index 760264d752..0a61c433d9 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -1,22 +1,22 @@
/* Zebra common header.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Kunihiro Ishiguro
+ *
+ * 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 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 _ZEBRA_H
#define _ZEBRA_H
@@ -393,6 +393,9 @@ extern const char *zserv_command_string (unsigned int command);
#define ZEBRA_FLAG_SCOPE_LINK 0x100
#define ZEBRA_FLAG_FIB_OVERRIDE 0x200
+/* Zebra FEC flags. */
+#define ZEBRA_FEC_REGISTER_LABEL_INDEX 0x1
+
#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */
#endif
@@ -401,8 +404,8 @@ extern const char *zserv_command_string (unsigned int command);
typedef enum {
AFI_IP = 1,
AFI_IP6 = 2,
- AFI_L2VPN = 4,
- AFI_MAX = 5
+ AFI_L2VPN = 3,
+ AFI_MAX = 4
} afi_t;
/* Subsequent Address Family Identifier. */
@@ -413,11 +416,13 @@ typedef enum {
#define SAFI_ENCAP 5
#define SAFI_RESERVED_5 5
#define SAFI_EVPN 6
-#define SAFI_MAX 7
+#define SAFI_LABELED_UNICAST 7
+#define SAFI_MAX 8
#define IANA_SAFI_RESERVED 0
#define IANA_SAFI_UNICAST 1
#define IANA_SAFI_MULTICAST 2
+#define IANA_SAFI_LABELED_UNICAST 4
#define IANA_SAFI_ENCAP 7
#define IANA_SAFI_MPLS_VPN 128
@@ -512,6 +517,8 @@ static inline safi_t safi_iana2int (safi_t safi)
return SAFI_ENCAP;
if (safi == IANA_SAFI_EVPN)
return SAFI_EVPN;
+ if (safi == IANA_SAFI_LABELED_UNICAST)
+ return SAFI_LABELED_UNICAST;
return SAFI_MAX;
}
@@ -527,6 +534,8 @@ static inline safi_t safi_int2iana (safi_t safi)
return IANA_SAFI_ENCAP;
if (safi == SAFI_EVPN)
return IANA_SAFI_EVPN;
+ if (safi == SAFI_LABELED_UNICAST)
+ return IANA_SAFI_LABELED_UNICAST;
return IANA_SAFI_RESERVED;
}
diff --git a/m4/.gitignore b/m4/.gitignore
index 3f3bd0a735..798188b0b9 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -4,4 +4,5 @@ Makefile.in
.arch-ids
*~
*.loT
-
+!ax_pthread.m4
+!ax_sys_weak_alias.m4
diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4
new file mode 100644
index 0000000000..d383ad5c6d
--- /dev/null
+++ b/m4/ax_pthread.m4
@@ -0,0 +1,332 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+# This macro figures out how to build C programs using POSIX threads. It
+# sets the PTHREAD_LIBS output variable to the threads library and linker
+# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+# flags that are needed. (The user can also force certain compiler
+# flags/libs to be tested by setting these environment variables.)
+#
+# Also sets PTHREAD_CC to any special C compiler that is needed for
+# multi-threaded programs (defaults to the value of CC otherwise). (This
+# is necessary on AIX to use the special cc_r compiler alias.)
+#
+# NOTE: You are assumed to not only compile your program with these flags,
+# but also link it with them as well. e.g. you should link with
+# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+# If you are only building threads programs, you may wish to use these
+# variables in your default LIBS, CFLAGS, and CC:
+#
+# LIBS="$PTHREAD_LIBS $LIBS"
+# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CC="$PTHREAD_CC"
+#
+# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+# PTHREAD_CFLAGS.
+#
+# ACTION-IF-FOUND is a list of shell commands to run if a threads library
+# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+# is not found. If ACTION-IF-FOUND is not specified, the default action
+# will define HAVE_PTHREAD.
+#
+# Please let the authors know if this macro fails on any platform, or if
+# you have any other suggestions or comments. This macro was based on work
+# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+# Alejandro Forero Cuervo to the autoconf macro repository. We are also
+# grateful for the helpful feedback of numerous users.
+#
+# Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 21
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+ AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
+ AC_MSG_RESULT([$ax_pthread_ok])
+ if test x"$ax_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+ solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+ ;;
+
+ darwin*)
+ ax_pthread_flags="-pthread $ax_pthread_flags"
+ ;;
+esac
+
+# Clang doesn't consider unrecognized options an error unless we specify
+# -Werror. We throw in some extra Clang-specific options to ensure that
+# this doesn't happen for GCC, which also accepts -Werror.
+
+AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
+save_CFLAGS="$CFLAGS"
+ax_pthread_extra_flags="-Werror"
+CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
+ [AC_MSG_RESULT([yes])],
+ [ax_pthread_extra_flags=
+ AC_MSG_RESULT([no])])
+CFLAGS="$save_CFLAGS"
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+ case $flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $flag])
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+ if test x"$ax_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$flag])
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+ static void routine(void *a) { a = 0; }
+ static void *start_routine(void *a) { return a; }],
+ [pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */])],
+ [ax_pthread_ok=yes],
+ [])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ AC_MSG_RESULT([$ax_pthread_ok])
+ if test "x$ax_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ AC_MSG_CHECKING([for joinable pthread attribute])
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+ [int attr = $attr; return attr /* ; */])],
+ [attr_name=$attr; break],
+ [])
+ done
+ AC_MSG_RESULT([$attr_name])
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+ AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
+ [Define to necessary symbol if this constant
+ uses a non-standard name on your system.])
+ fi
+
+ AC_MSG_CHECKING([if more special flags are required for pthreads])
+ flag=no
+ case ${host_os} in
+ aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+ osf* | hpux*) flag="-D_REENTRANT";;
+ solaris*)
+ if test "$GCC" = "yes"; then
+ flag="-D_REENTRANT"
+ else
+ # TODO: What about Clang on Solaris?
+ flag="-mt -D_REENTRANT"
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$flag])
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+ [ax_cv_PTHREAD_PRIO_INHERIT], [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+ [[int i = PTHREAD_PRIO_INHERIT;]])],
+ [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+ [ax_cv_PTHREAD_PRIO_INHERIT=no])
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+ [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ # More AIX lossage: compile with *_r variant
+ if test "x$GCC" != xyes; then
+ case $host_os in
+ aix*)
+ AS_CASE(["x/$CC"],
+ [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+ [#handle absolute path differently from PATH based program lookup
+ AS_CASE(["x$CC"],
+ [x/*],
+ [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+ [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+ ;;
+ esac
+ fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+ ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
+ :
+else
+ ax_pthread_ok=no
+ $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
diff --git a/nhrpd/netlink_arp.c b/nhrpd/netlink_arp.c
index 76419a7ff1..2b222e3c5c 100644
--- a/nhrpd/netlink_arp.c
+++ b/nhrpd/netlink_arp.c
@@ -124,7 +124,7 @@ static int netlink_route_recv(struct thread *t)
}
}
- thread_add_read(master, netlink_route_recv, 0, fd);
+ thread_add_read(master, netlink_route_recv, 0, fd, NULL);
return 0;
}
@@ -214,7 +214,8 @@ static int netlink_log_recv(struct thread *t)
}
}
- THREAD_READ_ON(master, netlink_log_thread, netlink_log_recv, 0, netlink_log_fd);
+ thread_add_read(master, netlink_log_recv, 0, netlink_log_fd,
+ &netlink_log_thread);
return 0;
}
@@ -230,7 +231,8 @@ void netlink_set_nflog_group(int nlgroup)
if (nlgroup) {
netlink_log_fd = znl_open(NETLINK_NETFILTER, 0);
netlink_log_register(netlink_log_fd, nlgroup);
- THREAD_READ_ON(master, netlink_log_thread, netlink_log_recv, 0, netlink_log_fd);
+ thread_add_read(master, netlink_log_recv, 0, netlink_log_fd,
+ &netlink_log_thread);
}
}
@@ -238,7 +240,8 @@ int netlink_init(void)
{
netlink_req_fd = znl_open(NETLINK_ROUTE, 0);
netlink_listen_fd = znl_open(NETLINK_ROUTE, RTMGRP_NEIGH);
- thread_add_read(master, netlink_route_recv, 0, netlink_listen_fd);
+ thread_add_read(master, netlink_route_recv, 0, netlink_listen_fd,
+ NULL);
return 0;
}
diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c
index d9094ec335..2d92842b5c 100644
--- a/nhrpd/nhrp_cache.c
+++ b/nhrpd/nhrp_cache.c
@@ -181,11 +181,14 @@ static void nhrp_cache_update_timers(struct nhrp_cache *c)
switch (c->cur.type) {
case NHRP_CACHE_INVALID:
if (!c->t_auth)
- THREAD_TIMER_MSEC_ON(master, c->t_timeout, nhrp_cache_do_free, c, 10);
+ thread_add_timer_msec(master, nhrp_cache_do_free, c,
+ 10, &c->t_timeout);
break;
default:
if (c->cur.expires)
- THREAD_TIMER_ON(master, c->t_timeout, nhrp_cache_do_timeout, c, c->cur.expires - monotime(NULL));
+ thread_add_timer(master, nhrp_cache_do_timeout, c,
+ c->cur.expires - monotime(NULL),
+ &c->t_timeout);
break;
}
}
@@ -239,7 +242,8 @@ static void nhrp_cache_newpeer_notifier(struct notifier_block *n, unsigned long
case NOTIFY_PEER_UP:
if (nhrp_peer_check(c->new.peer, 1)) {
evmgr_notify("authorize-binding", c, nhrp_cache_authorize_binding);
- THREAD_TIMER_ON(master, c->t_auth, nhrp_cache_do_auth_timeout, c, 10);
+ thread_add_timer(master, nhrp_cache_do_auth_timeout,
+ c, 10, &c->t_auth);
}
break;
case NOTIFY_PEER_DOWN:
@@ -294,7 +298,8 @@ int nhrp_cache_update_binding(struct nhrp_cache *c, enum nhrp_cache_type type, i
} else {
nhrp_peer_notify_add(c->new.peer, &c->newpeer_notifier, nhrp_cache_newpeer_notifier);
nhrp_cache_newpeer_notifier(&c->newpeer_notifier, NOTIFY_PEER_UP);
- THREAD_TIMER_ON(master, c->t_auth, nhrp_cache_do_auth_timeout, c, 60);
+ thread_add_timer(master, nhrp_cache_do_auth_timeout,
+ c, 60, &c->t_auth);
}
}
nhrp_cache_update_timers(c);
diff --git a/nhrpd/nhrp_event.c b/nhrpd/nhrp_event.c
index aab9ec642f..da86c585a4 100644
--- a/nhrpd/nhrp_event.c
+++ b/nhrpd/nhrp_event.c
@@ -40,8 +40,8 @@ static void evmgr_connection_error(struct event_manager *evmgr)
close(evmgr->fd);
evmgr->fd = -1;
if (nhrp_event_socket_path)
- THREAD_TIMER_MSEC_ON(master, evmgr->t_reconnect, evmgr_reconnect,
- evmgr, 10);
+ thread_add_timer_msec(master, evmgr_reconnect, evmgr, 10,
+ &evmgr->t_reconnect);
}
static void evmgr_recv_message(struct event_manager *evmgr, struct zbuf *zb)
@@ -85,7 +85,7 @@ static int evmgr_read(struct thread *t)
while (zbuf_may_pull_until(ibuf, "\n\n", &msg))
evmgr_recv_message(evmgr, &msg);
- THREAD_READ_ON(master, evmgr->t_read, evmgr_read, evmgr, evmgr->fd);
+ thread_add_read(master, evmgr_read, evmgr, evmgr->fd, &evmgr->t_read);
return 0;
}
@@ -97,7 +97,8 @@ static int evmgr_write(struct thread *t)
evmgr->t_write = NULL;
r = zbufq_write(&evmgr->obuf, evmgr->fd);
if (r > 0) {
- THREAD_WRITE_ON(master, evmgr->t_write, evmgr_write, evmgr, evmgr->fd);
+ thread_add_write(master, evmgr_write, evmgr, evmgr->fd,
+ &evmgr->t_write);
} else if (r < 0) {
evmgr_connection_error(evmgr);
}
@@ -170,7 +171,8 @@ static void evmgr_submit(struct event_manager *evmgr, struct zbuf *obuf)
zbuf_put(obuf, "\n", 1);
zbufq_queue(&evmgr->obuf, obuf);
if (evmgr->fd >= 0)
- THREAD_WRITE_ON(master, evmgr->t_write, evmgr_write, evmgr, evmgr->fd);
+ thread_add_write(master, evmgr_write, evmgr, evmgr->fd,
+ &evmgr->t_write);
}
static int evmgr_reconnect(struct thread *t)
@@ -186,13 +188,14 @@ static int evmgr_reconnect(struct thread *t)
zlog_warn("%s: failure connecting nhrp-event socket: %s",
__PRETTY_FUNCTION__, strerror(errno));
zbufq_reset(&evmgr->obuf);
- THREAD_TIMER_ON(master, evmgr->t_reconnect, evmgr_reconnect, evmgr, 10);
+ thread_add_timer(master, evmgr_reconnect, evmgr, 10,
+ &evmgr->t_reconnect);
return 0;
}
zlog_info("Connected to Event Manager");
evmgr->fd = fd;
- THREAD_READ_ON(master, evmgr->t_read, evmgr_read, evmgr, evmgr->fd);
+ thread_add_read(master, evmgr_read, evmgr, evmgr->fd, &evmgr->t_read);
return 0;
}
@@ -206,7 +209,8 @@ void evmgr_init(void)
evmgr->fd = -1;
zbuf_init(&evmgr->ibuf, evmgr->ibuf_data, sizeof(evmgr->ibuf_data), 0);
zbufq_init(&evmgr->obuf);
- THREAD_TIMER_MSEC_ON(master, evmgr->t_reconnect, evmgr_reconnect, evmgr, 10);
+ thread_add_timer_msec(master, evmgr_reconnect, evmgr, 10,
+ &evmgr->t_reconnect);
}
void evmgr_set_socket(const char *socket)
diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c
index a44ce35bb8..7c5d80336c 100644
--- a/nhrpd/nhrp_main.c
+++ b/nhrpd/nhrp_main.c
@@ -129,7 +129,7 @@ int main(int argc, char **argv)
/* Library inits. */
master = frr_init();
nhrp_interface_init();
- vrf_init();
+ vrf_init(NULL, NULL, NULL, NULL);
resolver_init();
/* Run with elevated capabilities, as for all netlink activity
diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c
index 555c0d1de1..b926a8d7b2 100644
--- a/nhrpd/nhrp_nhs.c
+++ b/nhrpd/nhrp_nhs.c
@@ -81,7 +81,8 @@ static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg)
/* RFC 2332 5.2.3 - Registration is recommend to be renewed
* every one third of holdtime */
- THREAD_TIMER_ON(master, r->t_register, nhrp_reg_send_req, r, holdtime / 3);
+ thread_add_timer(master, nhrp_reg_send_req, r, holdtime / 3,
+ &r->t_register);
r->proto_addr = p->dst_proto;
c = nhrp_cache_get(ifp, &p->dst_proto, 1);
@@ -104,7 +105,8 @@ static int nhrp_reg_timeout(struct thread *t)
r->timeout <<= 1;
if (r->timeout > 64) r->timeout = 2;
- THREAD_TIMER_MSEC_ON(master, r->t_register, nhrp_reg_send_req, r, 10);
+ thread_add_timer_msec(master, nhrp_reg_send_req, r, 10,
+ &r->t_register);
return 0;
}
@@ -122,7 +124,8 @@ static void nhrp_reg_peer_notify(struct notifier_block *n, unsigned long cmd)
debugf(NHRP_DEBUG_COMMON, "NHS: Flush timer for %s",
sockunion2str(&r->peer->vc->remote.nbma, buf, sizeof buf));
THREAD_TIMER_OFF(r->t_register);
- THREAD_TIMER_MSEC_ON(master, r->t_register, nhrp_reg_send_req, r, 10);
+ thread_add_timer_msec(master, nhrp_reg_send_req, r, 10,
+ &r->t_register);
break;
}
}
@@ -145,11 +148,13 @@ static int nhrp_reg_send_req(struct thread *t)
if (!nhrp_peer_check(r->peer, 2)) {
debugf(NHRP_DEBUG_COMMON, "NHS: Waiting link for %s",
sockunion2str(&r->peer->vc->remote.nbma, buf1, sizeof buf1));
- THREAD_TIMER_ON(master, r->t_register, nhrp_reg_send_req, r, 120);
+ thread_add_timer(master, nhrp_reg_send_req, r, 120,
+ &r->t_register);
return 0;
}
- THREAD_TIMER_ON(master, r->t_register, nhrp_reg_timeout, r, r->timeout);
+ thread_add_timer(master, nhrp_reg_timeout, r, r->timeout,
+ &r->t_register);
/* RFC2332 5.2.3 NHC uses it's own address as dst if NHS is unknown */
dst_proto = &nhs->proto_addr;
@@ -223,11 +228,13 @@ static void nhrp_nhs_resolve_cb(struct resolver_query *q, int n, union sockunion
nhs->t_resolve = NULL;
if (n < 0) {
/* Failed, retry in a moment */
- THREAD_TIMER_ON(master, nhs->t_resolve, nhrp_nhs_resolve, nhs, 5);
+ thread_add_timer(master, nhrp_nhs_resolve, nhs, 5,
+ &nhs->t_resolve);
return;
}
- THREAD_TIMER_ON(master, nhs->t_resolve, nhrp_nhs_resolve, nhs, 2*60*60);
+ thread_add_timer(master, nhrp_nhs_resolve, nhs, 2 * 60 * 60,
+ &nhs->t_resolve);
list_for_each_entry(reg, &nhs->reglist_head, reglist_entry)
reg->mark = 1;
@@ -252,7 +259,8 @@ static void nhrp_nhs_resolve_cb(struct resolver_query *q, int n, union sockunion
list_init(&reg->reglist_entry);
list_add_tail(&reg->reglist_entry, &nhs->reglist_head);
nhrp_peer_notify_add(reg->peer, &reg->peer_notifier, nhrp_reg_peer_notify);
- THREAD_TIMER_MSEC_ON(master, reg->t_register, nhrp_reg_send_req, reg, 50);
+ thread_add_timer_msec(master, nhrp_reg_send_req, reg, 50,
+ &reg->t_register);
}
list_for_each_entry_safe(reg, regn, &nhs->reglist_head, reglist_entry) {
@@ -300,7 +308,8 @@ int nhrp_nhs_add(struct interface *ifp, afi_t afi, union sockunion *proto_addr,
.reglist_head = LIST_INITIALIZER(nhs->reglist_head),
};
list_add_tail(&nhs->nhslist_entry, &nifp->afi[afi].nhslist_head);
- THREAD_TIMER_MSEC_ON(master, nhs->t_resolve, nhrp_nhs_resolve, nhs, 1000);
+ thread_add_timer_msec(master, nhrp_nhs_resolve, nhs, 1000,
+ &nhs->t_resolve);
return NHRP_OK;
}
diff --git a/nhrpd/nhrp_packet.c b/nhrpd/nhrp_packet.c
index 36dbdfd777..76c5f15170 100644
--- a/nhrpd/nhrp_packet.c
+++ b/nhrpd/nhrp_packet.c
@@ -269,7 +269,7 @@ static int nhrp_packet_recvraw(struct thread *t)
uint8_t addr[64];
size_t len, addrlen;
- thread_add_read(master, nhrp_packet_recvraw, 0, fd);
+ thread_add_read(master, nhrp_packet_recvraw, 0, fd, NULL);
zb = zbuf_alloc(1500);
if (!zb) return 0;
@@ -307,6 +307,6 @@ err:
int nhrp_packet_init(void)
{
- thread_add_read(master, nhrp_packet_recvraw, 0, os_socket());
+ thread_add_read(master, nhrp_packet_recvraw, 0, os_socket(), NULL);
return 0;
}
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index 3cc91a9083..5f1e43a608 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -79,9 +79,8 @@ static void __nhrp_peer_check(struct nhrp_peer *p)
* the up notification a bit to allow things
* settle down. This allows IKE to install
* SPDs and SAs. */
- THREAD_TIMER_MSEC_ON(
- master, p->t_fallback,
- nhrp_peer_notify_up, p, 50);
+ thread_add_timer_msec(master, nhrp_peer_notify_up, p,
+ 50, &p->t_fallback);
} else {
nhrp_peer_ref(p);
p->online = online;
@@ -230,7 +229,8 @@ static int nhrp_peer_request_timeout(struct thread *t)
p->fallback_requested = 1;
vici_request_vc(nifp->ipsec_fallback_profile,
&vc->local.nbma, &vc->remote.nbma, p->prio);
- THREAD_TIMER_ON(master, p->t_fallback, nhrp_peer_request_timeout, p, 30);
+ thread_add_timer(master, nhrp_peer_request_timeout, p, 30,
+ &p->t_fallback);
} else {
p->requested = p->fallback_requested = 0;
}
@@ -258,8 +258,9 @@ int nhrp_peer_check(struct nhrp_peer *p, int establish)
p->prio = establish > 1;
p->requested = 1;
vici_request_vc(nifp->ipsec_profile, &vc->local.nbma, &vc->remote.nbma, p->prio);
- THREAD_TIMER_ON(master, p->t_fallback, nhrp_peer_request_timeout, p,
- (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30);
+ thread_add_timer(master, nhrp_peer_request_timeout, p,
+ (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30,
+ &p->t_fallback);
return 0;
}
diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c
index cd33ff0280..4a6cbce31f 100644
--- a/nhrpd/nhrp_shortcut.c
+++ b/nhrpd/nhrp_shortcut.c
@@ -38,7 +38,8 @@ static int nhrp_shortcut_do_expire(struct thread *t)
struct nhrp_shortcut *s = THREAD_ARG(t);
s->t_timer = NULL;
- THREAD_TIMER_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, s->holding_time/3);
+ thread_add_timer(master, nhrp_shortcut_do_purge, s,
+ s->holding_time / 3, &s->t_timer);
s->expiring = 1;
nhrp_shortcut_check_use(s);
@@ -103,7 +104,8 @@ static void nhrp_shortcut_update_binding(struct nhrp_shortcut *s, enum nhrp_cach
if (holding_time) {
s->expiring = 0;
s->holding_time = holding_time;
- THREAD_TIMER_ON(master, s->t_timer, nhrp_shortcut_do_expire, s, 2*holding_time/3);
+ thread_add_timer(master, nhrp_shortcut_do_expire, s,
+ 2 * holding_time / 3, &s->t_timer);
}
}
@@ -180,7 +182,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, void *ar
nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid);
THREAD_OFF(s->t_timer);
- THREAD_TIMER_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, 1);
+ thread_add_timer(master, nhrp_shortcut_do_purge, s, 1, &s->t_timer);
if (pp->hdr->type != NHRP_PACKET_RESOLUTION_REPLY) {
if (pp->hdr->type == NHRP_PACKET_ERROR_INDICATION &&
@@ -326,7 +328,8 @@ void nhrp_shortcut_initiate(union sockunion *addr)
if (s && s->type != NHRP_CACHE_INCOMPLETE) {
s->addr = *addr;
THREAD_OFF(s->t_timer);
- THREAD_TIMER_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, 30);
+ thread_add_timer(master, nhrp_shortcut_do_purge, s, 30,
+ &s->t_timer);
nhrp_shortcut_send_resolution_req(s);
}
}
@@ -370,7 +373,8 @@ void nhrp_shortcut_purge(struct nhrp_shortcut *s, int force)
if (force) {
/* Immediate purge on route with draw or pending shortcut */
- THREAD_TIMER_MSEC_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, 5);
+ thread_add_timer_msec(master, nhrp_shortcut_do_purge, s, 5,
+ &s->t_timer);
} else {
/* Soft expire - force immediate renewal, but purge
* in few seconds to make sure stale route is not
@@ -379,7 +383,8 @@ void nhrp_shortcut_purge(struct nhrp_shortcut *s, int force)
* This allows to keep nhrp route up, and to not
* cause temporary rerouting via hubs causing latency
* jitter. */
- THREAD_TIMER_MSEC_ON(master, s->t_timer, nhrp_shortcut_do_purge, s, 3000);
+ thread_add_timer_msec(master, nhrp_shortcut_do_purge, s, 3000,
+ &s->t_timer);
s->expiring = 1;
nhrp_shortcut_check_use(s);
}
diff --git a/nhrpd/resolver.c b/nhrpd/resolver.c
index 07bdb735a3..c29be3cbf9 100644
--- a/nhrpd/resolver.c
+++ b/nhrpd/resolver.c
@@ -47,7 +47,8 @@ static int resolver_cb_socket_readable(struct thread *t)
ares_process_fd(r->channel, fd, ARES_SOCKET_BAD);
if (vector_lookup(r->read_threads, fd) == THREAD_RUNNING) {
t = NULL;
- THREAD_READ_ON(master, t, resolver_cb_socket_readable, r, fd);
+ thread_add_read(master, resolver_cb_socket_readable, r, fd,
+ &t);
vector_set_index(r->read_threads, fd, t);
}
resolver_update_timeouts(r);
@@ -64,7 +65,8 @@ static int resolver_cb_socket_writable(struct thread *t)
ares_process_fd(r->channel, ARES_SOCKET_BAD, fd);
if (vector_lookup(r->write_threads, fd) == THREAD_RUNNING) {
t = NULL;
- THREAD_WRITE_ON(master, t, resolver_cb_socket_writable, r, fd);
+ thread_add_write(master, resolver_cb_socket_writable, r, fd,
+ &t);
vector_set_index(r->write_threads, fd, t);
}
resolver_update_timeouts(r);
@@ -82,7 +84,8 @@ static void resolver_update_timeouts(struct resolver_state *r)
tv = ares_timeout(r->channel, NULL, &tvbuf);
if (tv) {
unsigned int timeoutms = tv->tv_sec * 1000 + tv->tv_usec / 1000;
- THREAD_TIMER_MSEC_ON(master, r->timeout, resolver_cb_timeout, r, timeoutms);
+ thread_add_timer_msec(master, resolver_cb_timeout, r,
+ timeoutms, &r->timeout);
}
}
@@ -94,7 +97,8 @@ static void ares_socket_cb(void *data, ares_socket_t fd, int readable, int writa
if (readable) {
t = vector_lookup_ensure(r->read_threads, fd);
if (!t) {
- THREAD_READ_ON(master, t, resolver_cb_socket_readable, r, fd);
+ thread_add_read(master, resolver_cb_socket_readable,
+ r, fd, &t);
vector_set_index(r->read_threads, fd, t);
}
} else {
@@ -110,7 +114,8 @@ static void ares_socket_cb(void *data, ares_socket_t fd, int readable, int writa
if (writable) {
t = vector_lookup_ensure(r->write_threads, fd);
if (!t) {
- THREAD_READ_ON(master, t, resolver_cb_socket_writable, r, fd);
+ thread_add_read(master, resolver_cb_socket_writable,
+ r, fd, &t);
vector_set_index(r->write_threads, fd, t);
}
} else {
diff --git a/nhrpd/vici.c b/nhrpd/vici.c
index 5491bacf7c..244562d547 100644
--- a/nhrpd/vici.c
+++ b/nhrpd/vici.c
@@ -73,7 +73,7 @@ static void vici_connection_error(struct vici_conn *vici)
close(vici->fd);
vici->fd = -1;
- THREAD_TIMER_ON(master, vici->t_reconnect, vici_reconnect, vici, 2);
+ thread_add_timer(master, vici_reconnect, vici, 2, &vici->t_reconnect);
}
static void vici_parse_message(
@@ -324,7 +324,7 @@ static int vici_read(struct thread *t)
vici_recv_message(vici, &pktbuf);
} while (1);
- THREAD_READ_ON(master, vici->t_read, vici_read, vici, vici->fd);
+ thread_add_read(master, vici_read, vici, vici->fd, &vici->t_read);
return 0;
}
@@ -336,7 +336,8 @@ static int vici_write(struct thread *t)
vici->t_write = NULL;
r = zbufq_write(&vici->obuf, vici->fd);
if (r > 0) {
- THREAD_WRITE_ON(master, vici->t_write, vici_write, vici, vici->fd);
+ thread_add_write(master, vici_write, vici, vici->fd,
+ &vici->t_write);
} else if (r < 0) {
vici_connection_error(vici);
}
@@ -352,7 +353,7 @@ static void vici_submit(struct vici_conn *vici, struct zbuf *obuf)
}
zbufq_queue(&vici->obuf, obuf);
- THREAD_WRITE_ON(master, vici->t_write, vici_write, vici, vici->fd);
+ thread_add_write(master, vici_write, vici, vici->fd, &vici->t_write);
}
static void vici_submit_request(struct vici_conn *vici, const char *name, ...)
@@ -422,13 +423,14 @@ static int vici_reconnect(struct thread *t)
if (fd < 0) {
zlog_warn("%s: failure connecting VICI socket: %s",
__PRETTY_FUNCTION__, strerror(errno));
- THREAD_TIMER_ON(master, vici->t_reconnect, vici_reconnect, vici, 2);
+ thread_add_timer(master, vici_reconnect, vici, 2,
+ &vici->t_reconnect);
return 0;
}
debugf(NHRP_DEBUG_COMMON, "VICI: Connected");
vici->fd = fd;
- THREAD_READ_ON(master, vici->t_read, vici_read, vici, vici->fd);
+ thread_add_read(master, vici_read, vici, vici->fd, &vici->t_read);
/* Send event subscribtions */
//vici_register_event(vici, "child-updown");
@@ -451,7 +453,8 @@ void vici_init(void)
vici->fd = -1;
zbuf_init(&vici->ibuf, vici->ibuf_data, sizeof(vici->ibuf_data), 0);
zbufq_init(&vici->obuf);
- THREAD_TIMER_MSEC_ON(master, vici->t_reconnect, vici_reconnect, vici, 10);
+ thread_add_timer_msec(master, vici_reconnect, vici, 10,
+ &vici->t_reconnect);
}
void vici_terminate(void)
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index 2e31535d24..7ef7fdd94a 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospf6d/ospf6_abr.h b/ospf6d/ospf6_abr.h
index 5bc2469e10..55d657cfc6 100644
--- a/ospf6d/ospf6_abr.h
+++ b/ospf6d/ospf6_abr.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_ABR_H
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 2b25585e6c..9f02a414de 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -406,26 +405,11 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
}
-#define OSPF6_CMD_AREA_LOOKUP(str, oa) \
-{ \
- u_int32_t area_id = 0; \
- if (inet_pton (AF_INET, str, &area_id) != 1) \
- { \
- vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
- return CMD_SUCCESS; \
- } \
- oa = ospf6_area_lookup (area_id, ospf6); \
- if (oa == NULL) \
- { \
- vty_out (vty, "No such Area: %s%s", str, VNL); \
- return CMD_SUCCESS; \
- } \
-}
-
#define OSPF6_CMD_AREA_GET(str, oa) \
{ \
- u_int32_t area_id = 0; \
- if (inet_pton (AF_INET, str, &area_id) != 1) \
+ char *ep; \
+ u_int32_t area_id = htonl (strtol(str, &ep, 10)); \
+ if (*ep && inet_pton (AF_INET, str, &area_id) != 1) \
{ \
vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
return CMD_SUCCESS; \
diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h
index 3b752d948c..8e2368b166 100644
--- a/ospf6d/ospf6_area.h
+++ b/ospf6d/ospf6_area.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF_AREA_H
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index da90e2f966..302d8c9865 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h
index da6bbdd9c3..aaa3c72a44 100644
--- a/ospf6d/ospf6_asbr.h
+++ b/ospf6d/ospf6_asbr.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_ASBR_H
diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c
index fed5021208..7d9abe2331 100644
--- a/ospf6d/ospf6_bfd.c
+++ b/ospf6d/ospf6_bfd.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
@@ -251,7 +250,7 @@ ospf6_bfd_interface_dest_update (int command, struct zclient *zclient,
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
{
THREAD_OFF (on->inactivity_timer);
- thread_add_event (master, inactivity_timer, on, 0);
+ thread_add_event(master, inactivity_timer, on, 0, NULL);
}
}
diff --git a/ospf6d/ospf6_bfd.h b/ospf6d/ospf6_bfd.h
index 9c3b57aa24..913f7dcf44 100644
--- a/ospf6d/ospf6_bfd.h
+++ b/ospf6d/ospf6_bfd.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 OSPF6_BFD_H
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c
index 6ac93d8984..8a8dcfcd20 100644
--- a/ospf6d/ospf6_flood.c
+++ b/ospf6d/ospf6_flood.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -112,8 +111,9 @@ ospf6_lsa_originate (struct ospf6_lsa *lsa)
lsdb_self = ospf6_get_scoped_lsdb_self (lsa);
ospf6_lsdb_add (ospf6_lsa_copy (lsa), lsdb_self);
- lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
- OSPF_LS_REFRESH_TIME);
+ lsa->refresh = NULL;
+ thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
+ &lsa->refresh);
if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type))
@@ -225,9 +225,11 @@ ospf6_install_lsa (struct ospf6_lsa *lsa)
}
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);
+ if (! OSPF6_LSA_IS_MAXAGE (lsa)) {
+ lsa->expire = NULL;
+ thread_add_timer(master, ospf6_lsa_expire, lsa, OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec,
+ &lsa->expire);
+ }
else
lsa->expire = NULL;
@@ -361,10 +363,8 @@ ospf6_flood_interface (struct ospf6_neighbor *from,
zlog_debug ("Add retrans-list of this neighbor");
ospf6_increment_retrans_count (lsa);
ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
- if (on->thread_send_lsupdate == NULL)
- on->thread_send_lsupdate =
- thread_add_timer (master, ospf6_lsupdate_send_neighbor,
- on, on->ospf6_if->rxmt_interval);
+ thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, on->ospf6_if->rxmt_interval,
+ &on->thread_send_lsupdate);
retrans_added++;
}
@@ -406,9 +406,8 @@ ospf6_flood_interface (struct ospf6_neighbor *from,
(oi->type == OSPF_IFTYPE_POINTOPOINT))
{
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
- if (oi->thread_send_lsupdate == NULL)
- oi->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
+ thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
+ &oi->thread_send_lsupdate);
}
else
{
@@ -416,8 +415,9 @@ ospf6_flood_interface (struct ospf6_neighbor *from,
for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
{
THREAD_OFF (on->thread_send_lsupdate);
- on->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
+ on->thread_send_lsupdate = NULL;
+ thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0,
+ &on->thread_send_lsupdate);
}
}
}
@@ -577,9 +577,8 @@ ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
/* Delayed acknowledgement */
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
- if (oi->thread_send_lsack == NULL)
- oi->thread_send_lsack =
- thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
+ thread_add_timer(master, ospf6_lsack_send_interface, oi, 3,
+ &oi->thread_send_lsack);
}
else
{
@@ -601,9 +600,8 @@ ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
/* Delayed acknowledgement */
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
- if (oi->thread_send_lsack == NULL)
- oi->thread_send_lsack =
- thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
+ thread_add_timer(master, ospf6_lsack_send_interface, oi, 3,
+ &oi->thread_send_lsack);
}
else
{
@@ -621,9 +619,8 @@ ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
if (is_debug)
zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
- if (from->thread_send_lsack == NULL)
- from->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
+ thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
+ &from->thread_send_lsack);
return;
}
@@ -665,9 +662,8 @@ ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
/* Delayed acknowledgement */
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
- if (oi->thread_send_lsack == NULL)
- oi->thread_send_lsack =
- thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
+ thread_add_timer(master, ospf6_lsack_send_interface, oi, 3,
+ &oi->thread_send_lsack);
return;
}
@@ -689,9 +685,8 @@ ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
if (is_debug)
zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
- if (from->thread_send_lsack == NULL)
- from->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
+ thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
+ &from->thread_send_lsack);
return;
}
@@ -828,9 +823,8 @@ ospf6_receive_lsa (struct ospf6_neighbor *from,
/* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
- if (from->thread_send_lsack == NULL)
- from->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
+ thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
+ &from->thread_send_lsack);
/* b) Discard */
ospf6_lsa_delete (new);
@@ -912,7 +906,8 @@ ospf6_receive_lsa (struct ospf6_neighbor *from,
zlog_debug ("Newer instance of the self-originated LSA");
zlog_debug ("Schedule reorigination");
}
- new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
+ new->refresh = NULL;
+ thread_add_event(master, ospf6_lsa_refresh, new, 0, &new->refresh);
}
return;
@@ -932,7 +927,7 @@ ospf6_receive_lsa (struct ospf6_neighbor *from,
}
/* BadLSReq */
- thread_add_event (master, bad_lsreq, from, 0);
+ thread_add_event(master, bad_lsreq, from, 0, NULL);
ospf6_lsa_delete (new);
return;
@@ -998,9 +993,8 @@ ospf6_receive_lsa (struct ospf6_neighbor *from,
/* XXX, MinLSArrival check !? RFC 2328 13 (8) */
ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
- if (from->thread_send_lsupdate == NULL)
- from->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
+ thread_add_event(master, ospf6_lsupdate_send_neighbor, from, 0,
+ &from->thread_send_lsupdate);
ospf6_lsa_delete (new);
return;
}
diff --git a/ospf6d/ospf6_flood.h b/ospf6d/ospf6_flood.h
index ba7fd25f93..72482cadf3 100644
--- a/ospf6d/ospf6_flood.h
+++ b/ospf6d/ospf6_flood.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_FLOOD_H
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 8cf7f4afaa..111ca3f3d2 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -392,9 +391,9 @@ ospf6_interface_state_update (struct interface *ifp)
if (if_is_operative (ifp)
&& (ospf6_interface_get_linklocal_address(oi->interface)
|| if_is_loopback(oi->interface)))
- thread_add_event (master, interface_up, oi, 0);
+ thread_add_event(master, interface_up, oi, 0, NULL);
else
- thread_add_event (master, interface_down, oi, 0);
+ thread_add_event(master, interface_down, oi, 0, NULL);
return;
}
@@ -671,7 +670,7 @@ dr_election (struct ospf6_interface *oi)
if (on->state < OSPF6_NEIGHBOR_TWOWAY)
continue;
/* Schedule AdjOK. */
- thread_add_event (master, adj_ok, on, 0);
+ thread_add_event(master, adj_ok, on, 0, NULL);
}
}
@@ -740,8 +739,8 @@ interface_up (struct thread *thread)
{
zlog_info("Scheduling %s for sso retry, trial count: %d",
oi->interface->name, oi->sso_try_cnt);
- thread_add_timer (master, interface_up, oi,
- OSPF6_INTERFACE_SSO_RETRY_INT);
+ thread_add_timer(master, interface_up, oi,
+ OSPF6_INTERFACE_SSO_RETRY_INT, NULL);
}
return 0;
}
@@ -752,8 +751,10 @@ interface_up (struct thread *thread)
/* Schedule Hello */
if (! CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE) &&
- !if_is_loopback (oi->interface))
- oi->thread_send_hello = thread_add_event (master, ospf6_hello_send, oi, 0);
+ !if_is_loopback (oi->interface)) {
+ oi->thread_send_hello = NULL;
+ thread_add_event(master, ospf6_hello_send, oi, 0, &oi->thread_send_hello);
+ }
/* decide next interface state */
if ((if_is_pointopoint (oi->interface)) ||
@@ -765,7 +766,7 @@ interface_up (struct thread *thread)
else
{
ospf6_interface_state_change (OSPF6_INTERFACE_WAITING, oi);
- thread_add_timer (master, wait_timer, oi, oi->dead_interval);
+ thread_add_timer(master, wait_timer, oi, oi->dead_interval, NULL);
}
return 0;
@@ -1140,7 +1141,7 @@ DEFUN (ipv6_ospf6_ifmtu,
for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
{
THREAD_OFF (on->inactivity_timer);
- thread_add_event (master, inactivity_timer, on, 0);
+ thread_add_event(master, inactivity_timer, on, 0, NULL);
}
return CMD_SUCCESS;
@@ -1187,7 +1188,7 @@ DEFUN (no_ipv6_ospf6_ifmtu,
for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
{
THREAD_OFF (on->inactivity_timer);
- thread_add_event (master, inactivity_timer, on, 0);
+ thread_add_event(master, inactivity_timer, on, 0, NULL);
}
return CMD_SUCCESS;
@@ -1490,7 +1491,7 @@ DEFUN (ipv6_ospf6_passive,
for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
{
THREAD_OFF (on->inactivity_timer);
- thread_add_event (master, inactivity_timer, on, 0);
+ thread_add_event(master, inactivity_timer, on, 0, NULL);
}
return CMD_SUCCESS;
@@ -1516,8 +1517,8 @@ DEFUN (no_ipv6_ospf6_passive,
UNSET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
THREAD_OFF (oi->thread_send_hello);
- oi->thread_send_hello =
- thread_add_event (master, ospf6_hello_send, oi, 0);
+ oi->thread_send_hello = NULL;
+ thread_add_event(master, ospf6_hello_send, oi, 0, &oi->thread_send_hello);
return CMD_SUCCESS;
}
@@ -1685,8 +1686,8 @@ DEFUN (ipv6_ospf6_network,
}
/* Reset the interface */
- thread_add_event (master, interface_down, oi, 0);
- thread_add_event (master, interface_up, oi, 0);
+ thread_add_event(master, interface_down, oi, 0, NULL);
+ thread_add_event(master, interface_up, oi, 0, NULL);
return CMD_SUCCESS;
}
@@ -1720,8 +1721,8 @@ DEFUN (no_ipv6_ospf6_network,
oi->type = type;
/* Reset the interface */
- thread_add_event (master, interface_down, oi, 0);
- thread_add_event (master, interface_up, oi, 0);
+ thread_add_event(master, interface_down, oi, 0, NULL);
+ thread_add_event(master, interface_up, oi, 0, NULL);
return CMD_SUCCESS;
}
@@ -1864,8 +1865,8 @@ ospf6_interface_clear (struct vty *vty, struct interface *ifp)
zlog_debug ("Interface %s: clear by reset", ifp->name);
/* Reset the interface */
- thread_add_event (master, interface_down, oi, 0);
- thread_add_event (master, interface_up, oi, 0);
+ thread_add_event(master, interface_down, oi, 0, NULL);
+ thread_add_event(master, interface_up, oi, 0, NULL);
}
/* Clear interface */
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index 846cde4191..0408fc69d6 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_INTERFACE_H
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 6461963856..92db9cd117 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ospf6d/ospf6_intra.h b/ospf6d/ospf6_intra.h
index c9660b6a5c..1147848354 100644
--- a/ospf6d/ospf6_intra.h
+++ b/ospf6d/ospf6_intra.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_INTRA_H
@@ -156,40 +155,30 @@ struct ospf6_intra_prefix_lsa
#define OSPF6_ROUTER_LSA_SCHEDULE(oa) \
do { \
- if (! (oa)->thread_router_lsa \
- && CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \
- (oa)->thread_router_lsa = \
- thread_add_event (master, ospf6_router_lsa_originate, oa, 0); \
+ if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \
+ thread_add_event (master, ospf6_router_lsa_originate, oa, 0, &(oa)->thread_router_lsa); \
} while (0)
#define OSPF6_NETWORK_LSA_SCHEDULE(oi) \
do { \
- if (! (oi)->thread_network_lsa \
- && ! CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
- (oi)->thread_network_lsa = \
- thread_add_event (master, ospf6_network_lsa_originate, oi, 0); \
+ if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
+ thread_add_event (master, ospf6_network_lsa_originate, oi, 0, &(oi)->thread_network_lsa); \
} while (0)
#define OSPF6_LINK_LSA_SCHEDULE(oi) \
do { \
- if (! (oi)->thread_link_lsa \
- && ! CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
- (oi)->thread_link_lsa = \
- thread_add_event (master, ospf6_link_lsa_originate, oi, 0); \
+ if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
+ thread_add_event (master, ospf6_link_lsa_originate, oi, 0, &(oi)->thread_link_lsa); \
} while (0)
#define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oa) \
do { \
- if (! (oa)->thread_intra_prefix_lsa \
- && CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \
- (oa)->thread_intra_prefix_lsa = \
- thread_add_event (master, ospf6_intra_prefix_lsa_originate_stub, \
- oa, 0); \
+ if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \
+ thread_add_event (master, ospf6_intra_prefix_lsa_originate_stub, \
+ oa, 0, &(oa)->thread_intra_prefix_lsa); \
} while (0)
#define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi) \
do { \
- if (! (oi)->thread_intra_prefix_lsa \
- && ! CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
- (oi)->thread_intra_prefix_lsa = \
- thread_add_event (master, ospf6_intra_prefix_lsa_originate_transit, \
- oi, 0); \
+ if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
+ thread_add_event (master, ospf6_intra_prefix_lsa_originate_transit, \
+ oi, 0, &(oi)->thread_intra_prefix_lsa); \
} while (0)
#define OSPF6_NETWORK_LSA_EXECUTE(oi) \
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index f943e16bf2..acc8fe3804 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -695,7 +694,6 @@ ospf6_lsa_refresh (struct thread *thread)
struct ospf6_lsa *old, *self, *new;
struct ospf6_lsdb *lsdb_self;
- assert (thread);
old = (struct ospf6_lsa *) THREAD_ARG (thread);
assert (old && old->header);
@@ -721,8 +719,9 @@ ospf6_lsa_refresh (struct thread *thread)
new = ospf6_lsa_create (self->header);
new->lsdb = old->lsdb;
- new->refresh = thread_add_timer (master, ospf6_lsa_refresh, new,
- OSPF_LS_REFRESH_TIME);
+ new->refresh = NULL;
+ thread_add_timer(master, ospf6_lsa_refresh, new, OSPF_LS_REFRESH_TIME,
+ &new->refresh);
/* store it in the LSDB for self-originated LSAs */
ospf6_lsdb_add (ospf6_lsa_copy (new), lsdb_self);
@@ -917,7 +916,6 @@ DEFUN (no_debug_ospf6_lsa_type,
return CMD_SUCCESS;
}
-
void
install_element_ospf6_debug_lsa (void)
{
diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h
index a95891ac5a..36cf559868 100644
--- a/ospf6d/ospf6_lsa.h
+++ b/ospf6d/ospf6_lsa.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_LSA_H
diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c
index 1d4b557cd5..cb522226ac 100644
--- a/ospf6d/ospf6_lsdb.c
+++ b/ospf6d/ospf6_lsdb.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ospf6d/ospf6_lsdb.h b/ospf6d/ospf6_lsdb.h
index b21d9ee282..866868080a 100644
--- a/ospf6d/ospf6_lsdb.h
+++ b/ospf6d/ospf6_lsdb.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_LSDB_H
diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
index 54ae4645ad..f69c1e1bca 100644
--- a/ospf6d/ospf6_main.c
+++ b/ospf6d/ospf6_main.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -222,7 +221,7 @@ main (int argc, char *argv[], char *envp[])
/* thread master */
master = frr_init ();
- vrf_init ();
+ vrf_init (NULL, NULL, NULL, NULL);
access_list_init ();
prefix_list_init ();
diff --git a/ospf6d/ospf6_memory.c b/ospf6d/ospf6_memory.c
index 7f2fbbf0b7..35d03f7e44 100644
--- a/ospf6d/ospf6_memory.c
+++ b/ospf6d/ospf6_memory.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
#ifdef HAVE_CONFIG_H
diff --git a/ospf6d/ospf6_memory.h b/ospf6d/ospf6_memory.h
index 3ff5de4c31..324065c3a1 100644
--- a/ospf6d/ospf6_memory.h
+++ b/ospf6d/ospf6_memory.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_OSPF6_MEMORY_H
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index 578b39a641..87c905af3f 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -352,9 +351,9 @@ ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst,
/* Schedule interface events */
if (backupseen)
- thread_add_event (master, backup_seen, oi, 0);
+ thread_add_event (master, backup_seen, oi, 0, NULL);
if (neighborchange)
- thread_add_event (master, neighbor_change, oi, 0);
+ thread_add_event (master, neighbor_change, oi, 0, NULL);
if (neighbor_ifindex_change && on->state == OSPF6_NEIGHBOR_FULL)
OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
@@ -428,7 +427,7 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Master/Slave bit mismatch");
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
@@ -436,7 +435,7 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Initialize bit mismatch");
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
@@ -444,7 +443,7 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Option field mismatch");
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
@@ -453,7 +452,7 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Sequence number mismatch (%#lx expected)",
(u_long) on->dbdesc_seqnum);
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
break;
@@ -471,7 +470,7 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Not duplicate dbdesc in state %s",
ospf6_neighbor_state_str[on->state]);
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
default:
@@ -517,7 +516,7 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
ospf6_lsa_delete (his);
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
@@ -549,19 +548,20 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
on->dbdesc_seqnum ++;
/* schedule send lsreq */
- if (on->request_list->count && (on->thread_send_lsreq == NULL))
- on->thread_send_lsreq =
- thread_add_event (master, ospf6_lsreq_send, on, 0);
+ if (on->request_list->count)
+ thread_add_event (master, ospf6_lsreq_send, on, 0, &on->thread_send_lsreq);
THREAD_OFF (on->thread_send_dbdesc);
/* More bit check */
if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
- thread_add_event (master, exchange_done, on, 0);
- else
- on->thread_send_dbdesc =
- thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
+ thread_add_event (master, exchange_done, on, 0, NULL);
+ else {
+ on->thread_send_dbdesc = NULL;
+ thread_add_event(master, ospf6_dbdesc_send_newone, on, 0,
+ &on->thread_send_dbdesc);
+ }
/* save last received dbdesc */
memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
@@ -637,8 +637,9 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Duplicated dbdesc causes retransmit");
THREAD_OFF (on->thread_send_dbdesc);
- on->thread_send_dbdesc =
- thread_add_event (master, ospf6_dbdesc_send, on, 0);
+ on->thread_send_dbdesc = NULL;
+ thread_add_event(master, ospf6_dbdesc_send, on, 0,
+ &on->thread_send_dbdesc);
return;
}
@@ -646,7 +647,7 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Master/Slave bit mismatch");
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
@@ -654,7 +655,7 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Initialize bit mismatch");
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
@@ -662,7 +663,7 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
{
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Option field mismatch");
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
@@ -671,7 +672,7 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Sequence number mismatch (%#lx expected)",
(u_long) on->dbdesc_seqnum + 1);
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
break;
@@ -684,15 +685,14 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Duplicated dbdesc causes retransmit");
THREAD_OFF (on->thread_send_dbdesc);
- on->thread_send_dbdesc =
- thread_add_event (master, ospf6_dbdesc_send, on, 0);
+ thread_add_event (master, ospf6_dbdesc_send, on, 0, &on->thread_send_dbdesc);
return;
}
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("Not duplicate dbdesc in state %s",
ospf6_neighbor_state_str[on->state]);
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
default:
@@ -735,7 +735,7 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
zlog_debug ("E-bit mismatch with LSA Headers");
ospf6_lsa_delete (his);
- thread_add_event (master, seqnumber_mismatch, on, 0);
+ thread_add_event (master, seqnumber_mismatch, on, 0, NULL);
return;
}
@@ -756,14 +756,11 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
/* schedule send lsreq */
- if ((on->thread_send_lsreq == NULL) &&
- (on->request_list->count))
- on->thread_send_lsreq =
- thread_add_event (master, ospf6_lsreq_send, on, 0);
+ if (on->request_list->count)
+ thread_add_event (master, ospf6_lsreq_send, on, 0, &on->thread_send_lsreq);
THREAD_OFF (on->thread_send_dbdesc);
- on->thread_send_dbdesc =
- thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
+ thread_add_event (master, ospf6_dbdesc_send_newone, on, 0, &on->thread_send_dbdesc);
/* save last received dbdesc */
memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
@@ -880,7 +877,7 @@ ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
ospf6_lstype_name (e->type), id, adv_router);
}
- thread_add_event (master, bad_lsreq, on, 0);
+ thread_add_event (master, bad_lsreq, on, 0, NULL);
return;
}
@@ -891,8 +888,7 @@ ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
/* schedule send lsupdate */
THREAD_OFF (on->thread_send_lsupdate);
- on->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
+ thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0, &on->thread_send_lsupdate);
}
/* Verify, that the specified memory area contains exactly N valid IPv6
@@ -1532,7 +1528,7 @@ ospf6_receive (struct thread *thread)
/* add next read thread */
sockfd = THREAD_FD (thread);
- thread_add_read (master, ospf6_receive, NULL, sockfd);
+ thread_add_read (master, ospf6_receive, NULL, sockfd, NULL);
/* initialize */
memset (&src, 0, sizeof (src));
@@ -1739,8 +1735,7 @@ ospf6_hello_send (struct thread *thread)
}
/* set next thread */
- oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,
- oi, oi->hello_interval);
+ thread_add_timer (master, ospf6_hello_send, oi, oi->hello_interval, &oi->thread_send_hello);
memset (sendbuf, 0, iobuflen);
oh = (struct ospf6_header *) sendbuf;
@@ -1804,9 +1799,9 @@ ospf6_dbdesc_send (struct thread *thread)
/* set next thread if master */
if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
- on->thread_send_dbdesc =
- thread_add_timer (master, ospf6_dbdesc_send, on,
- on->ospf6_if->rxmt_interval);
+ thread_add_timer (master, ospf6_dbdesc_send, on,
+ on->ospf6_if->rxmt_interval,
+ &on->thread_send_dbdesc);
memset (sendbuf, 0, iobuflen);
oh = (struct ospf6_header *) sendbuf;
@@ -1896,7 +1891,7 @@ ospf6_dbdesc_send_newone (struct thread *thread)
if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) &&
! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
- thread_add_event (master, exchange_done, on, 0);
+ thread_add_event (master, exchange_done, on, 0, NULL);
thread_execute (master, ospf6_dbdesc_send, on, 0);
return 0;
@@ -1927,7 +1922,7 @@ ospf6_lsreq_send (struct thread *thread)
/* schedule loading_done if request list is empty */
if (on->request_list->count == 0)
{
- thread_add_event (master, loading_done, on, 0);
+ thread_add_event (master, loading_done, on, 0, NULL);
return 0;
}
@@ -1978,9 +1973,9 @@ ospf6_lsreq_send (struct thread *thread)
/* set next thread */
if (on->request_list->count != 0)
{
- on->thread_send_lsreq =
- thread_add_timer (master, ospf6_lsreq_send, on,
- on->ospf6_if->rxmt_interval);
+ on->thread_send_lsreq = NULL;
+ thread_add_timer(master, ospf6_lsreq_send, on, on->ospf6_if->rxmt_interval,
+ &on->thread_send_lsreq);
}
return 0;
@@ -2097,13 +2092,16 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
on->ospf6_if, oh);
}
- if (on->lsupdate_list->count != 0)
- on->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
- else if (on->retrans_list->count != 0)
- on->thread_send_lsupdate =
- thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
- on->ospf6_if->rxmt_interval);
+ if (on->lsupdate_list->count != 0) {
+ on->thread_send_lsupdate = NULL;
+ thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0,
+ &on->thread_send_lsupdate);
+ }
+ else if (on->retrans_list->count != 0) {
+ on->thread_send_lsupdate = NULL;
+ thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, on->ospf6_if->rxmt_interval,
+ &on->thread_send_lsupdate);
+ }
return 0;
}
@@ -2178,8 +2176,9 @@ ospf6_lsupdate_send_interface (struct thread *thread)
if (oi->lsupdate_list->count > 0)
{
- oi->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
+ oi->thread_send_lsupdate = NULL;
+ thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
+ &oi->thread_send_lsupdate);
}
return 0;
@@ -2223,8 +2222,7 @@ ospf6_lsack_send_neighbor (struct thread *thread)
/* if we run out of packet size/space here,
better to try again soon. */
THREAD_OFF (on->thread_send_lsack);
- on->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
+ thread_add_event (master, ospf6_lsack_send_neighbor, on, 0, &on->thread_send_lsack);
ospf6_lsdb_lsa_unlock (lsa);
break;
@@ -2248,11 +2246,8 @@ ospf6_lsack_send_neighbor (struct thread *thread)
on->ospf6_if, oh);
}
- if (on->thread_send_lsack == NULL && on->lsack_list->count > 0)
- {
- on->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
- }
+ if (on->lsack_list->count > 0)
+ thread_add_event (master, ospf6_lsack_send_neighbor, on, 0, &on->thread_send_lsack);
return 0;
}
@@ -2295,8 +2290,8 @@ ospf6_lsack_send_interface (struct thread *thread)
/* if we run out of packet size/space here,
better to try again soon. */
THREAD_OFF (oi->thread_send_lsack);
- oi->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
+ thread_add_event (master, ospf6_lsack_send_interface, oi, 0,
+ &oi->thread_send_lsack);
ospf6_lsdb_lsa_unlock (lsa);
break;
@@ -2324,11 +2319,8 @@ ospf6_lsack_send_interface (struct thread *thread)
ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
}
- if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
- {
- oi->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
- }
+ if (oi->lsack_list->count > 0)
+ thread_add_event (master, ospf6_lsack_send_interface, oi, 0, &oi->thread_send_lsack);
return 0;
}
diff --git a/ospf6d/ospf6_message.h b/ospf6d/ospf6_message.h
index 4a9e0c7a66..b0107dffff 100644
--- a/ospf6d/ospf6_message.h
+++ b/ospf6d/ospf6_message.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_MESSAGE_H
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index 118210dfc7..c58922b0ea 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -238,8 +237,9 @@ hello_received (struct thread *thread)
/* reset Inactivity Timer */
THREAD_OFF (on->inactivity_timer);
- on->inactivity_timer = thread_add_timer (master, inactivity_timer, on,
- on->ospf6_if->dead_interval);
+ on->inactivity_timer = NULL;
+ thread_add_timer(master, inactivity_timer, on, on->ospf6_if->dead_interval,
+ &on->inactivity_timer);
if (on->state <= OSPF6_NEIGHBOR_DOWN)
ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
@@ -262,7 +262,7 @@ twoway_received (struct thread *thread)
if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
zlog_debug ("Neighbor Event %s: *2Way-Received*", on->name);
- thread_add_event (master, neighbor_change, on->ospf6_if, 0);
+ thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
if (! need_adjacency (on))
{
@@ -278,8 +278,8 @@ twoway_received (struct thread *thread)
SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
THREAD_OFF (on->thread_send_dbdesc);
- on->thread_send_dbdesc =
- thread_add_event (master, ospf6_dbdesc_send, on, 0);
+ on->thread_send_dbdesc = NULL;
+ thread_add_event(master, ospf6_dbdesc_send, on, 0, &on->thread_send_dbdesc);
return 0;
}
@@ -385,9 +385,8 @@ exchange_done (struct thread *thread)
ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on,
OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
- if (on->thread_send_lsreq == NULL)
- on->thread_send_lsreq =
- thread_add_event (master, ospf6_lsreq_send, on, 0);
+ thread_add_event(master, ospf6_lsreq_send, on, 0,
+ &on->thread_send_lsreq);
}
return 0;
@@ -406,13 +405,14 @@ ospf6_check_nbr_loading (struct ospf6_neighbor *on)
(on->state == OSPF6_NEIGHBOR_EXCHANGE))
{
if (on->request_list->count == 0)
- thread_add_event (master, loading_done, on, 0);
+ thread_add_event(master, loading_done, on, 0, NULL);
else if (on->last_ls_req == NULL)
{
if (on->thread_send_lsreq != NULL)
THREAD_OFF (on->thread_send_lsreq);
- on->thread_send_lsreq =
- thread_add_event (master, ospf6_lsreq_send, on, 0);
+ on->thread_send_lsreq = NULL;
+ thread_add_event(master, ospf6_lsreq_send, on, 0,
+ &on->thread_send_lsreq);
}
}
}
@@ -460,8 +460,9 @@ adj_ok (struct thread *thread)
SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
THREAD_OFF (on->thread_send_dbdesc);
- on->thread_send_dbdesc =
- thread_add_event (master, ospf6_dbdesc_send, on, 0);
+ on->thread_send_dbdesc = NULL;
+ thread_add_event(master, ospf6_dbdesc_send, on, 0,
+ &on->thread_send_dbdesc);
}
else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
@@ -515,8 +516,8 @@ seqnumber_mismatch (struct thread *thread)
THREAD_OFF (on->thread_send_dbdesc);
on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
- on->thread_send_dbdesc =
- thread_add_event (master, ospf6_dbdesc_send, on, 0);
+ on->thread_send_dbdesc = NULL;
+ thread_add_event(master, ospf6_dbdesc_send, on, 0, &on->thread_send_dbdesc);
return 0;
}
@@ -554,8 +555,8 @@ bad_lsreq (struct thread *thread)
THREAD_OFF (on->thread_send_dbdesc);
on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
- on->thread_send_dbdesc =
- thread_add_event (master, ospf6_dbdesc_send, on, 0);
+ on->thread_send_dbdesc = NULL;
+ thread_add_event(master, ospf6_dbdesc_send, on, 0, &on->thread_send_dbdesc);
return 0;
}
@@ -577,7 +578,7 @@ oneway_received (struct thread *thread)
ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
- thread_add_event (master, neighbor_change, on->ospf6_if, 0);
+ thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
ospf6_lsdb_remove_all (on->summary_list);
ospf6_lsdb_remove_all (on->request_list);
@@ -613,7 +614,7 @@ inactivity_timer (struct thread *thread)
ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on,
OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
- thread_add_event (master, neighbor_change, on->ospf6_if, 0);
+ thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
listnode_delete (on->ospf6_if->neighbor_list, on);
ospf6_neighbor_delete (on);
diff --git a/ospf6d/ospf6_neighbor.h b/ospf6d/ospf6_neighbor.h
index c275ff830e..3ff341933a 100644
--- a/ospf6d/ospf6_neighbor.h
+++ b/ospf6d/ospf6_neighbor.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_NEIGHBOR_H
diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c
index 0217d66038..9e7dd06bd8 100644
--- a/ospf6d/ospf6_network.c
+++ b/ospf6d/ospf6_network.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ospf6d/ospf6_network.h b/ospf6d/ospf6_network.h
index 4fa2839519..690901ca04 100644
--- a/ospf6d/ospf6_network.h
+++ b/ospf6d/ospf6_network.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_NETWORK_H
diff --git a/ospf6d/ospf6_proto.c b/ospf6d/ospf6_proto.c
index d011601f07..1538c891ca 100644
--- a/ospf6d/ospf6_proto.c
+++ b/ospf6d/ospf6_proto.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ospf6d/ospf6_proto.h b/ospf6d/ospf6_proto.h
index af60eb922e..e4f29aa3e8 100644
--- a/ospf6d/ospf6_proto.h
+++ b/ospf6d/ospf6_proto.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 OSPF6_PROTO_H
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index b8e5ca6196..117f7af6ee 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h
index 8b973d28ff..7cf69a26e7 100644
--- a/ospf6d/ospf6_route.h
+++ b/ospf6d/ospf6_route.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_ROUTE_H
diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c
index 96f1e3dd21..b30d3efb06 100644
--- a/ospf6d/ospf6_snmp.c
+++ b/ospf6d/ospf6_snmp.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index 333ce5588e..e7cfd3fc9a 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/* Shortest Path First calculation for OSPFv3 */
@@ -727,8 +726,9 @@ ospf6_spf_schedule (struct ospf6 *ospf6, unsigned int reason)
zlog_info ("SPF: Scheduled in %ld msec", delay);
- ospf6->t_spf_calc =
- thread_add_timer_msec (master, ospf6_spf_calculation_thread, ospf6, delay);
+ ospf6->t_spf_calc = NULL;
+ thread_add_timer_msec(master, ospf6_spf_calculation_thread, ospf6, delay,
+ &ospf6->t_spf_calc);
}
void
diff --git a/ospf6d/ospf6_spf.h b/ospf6d/ospf6_spf.h
index 7bf525d6fe..87a86c0ac8 100644
--- a/ospf6d/ospf6_spf.h
+++ b/ospf6d/ospf6_spf.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_SPF_H
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index e592d3c4f9..bafe86bff4 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -286,9 +285,9 @@ ospf6_maxage_remover (struct thread *thread)
void
ospf6_maxage_remove (struct ospf6 *o)
{
- if (o && ! o->maxage_remover)
- o->maxage_remover = thread_add_timer (master, ospf6_maxage_remover, o,
- OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT);
+ if (o)
+ thread_add_timer(master, ospf6_maxage_remover, o, OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT,
+ &o->maxage_remover);
}
/* start ospf6 */
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index 42a4d12483..5e101520d7 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_TOP_H
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index d0c9e4f042..fdf2f299cb 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ospf6d/ospf6_zebra.h b/ospf6d/ospf6_zebra.h
index 83032b64b1..f7f808c866 100644
--- a/ospf6d/ospf6_zebra.h
+++ b/ospf6d/ospf6_zebra.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6_ZEBRA_H
diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c
index aa219c7807..1ccf7ce7a9 100644
--- a/ospf6d/ospf6d.c
+++ b/ospf6d/ospf6d.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -1252,7 +1251,7 @@ ospf6_init (void)
/* Make ospf protocol socket. */
ospf6_serv_sock ();
- thread_add_read (master, ospf6_receive, NULL, ospf6_sock);
+ thread_add_read(master, ospf6_receive, NULL, ospf6_sock, NULL);
}
void
diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h
index f0bc022749..6595e70455 100644
--- a/ospf6d/ospf6d.h
+++ b/ospf6d/ospf6d.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 OSPF6D_H
diff --git a/ospfclient/ospf_apiclient.c b/ospfclient/ospf_apiclient.c
index c545d537fc..0ebae087e3 100644
--- a/ospfclient/ospf_apiclient.c
+++ b/ospfclient/ospf_apiclient.c
@@ -3,7 +3,7 @@
* Copyright (C) 2001, 2002, 2003 Ralph Keller
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfclient/ospf_apiclient.h b/ospfclient/ospf_apiclient.h
index 5a1de3b136..5882ac3496 100644
--- a/ospfclient/ospf_apiclient.h
+++ b/ospfclient/ospf_apiclient.h
@@ -3,7 +3,7 @@
* Copyright (C) 2001, 2002, 2003 Ralph Keller
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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 _OSPF_APICLIENT_H
diff --git a/ospfclient/ospfclient.c b/ospfclient/ospfclient.c
index 43ffa1da8e..195fd5b5a0 100644
--- a/ospfclient/ospfclient.c
+++ b/ospfclient/ospfclient.c
@@ -10,10 +10,9 @@
* 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.
+ * 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
*/
/*
@@ -168,7 +167,7 @@ lsa_read (struct thread *thread)
}
/* Reschedule read thread */
- thread_add_read (master, lsa_read, oclient, fd);
+ thread_add_read(master, lsa_read, oclient, fd, NULL);
return 0;
}
@@ -224,13 +223,13 @@ ready_callback (u_char lsa_type, u_char opaque_type, struct in_addr addr)
lsa_type, opaque_type, inet_ntoa (addr));
/* Schedule opaque LSA originate in 5 secs */
- thread_add_timer (master, lsa_inject, oclient, 5);
+ thread_add_timer(master, lsa_inject, oclient, 5, NULL);
/* Schedule opaque LSA update with new value */
- thread_add_timer (master, lsa_inject, oclient, 10);
+ thread_add_timer(master, lsa_inject, oclient, 10, NULL);
/* Schedule delete */
- thread_add_timer (master, lsa_delete, oclient, 30);
+ thread_add_timer(master, lsa_delete, oclient, 30, NULL);
}
static void
@@ -340,7 +339,7 @@ main (int argc, char *argv[])
ospf_apiclient_sync_lsdb (oclient);
/* Schedule thread that handles asynchronous messages */
- thread_add_read (master, lsa_read, oclient, oclient->fd_async);
+ thread_add_read(master, lsa_read, oclient, oclient->fd_async, NULL);
/* Now connection is established, run loop */
while (1)
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index a54170e048..53f6f3ce64 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -8,16 +8,15 @@
* 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.
+ *
+ * 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
*/
@@ -1881,7 +1880,6 @@ ospf_schedule_abr_task (struct ospf *ospf)
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Scheduling ABR task");
- if (ospf->t_abr_task == NULL)
- ospf->t_abr_task = thread_add_timer (master, ospf_abr_task_timer,
- ospf, OSPF_ABR_TASK_DELAY);
+ thread_add_timer(master, ospf_abr_task_timer, ospf, OSPF_ABR_TASK_DELAY,
+ &ospf->t_abr_task);
}
diff --git a/ospfd/ospf_abr.h b/ospfd/ospf_abr.h
index 2a728936d3..71eb71bdce 100644
--- a/ospfd/ospf_abr.h
+++ b/ospfd/ospf_abr.h
@@ -3,21 +3,20 @@
* Copyright (C) 1999 Alex Zinin
*
* 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.
+ * 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 _ZEBRA_OSPF_ABR_H
diff --git a/ospfd/ospf_api.c b/ospfd/ospf_api.c
index 9f90f671ce..69d61b12eb 100644
--- a/ospfd/ospf_api.c
+++ b/ospfd/ospf_api.c
@@ -3,7 +3,7 @@
* Copyright (C) 2001, 2002 Ralph Keller
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_api.h b/ospfd/ospf_api.h
index eb5ad0aae5..ee18c89346 100644
--- a/ospfd/ospf_api.h
+++ b/ospfd/ospf_api.h
@@ -3,7 +3,7 @@
* Copyright (C) 2001, 2002 Ralph Keller
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c
index aac8ef4b8b..8e619f74c7 100644
--- a/ospfd/ospf_apiserver.c
+++ b/ospfd/ospf_apiserver.c
@@ -3,7 +3,7 @@
* Copyright (C) 2001, 2002 Ralph Keller
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -301,31 +300,27 @@ ospf_apiserver_event (enum event event, int fd,
switch (event)
{
case OSPF_APISERVER_ACCEPT:
- (void)thread_add_read (master, ospf_apiserver_accept, apiserv, fd);
+ (void) thread_add_read(master, ospf_apiserver_accept, apiserv, fd, NULL);
break;
case OSPF_APISERVER_SYNC_READ:
- apiserv->t_sync_read =
- thread_add_read (master, ospf_apiserver_read, apiserv, fd);
+ apiserv->t_sync_read = NULL;
+ thread_add_read(master, ospf_apiserver_read, apiserv, fd,
+ &apiserv->t_sync_read);
break;
#ifdef USE_ASYNC_READ
case OSPF_APISERVER_ASYNC_READ:
- apiserv->t_async_read =
- thread_add_read (master, ospf_apiserver_read, apiserv, fd);
+ apiserv->t_async_read = NULL;
+ thread_add_read(master, ospf_apiserver_read, apiserv, fd,
+ &apiserv->t_async_read);
break;
#endif /* USE_ASYNC_READ */
case OSPF_APISERVER_SYNC_WRITE:
- if (!apiserv->t_sync_write)
- {
- apiserv->t_sync_write =
- thread_add_write (master, ospf_apiserver_sync_write, apiserv, fd);
- }
+ thread_add_write(master, ospf_apiserver_sync_write, apiserv, fd,
+ &apiserv->t_sync_write);
break;
case OSPF_APISERVER_ASYNC_WRITE:
- if (!apiserv->t_async_write)
- {
- apiserv->t_async_write =
- thread_add_write (master, ospf_apiserver_async_write, apiserv, fd);
- }
+ thread_add_write(master, ospf_apiserver_async_write, apiserv, fd,
+ &apiserv->t_async_write);
break;
}
}
diff --git a/ospfd/ospf_apiserver.h b/ospfd/ospf_apiserver.h
index b60f56b4fc..2fd8e7a373 100644
--- a/ospfd/ospf_apiserver.h
+++ b/ospfd/ospf_apiserver.h
@@ -3,7 +3,7 @@
* Copyright (C) 2001, 2002 Ralph Keller
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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 _OSPF_APISERVER_H
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index 284c564688..2ba3b55335 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h
index e2fa367455..2fd570d1b8 100644
--- a/ospfd/ospf_asbr.h
+++ b/ospfd/ospf_asbr.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_ASBR_H
diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c
index b063f317e2..b7cba7fd7b 100644
--- a/ospfd/ospf_ase.c
+++ b/ospfd/ospf_ase.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -705,9 +704,8 @@ ospf_ase_calculate_timer_add (struct ospf *ospf)
if (ospf == NULL)
return;
- if (! ospf->t_ase_calc)
- ospf->t_ase_calc = thread_add_timer (master, ospf_ase_calculate_timer,
- ospf, OSPF_ASE_CALC_INTERVAL);
+ thread_add_timer(master, ospf_ase_calculate_timer, ospf,
+ OSPF_ASE_CALC_INTERVAL, &ospf->t_ase_calc);
}
void
diff --git a/ospfd/ospf_ase.h b/ospfd/ospf_ase.h
index e6a1b2fb7a..d73322fcac 100644
--- a/ospfd/ospf_ase.h
+++ b/ospfd/ospf_ase.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_ASE_H
diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c
index 74bc38220b..05265171a1 100644
--- a/ospfd/ospf_bfd.c
+++ b/ospfd/ospf_bfd.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_bfd.h b/ospfd/ospf_bfd.h
index 793962dae3..75b8e11f48 100644
--- a/ospfd/ospf_bfd.h
+++ b/ospfd/ospf_bfd.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_BFD_H
diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c
index 21b2855499..469b661059 100644
--- a/ospfd/ospf_dump.c
+++ b/ospfd/ospf_dump.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h
index 9bed853eed..94918c2656 100644
--- a/ospfd/ospf_dump.h
+++ b/ospfd/ospf_dump.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_DUMP_H
diff --git a/ospfd/ospf_dump_api.c b/ospfd/ospf_dump_api.c
index 5ef262ce54..54cc7fb666 100644
--- a/ospfd/ospf_dump_api.c
+++ b/ospfd/ospf_dump_api.c
@@ -14,8 +14,8 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_dump_api.h b/ospfd/ospf_dump_api.h
index 1cd8257f0c..836d234551 100644
--- a/ospfd/ospf_dump_api.h
+++ b/ospfd/ospf_dump_api.h
@@ -14,8 +14,8 @@
* 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.
+ * 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 _ZEBRA_OSPF_DUMP_API_H
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index 4cc28f7486..00004a1efd 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -3,7 +3,7 @@
* Copyright (C) 1999, 2000 Toshiaki Takada
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h
index 1ab11b88b1..b083857546 100644
--- a/ospfd/ospf_flood.h
+++ b/ospfd/ospf_flood.h
@@ -3,7 +3,7 @@
* Copyright (C) 1999, 2000 Toshiaki Takada
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_FLOOD_H
diff --git a/ospfd/ospf_ia.c b/ospfd/ospf_ia.c
index b2d0faeb79..ebd267ded9 100644
--- a/ospfd/ospf_ia.c
+++ b/ospfd/ospf_ia.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
diff --git a/ospfd/ospf_ia.h b/ospfd/ospf_ia.h
index b65b938642..f102545f80 100644
--- a/ospfd/ospf_ia.h
+++ b/ospfd/ospf_ia.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_IA_H
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index aeb12a59fa..08f3bec479 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -3,7 +3,7 @@
* Copyright (C) 1999, 2000 Toshiaki Takada
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index 39202f777a..e6e7ddf80a 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -3,7 +3,7 @@
* Copyright (C) 1999 Toshiaki Takada
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_INTERFACE_H
diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c
index 717c99c21f..2a1f7bb32d 100644
--- a/ospfd/ospf_ism.c
+++ b/ospfd/ospf_ism.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_ism.h b/ospfd/ospf_ism.h
index fa8e6d70f6..f099fe8759 100644
--- a/ospfd/ospf_ism.h
+++ b/ospfd/ospf_ism.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_ISM_H
@@ -48,30 +47,23 @@
#define ISM_InterfaceDown 7
#define OSPF_ISM_EVENT_MAX 8
-#define OSPF_ISM_WRITE_ON(O) \
- do \
- { \
- if (oi->on_write_q == 0) \
- { \
- listnode_add ((O)->oi_write_q, oi); \
- oi->on_write_q = 1; \
- } \
- if ((O)->t_write == NULL) \
- (O)->t_write = \
- thread_add_write (master, ospf_write, (O), (O)->fd); \
- } while (0)
+#define OSPF_ISM_WRITE_ON(O) \
+ do \
+ { \
+ if (oi->on_write_q == 0) \
+ { \
+ listnode_add ((O)->oi_write_q, oi); \
+ oi->on_write_q = 1; \
+ } \
+ thread_add_write (master, ospf_write, (O), (O)->fd, &(O)->t_write); \
+ } while (0)
/* Macro for OSPF ISM timer turn on. */
#define OSPF_ISM_TIMER_ON(T,F,V) \
- do { \
- if (!(T)) \
- (T) = thread_add_timer (master, (F), oi, (V)); \
- } while (0)
+ thread_add_timer (master, (F), oi, (V), &(T))
+
#define OSPF_ISM_TIMER_MSEC_ON(T,F,V) \
- do { \
- if (!(T)) \
- (T) = thread_add_timer_msec (master, (F), oi, (V)); \
- } while (0)
+ thread_add_timer_msec (master, (F), oi, (V), &(T))
/* convenience macro to set hello timer correctly, according to
* whether fast-hello is set or not
@@ -98,7 +90,7 @@
/* Macro for OSPF schedule event. */
#define OSPF_ISM_EVENT_SCHEDULE(I,E) \
- thread_add_event (master, ospf_ism_event, (I), (E))
+ thread_add_event (master, ospf_ism_event, (I), (E), NULL)
/* Macro for OSPF execute event. */
#define OSPF_ISM_EVENT_EXECUTE(I,E) \
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index cf9943893a..acbb2bb079 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -3553,7 +3552,7 @@ ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
data->area = area;
data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
- thread_add_event (master, ospf_lsa_action, data, 0);
+ thread_add_event(master, ospf_lsa_action, data, 0, NULL);
}
void
@@ -3566,7 +3565,7 @@ ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
data->area = area;
data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
- thread_add_event (master, ospf_lsa_action, data, 0);
+ thread_add_event(master, ospf_lsa_action, data, 0, NULL);
}
@@ -3741,8 +3740,9 @@ 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->t_lsa_refresher = NULL;
+ thread_add_timer(master, ospf_lsa_refresh_walker, ospf, ospf->lsa_refresh_interval,
+ &ospf->t_lsa_refresher);
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 8b9a0d4c49..b6f2526c90 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_LSA_H
diff --git a/ospfd/ospf_lsdb.c b/ospfd/ospf_lsdb.c
index b92e7494ad..ac22f5bbe4 100644
--- a/ospfd/ospf_lsdb.c
+++ b/ospfd/ospf_lsdb.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_lsdb.h b/ospfd/ospf_lsdb.h
index 51ae45bf5b..ee31cda659 100644
--- a/ospfd/ospf_lsdb.h
+++ b/ospfd/ospf_lsdb.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_LSDB_H
diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c
index 38718b35d5..6cd6d02721 100644
--- a/ospfd/ospf_main.c
+++ b/ospfd/ospf_main.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -207,7 +206,7 @@ main (int argc, char **argv)
/* Library inits. */
debug_init ();
- vrf_init ();
+ vrf_init (NULL, NULL, NULL, NULL);
access_list_init ();
prefix_list_init ();
diff --git a/ospfd/ospf_memory.c b/ospfd/ospf_memory.c
index 0181e1e1fe..5639c0f607 100644
--- a/ospfd/ospf_memory.c
+++ b/ospfd/ospf_memory.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
#ifdef HAVE_CONFIG_H
diff --git a/ospfd/ospf_memory.h b/ospfd/ospf_memory.h
index b082c95031..5f5960eec7 100644
--- a/ospfd/ospf_memory.h
+++ b/ospfd/ospf_memory.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_OSPF_MEMORY_H
diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c
index a573936c18..fc86cd09f4 100644
--- a/ospfd/ospf_neighbor.c
+++ b/ospfd/ospf_neighbor.c
@@ -3,7 +3,7 @@
* Copyright (C) 1999, 2000 Toshiaki Takada
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_neighbor.h b/ospfd/ospf_neighbor.h
index d62de44b5e..70e3832d9f 100644
--- a/ospfd/ospf_neighbor.h
+++ b/ospfd/ospf_neighbor.h
@@ -3,7 +3,7 @@
* Copyright (C) 1999, 2000 Toshiaki Takada
*
* 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
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_NEIGHBOR_H
diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c
index d7ec256214..0f5785966f 100644
--- a/ospfd/ospf_network.c
+++ b/ospfd/ospf_network.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_network.h b/ospfd/ospf_network.h
index bc01a84325..506a419058 100644
--- a/ospfd/ospf_network.h
+++ b/ospfd/ospf_network.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_NETWORK_H
diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c
index 97f3f6a382..b3888dd832 100644
--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_nsm.h b/ospfd/ospf_nsm.h
index 4531f6ec7d..4f363b4e66 100644
--- a/ospfd/ospf_nsm.h
+++ b/ospfd/ospf_nsm.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_NSM_H
@@ -57,11 +56,7 @@
#define OSPF_NSM_EVENT_MAX 14
/* Macro for OSPF NSM timer turn on. */
-#define OSPF_NSM_TIMER_ON(T,F,V) \
- do { \
- if (!(T)) \
- (T) = thread_add_timer (master, (F), nbr, (V)); \
- } while (0)
+#define OSPF_NSM_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr, (V), &(T))
/* Macro for OSPF NSM timer turn off. */
#define OSPF_NSM_TIMER_OFF(X) \
@@ -75,7 +70,7 @@
/* Macro for OSPF NSM schedule event. */
#define OSPF_NSM_EVENT_SCHEDULE(N,E) \
- thread_add_event (master, ospf_nsm_event, (N), (E))
+ thread_add_event (master, ospf_nsm_event, (N), (E), NULL)
/* Macro for OSPF NSM execute event. */
#define OSPF_NSM_EVENT_EXECUTE(N,E) \
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 56efa2ebd6..fa87434a14 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -9,16 +9,15 @@
* 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.
+ * 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>
@@ -1342,8 +1341,9 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0)
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d ms later.", delay);
- oi->t_opaque_lsa_self =
- thread_add_timer_msec (master, ospf_opaque_type9_lsa_originate, oi, delay);
+ oi->t_opaque_lsa_self = NULL;
+ thread_add_timer_msec(master, ospf_opaque_type9_lsa_originate, oi, delay,
+ &oi->t_opaque_lsa_self);
delay += top->min_ls_interval;
}
@@ -1358,9 +1358,9 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0)
*/
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d ms later.", delay);
- area->t_opaque_lsa_self =
- thread_add_timer_msec (master, ospf_opaque_type10_lsa_originate,
- area, delay);
+ area->t_opaque_lsa_self = NULL;
+ thread_add_timer_msec(master, ospf_opaque_type10_lsa_originate, area, delay,
+ &area->t_opaque_lsa_self);
delay += top->min_ls_interval;
}
@@ -1375,9 +1375,9 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0)
*/
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d ms later.", delay);
- top->t_opaque_lsa_self =
- thread_add_timer_msec (master, ospf_opaque_type11_lsa_originate,
- top, delay);
+ top->t_opaque_lsa_self = NULL;
+ thread_add_timer_msec(master, ospf_opaque_type11_lsa_originate, top, delay,
+ &top->t_opaque_lsa_self);
delay += top->min_ls_interval;
}
@@ -1654,9 +1654,7 @@ ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)
* triggered by external interventions (vty session, signaling, etc).
*------------------------------------------------------------------------*/
-#define OSPF_OPAQUE_TIMER_ON(T,F,L,V) \
- if (!(T)) \
- (T) = thread_add_timer_msec (master, (F), (L), (V))
+#define OSPF_OPAQUE_TIMER_ON(T,F,L,V) thread_add_timer_msec (master, (F), (L), (V), &(T))
static struct ospf_lsa *pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area, u_char lsa_type, u_char opaque_type);
static int ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t);
diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h
index 2ac9b41efc..69cbb07663 100644
--- a/ospfd/ospf_opaque.h
+++ b/ospfd/ospf_opaque.h
@@ -9,16 +9,15 @@
* 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.
+ * 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 _ZEBRA_OSPF_OPAQUE_H
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index b7721adb3e..11434071ad 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -487,7 +486,8 @@ ospf_ls_req_event (struct ospf_neighbor *nbr)
thread_cancel (nbr->t_ls_req);
nbr->t_ls_req = NULL;
}
- nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
+ nbr->t_ls_req = NULL;
+ thread_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req);
}
/* Cyclic timer function. Fist registered in ospf_nbr_new () in
@@ -850,9 +850,10 @@ ospf_write (struct thread *thread)
}
/* If packets still remain in queue, call write thread. */
- if (!list_isempty (ospf->oi_write_q))
- ospf->t_write =
- thread_add_write (master, ospf_write, ospf, ospf->fd);
+ if (!list_isempty (ospf->oi_write_q)) {
+ ospf->t_write = NULL;
+ thread_add_write(master, ospf_write, ospf, ospf->fd, &ospf->t_write);
+ }
return 0;
}
@@ -2772,7 +2773,8 @@ ospf_read (struct thread *thread)
ospf = THREAD_ARG (thread);
/* prepare for next packet. */
- ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
+ ospf->t_read = NULL;
+ thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read);
stream_reset(ospf->ibuf);
if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
@@ -3802,8 +3804,9 @@ ospf_ls_upd_send_queue_event (struct thread *thread)
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
" %d nodes to try again, raising new event", again);
- oi->t_ls_upd_event =
- thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
+ oi->t_ls_upd_event = NULL;
+ thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
+ &oi->t_ls_upd_event);
}
if (IS_DEBUG_OSPF_EVENT)
@@ -3858,9 +3861,8 @@ ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
- if (oi->t_ls_upd_event == NULL)
- oi->t_ls_upd_event =
- thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
+ thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
+ &oi->t_ls_upd_event);
}
static void
@@ -3921,9 +3923,8 @@ ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
- if (oi->t_ls_ack_direct == NULL)
- oi->t_ls_ack_direct =
- thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
+ thread_add_event(master, ospf_ls_ack_send_event, oi, 0,
+ &oi->t_ls_ack_direct);
}
/* Send Link State Acknowledgment delayed. */
diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h
index 60761322df..ebc5d892dd 100644
--- a/ospfd/ospf_packet.h
+++ b/ospfd/ospf_packet.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_PACKET_H
diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c
index 883ea7cad9..4723f4a919 100644
--- a/ospfd/ospf_ri.c
+++ b/ospfd/ospf_ri.c
@@ -19,10 +19,9 @@
* 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 Quagga; see the file COPYING. If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 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>
diff --git a/ospfd/ospf_ri.h b/ospfd/ospf_ri.h
index 3f898ac598..c9ed3c56a5 100644
--- a/ospfd/ospf_ri.h
+++ b/ospfd/ospf_ri.h
@@ -19,10 +19,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_ROUTER_INFO_H
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index 175850c318..fcd5f18a7f 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h
index 6b6d9f1fab..16c6b0000c 100644
--- a/ospfd/ospf_route.h
+++ b/ospfd/ospf_route.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_ROUTE_H
diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c
index db51abca23..e2656e5169 100644
--- a/ospfd/ospf_routemap.c
+++ b/ospfd/ospf_routemap.c
@@ -16,10 +16,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c
index 32449d5597..e952df4eb3 100644
--- a/ospfd/ospf_snmp.c
+++ b/ospfd/ospf_snmp.c
@@ -16,10 +16,9 @@
* 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.
+ * 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>
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 31f0d9d286..e0fa23f35f 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -1,22 +1,22 @@
/* OSPF SPF calculation.
- Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
-
-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. */
+ * Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
+ *
+ * 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 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>
@@ -1464,6 +1464,7 @@ ospf_spf_calculate_schedule (struct ospf *ospf, ospf_spf_reason_t reason)
zlog_info ("SPF: Scheduled in %ld msec", delay);
- ospf->t_spf_calc =
- thread_add_timer_msec (master, ospf_spf_calculate_timer, ospf, delay);
+ ospf->t_spf_calc = NULL;
+ thread_add_timer_msec(master, ospf_spf_calculate_timer, ospf, delay,
+ &ospf->t_spf_calc);
}
diff --git a/ospfd/ospf_spf.h b/ospfd/ospf_spf.h
index e33b3e5f53..349f461c9b 100644
--- a/ospfd/ospf_spf.h
+++ b/ospfd/ospf_spf.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_OSPF_SPF_H
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index a89d67c6bb..804b1fb652 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -12,16 +12,15 @@
* 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.
+ * 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
*/
/* Add support of RFC7471 */
diff --git a/ospfd/ospf_te.h b/ospfd/ospf_te.h
index 36f2d8241c..885180bc1d 100644
--- a/ospfd/ospf_te.h
+++ b/ospfd/ospf_te.h
@@ -12,16 +12,15 @@
* 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.
+ * 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
*/
/* Add support of RFC7471 */
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 44bf1b8667..22fbf28e52 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -6333,7 +6332,7 @@ DEFUN (no_ip_ospf_dead_interval,
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = argc - 1;
- struct in_addr addr;
+ struct in_addr addr = { .s_addr = 0L};
int ret;
struct ospf_if_params *params;
struct ospf_interface *oi;
@@ -6465,6 +6464,7 @@ DEFUN (no_ip_ospf_hello_interval,
int idx = 0;
struct in_addr addr;
struct ospf_if_params *params;
+
params = IF_DEF_PARAMS (ifp);
if (argv_find (argv, argc, "A.B.C.D", &idx))
diff --git a/ospfd/ospf_vty.h b/ospfd/ospf_vty.h
index 429ac318f7..57090e9b15 100644
--- a/ospfd/ospf_vty.h
+++ b/ospfd/ospf_vty.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _QUAGGA_OSPF_VTY_H
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index abb6db0347..4df49db9b2 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -883,7 +882,7 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate,
if (ospf->router_id.s_addr == 0)
ospf->external_origin |= (1 << DEFAULT_ROUTE);
else
- thread_add_timer (master, ospf_default_originate_timer, ospf, 1);
+ thread_add_timer(master, ospf_default_originate_timer, ospf, 1, NULL);
ospf_asbr_status_update (ospf, ++ospf->redistribute);
@@ -1278,9 +1277,9 @@ ospf_distribute_list_update (struct ospf *ospf, uintptr_t type,
return;
/* Set timer. */
- ospf->t_distribute_update =
- thread_add_timer_msec (master, ospf_distribute_list_update_timer,
- (void *) type, ospf->min_ls_interval);
+ ospf->t_distribute_update = NULL;
+ thread_add_timer_msec(master, ospf_distribute_list_update_timer, (void *)type, ospf->min_ls_interval,
+ &ospf->t_distribute_update);
}
/* If access-list is updated, apply some check. */
diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h
index 22c71a49e1..c0b99a95ae 100644
--- a/ospfd/ospf_zebra.h
+++ b/ospfd/ospf_zebra.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_OSPF_ZEBRA_H
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 30b1e9622f..0c98c428f5 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -1,22 +1,22 @@
/* OSPF version 2 daemon program.
- Copyright (C) 1999, 2000 Toshiaki Takada
-
-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. */
+ * Copyright (C) 1999, 2000 Toshiaki Takada
+ *
+ * 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 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>
@@ -135,11 +135,12 @@ ospf_router_id_update (struct ospf *ospf)
/* Originate each redistributed external route. */
for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
if (ospf->external_origin & (1 << type))
- thread_add_event (master, ospf_external_lsa_originate_timer,
- ospf, type);
+ thread_add_event(master, ospf_external_lsa_originate_timer,
+ ospf, type, NULL);
/* Originate Deafult. */
if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
- thread_add_event (master, ospf_default_originate_timer, ospf, 0);
+ thread_add_event(master, ospf_default_originate_timer, ospf, 0,
+ NULL);
ospf->external_origin = 0;
}
@@ -184,9 +185,9 @@ ospf_router_id_update (struct ospf *ospf)
/* Originate each redistributed external route. */
for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
- thread_add_event (master, ospf_external_lsa_originate_timer,
- ospf, type);
- thread_add_event (master, ospf_default_originate_timer, ospf, 0);
+ thread_add_event(master, ospf_external_lsa_originate_timer, ospf,
+ type, NULL);
+ thread_add_event(master, ospf_default_originate_timer, ospf, 0, NULL);
/* update router-lsa's for each area */
ospf_router_lsa_update (ospf);
@@ -263,17 +264,18 @@ ospf_new (u_short instance)
/* MaxAge init. */
new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
new->maxage_lsa = route_table_init();
- new->t_maxage_walker =
- thread_add_timer (master, ospf_lsa_maxage_walker,
- new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
+ new->t_maxage_walker = NULL;
+ thread_add_timer(master, ospf_lsa_maxage_walker, new, OSPF_LSA_MAXAGE_CHECK_INTERVAL,
+ &new->t_maxage_walker);
/* Distance table init. */
new->distance_table = route_table_init ();
new->lsa_refresh_queue.index = 0;
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->t_lsa_refresher = NULL;
+ thread_add_timer(master, ospf_lsa_refresh_walker, new, new->lsa_refresh_interval,
+ &new->t_lsa_refresher);
new->lsa_refresher_started = monotime(NULL);
if ((new->fd = ospf_sock_init()) < 0)
@@ -288,7 +290,8 @@ ospf_new (u_short instance)
OSPF_MAX_PACKET_SIZE+1);
exit(1);
}
- new->t_read = thread_add_read (master, ospf_read, new, new->fd);
+ new->t_read = NULL;
+ thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
new->oi_write_q = list_new ();
new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
@@ -1592,8 +1595,8 @@ ospf_timers_refresh_set (struct ospf *ospf, int interval)
if (time_left > interval)
{
OSPF_TIMER_OFF (ospf->t_lsa_refresher);
- ospf->t_lsa_refresher =
- thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
+ thread_add_timer(master, ospf_lsa_refresh_walker, ospf, interval,
+ &ospf->t_lsa_refresher);
}
ospf->lsa_refresh_interval = interval;
@@ -1611,9 +1614,9 @@ ospf_timers_refresh_unset (struct ospf *ospf)
if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
{
OSPF_TIMER_OFF (ospf->t_lsa_refresher);
- ospf->t_lsa_refresher =
- thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
- OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
+ ospf->t_lsa_refresher = NULL;
+ thread_add_timer(master, ospf_lsa_refresh_walker, ospf, OSPF_LSA_REFRESH_INTERVAL_DEFAULT,
+ &ospf->t_lsa_refresher);
}
ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 9198d5c620..7cc629196b 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -8,16 +8,15 @@
* 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.
+ * 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 _ZEBRA_OSPFD_H
@@ -480,26 +479,10 @@ struct ospf_nbr_nbma
#define LSA_OPTIONS_NSSA_GET(area) \
(((area)->external_routing == OSPF_AREA_NSSA) ? OSPF_OPTION_NP : 0)
-#define OSPF_TIMER_ON(T,F,V) \
- do { \
- if (!(T)) \
- (T) = thread_add_timer (master, (F), ospf, (V)); \
- } while (0)
-
-#define OSPF_AREA_TIMER_ON(T,F,V) \
- do { \
- if (!(T)) \
- (T) = thread_add_timer (master, (F), area, (V)); \
- } while (0)
-
-#define OSPF_POLL_TIMER_ON(T,F,V) \
- do { \
- if (!(T)) \
- (T) = thread_add_timer (master, (F), nbr_nbma, (V)); \
- } while (0)
-
-#define OSPF_POLL_TIMER_OFF(X) OSPF_TIMER_OFF((X))
-
+#define OSPF_TIMER_ON(T,F,V) thread_add_timer (master,(F),ospf,(V),&(T))
+#define OSPF_AREA_TIMER_ON(T,F,V) thread_add_timer (master, (F), area, (V), &(T))
+#define OSPF_POLL_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr_nbma, (V), &(T))
+#define OSPF_POLL_TIMER_OFF(X) OSPF_TIMER_OFF((X))
#define OSPF_TIMER_OFF(X) \
do { \
if (X) \
diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c
index f2bfb846dd..37515cee59 100644
--- a/pimd/pim_assert.c
+++ b/pimd/pim_assert.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -230,6 +229,7 @@ int pim_assert_recv(struct interface *ifp,
int offset;
uint8_t *curr;
int curr_size;
+ struct pim_interface *pim_ifp = NULL;
on_trace(__PRETTY_FUNCTION__, ifp, src_addr);
@@ -311,6 +311,10 @@ int pim_assert_recv(struct interface *ifp,
msg_metric.ip_address = src_addr;
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+ ++pim_ifp->pim_ifstat_assert_recv;
+
return dispatch_assert(ifp,
msg_source_addr.u.prefix4,
sg.grp,
@@ -473,6 +477,7 @@ static int pim_assert_do(struct pim_ifchannel *ch,
metric.route_metric,
PIM_FORCE_BOOLEAN(metric.rpt_bit_flag));
}
+ ++pim_ifp->pim_ifstat_assert_send;
if (pim_msg_send(pim_ifp->pim_sock_fd,
pim_ifp->primary_address,
@@ -570,9 +575,8 @@ static void pim_assert_timer_set(struct pim_ifchannel *ch,
ch->sg_str, interval, ch->interface->name);
}
- THREAD_TIMER_ON(master, ch->t_ifassert_timer,
- on_assert_timer,
- ch, interval);
+ thread_add_timer(master, on_assert_timer, ch, interval,
+ &ch->t_ifassert_timer);
}
static void pim_assert_timer_reset(struct pim_ifchannel *ch)
diff --git a/pimd/pim_assert.h b/pimd/pim_assert.h
index ec18cab85e..b2fc115231 100644
--- a/pimd/pim_assert.h
+++ b/pimd/pim_assert.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_ASSERT_H
#define PIM_ASSERT_H
diff --git a/pimd/pim_br.c b/pimd/pim_br.c
index 3f84de79c8..19a0293c46 100644
--- a/pimd/pim_br.c
+++ b/pimd/pim_br.c
@@ -13,10 +13,9 @@
* 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
+ * 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>
diff --git a/pimd/pim_br.h b/pimd/pim_br.h
index 8e4f719ed0..345dd011e8 100644
--- a/pimd/pim_br.h
+++ b/pimd/pim_br.h
@@ -13,10 +13,9 @@
* 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
+ * 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_BR_H
#define PIM_BR_H
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index d5dbe4f7ab..c1bce0a222 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -820,6 +819,7 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname, u_ch
mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
if (uj) {
+ char pbuf[PREFIX2STR_BUFFER];
json_row = json_object_new_object();
json_object_pim_ifp_add(json_row, ifp);
@@ -831,7 +831,10 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname, u_ch
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_array_add(sec_list,
+ json_object_new_string(prefix2str(&sec_addr->addr,
+ pbuf,
+ sizeof(pbuf))));
}
json_object_object_add(json_row, "secondaryAddressList", sec_list);
}
@@ -922,11 +925,14 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname, u_ch
vty_out(vty, "Use Source : %s%s", inet_ntoa(pim_ifp->update_source), VTY_NEWLINE);
}
if (pim_ifp->sec_addr_list) {
+ char pbuf[PREFIX2STR_BUFFER];
vty_out(vty, "Address : %s (primary)%s",
- inet_ntoa(ifaddr), VTY_NEWLINE);
+ 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);
+ prefix2str(&sec_addr->addr,
+ pbuf,
+ sizeof(pbuf)), VTY_NEWLINE);
}
} else {
vty_out(vty, "Address : %s%s", inet_ntoa(ifaddr), VTY_NEWLINE);
@@ -1116,6 +1122,163 @@ static void pim_show_interfaces(struct vty *vty, u_char uj)
json_object_free(json);
}
+static void pim_show_interface_traffic (struct vty *vty, u_char uj)
+{
+ struct interface *ifp = NULL;
+ struct pim_interface *pim_ifp = NULL;
+ struct listnode *node = NULL;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object ();
+ else
+ {
+ vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
+ " HELLO", " JOIN", " PRUNE", " REGISTER",
+ " REGISTER-STOP", " ASSERT", VTY_NEWLINE);
+ vty_out (vty,
+ "%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
+ "", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
+ " Rx/Tx", " Rx/Tx", VTY_NEWLINE);
+ vty_out (vty,
+ "---------------------------------------------------------------------------------------------------------------%s",
+ VTY_NEWLINE);
+ }
+
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
+ {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+ if (uj)
+ {
+ json_row = json_object_new_object ();
+ json_object_pim_ifp_add (json_row, ifp);
+ json_object_int_add (json_row, "helloRx", pim_ifp->pim_ifstat_hello_recv);
+ json_object_int_add (json_row, "helloTx", pim_ifp->pim_ifstat_hello_sent);
+ json_object_int_add (json_row, "joinRx", pim_ifp->pim_ifstat_join_recv);
+ json_object_int_add (json_row, "joinTx", pim_ifp->pim_ifstat_join_send);
+ json_object_int_add (json_row, "registerRx", pim_ifp->pim_ifstat_reg_recv);
+ json_object_int_add (json_row, "registerTx", pim_ifp->pim_ifstat_reg_recv);
+ json_object_int_add (json_row, "registerStopRx", pim_ifp->pim_ifstat_reg_stop_recv);
+ json_object_int_add (json_row, "registerStopTx", pim_ifp->pim_ifstat_reg_stop_send);
+ json_object_int_add (json_row, "assertRx", pim_ifp->pim_ifstat_assert_recv);
+ json_object_int_add (json_row, "assertTx", pim_ifp->pim_ifstat_assert_send);
+
+ json_object_object_add (json, ifp->name, json_row);
+ }
+ else
+ {
+ vty_out (vty,
+ "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
+ ifp->name, pim_ifp->pim_ifstat_hello_recv,
+ pim_ifp->pim_ifstat_hello_sent, pim_ifp->pim_ifstat_join_recv,
+ pim_ifp->pim_ifstat_join_send, pim_ifp->pim_ifstat_prune_recv,
+ pim_ifp->pim_ifstat_prune_send, pim_ifp->pim_ifstat_reg_recv,
+ pim_ifp->pim_ifstat_reg_send,
+ pim_ifp->pim_ifstat_reg_stop_recv,
+ pim_ifp->pim_ifstat_reg_stop_send,
+ pim_ifp->pim_ifstat_assert_recv,
+ pim_ifp->pim_ifstat_assert_send, 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_interface_traffic_single (struct vty *vty, const char *ifname, u_char uj)
+{
+ struct interface *ifp = NULL;
+ struct pim_interface *pim_ifp = NULL;
+ struct listnode *node = NULL;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+ uint8_t found_ifname = 0;
+
+ if (uj)
+ json = json_object_new_object ();
+ else
+ {
+ vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
+ " HELLO", " JOIN", " PRUNE", " REGISTER",
+ " REGISTER-STOP", " ASSERT", VTY_NEWLINE);
+ vty_out (vty,
+ "%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
+ "", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
+ " Rx/Tx", " Rx/Tx", VTY_NEWLINE);
+ vty_out (vty,
+ "---------------------------------------------------------------------------------------------------------------%s",
+ VTY_NEWLINE);
+ }
+
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
+ {
+ if (strcmp (ifname, ifp->name))
+ continue;
+
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ found_ifname = 1;
+ if (uj)
+ {
+ json_row = json_object_new_object ();
+ json_object_pim_ifp_add (json_row, ifp);
+ json_object_int_add (json_row, "helloRx", pim_ifp->pim_ifstat_hello_recv);
+ json_object_int_add (json_row, "helloTx", pim_ifp->pim_ifstat_hello_sent);
+ json_object_int_add (json_row, "joinRx", pim_ifp->pim_ifstat_join_recv);
+ json_object_int_add (json_row, "joinTx", pim_ifp->pim_ifstat_join_send);
+ json_object_int_add (json_row, "registerRx", pim_ifp->pim_ifstat_reg_recv);
+ json_object_int_add (json_row, "registerTx", pim_ifp->pim_ifstat_reg_recv);
+ json_object_int_add (json_row, "registerStopRx", pim_ifp->pim_ifstat_reg_stop_recv);
+ json_object_int_add (json_row, "registerStopTx", pim_ifp->pim_ifstat_reg_stop_send);
+ json_object_int_add (json_row, "assertRx", pim_ifp->pim_ifstat_assert_recv);
+ json_object_int_add (json_row, "assertTx", pim_ifp->pim_ifstat_assert_send);
+
+ json_object_object_add (json, ifp->name, json_row);
+ }
+ else
+ {
+ vty_out (vty,
+ "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
+ ifp->name, pim_ifp->pim_ifstat_hello_recv,
+ pim_ifp->pim_ifstat_hello_sent, pim_ifp->pim_ifstat_join_recv,
+ pim_ifp->pim_ifstat_join_send, pim_ifp->pim_ifstat_prune_recv,
+ pim_ifp->pim_ifstat_prune_send, pim_ifp->pim_ifstat_reg_recv,
+ pim_ifp->pim_ifstat_reg_send,
+ pim_ifp->pim_ifstat_reg_stop_recv,
+ pim_ifp->pim_ifstat_reg_stop_send,
+ pim_ifp->pim_ifstat_assert_recv,
+ pim_ifp->pim_ifstat_assert_send, 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_join(struct vty *vty, u_char uj)
{
struct pim_interface *pim_ifp;
@@ -1617,13 +1780,9 @@ 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[INET_ADDRSTRLEN];
-
- if (p->family != AF_INET)
- continue;
+ char neigh_sec_str[PREFIX2STR_BUFFER];
- pim_inet4_dump("<src?>", p->u.prefix4,
- neigh_sec_str, sizeof(neigh_sec_str));
+ prefix2str(p, neigh_sec_str, sizeof(neigh_sec_str));
vty_out(vty, "%-9s %-15s %-15s %-15s%s",
ifp->name,
@@ -2494,6 +2653,45 @@ DEFUN (clear_ip_pim_interfaces,
return CMD_SUCCESS;
}
+DEFUN (clear_ip_pim_interface_traffic,
+ clear_ip_pim_interface_traffic_cmd,
+ "clear ip pim interface traffic",
+ "Reset functions\n"
+ "IP information\n"
+ "PIM clear commands\n"
+ "Reset PIM interfaces\n"
+ "Reset Protocol Packet counters\n")
+{
+ struct listnode *ifnode = NULL;
+ struct listnode *ifnextnode = NULL;
+ struct interface *ifp = NULL;
+ struct pim_interface *pim_ifp = NULL;
+
+ for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp))
+ {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ pim_ifp->pim_ifstat_hello_recv = 0;
+ pim_ifp->pim_ifstat_hello_sent = 0;
+ pim_ifp->pim_ifstat_join_recv = 0;
+ pim_ifp->pim_ifstat_join_send = 0;
+ pim_ifp->pim_ifstat_prune_recv = 0;
+ pim_ifp->pim_ifstat_prune_send = 0;
+ pim_ifp->pim_ifstat_reg_recv = 0;
+ pim_ifp->pim_ifstat_reg_send = 0;
+ pim_ifp->pim_ifstat_reg_stop_recv = 0;
+ pim_ifp->pim_ifstat_reg_stop_send = 0;
+ pim_ifp->pim_ifstat_assert_recv = 0;
+ pim_ifp->pim_ifstat_assert_send = 0;
+
+ }
+
+ return CMD_SUCCESS;
+}
+
DEFUN (clear_ip_pim_oil,
clear_ip_pim_oil_cmd,
"clear ip pim oil",
@@ -2880,7 +3078,7 @@ DEFUN (show_ip_pim_nexthop_lookup,
char nexthop_addr_str[PREFIX_STRLEN];
char grp_str[PREFIX_STRLEN];
- addr_str = (const char *)argv[0];
+ addr_str = argv[4]->arg;
result = inet_pton (AF_INET, addr_str, &src_addr);
if (result <= 0)
{
@@ -2895,7 +3093,7 @@ DEFUN (show_ip_pim_nexthop_lookup,
return CMD_WARNING;
}
- addr_str1 = (const char *)argv[1];
+ addr_str1 = argv[5]->arg;
result = inet_pton (AF_INET, addr_str1, &grp_addr);
if (result <= 0)
{
@@ -2939,6 +3137,28 @@ DEFUN (show_ip_pim_nexthop_lookup,
return CMD_SUCCESS;
}
+DEFUN (show_ip_pim_interface_traffic,
+ show_ip_pim_interface_traffic_cmd,
+ "show ip pim interface traffic [WORD] [json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ "PIM interface information\n"
+ "Protocol Packet counters\n"
+ "Interface name\n"
+ "JavaScript Object Notation\n")
+{
+ u_char uj = use_json (argc, argv);
+ int idx = 0;
+
+ if (argv_find(argv, argc, "WORD", &idx))
+ pim_show_interface_traffic_single (vty, argv[idx]->arg, uj);
+ else
+ pim_show_interface_traffic (vty, uj);
+
+ return CMD_SUCCESS;
+}
+
static void show_multicast_interfaces(struct vty *vty)
{
struct listnode *node;
@@ -3735,6 +3955,31 @@ DEFUN (no_ip_pim_packets,
return CMD_SUCCESS;
}
+DEFUN (ip_pim_v6_secondary,
+ ip_pim_v6_secondary_cmd,
+ "ip pim send-v6-secondary",
+ IP_STR
+ "pim multicast routing\n"
+ "Send v6 secondary addresses\n")
+{
+ pimg->send_v6_secondary = 1;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_v6_secondary,
+ no_ip_pim_v6_secondary_cmd,
+ "no ip pim send-v6-secondary",
+ NO_STR
+ IP_STR
+ "pim multicast routing\n"
+ "Send v6 secondary addresses\n")
+{
+ pimg->send_v6_secondary = 0;
+
+ return CMD_SUCCESS;
+}
+
DEFUN (ip_pim_rp,
ip_pim_rp_cmd,
"ip pim rp A.B.C.D [A.B.C.D/M]",
@@ -3803,12 +4048,12 @@ DEFUN (no_ip_pim_rp,
"ip address of RP\n"
"Group Address range to cover\n")
{
- int idx_ipv4 = 4;
+ int idx_ipv4 = 4, idx_group = 0;
- if (argc == (idx_ipv4 + 1))
- return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
+ if (argv_find (argv, argc, "A.B.C.D/M", &idx_group))
+ return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_group]->arg, NULL);
else
- return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+ return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
}
DEFUN (no_ip_pim_rp_prefix_list,
@@ -5075,11 +5320,16 @@ DEFUN (interface_ip_pim_hello,
pim_ifp = ifp->info;
- if (!pim_ifp) {
- vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (!pim_ifp)
+ {
+ if (!pim_cmd_interface_add(ifp))
+ {
+ vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ pim_ifp = ifp->info;
pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
if (argc == idx_hold + 1)
@@ -6457,13 +6707,16 @@ DEFUN (show_ip_msdp_sa_sg,
"JavaScript Object Notation\n")
{
u_char uj = use_json(argc, argv);
- if (uj)
- argc--;
- if (argc == 6)
- ip_msdp_show_sa_sg(vty, argv[4]->arg, argv[5]->arg, uj);
- else if (argc == 5)
- ip_msdp_show_sa_addr(vty, argv[4]->arg, uj);
+ int idx = 0;
+ char *src_ip = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg : NULL;
+ char *grp_ip = idx < argc && argv_find (argv, argc, "A.B.C.D", &idx) ?
+ argv[idx]->arg : NULL;
+
+ if (src_ip && grp_ip)
+ ip_msdp_show_sa_sg(vty, src_ip, grp_ip, uj);
+ else if (src_ip)
+ ip_msdp_show_sa_addr(vty, src_ip, uj);
else
ip_msdp_show_sa(vty, uj);
@@ -6499,6 +6752,8 @@ void pim_cmd_init()
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_pim_v6_secondary_cmd);
+ install_element (CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
@@ -6545,6 +6800,7 @@ void pim_cmd_init()
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_interface_traffic_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_local_membership_cmd);
@@ -6569,6 +6825,7 @@ void pim_cmd_init()
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_interface_traffic_cmd);
install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
install_element (ENABLE_NODE, &debug_igmp_cmd);
diff --git a/pimd/pim_cmd.h b/pimd/pim_cmd.h
index e08cefb29b..64751d8682 100644
--- a/pimd/pim_cmd.h
+++ b/pimd/pim_cmd.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_CMD_H
#define PIM_CMD_H
diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c
index 3d7ae4ad22..0c08cfa46d 100644
--- a/pimd/pim_hello.c
+++ b/pimd/pim_hello.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -428,15 +427,14 @@ int pim_hello_recv(struct interface *ifp,
return 0;
}
-int pim_hello_build_tlv(const char *ifname,
+int pim_hello_build_tlv(struct interface *ifp,
uint8_t *tlv_buf, int tlv_buf_size,
uint16_t holdtime,
uint32_t dr_priority,
uint32_t generation_id,
uint16_t propagation_delay,
uint16_t override_interval,
- int can_disable_join_suppression,
- struct list *ifconnected)
+ int can_disable_join_suppression)
{
uint8_t *curr = tlv_buf;
uint8_t *pastend = tlv_buf + tlv_buf_size;
@@ -454,7 +452,7 @@ int pim_hello_build_tlv(const char *ifname,
if (!curr) {
if (PIM_DEBUG_PIM_HELLO) {
zlog_debug("%s: could not set PIM hello Holdtime option for interface %s",
- __PRETTY_FUNCTION__, ifname);
+ __PRETTY_FUNCTION__, ifp->name);
}
return -1;
}
@@ -468,7 +466,7 @@ int pim_hello_build_tlv(const char *ifname,
if (!tmp) {
if (PIM_DEBUG_PIM_HELLO) {
zlog_debug("%s: could not set PIM LAN Prune Delay option for interface %s",
- __PRETTY_FUNCTION__, ifname);
+ __PRETTY_FUNCTION__, ifp->name);
}
return -1;
}
@@ -485,7 +483,7 @@ int pim_hello_build_tlv(const char *ifname,
if (!curr) {
if (PIM_DEBUG_PIM_HELLO) {
zlog_debug("%s: could not set PIM hello DR Priority option for interface %s",
- __PRETTY_FUNCTION__, ifname);
+ __PRETTY_FUNCTION__, ifp->name);
}
return -2;
}
@@ -498,23 +496,38 @@ int pim_hello_build_tlv(const char *ifname,
if (!curr) {
if (PIM_DEBUG_PIM_HELLO) {
zlog_debug("%s: could not set PIM hello Generation ID option for interface %s",
- __PRETTY_FUNCTION__, ifname);
+ __PRETTY_FUNCTION__, ifp->name);
}
return -3;
}
/* Secondary Address List */
- if (ifconnected) {
+ if (ifp->connected->count) {
curr = pim_tlv_append_addrlist_ucast(curr,
pastend,
- ifconnected);
+ ifp->connected,
+ AF_INET);
if (!curr) {
if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("%s: could not set PIM hello Secondary Address List option for interface %s",
- __PRETTY_FUNCTION__, ifname);
+ zlog_debug("%s: could not set PIM hello v4 Secondary Address List option for interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
}
return -4;
}
+ if (pimg->send_v6_secondary)
+ {
+ curr = pim_tlv_append_addrlist_ucast(curr,
+ pastend,
+ ifp->connected,
+ AF_INET6);
+ if (!curr) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug("%s: could not sent PIM hello v6 secondary Address List option for interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ return -4;
+ }
+ }
}
return curr - tlv_buf;
diff --git a/pimd/pim_hello.h b/pimd/pim_hello.h
index 3a6d3361ba..ff799b20f8 100644
--- a/pimd/pim_hello.h
+++ b/pimd/pim_hello.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_HELLO_H
#define PIM_HELLO_H
@@ -29,15 +28,14 @@ int pim_hello_recv(struct interface *ifp,
struct in_addr src_addr,
uint8_t *tlv_buf, int tlv_buf_size);
-int pim_hello_build_tlv(const char *ifname,
+int pim_hello_build_tlv(struct interface *ifp,
uint8_t *tlv_buf, int tlv_buf_size,
uint16_t holdtime,
uint32_t dr_priority,
uint32_t generation_id,
uint16_t propagation_delay,
uint16_t override_interval,
- int can_disable_join_suppression,
- struct list *ifconnected);
+ int can_disable_join_suppression);
void pim_hello_require(struct interface *ifp);
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index cce87ae5fd..f36a9b3cbb 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -1,21 +1,20 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ * 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>
@@ -61,7 +60,6 @@ pim_if_init (void)
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;
}
@@ -328,12 +326,29 @@ 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))
+ if (sec1->addr.family == AF_INET &&
+ sec2->addr.family == AF_INET6)
return -1;
- if (ntohl(sec1->addr.s_addr) > ntohl(sec2->addr.s_addr))
+ if (sec1->addr.family == AF_INET6 &&
+ sec2->addr.family == AF_INET)
return 1;
+ if (sec1->addr.family == AF_INET)
+ {
+ if (ntohl(sec1->addr.u.prefix4.s_addr) < ntohl(sec2->addr.u.prefix4.s_addr))
+ return -1;
+
+ if (ntohl(sec1->addr.u.prefix4.s_addr) > ntohl(sec2->addr.u.prefix4.s_addr))
+ return 1;
+ }
+ else
+ {
+ return memcmp (&sec1->addr.u.prefix6,
+ &sec2->addr.u.prefix6,
+ sizeof (struct in6_addr));
+ }
+
return 0;
}
@@ -343,7 +358,7 @@ static void pim_sec_addr_free(struct pim_secondary_addr *sec_addr)
}
static struct pim_secondary_addr *
-pim_sec_addr_find(struct pim_interface *pim_ifp, struct in_addr addr)
+pim_sec_addr_find(struct pim_interface *pim_ifp, struct prefix *addr)
{
struct pim_secondary_addr *sec_addr;
struct listnode *node;
@@ -353,7 +368,7 @@ pim_sec_addr_find(struct pim_interface *pim_ifp, struct in_addr addr)
}
for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
- if (sec_addr->addr.s_addr == addr.s_addr) {
+ if (prefix_cmp(&sec_addr->addr, addr)) {
return sec_addr;
}
}
@@ -368,7 +383,7 @@ static void pim_sec_addr_del(struct pim_interface *pim_ifp,
pim_sec_addr_free(sec_addr);
}
-static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct in_addr addr)
+static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct prefix *addr)
{
int changed = 0;
struct pim_secondary_addr *sec_addr;
@@ -395,7 +410,7 @@ static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct in_addr addr)
}
changed = 1;
- sec_addr->addr = addr;
+ sec_addr->addr = *addr;
listnode_add_sort(pim_ifp->sec_addr_list, sec_addr);
return changed;
@@ -437,10 +452,6 @@ static int pim_sec_addr_update(struct interface *ifp)
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;
}
@@ -450,7 +461,7 @@ static int pim_sec_addr_update(struct interface *ifp)
continue;
}
- if (pim_sec_addr_add(pim_ifp, p->u.prefix4)) {
+ if (pim_sec_addr_add(pim_ifp, p)) {
changed = 1;
}
}
@@ -575,12 +586,15 @@ void pim_if_addr_add(struct connected *ifc)
detect_address_change(ifp, 0, __PRETTY_FUNCTION__);
+ if (ifc->address->family != AF_INET)
+ return;
+
if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
struct igmp_sock *igmp;
/* lookup IGMP socket */
igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
- ifaddr);
+ ifaddr);
if (!igmp) {
/* if addr new, add IGMP socket */
pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, ifp);
@@ -727,14 +741,17 @@ void pim_if_addr_del(struct connected *ifc, int force_prim_as_any)
ifp = ifc->ifp;
zassert(ifp);
+ if (ifc->address->family != AF_INET)
+ return;
+
if (PIM_DEBUG_ZEBRA) {
char buf[BUFSIZ];
prefix2str(ifc->address, buf, BUFSIZ);
zlog_debug("%s: %s ifindex=%d disconnected IP address %s %s",
- __PRETTY_FUNCTION__,
- ifp->name, ifp->ifindex, buf,
- CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
- "secondary" : "primary");
+ __PRETTY_FUNCTION__,
+ ifp->name, ifp->ifindex, buf,
+ CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
+ "secondary" : "primary");
}
detect_address_change(ifp, force_prim_as_any, __PRETTY_FUNCTION__);
@@ -761,12 +778,9 @@ void pim_if_addr_add_all(struct interface *ifp)
struct prefix *p = ifc->address;
if (p->family != AF_INET)
- {
- v6_addrs++;
- continue;
- }
-
- v4_addrs++;
+ v6_addrs++;
+ else
+ v4_addrs++;
pim_if_addr_add(ifc);
}
@@ -1157,6 +1171,7 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
struct listnode *neighnode;
struct pim_neighbor *neigh;
struct pim_interface *pim_ifp;
+ struct prefix p;
zassert(ifp);
@@ -1168,6 +1183,10 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
return 0;
}
+ p.family = AF_INET;
+ p.u.prefix4 = addr;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
/* primary address ? */
@@ -1175,7 +1194,7 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
return neigh;
/* secondary address ? */
- if (pim_neighbor_find_secondary(neigh, addr))
+ if (pim_neighbor_find_secondary(neigh, &p))
return neigh;
}
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index e98c17fed2..fa623d45b4 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -1,21 +1,20 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_IFACE_H
@@ -64,7 +63,7 @@ enum pim_secondary_addr_flags {
};
struct pim_secondary_addr {
- struct in_addr addr;
+ struct prefix addr;
enum pim_secondary_addr_flags flags;
};
@@ -118,6 +117,16 @@ struct pim_interface {
uint32_t pim_ifstat_hello_sendfail;
uint32_t pim_ifstat_hello_recv;
uint32_t pim_ifstat_hello_recvfail;
+ uint32_t pim_ifstat_join_recv;
+ uint32_t pim_ifstat_join_send;
+ uint32_t pim_ifstat_prune_recv;
+ uint32_t pim_ifstat_prune_send;
+ uint32_t pim_ifstat_reg_recv;
+ uint32_t pim_ifstat_reg_send;
+ uint32_t pim_ifstat_reg_stop_recv;
+ uint32_t pim_ifstat_reg_stop_send;
+ uint32_t pim_ifstat_assert_recv;
+ uint32_t pim_ifstat_assert_send;
};
extern struct interface *pim_regiface;
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index f4fe609605..735df82581 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -148,7 +147,6 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
/* SGRpt entry could have empty oil */
if (ch->upstream->channel_oil)
pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
- 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.
@@ -179,6 +177,10 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
pim_upstream_update_join_desired(ch->upstream);
}
+ /* upstream is common across ifchannels, check if upstream's
+ ifchannel list is empty before deleting upstream_del
+ ref count will take care of it.
+ */
pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__);
ch->upstream = NULL;
@@ -200,6 +202,9 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
hash_release(pim_ifp->pim_ifchannel_hash, ch);
listnode_delete(pim_ifchannel_list, ch);
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug ("%s: ifchannel entry %s is deleted ", __PRETTY_FUNCTION__, ch->sg_str);
+
pim_ifchannel_free(ch);
}
@@ -571,14 +576,18 @@ pim_ifchannel_add(struct interface *ifp,
listnode_add_sort(up->ifchannels, ch);
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug ("%s: ifchannel %s is created ", __PRETTY_FUNCTION__, ch->sg_str);
+
return ch;
}
-static void ifjoin_to_noinfo(struct pim_ifchannel *ch)
+static void ifjoin_to_noinfo(struct pim_ifchannel *ch, bool ch_del)
{
pim_forward_stop(ch);
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
- delete_on_noinfo(ch);
+ if (ch_del)
+ delete_on_noinfo(ch);
}
static int on_ifjoin_expiry_timer(struct thread *t)
@@ -589,7 +598,7 @@ static int on_ifjoin_expiry_timer(struct thread *t)
ch->t_ifjoin_expiry_timer = NULL;
- ifjoin_to_noinfo(ch);
+ ifjoin_to_noinfo(ch, true);
/* ch may have been deleted */
return 0;
@@ -613,10 +622,6 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
pim_ifp = ifp->info;
send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
- //ch->ifjoin_state transition to NOINFO
- ifjoin_to_noinfo(ch);
- /* from here ch may have been deleted */
-
if (send_prune_echo)
{
struct pim_rpf rpf;
@@ -625,6 +630,23 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
rpf.rpf_addr.u.prefix4 = pim_ifp->primary_address;
pim_jp_agg_single_upstream_send(&rpf, ch->upstream, 0);
}
+ /* If SGRpt flag is set on ifchannel, Trigger SGRpt
+ message on RP path upon prune timer expiry.
+ */
+ if (PIM_IF_FLAG_TEST_S_G_RPT (ch->flags))
+ {
+ if (ch->upstream)
+ pim_upstream_update_join_desired(ch->upstream);
+ /*
+ ch->ifjoin_state transition to NOINFO state
+ ch_del is set to 0 for not deleteing from here.
+ Holdtime expiry (ch_del set to 1) delete the entry.
+ */
+ ifjoin_to_noinfo(ch, false);
+ }
+ else
+ ifjoin_to_noinfo(ch, true);
+ /* from here ch may have been deleted */
}
else
{
@@ -801,7 +823,7 @@ void pim_ifchannel_join_add(struct interface *ifp,
(ch->upstream->parent->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) &&
!(ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR))
{
- pim_upstream_ref (ch->upstream, PIM_UPSTREAM_FLAG_MASK_SRC_LHR);
+ pim_upstream_ref (ch->upstream, PIM_UPSTREAM_FLAG_MASK_SRC_LHR, __PRETTY_FUNCTION__);
pim_upstream_keep_alive_timer_start (ch->upstream, qpim_keep_alive_time);
}
break;
@@ -855,9 +877,8 @@ void pim_ifchannel_join_add(struct interface *ifp,
}
if (holdtime != 0xFFFF) {
- THREAD_TIMER_ON(master, ch->t_ifjoin_expiry_timer,
- on_ifjoin_expiry_timer,
- ch, holdtime);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
}
@@ -895,8 +916,10 @@ void pim_ifchannel_prune(struct interface *ifp,
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 (!(source_flags & PIM_ENCODE_WC_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
@@ -907,12 +930,11 @@ void pim_ifchannel_prune(struct interface *ifp,
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);
+ thread_add_timer_msec(master, on_ifjoin_prune_pending_timer, ch,
+ jp_override_interval_msec,
+ &ch->t_ifjoin_prune_pending_timer);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
pim_upstream_update_join_desired(ch->upstream);
}
break;
@@ -932,17 +954,16 @@ void pim_ifchannel_prune(struct interface *ifp,
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);
+ thread_add_timer_msec(master, on_ifjoin_prune_pending_timer, ch,
+ jp_override_interval_msec,
+ &ch->t_ifjoin_prune_pending_timer);
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);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
case PIM_IFJOIN_PRUNE_TMP:
@@ -950,9 +971,8 @@ void pim_ifchannel_prune(struct interface *ifp,
{
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);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
case PIM_IFJOIN_PRUNE_PENDING_TMP:
@@ -960,9 +980,8 @@ void pim_ifchannel_prune(struct interface *ifp,
{
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_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
}
@@ -1306,7 +1325,7 @@ pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t
if (up)
{
if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: del inherit oif from up %s", __PRETTY_FUNCTION__, up->sg_str);
+ zlog_debug ("%s: SGRpt Set, del inherit oif from up %s", __PRETTY_FUNCTION__, up->sg_str);
pim_channel_del_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
}
}
diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h
index 3ffb9190fb..e8c2ddd072 100644
--- a/pimd/pim_ifchannel.h
+++ b/pimd/pim_ifchannel.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_IFCHANNEL_H
#define PIM_IFCHANNEL_H
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index ee88e7d8ea..b9be8fc040 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -39,6 +38,7 @@
#include "pim_zebra.h"
static void group_timer_off(struct igmp_group *group);
+static int pim_igmp_general_query(struct thread *t);
/* This socket is used for TXing IGMP packets only, IGMP RX happens
* in pim_mroute_msg()
@@ -172,8 +172,11 @@ static int pim_igmp_other_querier_expire(struct thread *t)
/*
We are the current querier, then
re-start sending general queries.
+ RFC 2236 - sec 7 Other Querier
+ present timer expired (Send General
+ Query, Set Gen. Query. timer)
*/
- pim_igmp_general_query_on(igmp);
+ pim_igmp_general_query(t);
return 0;
}
@@ -247,9 +250,9 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
other_querier_present_interval_msec % 1000);
}
- THREAD_TIMER_MSEC_ON(master, igmp->t_other_querier_timer,
- pim_igmp_other_querier_expire,
- igmp, other_querier_present_interval_msec);
+ thread_add_timer_msec(master, pim_igmp_other_querier_expire, igmp,
+ other_querier_present_interval_msec,
+ &igmp->t_other_querier_timer);
}
void pim_igmp_other_querier_timer_off(struct igmp_sock *igmp)
@@ -497,8 +500,6 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
return -1;
}
-static int pim_igmp_general_query(struct thread *t);
-
void pim_igmp_general_query_on(struct igmp_sock *igmp)
{
struct pim_interface *pim_ifp;
@@ -551,9 +552,8 @@ void pim_igmp_general_query_on(struct igmp_sock *igmp)
igmp->fd);
}
igmp->t_igmp_query_timer = NULL;
- THREAD_TIMER_ON(master, igmp->t_igmp_query_timer,
- pim_igmp_general_query,
- igmp, query_interval);
+ thread_add_timer(master, pim_igmp_general_query, igmp, query_interval,
+ &igmp->t_igmp_query_timer);
}
void pim_igmp_general_query_off(struct igmp_sock *igmp)
@@ -896,7 +896,7 @@ igmp_read_on (struct igmp_sock *igmp)
igmp->fd);
}
igmp->t_igmp_read = NULL;
- THREAD_READ_ON(master, igmp->t_igmp_read, pim_igmp_read, igmp, igmp->fd);
+ thread_add_read(master, pim_igmp_read, igmp, igmp->fd, &igmp->t_igmp_read);
}
@@ -1029,9 +1029,8 @@ void igmp_group_timer_on(struct igmp_group *group,
*/
zassert(group->group_filtermode_isexcl);
- THREAD_TIMER_MSEC_ON(master, group->t_group_timer,
- igmp_group_timer,
- group, interval_msec);
+ thread_add_timer_msec(master, igmp_group_timer, group, interval_msec,
+ &group->t_group_timer);
}
struct igmp_group *
diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h
index 9c569bbd20..2f36094bd3 100644
--- a/pimd/pim_igmp.h
+++ b/pimd/pim_igmp.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_IGMP_H
#define PIM_IGMP_H
diff --git a/pimd/pim_igmp_join.h b/pimd/pim_igmp_join.h
index 228d30c5c4..31fc1b0471 100644
--- a/pimd/pim_igmp_join.h
+++ b/pimd/pim_igmp_join.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_IGMP_JOIN_H
#define PIM_IGMP_JOIN_H
diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c
index ee4aa7bd9d..d4b3010d3c 100644
--- a/pimd/pim_igmpv2.c
+++ b/pimd/pim_igmpv2.c
@@ -13,10 +13,9 @@
* 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
+ * 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"
diff --git a/pimd/pim_igmpv2.h b/pimd/pim_igmpv2.h
index 10a2477724..fa8d163944 100644
--- a/pimd/pim_igmpv2.h
+++ b/pimd/pim_igmpv2.h
@@ -13,10 +13,9 @@
* 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
+ * 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
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index 86509a20c4..51db9ac3b7 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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 "log.h"
@@ -215,9 +214,8 @@ static void igmp_source_timer_on(struct igmp_group *group,
group->group_igmp_sock->interface->name);
}
- THREAD_TIMER_MSEC_ON(master, source->t_source_timer,
- igmp_source_timer,
- source, interval_msec);
+ thread_add_timer_msec(master, igmp_source_timer, source, interval_msec,
+ &source->t_source_timer);
zassert(source->t_source_timer);
/*
@@ -1328,9 +1326,8 @@ static void group_retransmit_timer_on(struct igmp_group *group)
igmp->interface->name);
}
- THREAD_TIMER_MSEC_ON(master, group->t_group_query_retransmit_timer,
- igmp_group_retransmit,
- group, lmqi_msec);
+ thread_add_timer_msec(master, igmp_group_retransmit, group, lmqi_msec,
+ &group->t_group_query_retransmit_timer);
}
static long igmp_group_timer_remain_msec(struct igmp_group *group)
diff --git a/pimd/pim_igmpv3.h b/pimd/pim_igmpv3.h
index 3a4a81d97e..99f7b84b81 100644
--- a/pimd/pim_igmpv3.h
+++ b/pimd/pim_igmpv3.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_IGMPV3_H
#define PIM_IGMPV3_H
diff --git a/pimd/pim_int.c b/pimd/pim_int.c
index 44b8386a3d..577bf15c6a 100644
--- a/pimd/pim_int.c
+++ b/pimd/pim_int.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_int.h b/pimd/pim_int.h
index a6349b5b3d..54623ed218 100644
--- a/pimd/pim_int.h
+++ b/pimd/pim_int.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_INT_H
#define PIM_INT_H
diff --git a/pimd/pim_join.c b/pimd/pim_join.c
index 828781a467..5462dba61d 100644
--- a/pimd/pim_join.c
+++ b/pimd/pim_join.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -59,6 +58,8 @@ static void recv_join(struct interface *ifp,
struct prefix_sg *sg,
uint8_t source_flags)
{
+ struct pim_interface *pim_ifp = NULL;
+
if (PIM_DEBUG_PIM_TRACE) {
char up_str[INET_ADDRSTRLEN];
char neigh_str[INET_ADDRSTRLEN];
@@ -72,6 +73,11 @@ static void recv_join(struct interface *ifp,
up_str, holdtime, neigh_str, ifp->name);
}
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ ++pim_ifp->pim_ifstat_join_recv;
+
/*
* If the RPT and WC are set it's a (*,G)
* and the source is the RP
@@ -104,6 +110,8 @@ static void recv_prune(struct interface *ifp,
struct prefix_sg *sg,
uint8_t source_flags)
{
+ struct pim_interface *pim_ifp = NULL;
+
if (PIM_DEBUG_PIM_TRACE) {
char up_str[INET_ADDRSTRLEN];
char neigh_str[INET_ADDRSTRLEN];
@@ -117,6 +125,11 @@ static void recv_prune(struct interface *ifp,
up_str, holdtime, neigh_str, ifp->name);
}
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ ++pim_ifp->pim_ifstat_prune_recv;
+
if ((source_flags & PIM_RPT_BIT_MASK) &&
(source_flags & PIM_WILDCARD_BIT_MASK))
{
@@ -502,6 +515,9 @@ int pim_joinprune_send(struct pim_rpf *rpf,
packet_size += group_size;
pim_msg_build_jp_groups (grp, group, group_size);
+ pim_ifp->pim_ifstat_join_send += ntohs(grp->joins);
+ pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes);
+
grp = (struct pim_jp_groups *)curr_ptr;
if (packet_left < sizeof (struct pim_jp_groups) || msg->num_groups == 255)
{
diff --git a/pimd/pim_join.h b/pimd/pim_join.h
index adedde3cf8..6dc1b3e8f1 100644
--- a/pimd/pim_join.h
+++ b/pimd/pim_join.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_JOIN_H
#define PIM_JOIN_H
diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c
index 46c6cbc690..25530f40b9 100644
--- a/pimd/pim_jp_agg.c
+++ b/pimd/pim_jp_agg.c
@@ -13,10 +13,9 @@
* 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
+ * 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>
diff --git a/pimd/pim_jp_agg.h b/pimd/pim_jp_agg.h
index ad014d9520..c3955f32f4 100644
--- a/pimd/pim_jp_agg.h
+++ b/pimd/pim_jp_agg.h
@@ -13,10 +13,9 @@
* 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
+ * 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_JP_AGG_H__
#define __PIM_JP_AGG_H__
diff --git a/pimd/pim_macro.c b/pimd/pim_macro.c
index 127e0f6252..1f3b29554f 100644
--- a/pimd/pim_macro.c
+++ b/pimd/pim_macro.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_macro.h b/pimd/pim_macro.h
index 3079ca80cc..e07b2ece94 100644
--- a/pimd/pim_macro.h
+++ b/pimd/pim_macro.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_MACRO_H
#define PIM_MACRO_H
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index d814af6b2c..19dcd3aa9a 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_memory.c b/pimd/pim_memory.c
index ab92665b97..d18b7f0c8e 100644
--- a/pimd/pim_memory.c
+++ b/pimd/pim_memory.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
#ifdef HAVE_CONFIG_H
diff --git a/pimd/pim_memory.h b/pimd/pim_memory.h
index e366377c87..01189aca76 100644
--- a/pimd/pim_memory.h
+++ b/pimd/pim_memory.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_PIM_MEMORY_H
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index ce2f98f318..c3d68e24d4 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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 "log.h"
@@ -636,8 +635,8 @@ static void mroute_read_on()
{
zassert(!qpim_mroute_socket_reader);
- THREAD_READ_ON(master, qpim_mroute_socket_reader,
- mroute_read, 0, qpim_mroute_socket_fd);
+ thread_add_read(master, mroute_read, 0, qpim_mroute_socket_fd,
+ &qpim_mroute_socket_reader);
}
static void mroute_read_off()
diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h
index 3c15c800da..36dce8e610 100644
--- a/pimd/pim_mroute.h
+++ b/pimd/pim_mroute.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_MROUTE_H
#define PIM_MROUTE_H
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 93141f39de..001e080d5d 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -12,10 +12,9 @@
* 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
+ * 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>
@@ -82,8 +81,8 @@ 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);
+ thread_add_timer(msdp->master, pim_msdp_sa_adv_timer_cb, NULL,
+ PIM_MSDP_SA_ADVERTISMENT_TIME, &msdp->sa_adv_timer);
}
}
@@ -108,8 +107,8 @@ 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);
+ thread_add_timer(msdp->master, pim_msdp_sa_state_timer_cb, sa,
+ PIM_MSDP_SA_HOLD_TIME, &sa->sa_state_timer);
}
}
@@ -920,8 +919,8 @@ 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);
+ thread_add_timer(msdp->master, pim_msdp_peer_hold_timer_cb, mp,
+ PIM_MSDP_PEER_HOLD_TIME, &mp->hold_timer);
}
}
@@ -948,8 +947,8 @@ 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);
+ thread_add_timer(msdp->master, pim_msdp_peer_ka_timer_cb, mp,
+ PIM_MSDP_PEER_KA_TIME, &mp->ka_timer);
}
}
@@ -1013,8 +1012,8 @@ 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);
+ thread_add_timer(msdp->master, pim_msdp_peer_cr_timer_cb, mp,
+ PIM_MSDP_PEER_CONNECT_RETRY_TIME, &mp->cr_timer);
}
}
diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h
index 33c1d88a45..308b437a63 100644
--- a/pimd/pim_msdp.h
+++ b/pimd/pim_msdp.h
@@ -12,10 +12,9 @@
* 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
+ * 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
@@ -197,8 +196,11 @@ struct pim_msdp {
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_ON(mp) \
+ thread_add_read (msdp->master, pim_msdp_read, mp, mp->fd, &mp->t_read)
+
+#define PIM_MSDP_PEER_WRITE_ON(mp) \
+ thread_add_write (msdp->master, pim_msdp_write, mp, mp->fd, &mp->t_write)
#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)
diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c
index fbf34cd91c..0a8679336a 100644
--- a/pimd/pim_msdp_packet.c
+++ b/pimd/pim_msdp_packet.c
@@ -12,10 +12,9 @@
* 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
+ * 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>
diff --git a/pimd/pim_msdp_packet.h b/pimd/pim_msdp_packet.h
index f6fcfee6bb..aa42bbfe4b 100644
--- a/pimd/pim_msdp_packet.h
+++ b/pimd/pim_msdp_packet.h
@@ -12,10 +12,9 @@
* 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
+ * 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
diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c
index 805e812cae..9662f054e8 100644
--- a/pimd/pim_msdp_socket.c
+++ b/pimd/pim_msdp_socket.c
@@ -12,10 +12,9 @@
* 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
+ * 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>
@@ -70,8 +69,9 @@ pim_msdp_sock_accept(struct thread *thread)
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);
+ listener->thread = NULL;
+ thread_add_read(master, pim_msdp_sock_accept, listener, accept_sock,
+ &listener->thread);
/* accept client connection. */
msdp_sock = sockunion_accept(accept_sock, &su);
@@ -173,7 +173,9 @@ pim_msdp_sock_listen(void)
/* add accept thread */
listener->fd = sock;
memcpy(&listener->su, &sin, socklen);
- listener->thread = thread_add_read(msdp->master, pim_msdp_sock_accept, listener, sock);
+ listener->thread = NULL;
+ thread_add_read(msdp->master, pim_msdp_sock_accept, listener, sock,
+ &listener->thread);
msdp->flags |= PIM_MSDPF_LISTENER;
return 0;
diff --git a/pimd/pim_msdp_socket.h b/pimd/pim_msdp_socket.h
index bf3d12ad2c..0abcd57da0 100644
--- a/pimd/pim_msdp_socket.h
+++ b/pimd/pim_msdp_socket.h
@@ -12,10 +12,9 @@
* 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
+ * 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
diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c
index a9e0130905..e077a85168 100644
--- a/pimd/pim_msg.c
+++ b/pimd/pim_msg.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_msg.h b/pimd/pim_msg.h
index de663aa3b5..38ffaf6a7d 100644
--- a/pimd/pim_msg.h
+++ b/pimd/pim_msg.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_MSG_H
#define PIM_MSG_H
@@ -34,7 +33,11 @@
From:
http://www.iana.org/assignments/address-family-numbers
*/
-#define PIM_MSG_ADDRESS_FAMILY_IPV4 (1)
+enum pim_msg_address_family {
+ PIM_MSG_ADDRESS_FAMILY_RESERVED,
+ PIM_MSG_ADDRESS_FAMILY_IPV4,
+ PIM_MSG_ADDRESS_FAMILY_IPV6,
+};
/*
* Network Order pim_msg_hdr
diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c
index 181a71210c..00190bd830 100644
--- a/pimd/pim_neighbor.c
+++ b/pimd/pim_neighbor.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -262,9 +261,8 @@ void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime)
neigh->holdtime, src_str, neigh->interface->name);
}
- THREAD_TIMER_ON(master, neigh->t_expire_timer,
- on_neighbor_timer,
- neigh, neigh->holdtime);
+ thread_add_timer(master, on_neighbor_timer, neigh, neigh->holdtime,
+ &neigh->t_expire_timer);
}
static int
@@ -286,9 +284,8 @@ on_neighbor_jp_timer (struct thread *t)
rpf.rpf_addr.u.prefix4 = neigh->source_addr;
pim_joinprune_send(&rpf, neigh->upstream_jp_agg);
- THREAD_TIMER_ON(master, neigh->jp_timer,
- on_neighbor_jp_timer,
- neigh, qpim_t_periodic);
+ thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic,
+ &neigh->jp_timer);
return 0;
}
@@ -297,9 +294,8 @@ static void
pim_neighbor_start_jp_timer (struct pim_neighbor *neigh)
{
THREAD_TIMER_OFF(neigh->jp_timer);
- THREAD_TIMER_ON(master, neigh->jp_timer,
- on_neighbor_jp_timer,
- neigh, qpim_t_periodic);
+ thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic,
+ &neigh->jp_timer);
}
static struct pim_neighbor *pim_neighbor_new(struct interface *ifp,
@@ -423,6 +419,31 @@ void pim_neighbor_free(struct pim_neighbor *neigh)
XFREE(MTYPE_PIM_NEIGHBOR, neigh);
}
+struct pim_neighbor *
+pim_neighbor_find_by_secondary (struct interface *ifp,
+ struct prefix *src)
+{
+ struct pim_interface *pim_ifp;
+ struct listnode *node, *pnode;
+ struct pim_neighbor *neigh;
+ struct prefix *p;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh))
+ {
+ for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, pnode, p))
+ {
+ if (prefix_same (p, src))
+ return neigh;
+ }
+ }
+
+ return NULL;
+}
+
struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
struct in_addr source_addr)
{
@@ -686,7 +707,7 @@ void pim_neighbor_delete_all(struct interface *ifp,
}
struct prefix *pim_neighbor_find_secondary(struct pim_neighbor *neigh,
- struct in_addr addr)
+ struct prefix *addr)
{
struct listnode *node;
struct prefix *p;
@@ -695,14 +716,11 @@ struct prefix *pim_neighbor_find_secondary(struct pim_neighbor *neigh,
return 0;
for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, node, p)) {
- if (p->family == AF_INET) {
- if (addr.s_addr == p->u.prefix4.s_addr) {
- return p;
- }
- }
+ if (prefix_same (p, addr))
+ return p;
}
- return 0;
+ return NULL;
}
/*
@@ -746,7 +764,7 @@ static void delete_from_neigh_addr(struct interface *ifp,
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neigh_node,
neigh)) {
{
- struct prefix *p = pim_neighbor_find_secondary(neigh, addr->u.prefix4);
+ struct prefix *p = pim_neighbor_find_secondary(neigh, addr);
if (p) {
char addr_str[INET_ADDRSTRLEN];
char this_neigh_str[INET_ADDRSTRLEN];
diff --git a/pimd/pim_neighbor.h b/pimd/pim_neighbor.h
index 986721666e..a3d39d2622 100644
--- a/pimd/pim_neighbor.h
+++ b/pimd/pim_neighbor.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_NEIGHBOR_H
#define PIM_NEIGHBOR_H
@@ -50,7 +49,8 @@ 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_by_secondary (struct interface *ifp,
+ struct prefix *src);
struct pim_neighbor *pim_neighbor_find_if (struct interface *ifp);
@@ -77,7 +77,7 @@ void pim_neighbor_update(struct pim_neighbor *neigh,
uint32_t dr_priority,
struct list *addr_list);
struct prefix *pim_neighbor_find_secondary(struct pim_neighbor *neigh,
- struct in_addr addr);
+ struct prefix *addr);
int pim_if_dr_election(struct interface *ifp);
#endif /* PIM_NEIGHBOR_H */
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index c5f8d1d826..01ba2039fb 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -13,10 +13,9 @@
* 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
+ * 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 "network.h"
@@ -567,7 +566,7 @@ pim_ecmp_nexthop_search (struct pim_nexthop_cache *pnc,
//PIM ECMP flag is enable then choose ECMP path.
hash_val = pim_compute_ecmp_hash (src, grp);
mod_val = hash_val % pnc->nexthop_num;
- if (PIM_DEBUG_TRACE)
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: hash_val %u mod_val %u ",
__PRETTY_FUNCTION__, hash_val, mod_val);
}
@@ -914,7 +913,7 @@ pim_ecmp_nexthop_lookup (struct pim_nexthop *nexthop, struct in_addr addr,
{
hash_val = pim_compute_ecmp_hash (src, grp);
mod_val = hash_val % num_ifindex;
- if (PIM_DEBUG_TRACE)
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: hash_val %u mod_val %u",
__PRETTY_FUNCTION__, hash_val, mod_val);
}
@@ -1037,7 +1036,7 @@ int pim_ecmp_fib_lookup_if_vif_index(struct in_addr addr,
{
hash_val = pim_compute_ecmp_hash (src, grp);
mod_val = hash_val % num_ifindex;
- if (PIM_DEBUG_TRACE)
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug ("%s: hash_val %u mod_val %u",
__PRETTY_FUNCTION__, hash_val, mod_val);
}
diff --git a/pimd/pim_nht.h b/pimd/pim_nht.h
index 0ccc5399c3..6bd2249928 100644
--- a/pimd/pim_nht.h
+++ b/pimd/pim_nht.h
@@ -13,10 +13,9 @@
* 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
+ * 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_NHT_H
#define PIM_NHT_H
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index 7f5f3970ae..71ca576d93 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h
index a7bb23cd0e..02c7e740ef 100644
--- a/pimd/pim_oil.h
+++ b/pimd/pim_oil.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_OIL_H
#define PIM_OIL_H
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index b2f858b7d9..2a2f3060ab 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -383,8 +382,8 @@ static void pim_sock_read_on(struct interface *ifp)
pim_ifp->pim_sock_fd);
}
pim_ifp->t_pim_sock_read = NULL;
- THREAD_READ_ON(master, pim_ifp->t_pim_sock_read, pim_sock_read, ifp,
- pim_ifp->pim_sock_fd);
+ thread_add_read(master, pim_sock_read, ifp, pim_ifp->pim_sock_fd,
+ &pim_ifp->t_pim_sock_read);
}
static int pim_sock_open(struct interface *ifp)
@@ -627,7 +626,7 @@ static int hello_send(struct interface *ifp,
listcount(ifp->connected));
}
- pim_tlv_size = pim_hello_build_tlv(ifp->name,
+ pim_tlv_size = pim_hello_build_tlv(ifp,
pim_msg + PIM_PIM_MIN_LEN,
sizeof(pim_msg) - PIM_PIM_MIN_LEN,
holdtime,
@@ -635,8 +634,7 @@ static int hello_send(struct interface *ifp,
pim_ifp->pim_generation_id,
pim_ifp->pim_propagation_delay_msec,
pim_ifp->pim_override_interval_msec,
- PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options),
- ifp->connected);
+ PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options));
if (pim_tlv_size < 0) {
return -1;
}
@@ -704,9 +702,8 @@ static void hello_resched(struct interface *ifp)
pim_ifp->pim_hello_period, ifp->name);
}
THREAD_OFF(pim_ifp->t_pim_hello_timer);
- THREAD_TIMER_ON(master, pim_ifp->t_pim_hello_timer,
- on_pim_hello_send,
- ifp, pim_ifp->pim_hello_period);
+ thread_add_timer(master, on_pim_hello_send, ifp, pim_ifp->pim_hello_period,
+ &pim_ifp->t_pim_hello_timer);
}
/*
@@ -815,9 +812,8 @@ void pim_hello_restart_triggered(struct interface *ifp)
random_msec, ifp->name);
}
- THREAD_TIMER_MSEC_ON(master, pim_ifp->t_pim_hello_timer,
- on_pim_hello_send,
- ifp, random_msec);
+ thread_add_timer_msec(master, on_pim_hello_send, ifp, random_msec,
+ &pim_ifp->t_pim_hello_timer);
}
int pim_sock_add(struct interface *ifp)
diff --git a/pimd/pim_pim.h b/pimd/pim_pim.h
index 690b6c05cd..7e2872184a 100644
--- a/pimd/pim_pim.h
+++ b/pimd/pim_pim.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_PIM_H
#define PIM_PIM_H
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index 8dc179c144..682a6401ca 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -13,10 +13,9 @@
* 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
+ * 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>
@@ -110,6 +109,7 @@ pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg,
__PRETTY_FUNCTION__, ifp->name);
}
}
+ ++pinfo->pim_ifstat_reg_stop_send;
}
int
@@ -205,6 +205,8 @@ pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct
pim_msg_build_header(buffer, buf_size + PIM_MSG_REGISTER_LEN, PIM_MSG_TYPE_REGISTER);
+ ++pinfo->pim_ifstat_reg_send;
+
if (pim_msg_send(pinfo->pim_sock_fd,
src,
rpg->rpf_addr.u.prefix4,
@@ -274,6 +276,7 @@ pim_register_recv (struct interface *ifp,
struct prefix_sg sg;
uint32_t *bits;
int i_am_rp = 0;
+ struct pim_interface *pim_ifp = NULL;
#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
@@ -289,6 +292,10 @@ pim_register_recv (struct interface *ifp,
return 0;
}
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+ ++pim_ifp->pim_ifstat_reg_recv;
+
/*
* Please note this is not drawn to get the correct bit/data size
*
@@ -346,7 +353,7 @@ pim_register_recv (struct interface *ifp,
zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet",
__func__, "Sender");
/* Drop Packet Silently */
- return 1;
+ return 0;
}
}
@@ -408,5 +415,5 @@ pim_register_recv (struct interface *ifp,
pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
}
- return 1;
+ return 0;
}
diff --git a/pimd/pim_register.h b/pimd/pim_register.h
index 210a904ae9..adb703c611 100644
--- a/pimd/pim_register.h
+++ b/pimd/pim_register.h
@@ -13,10 +13,9 @@
* 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
+ * 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_REGISTER_H
#define PIM_REGISTER_H
diff --git a/pimd/pim_routemap.c b/pimd/pim_routemap.c
index a8525b690e..20c716c3e9 100644
--- a/pimd/pim_routemap.c
+++ b/pimd/pim_routemap.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 6c4504d9b0..d3d9beb053 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -12,11 +12,10 @@
* 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
+ *
+ * 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>
@@ -250,7 +249,7 @@ pim_rp_check_interface_addrs(struct rp_info *rp_info,
}
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) {
+ if (prefix_same(&sec_addr->addr, &rp_info->rp.rpf_addr)) {
return 1;
}
}
diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h
index df18c998d6..319fe573ca 100644
--- a/pimd/pim_rp.h
+++ b/pimd/pim_rp.h
@@ -12,11 +12,10 @@
* 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
+ *
+ * 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_RP_H
#define PIM_RP_H
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index f46ebfb979..3e72d8df21 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h
index 85fb1ed897..bb7ee365b1 100644
--- a/pimd/pim_rpf.h
+++ b/pimd/pim_rpf.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_RPF_H
#define PIM_RPF_H
diff --git a/pimd/pim_signals.c b/pimd/pim_signals.c
index 053ef6a67b..ef492d0d83 100644
--- a/pimd/pim_signals.c
+++ b/pimd/pim_signals.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_signals.h b/pimd/pim_signals.h
index d7a4926d4d..a82915691b 100644
--- a/pimd/pim_signals.h
+++ b/pimd/pim_signals.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_SIGNALS_H
#define PIM_SIGNALS_H
diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c
index 07b137bb51..ba70cf2e11 100644
--- a/pimd/pim_sock.c
+++ b/pimd/pim_sock.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_sock.h b/pimd/pim_sock.h
index b4ce901d10..9fb64677c8 100644
--- a/pimd/pim_sock.h
+++ b/pimd/pim_sock.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_SOCK_H
#define PIM_SOCK_H
diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c
index 41bf1e5668..d4f88ec2c1 100644
--- a/pimd/pim_ssm.c
+++ b/pimd/pim_ssm.c
@@ -12,10 +12,9 @@
* 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
+ * 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>
diff --git a/pimd/pim_ssm.h b/pimd/pim_ssm.h
index ca82d334f1..fe337be8f1 100644
--- a/pimd/pim_ssm.h
+++ b/pimd/pim_ssm.h
@@ -12,10 +12,9 @@
* 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
+ * 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_SSM_H
#define PIM_SSM_H
diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c
index 76b327ab07..1249e0ee57 100644
--- a/pimd/pim_ssmpingd.c
+++ b/pimd/pim_ssmpingd.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -331,8 +330,8 @@ static int ssmpingd_sock_read(struct thread *t)
static void ssmpingd_read_on(struct ssmpingd_sock *ss)
{
zassert(!ss->t_sock_read);
- THREAD_READ_ON(master, ss->t_sock_read,
- ssmpingd_sock_read, ss, ss->sock_fd);
+ thread_add_read(master, ssmpingd_sock_read, ss, ss->sock_fd,
+ &ss->t_sock_read);
}
static struct ssmpingd_sock *ssmpingd_new(struct in_addr source_addr)
diff --git a/pimd/pim_ssmpingd.h b/pimd/pim_ssmpingd.h
index 54f787e2a3..02aa6271ca 100644
--- a/pimd/pim_ssmpingd.h
+++ b/pimd/pim_ssmpingd.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_SSMPINGD_H
#define PIM_SSMPINGD_H
diff --git a/pimd/pim_static.c b/pimd/pim_static.c
index daaa95ab57..63762ef327 100644
--- a/pimd/pim_static.c
+++ b/pimd/pim_static.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga: add the ability to configure multicast static routes
- Copyright (C) 2014 Nathan Bahr, ATCorp
-
- 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
-*/
+ * PIM for Quagga: add the ability to configure multicast static routes
+ * Copyright (C) 2014 Nathan Bahr, ATCorp
+ *
+ * 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>
diff --git a/pimd/pim_static.h b/pimd/pim_static.h
index c288aa7ff4..4b5ef7921d 100644
--- a/pimd/pim_static.h
+++ b/pimd/pim_static.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga: add the ability to configure multicast static routes
- Copyright (C) 2014 Nathan Bahr, ATCorp
-
- 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
-*/
+ * PIM for Quagga: add the ability to configure multicast static routes
+ * Copyright (C) 2014 Nathan Bahr, ATCorp
+ *
+ * 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_STATIC_H_
#define PIM_STATIC_H_
diff --git a/pimd/pim_str.c b/pimd/pim_str.c
index 83f2a635b3..d1219a8681 100644
--- a/pimd/pim_str.c
+++ b/pimd/pim_str.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_str.h b/pimd/pim_str.h
index 97263e6a37..0ca517102a 100644
--- a/pimd/pim_str.h
+++ b/pimd/pim_str.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_STR_H
#define PIM_STR_H
diff --git a/pimd/pim_time.c b/pimd/pim_time.c
index 348793cd0b..406fec58d3 100644
--- a/pimd/pim_time.c
+++ b/pimd/pim_time.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_time.h b/pimd/pim_time.h
index de304a9f71..5d02d6efc4 100644
--- a/pimd/pim_time.h
+++ b/pimd/pim_time.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_TIME_H
#define PIM_TIME_H
diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c
index 5223f60e1b..550fdde8eb 100644
--- a/pimd/pim_tlv.c
+++ b/pimd/pim_tlv.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -94,6 +93,7 @@ uint8_t *pim_tlv_append_uint32(uint8_t *buf,
}
#define ucast_ipv4_encoding_len (2 + sizeof(struct in_addr))
+#define ucast_ipv6_encoding_len (2 + sizeof(struct in6_addr))
/*
* An Encoded-Unicast address takes the following format:
@@ -135,6 +135,14 @@ pim_encode_addr_ucast (uint8_t *buf, struct prefix *p)
memcpy (buf, &p->u.prefix4, sizeof (struct in_addr));
return ucast_ipv4_encoding_len;
break;
+ case AF_INET6:
+ *(uint8_t *)buf = PIM_MSG_ADDRESS_FAMILY_IPV6;
+ ++buf;
+ *(uint8_t *)buf = 0;
+ ++buf;
+ memcpy (buf, &p->u.prefix6, sizeof (struct in6_addr));
+ return ucast_ipv6_encoding_len;
+ break;
default:
return 0;
break;
@@ -216,12 +224,13 @@ pim_encode_addr_group (uint8_t *buf, afi_t afi, int bidir, int scope, struct in_
uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
const uint8_t *buf_pastend,
- struct list *ifconnected)
+ struct list *ifconnected,
+ int family)
{
struct listnode *node;
uint16_t option_len = 0;
-
uint8_t *curr;
+ size_t uel;
node = listhead(ifconnected);
@@ -230,8 +239,10 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
return buf;
}
- /* Skip first address (primary) */
- node = listnextnode(node);
+ if (family == AF_INET)
+ uel = ucast_ipv4_encoding_len;
+ else
+ uel = ucast_ipv6_encoding_len;
/* Scan secondary address list */
curr = buf + 4; /* skip T and L */
@@ -240,8 +251,14 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
struct prefix *p = ifc->address;
int l_encode;
- if ((curr + ucast_ipv4_encoding_len) > buf_pastend)
- return 0;
+ if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
+ continue;
+
+ if ((curr + uel) > buf_pastend)
+ return 0;
+
+ if (p->family != family)
+ continue;
l_encode = pim_encode_addr_ucast (curr, p);
curr += l_encode;
@@ -251,7 +268,7 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
if (PIM_DEBUG_PIM_TRACE_DETAIL) {
zlog_debug("%s: number of encoded secondary unicast IPv4 addresses: %zu",
__PRETTY_FUNCTION__,
- option_len / ucast_ipv4_encoding_len);
+ option_len / uel);
}
if (option_len < 1) {
@@ -491,10 +508,24 @@ pim_parse_addr_ucast (struct prefix *p,
p->family = AF_INET; /* notice: AF_INET != PIM_MSG_ADDRESS_FAMILY_IPV4 */
memcpy(&p->u.prefix4, addr, sizeof(struct in_addr));
-
+ p->prefixlen = IPV4_MAX_PREFIXLEN;
addr += sizeof(struct in_addr);
break;
+ case PIM_MSG_ADDRESS_FAMILY_IPV6:
+ if ((addr + sizeof(struct in6_addr)) > pastend) {
+ zlog_warn ("%s: IPv6 unicast address overflow: left=%zd needed %zu",
+ __PRETTY_FUNCTION__,
+ pastend - addr, sizeof(struct in6_addr));
+ return -3;
+ }
+
+ p->family = AF_INET6;
+ p->prefixlen = IPV6_MAX_PREFIXLEN;
+ memcpy(&p->u.prefix6, addr, sizeof(struct in6_addr));
+ addr += sizeof(struct in6_addr);
+
+ break;
default:
{
zlog_warn("%s: unknown unicast address encoding family=%d from",
@@ -706,6 +737,8 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
addr_str, src_str, ifname);
}
break;
+ case AF_INET6:
+ break;
default:
{
char src_str[INET_ADDRSTRLEN];
@@ -759,8 +792,7 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
FREE_ADDR_LIST(*hello_option_addr_list);
return -3;
}
- p->family = tmp.family;
- p->u.prefix4 = tmp.u.prefix4;
+ prefix_copy(p, &tmp);
listnode_add(*hello_option_addr_list, p);
}
diff --git a/pimd/pim_tlv.h b/pimd/pim_tlv.h
index 9c4ebc9f0f..f80e1fba27 100644
--- a/pimd/pim_tlv.h
+++ b/pimd/pim_tlv.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_TLV_H
#define PIM_TLV_H
@@ -80,7 +79,8 @@ uint8_t *pim_tlv_append_uint32(uint8_t *buf,
uint32_t option_value);
uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
const uint8_t *buf_pastend,
- struct list *ifconnected);
+ struct list *ifconnected,
+ int family);
int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index dd6eab9cfe..f949dd0257 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -78,9 +77,17 @@ pim_upstream_remove_children (struct pim_upstream *up)
while (!list_isempty (up->sources))
{
child = listnode_head (up->sources);
- child->parent = NULL;
listnode_delete (up->sources, child);
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
+ {
+ PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
+ child = pim_upstream_del(child, __PRETTY_FUNCTION__);
+ }
+ if (child)
+ child->parent = NULL;
}
+ list_delete(up->sources);
+ up->sources = NULL;
}
/*
@@ -149,10 +156,14 @@ void pim_upstream_free(struct pim_upstream *up)
static void upstream_channel_oil_detach(struct pim_upstream *up)
{
- if (up->channel_oil) {
- pim_channel_oil_del(up->channel_oil);
- up->channel_oil = NULL;
- }
+ if (up->channel_oil)
+ {
+ /* Detaching from channel_oil, channel_oil may exist post del,
+ but upstream would not keep reference of it
+ */
+ pim_channel_oil_del(up->channel_oil);
+ up->channel_oil = NULL;
+ }
}
struct pim_upstream *
@@ -163,7 +174,7 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
if (PIM_DEBUG_TRACE)
zlog_debug ("%s(%s): Delete %s ref count: %d , flags: %d c_oil ref count %d (Pre decrement)",
- __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count, up->flags,
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count, up->flags,
up->channel_oil->oil_ref_count);
--up->ref_count;
@@ -195,25 +206,11 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
}
pim_upstream_remove_children (up);
- pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__);
- upstream_channel_oil_detach(up);
-
if (up->sources)
- {
- struct listnode *node, *nnode;
- struct pim_upstream *child;
- for (ALL_LIST_ELEMENTS (up->sources, node, nnode, child))
- {
- if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
- {
- PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
- pim_upstream_del(child, __PRETTY_FUNCTION__);
- }
- }
-
- list_delete (up->sources);
- }
+ list_delete (up->sources);
up->sources = NULL;
+ pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__);
+ upstream_channel_oil_detach(up);
list_delete (up->ifchannels);
up->ifchannels = NULL;
@@ -223,11 +220,10 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
into pim_upstream_free() because the later is
called by list_delete_all_node()
*/
- if (up->parent)
- {
- listnode_delete (up->parent->sources, up);
- up->parent = NULL;
- }
+ if (up->parent && up->parent->sources)
+ listnode_delete (up->parent->sources, up);
+ up->parent = NULL;
+
listnode_delete (pim_upstream_list, up);
hash_release (pim_upstream_hash, up);
@@ -340,9 +336,8 @@ join_timer_start(struct pim_upstream *up)
else
{
THREAD_OFF (up->t_join_timer);
- THREAD_TIMER_ON(master, up->t_join_timer,
- on_join_timer,
- up, qpim_t_periodic);
+ thread_add_timer(master, on_join_timer, up, qpim_t_periodic,
+ &up->t_join_timer);
}
pim_jp_agg_upstream_verification (up, true);
}
@@ -371,9 +366,8 @@ static void pim_upstream_join_timer_restart_msec(struct pim_upstream *up,
}
THREAD_OFF(up->t_join_timer);
- THREAD_TIMER_MSEC_ON(master, up->t_join_timer,
- on_join_timer,
- up, interval_msec);
+ thread_add_timer_msec(master, on_join_timer, up, interval_msec,
+ &up->t_join_timer);
}
void pim_upstream_join_suppress(struct pim_upstream *up,
@@ -538,13 +532,14 @@ pim_upstream_switch(struct pim_upstream *up,
{
enum pim_upstream_state old_state = up->join_state;
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
+ if (PIM_DEBUG_PIM_EVENTS)
+ {
+ zlog_debug ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
__PRETTY_FUNCTION__,
up->sg_str,
pim_upstream_state2str (up->join_state),
pim_upstream_state2str (new_state));
- }
+ }
up->join_state = new_state;
if (old_state != new_state)
@@ -584,7 +579,17 @@ pim_upstream_switch(struct pim_upstream *up,
if (old_state == PIM_UPSTREAM_JOINED)
pim_msdp_up_join_state_changed(up);
- pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */);
+ /* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT */
+ if (pim_upstream_is_sg_rpt(up) && up->parent)
+ {
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug ("%s: *,G IIF %s S,G IIF %s ", __PRETTY_FUNCTION__,
+ up->parent->rpf.source_nexthop.interface->name,
+ up->rpf.source_nexthop.interface->name);
+ pim_jp_agg_single_upstream_send(&up->parent->rpf, up->parent, 1 /* (W,G) Join */);
+ }
+ else
+ pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */);
join_timer_stop(up);
}
}
@@ -717,9 +722,9 @@ pim_upstream_new (struct prefix_sg *sg,
if (PIM_DEBUG_TRACE)
{
- zlog_debug ("%s: Created Upstream %s upstream_addr %s",
+ zlog_debug ("%s: Created Upstream %s upstream_addr %s ref count %d increment",
__PRETTY_FUNCTION__, up->sg_str,
- inet_ntoa (up->upstream_addr));
+ inet_ntoa (up->upstream_addr), up->ref_count);
}
return up;
@@ -750,6 +755,9 @@ pim_upstream_find_or_add(struct prefix_sg *sg,
{
up->flags |= flags;
up->ref_count++;
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s(%s): upstream %s ref count %d increment",
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
}
}
else
@@ -759,10 +767,13 @@ pim_upstream_find_or_add(struct prefix_sg *sg,
}
void
-pim_upstream_ref(struct pim_upstream *up, int flags)
+pim_upstream_ref(struct pim_upstream *up, int flags, const char *name)
{
up->flags |= flags;
++up->ref_count;
+ if (PIM_DEBUG_TRACE)
+ zlog_debug ("%s(%s): upstream %s ref count %d increment",
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
}
struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
@@ -773,7 +784,7 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
int found = 0;
up = pim_upstream_find(sg);
if (up) {
- pim_upstream_ref(up, flags);
+ pim_upstream_ref(up, flags, name);
found = 1;
}
else {
@@ -786,10 +797,11 @@ struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
{
char buf[PREFIX2STR_BUFFER];
prefix2str (&up->rpf.rpf_addr, buf, sizeof (buf));
- zlog_debug("%s(%s): %s, iif %s found: %d: ref_count: %d",
+ zlog_debug("%s(%s): %s, iif %s (%s) found: %d: ref_count: %d",
__PRETTY_FUNCTION__, name,
- up->sg_str, buf, found,
- up->ref_count);
+ up->sg_str, buf, up->rpf.source_nexthop.interface ?
+ up->rpf.source_nexthop.interface->name : "NIL" ,
+ found, up->ref_count);
}
else
zlog_debug("%s(%s): (%s) failure to create",
@@ -1119,10 +1131,8 @@ pim_upstream_keep_alive_timer_start (struct pim_upstream *up,
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);
+ thread_add_timer(master, pim_upstream_keep_alive_timer, up, time,
+ &up->t_ka_timer);
/* any time keepalive is started against a SG we will have to
* re-evaluate our active source database */
@@ -1146,8 +1156,8 @@ 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);
+ thread_add_timer(master, pim_upstream_msdp_reg_timer, up,
+ PIM_MSDP_REG_RXED_PERIOD, &up->t_msdp_reg_timer);
pim_msdp_sa_local_update(up);
}
@@ -1408,9 +1418,8 @@ pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_regist
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);
+ thread_add_timer(master, pim_upstream_register_stop_timer, up, time,
+ &up->t_rs_timer);
}
int
@@ -1660,7 +1669,7 @@ pim_upstream_sg_running (void *arg)
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_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, __PRETTY_FUNCTION__);
PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
pim_upstream_fhr_kat_start(up);
}
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index f1c8df35b1..87b45059f3 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_UPSTREAM_H
#define PIM_UPSTREAM_H
@@ -145,7 +144,7 @@ struct pim_upstream *pim_upstream_find_or_add (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_ref (struct pim_upstream *up, int flags);
+void pim_upstream_ref (struct pim_upstream *up, int flags, const char *name);
struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name);
int pim_upstream_evaluate_join_desired(struct pim_upstream *up);
diff --git a/pimd/pim_util.c b/pimd/pim_util.c
index 1125db00a9..139c0e3fb1 100644
--- a/pimd/pim_util.c
+++ b/pimd/pim_util.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_util.h b/pimd/pim_util.h
index 94635466d9..4788005206 100644
--- a/pimd/pim_util.h
+++ b/pimd/pim_util.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_UTIL_H
#define PIM_UTIL_H
diff --git a/pimd/pim_version.c b/pimd/pim_version.c
index a43c27d5b5..1da4b9663f 100644
--- a/pimd/pim_version.c
+++ b/pimd/pim_version.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pimd/pim_version.h b/pimd/pim_version.h
index 64e07862d6..589c6f68a5 100644
--- a/pimd/pim_version.h
+++ b/pimd/pim_version.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_VERSION_H
#define PIM_VERSION_H
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index 754cf8468b..9cf5c30469 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -150,6 +149,12 @@ int pim_global_config_write(struct vty *vty)
writes += pim_msdp_config_write (vty);
+ if (!pimg->send_v6_secondary)
+ {
+ vty_out (vty, "no ip pim send-v6-secondary%s", VTY_NEWLINE);
+ ++writes;
+ }
+
writes += pim_rp_config_write (vty);
if (qpim_register_suppress_time != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT)
@@ -289,7 +294,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, " ip igpm query-max-response-time %d%s",
+ vty_out(vty, " ip igmp query-max-response-time %d%s",
pim_ifp->igmp_query_max_response_time_dsec,
VTY_NEWLINE);
++writes;
diff --git a/pimd/pim_vty.h b/pimd/pim_vty.h
index 18a632e016..54bab623dc 100644
--- a/pimd/pim_vty.h
+++ b/pimd/pim_vty.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_VTY_H
#define PIM_VTY_H
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index baf296623f..4506e8cdb5 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -257,31 +256,11 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
#endif
}
- 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 */
struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
- if (primary_addr.s_addr != p->u.prefix4.s_addr) {
+ if (p->family != AF_INET || primary_addr.s_addr != p->u.prefix4.s_addr) {
if (PIM_DEBUG_ZEBRA) {
/* but we had a primary address already */
@@ -637,9 +616,9 @@ void sched_rpf_cache_refresh(void)
qpim_rpf_cache_refresh_delay_msec);
}
- THREAD_TIMER_MSEC_ON(master, qpim_rpf_cache_refresher,
- on_rpf_cache_refresh,
- 0, qpim_rpf_cache_refresh_delay_msec);
+ thread_add_timer_msec(master, on_rpf_cache_refresh, 0,
+ qpim_rpf_cache_refresh_delay_msec,
+ &qpim_rpf_cache_refresher);
}
static void
diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h
index 2ed463efaa..37024073ea 100644
--- a/pimd/pim_zebra.h
+++ b/pimd/pim_zebra.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_ZEBRA_H
#define PIM_ZEBRA_H
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index f77990ab5a..9c26745e77 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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 "zebra/rib.h"
@@ -77,9 +76,8 @@ static void zclient_lookup_sched(struct zclient *zlookup, int delay)
{
zassert(!zlookup->t_connect);
- THREAD_TIMER_ON(master, zlookup->t_connect,
- zclient_lookup_connect,
- zlookup, delay);
+ thread_add_timer(master, zclient_lookup_connect, zlookup, delay,
+ &zlookup->t_connect);
zlog_notice("%s: zclient lookup connection scheduled for %d seconds",
__PRETTY_FUNCTION__, delay);
@@ -89,9 +87,8 @@ static void zclient_lookup_sched(struct zclient *zlookup, int delay)
static void zclient_lookup_sched_now(struct zclient *zlookup)
{
zassert(!zlookup->t_connect);
-
- zlookup->t_connect = thread_add_event(master, zclient_lookup_connect,
- zlookup, 0);
+ thread_add_event(master, zclient_lookup_connect, zlookup, 0,
+ &zlookup->t_connect);
zlog_notice("%s: zclient lookup immediate connection scheduled",
__PRETTY_FUNCTION__);
@@ -222,6 +219,7 @@ static int zclient_read_nexthop(struct zclient *zlookup,
for (i = 0; i < nexthop_num; ++i) {
enum nexthop_types_t nexthop_type;
struct pim_neighbor *nbr;
+ struct prefix p;
nexthop_type = stream_getc(s);
if (num_ifindex >= tab_size) {
@@ -251,9 +249,24 @@ static int zclient_read_nexthop(struct zclient *zlookup,
break;
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);
+ stream_get (&nexthop_tab[num_ifindex].nexthop_addr.u.prefix6,
+ s,
+ sizeof(struct in6_addr));
nexthop_tab[num_ifindex].ifindex = stream_getl (s);
- nbr = pim_neighbor_find_if (if_lookup_by_index (nexthop_tab[num_ifindex].ifindex, VRF_DEFAULT));
+
+ p.family = AF_INET6;
+ p.prefixlen = IPV6_MAX_PREFIXLEN;
+ memcpy (&p.u.prefix6,
+ &nexthop_tab[num_ifindex].nexthop_addr.u.prefix6,
+ sizeof(struct in6_addr));
+
+ /*
+ * If we are sending v6 secondary assume we receive v6 secondary
+ */
+ if (pimg->send_v6_secondary)
+ nbr = pim_neighbor_find_by_secondary(if_lookup_by_index (nexthop_tab[num_ifindex].ifindex, VRF_DEFAULT), &p);
+ else
+ nbr = pim_neighbor_find_if (if_lookup_by_index (nexthop_tab[num_ifindex].ifindex, VRF_DEFAULT));
if (nbr)
{
nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
diff --git a/pimd/pim_zlookup.h b/pimd/pim_zlookup.h
index 34b1434c66..08c8768d14 100644
--- a/pimd/pim_zlookup.h
+++ b/pimd/pim_zlookup.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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_ZLOOKUP_H
#define PIM_ZLOOKUP_H
diff --git a/pimd/pimd.c b/pimd/pimd.c
index 749f1e2b0d..8aab5d2ef7 100644
--- a/pimd/pimd.c
+++ b/pimd/pimd.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
@@ -117,7 +116,10 @@ pim_vrf_enable (struct vrf *vrf)
* We will crash and burn otherwise
*/
exit(1);
- }
+ }
+
+ pimg->send_v6_secondary = 1;
+
}
return 0;
}
@@ -138,22 +140,15 @@ pim_vrf_disable (struct vrf *vrf)
void
pim_vrf_init (void)
{
- vrf_add_hook (VRF_NEW_HOOK, pim_vrf_new);
- vrf_add_hook (VRF_ENABLE_HOOK, pim_vrf_enable);
- vrf_add_hook (VRF_DISABLE_HOOK, pim_vrf_disable);
- vrf_add_hook (VRF_DELETE_HOOK, pim_vrf_delete);
-
- vrf_init ();
+ vrf_init (pim_vrf_new,
+ pim_vrf_enable,
+ pim_vrf_disable,
+ pim_vrf_delete);
}
static void
pim_vrf_terminate (void)
{
- vrf_add_hook (VRF_NEW_HOOK, NULL);
- vrf_add_hook (VRF_ENABLE_HOOK, NULL);
- vrf_add_hook (VRF_DISABLE_HOOK, NULL);
- vrf_add_hook (VRF_DELETE_HOOK, NULL);
-
vrf_terminate ();
}
diff --git a/pimd/pimd.h b/pimd/pimd.h
index 693cce7e9f..ec98c5bfd1 100644
--- a/pimd/pimd.h
+++ b/pimd/pimd.h
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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 PIMD_H
#define PIMD_H
@@ -257,7 +256,10 @@ struct pim_instance
} spt;
struct hash *rpf_hash;
+
void *ssm_info; /* per-vrf SSM configuration */
+
+ int send_v6_secondary;
};
extern struct pim_instance *pimg; //Pim Global Instance
diff --git a/pimd/test_igmpv3_join.c b/pimd/test_igmpv3_join.c
index 29143f362e..f363152ad4 100644
--- a/pimd/test_igmpv3_join.c
+++ b/pimd/test_igmpv3_join.c
@@ -1,22 +1,21 @@
/*
- PIM for Quagga
- Copyright (C) 2008 Everton da Silva Marques
-
- 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
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008 Everton da Silva Marques
+ *
+ * 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>
diff --git a/pkgsrc/eigrpd.sh.in b/pkgsrc/eigrpd.sh.in
new file mode 100644
index 0000000000..b28b81eeda
--- /dev/null
+++ b/pkgsrc/eigrpd.sh.in
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# eigrpd is part of the quagga routing beast
+#
+# PROVIDE: eigrpd
+# REQUIRE: zebra
+##
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:@prefix@/sbin:@prefix@/bin
+export PATH
+
+if [ -f /etc/rc.subr ]
+then
+ . /etc/rc.subr
+fi
+
+name="eigrpd"
+rcvar=$name
+required_files="@sysconfdir@/${name}.conf"
+command="@prefix@/sbin/${name}"
+command_args="-d"
+
+start_precmd="zebra_precmd"
+socket_dir=@localstatedir@
+pidfile="${socket_dir}/${name}.pid"
+
+zebra_precmd()
+{
+ rc_flags="$(
+ set -- $rc_flags
+ while [ $# -ne 0 ]; do
+ if [ X"$1" = X-P -o X"$1" = X-A ]; then
+ break
+ fi
+ shift
+ done
+ if [ $# -eq 0 ]; then
+ echo "-P 0"
+ fi
+ ) $rc_flags"
+}
+
+load_rc_config $name
+run_rc_command "$1"
diff --git a/qpb/linear_allocator.h b/qpb/linear_allocator.h
index e3ebbc64f3..273bc7369d 100644
--- a/qpb/linear_allocator.h
+++ b/qpb/linear_allocator.h
@@ -17,10 +17,9 @@
* 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.
+ * 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
*/
/*
diff --git a/qpb/qpb.c b/qpb/qpb.c
index 1b2b47fce5..9c47a80d28 100644
--- a/qpb/qpb.c
+++ b/qpb/qpb.c
@@ -17,10 +17,9 @@
* 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.
+ * 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
*/
/*
diff --git a/qpb/qpb.h b/qpb/qpb.h
index ad5bdc8b8e..f5d00900f7 100644
--- a/qpb/qpb.h
+++ b/qpb/qpb.h
@@ -17,10 +17,9 @@
* 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.
+ * 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
*/
/*
diff --git a/qpb/qpb_allocator.c b/qpb/qpb_allocator.c
index 4b4830a476..ae48d55891 100644
--- a/qpb/qpb_allocator.c
+++ b/qpb/qpb_allocator.c
@@ -17,10 +17,9 @@
* 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.
+ * 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 "linear_allocator.h"
diff --git a/qpb/qpb_allocator.h b/qpb/qpb_allocator.h
index bb7dcf38f3..bdf2dc0e7f 100644
--- a/qpb/qpb_allocator.h
+++ b/qpb/qpb_allocator.h
@@ -17,10 +17,9 @@
* 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.
+ * 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
*/
/*
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index c32e3e3af8..aef7a7cd2a 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -34,7 +34,7 @@
%define zeb_rh_src %{zeb_src}/redhat
%define zeb_docs %{zeb_src}/doc
%define frr_tools %{zeb_src}/tools
-%define cumulus_dir %{zeb_src}/cumulus/etc
+%define frr_tools_etc %{frr_tools}/etc
# defines for configure
%define _localstatedir /var/run/frr
@@ -291,9 +291,9 @@ for daemon in %{all_daemons} ; do
done
%endif
-install %{cumulus_dir}/frr/debian.conf %{buildroot}/etc/frr
-install %{cumulus_dir}/frr/daemons %{buildroot}/etc/frr
-install -m644 %{cumulus_dir}/default/frr %{buildroot}/etc/default
+install %{frr_tools_dir}/frr/daemons.conf %{buildroot}/etc/frr
+install %{frr_tools_dir}/frr/daemons %{buildroot}/etc/frr
+install -m644 %{frr_tools_dir}/default/frr %{buildroot}/etc/default
install -m644 %{zeb_rh_src}/frr.pam \
%{buildroot}/etc/pam.d/frr
install -m644 %{zeb_rh_src}/frr.logrotate \
diff --git a/ripd/rip_debug.c b/ripd/rip_debug.c
index fbf2262b8c..35d5d9b825 100644
--- a/ripd/rip_debug.c
+++ b/ripd/rip_debug.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ripd/rip_debug.h b/ripd/rip_debug.h
index 990ec908a8..e1dcd2fa7a 100644
--- a/ripd/rip_debug.h
+++ b/ripd/rip_debug.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_RIP_DEBUG_H
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index a4ee2ba570..fce5d97dc2 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -1011,9 +1010,8 @@ rip_enable_apply (struct interface *ifp)
zlog_debug ("turn on %s", ifp->name);
/* Add interface wake up thread. */
- if (! ri->t_wakeup)
- ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
- ifp, 1);
+ thread_add_timer(master, rip_interface_wakeup, ifp, 1,
+ &ri->t_wakeup);
rip_connect_set (ifp, 1);
}
}
diff --git a/ripd/rip_interface.h b/ripd/rip_interface.h
index d9dfbb7cc3..9513bafc22 100644
--- a/ripd/rip_interface.h
+++ b/ripd/rip_interface.h
@@ -12,10 +12,9 @@
* 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.
+ * 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 _QUAGGA_RIP_INTERFACE_H
diff --git a/ripd/rip_main.c b/ripd/rip_main.c
index 62ea6dd078..38c2875949 100644
--- a/ripd/rip_main.c
+++ b/ripd/rip_main.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -178,7 +177,7 @@ main (int argc, char **argv)
/* Library initialization. */
keychain_init ();
- vrf_init ();
+ vrf_init (NULL, NULL, NULL, NULL);
/* RIP related initialization. */
rip_init ();
diff --git a/ripd/rip_memory.c b/ripd/rip_memory.c
index d2a958064f..662a6ccedd 100644
--- a/ripd/rip_memory.c
+++ b/ripd/rip_memory.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
#ifdef HAVE_CONFIG_H
diff --git a/ripd/rip_memory.h b/ripd/rip_memory.h
index 7aec219305..57abedd3aa 100644
--- a/ripd/rip_memory.h
+++ b/ripd/rip_memory.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_RIP_MEMORY_H
diff --git a/ripd/rip_offset.c b/ripd/rip_offset.c
index 5e0e71579a..76f3cec66d 100644
--- a/ripd/rip_offset.c
+++ b/ripd/rip_offset.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ripd/rip_peer.c b/ripd/rip_peer.c
index 6a3add640a..464c3f4dd3 100644
--- a/ripd/rip_peer.c
+++ b/ripd/rip_peer.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -107,8 +106,9 @@ rip_peer_get (struct in_addr *addr)
}
/* Update timeout thread. */
- peer->t_timeout = thread_add_timer (master, rip_peer_timeout, peer,
- RIP_PEER_TIMER_DEFAULT);
+ peer->t_timeout = NULL;
+ thread_add_timer(master, rip_peer_timeout, peer, RIP_PEER_TIMER_DEFAULT,
+ &peer->t_timeout);
/* Last update time set. */
time (&peer->uptime);
diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c
index baba9592e0..3f1495c0f0 100644
--- a/ripd/rip_routemap.c
+++ b/ripd/rip_routemap.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ripd/rip_snmp.c b/ripd/rip_snmp.c
index 06cd3cef6c..6a4ae11ae1 100644
--- a/ripd/rip_snmp.c
+++ b/ripd/rip_snmp.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index 578c513c78..3b3fc9494c 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 9e8c21da31..58c8aed130 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -2624,8 +2623,9 @@ rip_triggered_update (struct thread *t)
update is triggered when the timer expires. */
interval = (random () % 5) + 1;
- rip->t_triggered_interval =
- thread_add_timer (master, rip_triggered_interval, NULL, interval);
+ rip->t_triggered_interval = NULL;
+ thread_add_timer(master, rip_triggered_interval, NULL, interval,
+ &rip->t_triggered_interval);
return 0;
}
@@ -2780,21 +2780,20 @@ rip_event (enum rip_event event, int sock)
switch (event)
{
case RIP_READ:
- rip->t_read = thread_add_read (master, rip_read, NULL, sock);
+ rip->t_read = NULL;
+ thread_add_read(master, rip_read, NULL, sock, &rip->t_read);
break;
case RIP_UPDATE_EVENT:
RIP_TIMER_OFF (rip->t_update);
jitter = rip_update_jitter (rip->update_time);
- rip->t_update =
- thread_add_timer (master, rip_update, NULL,
- sock ? 2 : rip->update_time + jitter);
+ thread_add_timer(master, rip_update, NULL, sock ? 2 : rip->update_time + jitter,
+ &rip->t_update);
break;
case RIP_TRIGGERED_UPDATE:
if (rip->t_triggered_interval)
- rip->trigger = 1;
- else if (! rip->t_triggered_update)
- rip->t_triggered_update =
- thread_add_event (master, rip_triggered_update, NULL, 0);
+ rip->trigger = 1;
+ else thread_add_event(master, rip_triggered_update, NULL, 0,
+ &rip->t_triggered_update);
break;
default:
break;
diff --git a/ripd/ripd.h b/ripd/ripd.h
index eeb008e3d5..d52df0d992 100644
--- a/ripd/ripd.h
+++ b/ripd/ripd.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_RIP_H
@@ -371,11 +370,7 @@ enum rip_event
};
/* Macro for timer turn on. */
-#define RIP_TIMER_ON(T,F,V) \
- do { \
- if (!(T)) \
- (T) = thread_add_timer (master, (F), rinfo, (V)); \
- } while (0)
+#define RIP_TIMER_ON(T,F,V) thread_add_timer (master, (F), rinfo, (V), &(T))
/* Macro for timer turn off. */
#define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X)
diff --git a/ripngd/ripng_debug.c b/ripngd/ripng_debug.c
index 16c8b3400d..372ab85e67 100644
--- a/ripngd/ripng_debug.c
+++ b/ripngd/ripng_debug.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ripngd/ripng_debug.h b/ripngd/ripng_debug.h
index 674345c0b9..b4e1455ad7 100644
--- a/ripngd/ripng_debug.h
+++ b/ripngd/ripng_debug.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_RIPNG_DEBUG_H
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index 1ac9e40f67..81b68ad9d7 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -761,9 +760,8 @@ ripng_enable_apply (struct interface *ifp)
zlog_debug ("RIPng turn on %s", ifp->name);
/* Add interface wake up thread. */
- if (! ri->t_wakeup)
- ri->t_wakeup = thread_add_timer (master, ripng_interface_wakeup,
- ifp, 1);
+ thread_add_timer(master, ripng_interface_wakeup, ifp, 1,
+ &ri->t_wakeup);
ripng_connect_set (ifp, 1);
}
diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c
index 9d97df5c41..e517817147 100644
--- a/ripngd/ripng_main.c
+++ b/ripngd/ripng_main.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -178,7 +177,7 @@ main (int argc, char **argv)
master = frr_init ();
/* Library inits. */
- vrf_init ();
+ vrf_init (NULL, NULL, NULL, NULL);
/* RIPngd inits. */
ripng_init ();
diff --git a/ripngd/ripng_memory.c b/ripngd/ripng_memory.c
index 1d2320ee26..60fb1751d7 100644
--- a/ripngd/ripng_memory.c
+++ b/ripngd/ripng_memory.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
#ifdef HAVE_CONFIG_H
diff --git a/ripngd/ripng_memory.h b/ripngd/ripng_memory.h
index 76b830afb4..a4102086c7 100644
--- a/ripngd/ripng_memory.h
+++ b/ripngd/ripng_memory.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_RIPNG_MEMORY_H
diff --git a/ripngd/ripng_nexthop.c b/ripngd/ripng_nexthop.c
index b966af001e..0af636efcb 100644
--- a/ripngd/ripng_nexthop.c
+++ b/ripngd/ripng_nexthop.c
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/* This file is required in order to support properly the RIPng nexthop
diff --git a/ripngd/ripng_nexthop.h b/ripngd/ripng_nexthop.h
index 19bd32b503..76873f80eb 100644
--- a/ripngd/ripng_nexthop.h
+++ b/ripngd/ripng_nexthop.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_RIPNG_RIPNG_NEXTHOP_H
diff --git a/ripngd/ripng_offset.c b/ripngd/ripng_offset.c
index dcddf96ebf..adb3182a5b 100644
--- a/ripngd/ripng_offset.c
+++ b/ripngd/ripng_offset.c
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/* RIPng support by Vincent Jardin <vincent.jardin@6wind.com>
diff --git a/ripngd/ripng_peer.c b/ripngd/ripng_peer.c
index b12e146041..461ee98bb7 100644
--- a/ripngd/ripng_peer.c
+++ b/ripngd/ripng_peer.c
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/* RIPng support added by Vincent Jardin <vincent.jardin@6wind.com>
@@ -115,8 +114,9 @@ ripng_peer_get (struct in6_addr *addr)
}
/* Update timeout thread. */
- peer->t_timeout = thread_add_timer (master, ripng_peer_timeout, peer,
- RIPNG_PEER_TIMER_DEFAULT);
+ peer->t_timeout = NULL;
+ thread_add_timer(master, ripng_peer_timeout, peer, RIPNG_PEER_TIMER_DEFAULT,
+ &peer->t_timeout);
/* Last update time set. */
time (&peer->uptime);
diff --git a/ripngd/ripng_route.c b/ripngd/ripng_route.c
index 8538b07a98..f7d3ef89f4 100644
--- a/ripngd/ripng_route.c
+++ b/ripngd/ripng_route.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ripngd/ripng_route.h b/ripngd/ripng_route.h
index 9ff90aa8d0..90dae04700 100644
--- a/ripngd/ripng_route.h
+++ b/ripngd/ripng_route.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_RIPNG_ROUTE_H
diff --git a/ripngd/ripng_routemap.c b/ripngd/ripng_routemap.c
index ad8dbc92f3..69ff84b220 100644
--- a/ripngd/ripng_routemap.c
+++ b/ripngd/ripng_routemap.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index 964af81d1f..e7f1e9e157 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index 8ea66517c3..a58b7c250d 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -1539,8 +1538,9 @@ ripng_triggered_update (struct thread *t)
update is triggered when the timer expires. */
interval = (random () % 5) + 1;
- ripng->t_triggered_interval =
- thread_add_timer (master, ripng_triggered_interval, NULL, interval);
+ ripng->t_triggered_interval = NULL;
+ thread_add_timer(master, ripng_triggered_interval, NULL, interval,
+ &ripng->t_triggered_interval);
return 0;
}
@@ -1898,8 +1898,7 @@ ripng_event (enum ripng_event event, int sock)
switch (event)
{
case RIPNG_READ:
- if (!ripng->t_read)
- ripng->t_read = thread_add_read (master, ripng_read, NULL, sock);
+ thread_add_read(master, ripng_read, NULL, sock, &ripng->t_read);
break;
case RIPNG_UPDATE_EVENT:
if (ripng->t_update)
@@ -1910,16 +1909,15 @@ ripng_event (enum ripng_event event, int sock)
/* Update timer jitter. */
jitter = ripng_update_jitter (ripng->update_time);
- ripng->t_update =
- thread_add_timer (master, ripng_update, NULL,
- sock ? 2 : ripng->update_time + jitter);
+ ripng->t_update = NULL;
+ thread_add_timer(master, ripng_update, NULL, sock ? 2 : ripng->update_time + jitter,
+ &ripng->t_update);
break;
case RIPNG_TRIGGERED_UPDATE:
if (ripng->t_triggered_interval)
ripng->trigger = 1;
- else if (! ripng->t_triggered_update)
- ripng->t_triggered_update =
- thread_add_event (master, ripng_triggered_update, NULL, 0);
+ else thread_add_event(master, ripng_triggered_update, NULL, 0,
+ &ripng->t_triggered_update);
break;
default:
break;
diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h
index 70cba3c680..62b7b073f8 100644
--- a/ripngd/ripngd.h
+++ b/ripngd/ripngd.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_RIPNG_RIPNGD_H
@@ -324,11 +323,7 @@ enum ripng_event
};
/* RIPng timer on/off macro. */
-#define RIPNG_TIMER_ON(T,F,V) \
-do { \
- if (!(T)) \
- (T) = thread_add_timer (master, (F), rinfo, (V)); \
-} while (0)
+#define RIPNG_TIMER_ON(T,F,V) thread_add_timer (master, (F), rinfo, (V), &(T))
#define RIPNG_TIMER_OFF(T) \
do { \
diff --git a/tests/bgpd/test_aspath.c b/tests/bgpd/test_aspath.c
index e5ff6a1377..2d83fe6828 100644
--- a/tests/bgpd/test_aspath.c
+++ b/tests/bgpd/test_aspath.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/tests/bgpd/test_capability.c b/tests/bgpd/test_capability.c
index c3de6a16e8..1e3a5be4e3 100644
--- a/tests/bgpd/test_capability.c
+++ b/tests/bgpd/test_capability.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -651,7 +650,7 @@ main (void)
qobj_init ();
master = thread_master_create ();
bgp_master_init (master);
- vrf_init ();
+ vrf_init (NULL, NULL, NULL, NULL);
bgp_option_set (BGP_OPT_NO_LISTEN);
if (fileno (stdout) >= 0)
diff --git a/tests/bgpd/test_ecommunity.c b/tests/bgpd/test_ecommunity.c
index 9174191cb3..564d471296 100644
--- a/tests/bgpd/test_ecommunity.c
+++ b/tests/bgpd/test_ecommunity.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/tests/bgpd/test_mp_attr.c b/tests/bgpd/test_mp_attr.c
index 6824c11fea..e323748e97 100644
--- a/tests/bgpd/test_mp_attr.c
+++ b/tests/bgpd/test_mp_attr.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -751,7 +750,7 @@ main (void)
qobj_init ();
master = thread_master_create ();
bgp_master_init (master);
- vrf_init ();
+ vrf_init (NULL, NULL, NULL, NULL);
bgp_option_set (BGP_OPT_NO_LISTEN);
bgp_attr_init ();
diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c
index a2fd66528c..affebbafea 100644
--- a/tests/bgpd/test_mpath.c
+++ b/tests/bgpd/test_mpath.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -380,7 +379,7 @@ global_test_init (void)
master = thread_master_create ();
zclient = zclient_new(master);
bgp_master_init (master);
- vrf_init ();
+ vrf_init (NULL, NULL, NULL, NULL);
bgp_option_set (BGP_OPT_NO_LISTEN);
if (fileno (stdout) >= 0)
diff --git a/tests/helpers/c/main.c b/tests/helpers/c/main.c
index b3e6e706ff..b0e80fb674 100644
--- a/tests/helpers/c/main.c
+++ b/tests/helpers/c/main.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -59,14 +58,14 @@ test_timer (struct thread *thread)
int *count = THREAD_ARG(thread);
printf ("run %d of timer\n", (*count)++);
- thread_add_timer (master, test_timer, count, 5);
+ thread_add_timer(master, test_timer, count, 5, NULL);
return 0;
}
static void
test_timer_init()
{
- thread_add_timer (master, test_timer, &timer_count, 10);
+ thread_add_timer(master, test_timer, &timer_count, 10, NULL);
}
static void
diff --git a/tests/helpers/c/prng.c b/tests/helpers/c/prng.c
index bdcfb07af1..4b9fd57159 100644
--- a/tests/helpers/c/prng.c
+++ b/tests/helpers/c/prng.c
@@ -17,10 +17,9 @@
* 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.
+ * 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>
diff --git a/tests/helpers/c/prng.h b/tests/helpers/c/prng.h
index cf0bacc5f8..6cc6289a1e 100644
--- a/tests/helpers/c/prng.h
+++ b/tests/helpers/c/prng.h
@@ -17,10 +17,9 @@
* 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.
+ * 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 _PRNG_H
#define _PRNG_H
diff --git a/tests/helpers/c/tests.h b/tests/helpers/c/tests.h
index a528e55f05..aaf35c27d2 100644
--- a/tests/helpers/c/tests.h
+++ b/tests/helpers/c/tests.h
@@ -16,10 +16,9 @@
* 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.
+ * 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 _QUAGGA_TESTS_H
diff --git a/tests/helpers/python/frrtest.py b/tests/helpers/python/frrtest.py
index a7ef1c56b7..da9e447fc0 100644
--- a/tests/helpers/python/frrtest.py
+++ b/tests/helpers/python/frrtest.py
@@ -87,7 +87,8 @@ class _TestMultiOut(object):
def _add_test(cls, method, *args, **kwargs):
if 'tests' not in dir(cls):
setattr(cls,'tests',[])
- cls._add_test(cls._exit_cleanly)
+ if method is not cls._exit_cleanly:
+ cls._add_test(cls._exit_cleanly)
def matchfunction(self):
method(self, *args, **kwargs)
diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c
index 56db460438..7825564e54 100644
--- a/tests/lib/cli/common_cli.c
+++ b/tests/lib/cli/common_cli.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/cli/common_cli.h b/tests/lib/cli/common_cli.h
index 9e7fe99830..9a0ef47c83 100644
--- a/tests/lib/cli/common_cli.h
+++ b/tests/lib/cli/common_cli.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _COMMON_CLI_H
diff --git a/tests/lib/cli/test_cli.c b/tests/lib/cli/test_cli.c
index 54b34bc799..ba1218120c 100644
--- a/tests/lib/cli/test_cli.c
+++ b/tests/lib/cli/test_cli.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/cli/test_cli.refout.in b/tests/lib/cli/test_cli.refout.in
index 18822c150d..db9da429ab 100644
--- a/tests/lib/cli/test_cli.refout.in
+++ b/tests/lib/cli/test_cli.refout.in
@@ -61,7 +61,7 @@ cmd2 with 3 args.
[01]: ipv6
[02]: de4d:b33f::cafe
test# arg ipv6 de4d:b3
-% There is no matched command.
+ X:X::X:X 02
test# arg ipv6 de4d:b33f::caf
X:X::X:X 02
test# arg ipv6 de4d:b33f::cafe
@@ -264,7 +264,8 @@ cmd10 with 3 args.
test#
test# alt a
test# alt a a
- WORD 02
+ WORD 02
+ X:X::X:X 02
test# alt a ab
cmd11 with 3 args.
[00]: alt
@@ -281,7 +282,8 @@ cmd12 with 3 args.
[02]: 1.2.3.4
test# alt a 1
test# alt a 1:2
- WORD 02
+ WORD 02
+ X:X::X:X 02
test# alt a 1:2
test# alt a 1:2::
WORD 02
diff --git a/tests/lib/cli/test_commands.c b/tests/lib/cli/test_commands.c
index 272e3d12b7..249a6f760e 100644
--- a/tests/lib/cli/test_commands.c
+++ b/tests/lib/cli/test_commands.c
@@ -21,10 +21,9 @@
* 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.
+ * 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
*/
#define REALLY_NEED_PLAIN_GETOPT 1
diff --git a/tests/lib/test_buffer.c b/tests/lib/test_buffer.c
index 67e4035806..b9f5fd7252 100644
--- a/tests/lib/test_buffer.c
+++ b/tests/lib/test_buffer.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_checksum.c b/tests/lib/test_checksum.c
index 53ab260e26..267a057ccf 100644
--- a/tests/lib/test_checksum.c
+++ b/tests/lib/test_checksum.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_heavy.c b/tests/lib/test_heavy.c
index 6ba8d9aa6d..1ba7b9a204 100644
--- a/tests/lib/test_heavy.c
+++ b/tests/lib/test_heavy.c
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/* This programme shows the effects of 'heavy' long-running functions
diff --git a/tests/lib/test_heavy_thread.c b/tests/lib/test_heavy_thread.c
index c43fa76c0e..3b85619d3a 100644
--- a/tests/lib/test_heavy_thread.c
+++ b/tests/lib/test_heavy_thread.c
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/* This programme shows the effects of 'heavy' long-running functions
@@ -91,7 +90,7 @@ clear_something (struct thread *thread)
ws->i++;
if (thread_should_yield(thread))
{
- thread_add_background(master, clear_something, ws, 0);
+ thread_add_background(master, clear_something, ws, 0, NULL);
return 0;
}
}
@@ -135,7 +134,7 @@ DEFUN (clear_foo,
ws->vty = vty;
ws->i = ITERS_FIRST;
- thread_add_background(master, clear_something, ws, 0);
+ thread_add_background(master, clear_something, ws, 0, NULL);
return CMD_SUCCESS;
}
diff --git a/tests/lib/test_heavy_wq.c b/tests/lib/test_heavy_wq.c
index 97371face1..57e206931b 100644
--- a/tests/lib/test_heavy_wq.c
+++ b/tests/lib/test_heavy_wq.c
@@ -11,10 +11,9 @@
* 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.
+ * 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
*/
/* This programme shows the effects of 'heavy' long-running functions
diff --git a/tests/lib/test_memory.c b/tests/lib/test_memory.c
index 6849b9dceb..633ee0d562 100644
--- a/tests/lib/test_memory.c
+++ b/tests/lib/test_memory.c
@@ -11,10 +11,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_nexthop_iter.c b/tests/lib/test_nexthop_iter.c
index 250379329b..77515386c7 100644
--- a/tests/lib/test_nexthop_iter.c
+++ b/tests/lib/test_nexthop_iter.c
@@ -17,10 +17,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_privs.c b/tests/lib/test_privs.c
index c6ccc28e7a..26f3b5f693 100644
--- a/tests/lib/test_privs.c
+++ b/tests/lib/test_privs.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_segv.c b/tests/lib/test_segv.c
index dfc9d5f482..c43431622d 100644
--- a/tests/lib/test_segv.c
+++ b/tests/lib/test_segv.c
@@ -18,10 +18,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_sig.c b/tests/lib/test_sig.c
index 10bce2303e..a04c9f4206 100644
--- a/tests/lib/test_sig.c
+++ b/tests/lib/test_sig.c
@@ -11,10 +11,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_srcdest_table.c b/tests/lib/test_srcdest_table.c
index cfc2deb8d6..07f60668e7 100644
--- a/tests/lib/test_srcdest_table.c
+++ b/tests/lib/test_srcdest_table.c
@@ -16,10 +16,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_stream.c b/tests/lib/test_stream.c
index 3ac45eb203..596b73afc3 100644
--- a/tests/lib/test_stream.c
+++ b/tests/lib/test_stream.c
@@ -1,5 +1,5 @@
/* Simple stream test.
- *
+ *
* Copyright (C) 2006 Sun Microsystems, Inc.
*
* This file is part of Quagga.
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_table.c b/tests/lib/test_table.c
index 4042e1aaa2..8c98bc948c 100644
--- a/tests/lib/test_table.c
+++ b/tests/lib/test_table.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/tests/lib/test_timer_correctness.c b/tests/lib/test_timer_correctness.c
index e523929be1..10461be1ef 100644
--- a/tests/lib/test_timer_correctness.c
+++ b/tests/lib/test_timer_correctness.c
@@ -17,10 +17,9 @@
* 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.
+ * 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>
@@ -139,7 +138,9 @@ int main(int argc, char **argv)
/* Schedule timers to expire in 0..5 seconds */
interval_msec = prng_rand(prng) % 5000;
arg = XMALLOC(MTYPE_TMP, TIMESTR_LEN + 1);
- timers[i] = thread_add_timer_msec(master, timer_func, arg, interval_msec);
+ timers[i] = NULL;
+ thread_add_timer_msec(master, timer_func, arg, interval_msec,
+ &timers[i]);
ret = snprintf(arg, TIMESTR_LEN + 1, "%lld.%06lld",
(long long)timers[i]->u.sands.tv_sec,
(long long)timers[i]->u.sands.tv_usec);
diff --git a/tests/lib/test_timer_performance.c b/tests/lib/test_timer_performance.c
index a7d09beecc..b67af19aea 100644
--- a/tests/lib/test_timer_performance.c
+++ b/tests/lib/test_timer_performance.c
@@ -17,10 +17,9 @@
* 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.
+ * 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>
@@ -56,8 +55,10 @@ int main(int argc, char **argv)
/* create thread structures so they won't be allocated during the
* time measurement */
- for (i = 0; i < SCHEDULE_TIMERS; i++)
- timers[i] = thread_add_timer_msec(master, dummy_func, NULL, 0);
+ for (i = 0; i < SCHEDULE_TIMERS; i++) {
+ timers[i] = NULL;
+ thread_add_timer_msec(master, dummy_func, NULL, 0, &timers[i]);
+ }
for (i = 0; i < SCHEDULE_TIMERS; i++)
thread_cancel(timers[i]);
@@ -68,8 +69,9 @@ int main(int argc, char **argv)
long interval_msec;
interval_msec = prng_rand(prng) % (100 * SCHEDULE_TIMERS);
- timers[i] = thread_add_timer_msec(master, dummy_func,
- NULL, interval_msec);
+ timers[i] = NULL;
+ thread_add_timer_msec(master, dummy_func, NULL, interval_msec,
+ &timers[i]);
}
monotime(&tv_lap);
diff --git a/tests/test_lblmgr.c b/tests/test_lblmgr.c
index 4a4aaa0014..d830094bad 100644
--- a/tests/test_lblmgr.c
+++ b/tests/test_lblmgr.c
@@ -16,10 +16,9 @@
* 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.
+ * 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 "lib/stream.h"
diff --git a/tools/.gitignore b/tools/.gitignore
index 066b0887ae..2e3b89cc26 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -5,4 +5,5 @@
*.loT
.libs
*.o
-permutations
+/permutations
+/ssd
diff --git a/tools/Makefile.am b/tools/Makefile.am
index b2d56170c1..de81919cdd 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -4,6 +4,8 @@ AM_CFLAGS = $(WERROR)
EXTRA_DIST =
bin_PROGRAMS = permutations
+sbin_PROGRAMS = ssd
+
permutations_SOURCES = permutations.c
permutations_LDADD = ../lib/libfrr.la
@@ -12,3 +14,5 @@ sbin_SCRIPTS = frr-reload.py frr
EXTRA_DIST += frr.service frr-reload.py frr
EXTRA_DIST += xml2cli.pl
+
+ssd_SOURCES = start-stop-daemon.c
diff --git a/tools/cocci.h b/tools/cocci.h
index 3d877a7b4b..50199fa829 100644
--- a/tools/cocci.h
+++ b/tools/cocci.h
@@ -1,4 +1,5 @@
-/* some of this stuff doesn't seem to parse properly in coccinelle */
+/* some of this stuff doesn't seem to parse properly in coccinelle
+ */
#define DEFUN(funcname, cmdname, str, help) \
static int funcname \
diff --git a/cumulus/etc/default/frr b/tools/etc/default/frr
index ae960b9e19..693fa63390 100644
--- a/cumulus/etc/default/frr
+++ b/tools/etc/default/frr
@@ -7,3 +7,4 @@ OSPF6D_OPTIONS="-A ::1"
RIPD_OPTIONS="-A 127.0.0.1"
RIPNGD_OPTIONS="-A ::1"
ISISD_OPTIONS="-A 127.0.0.1"
+EIGRP_OPTIONS="-A 127.0.0.1"
diff --git a/cumulus/etc/frr/daemons b/tools/etc/frr/daemons
index 17dfc92ec4..eb7a5c9a96 100644
--- a/cumulus/etc/frr/daemons
+++ b/tools/etc/frr/daemons
@@ -19,7 +19,7 @@
# group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
#
# The watchfrr daemon is always started. Per default in monitoring-only but
-# that can be changed via /etc/frr/debian.conf.
+# that can be changed via /etc/frr/daemons.conf.
#
zebra=no
bgpd=no
@@ -31,3 +31,4 @@ isisd=no
pimd=no
ldpd=no
nhrpd=no
+eigrpd=no
diff --git a/cumulus/etc/frr/debian.conf b/tools/etc/frr/daemons.conf
index eed8379e8c..21ae29d4c0 100644
--- a/cumulus/etc/frr/debian.conf
+++ b/tools/etc/frr/daemons.conf
@@ -14,7 +14,13 @@ isisd_options=" --daemon -A 127.0.0.1"
pimd_options=" --daemon -A 127.0.0.1"
ldpd_options=" --daemon -A 127.0.0.1"
nhrpd_options=" --daemon -A 127.0.0.1"
+eigrpd_options=" --daemon -A 127.0.0.1"
# The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes
watchfrr_options=(-adz -r /usr/sbin/servicebBfrrbBrestartbB%s -s /usr/sbin/servicebBfrrbBstartbB%s -k /usr/sbin/servicebBfrrbBstopbB%s -b bB -t 30)
+
+# If valgrind_enable is 'yes' the frr daemons will be started via valgrind.
+# The use case for doing so is tracking down memory leaks, etc in frr.
+valgrind_enable=no
+valgrind=/usr/bin/valgrind
diff --git a/cumulus/etc/frr/frr.conf b/tools/etc/frr/frr.conf
index 2cd05bf803..2cd05bf803 100644
--- a/cumulus/etc/frr/frr.conf
+++ b/tools/etc/frr/frr.conf
diff --git a/cumulus/etc/frr/vtysh.conf b/tools/etc/frr/vtysh.conf
index 80ceb00891..80ceb00891 100644
--- a/cumulus/etc/frr/vtysh.conf
+++ b/tools/etc/frr/vtysh.conf
diff --git a/tools/etc/iproute2/rt_protos.d/frr.conf b/tools/etc/iproute2/rt_protos.d/frr.conf
new file mode 100644
index 0000000000..3f55b11268
--- /dev/null
+++ b/tools/etc/iproute2/rt_protos.d/frr.conf
@@ -0,0 +1,8 @@
+# Additional protocol strings defined by frr for each of its daemons
+
+186 bgp
+187 isis
+188 ospf
+189 rip
+190 ripng
+191 static
diff --git a/tools/frr b/tools/frr
index 80dd9e8747..0bea3ee81d 100755
--- a/tools/frr
+++ b/tools/frr
@@ -21,7 +21,7 @@ V_PATH=/var/run/frr
# Local Daemon selection may be done by using /etc/frr/daemons.
# See /usr/share/doc/frr/README.Debian.gz for further information.
# Keep zebra first and do not list watchfrr!
-DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd"
+DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd"
MAX_INSTANCES=5
RELOAD_SCRIPT=/usr/lib/frr/frr-reload.py
@@ -150,12 +150,21 @@ start()
return;
fi
- ${SSD} \
+ if [ "$valgrind_enable" = "yes" ]; then
+ ${SSD} \
+ --start \
+ --pidfile=`pidfile $1` \
+ --exec "$valgrind" \
+ -- --trace-children=no --leak-check=full --log-file=/var/log/frr/$1-valgrind.log $D_PATH/$1 \
+ `eval echo "$""$1""_options"`
+ else
+ ${SSD} \
--start \
--pidfile=`pidfile $1` \
--exec "$D_PATH/$1" \
-- \
`eval echo "$""$1""_options"`
+ fi
fi
}
@@ -476,7 +485,7 @@ check_status()
# Load configuration
. "$C_PATH/daemons"
-. "$C_PATH/debian.conf"
+. "$C_PATH/daemons.conf"
# Read configuration variable file if it is present
[ -r /etc/default/frr ] && . /etc/default/frr
@@ -532,8 +541,15 @@ case "$1" in
fi
if [ -z "$dmn" -o "$dmn" = "zebra" ]; then
- echo "Removing all routes made by zebra."
+ echo "Removing all routes made by FRR."
+ ip route flush proto bgp
+ ip route flush proto ospf
+ ip route flush proto static
+ ip route flush proto rip
+ ip route flush proto ripng
ip route flush proto zebra
+ ip route flush proto isis
+
else
[ -n "$dmn" ] && eval "${dmn/-/_}=0"
start_watchfrr
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index c91392da15..a7a04be639 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -109,9 +109,12 @@ class Config(object):
log.info('Loading Config object from file %s', filename)
try:
- file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename])
+ file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename],
+ stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
- raise VtyshMarkException(str(e))
+ ve = VtyshMarkException(e)
+ ve.output = e.output
+ raise ve
for line in file_output.split('\n'):
line = line.strip()
@@ -134,9 +137,11 @@ class Config(object):
try:
config_text = subprocess.check_output(
"/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -",
- shell=True)
+ shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
- raise VtyshMarkException(str(e))
+ ve = VtyshMarkException(e)
+ ve.output = e.output
+ raise ve
for line in config_text.split('\n'):
line = line.strip()
@@ -342,10 +347,12 @@ end
# the keywords that we know are single line contexts. bgp in this case
# is not the main router bgp block, but enabling multi-instance
oneline_ctx_keywords = ("access-list ",
+ "agentx",
"bgp ",
"debug ",
"dump ",
"enable ",
+ "frr ",
"hostname ",
"ip ",
"ipv6 ",
@@ -815,6 +822,14 @@ def compare_context_objects(newconf, running):
elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd:
continue
+ elif ("router bgp" in running_ctx_keys[0] and
+ len(running_ctx_keys) > 1 and
+ running_ctx_keys[1].startswith('address-family')):
+ # There's no 'no address-family' support and so we have to
+ # delete each line individually again
+ for line in running_ctx.lines:
+ lines_to_del.append((running_ctx_keys, line))
+
# Non-global context
elif running_ctx_keys and not any("address-family" in key for key in running_ctx_keys):
lines_to_del.append((running_ctx_keys, None))
@@ -890,11 +905,15 @@ if __name__ == '__main__':
# Verify the new config file is valid
if not os.path.isfile(args.filename):
- print "Filename %s does not exist" % args.filename
+ msg = "Filename %s does not exist" % args.filename
+ print msg
+ log.error(msg)
sys.exit(1)
if not os.path.getsize(args.filename):
- print "Filename %s is an empty file" % args.filename
+ msg = "Filename %s is an empty file" % args.filename
+ print msg
+ log.error(msg)
sys.exit(1)
# Verify that 'service integrated-vtysh-config' is configured
@@ -911,7 +930,9 @@ if __name__ == '__main__':
break
if not service_integrated_vtysh_config:
- print "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'"
+ msg = "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'"
+ print msg
+ log.error(msg)
sys.exit(1)
if args.debug:
@@ -922,6 +943,7 @@ if __name__ == '__main__':
# Create a Config object from the config generated by newconf
newconf = Config()
newconf.load_from_file(args.filename)
+ reload_ok = True
if args.test:
@@ -1064,7 +1086,7 @@ if __name__ == '__main__':
# 'no ip ospf authentication message-digest 1.1.1.1' in
# our example above
# - Split that last entry by whitespace and drop the last word
- log.warning('Failed to execute %s', ' '.join(cmd))
+ log.info('Failed to execute %s', ' '.join(cmd))
last_arg = cmd[-1].split(' ')
if len(last_arg) <= 2:
@@ -1099,9 +1121,25 @@ if __name__ == '__main__':
with open(filename, 'w') as fh:
for line in lines_to_configure:
fh.write(line + '\n')
- subprocess.call(['/usr/bin/vtysh', '-f', filename])
+
+ output = subprocess.check_output(['/usr/bin/vtysh', '-f', filename])
+
+ # exit non-zero if we see these errors
+ for x in ('BGP instance name and AS number mismatch',
+ 'BGP instance is already running',
+ '% not a local address'):
+ for line in output.splitlines():
+ if x in line:
+ msg = "ERROR: %s" % x
+ log.error(msg)
+ print msg
+ reload_ok = False
+
os.unlink(filename)
# Make these changes persistent
if args.overwrite or args.filename != '/etc/frr/frr.conf':
subprocess.call(['/usr/bin/vtysh', '-c', 'write'])
+
+ if not reload_ok:
+ sys.exit(1)
diff --git a/tools/permutations.c b/tools/permutations.c
index 88d1464697..fa1817a8e1 100644
--- a/tools/permutations.c
+++ b/tools/permutations.c
@@ -15,10 +15,9 @@
* 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.
+ * 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 "command.h"
@@ -43,9 +42,9 @@ int main (int argc, char *argv[])
cmd->string = strdup(argv[1]);
struct graph *graph = graph_new();
- struct cmd_token *token = new_cmd_token (START_TKN, cmd->attr, NULL, NULL);
+ struct cmd_token *token = cmd_token_new (START_TKN, cmd->attr, NULL, NULL);
graph_new_node (graph, token, NULL);
- command_parse_format (graph, cmd);
+ cmd_graph_parse (graph, cmd);
permute (vector_slot (graph->nodes, 0));
}
diff --git a/cumulus/start-stop-daemon.c b/tools/start-stop-daemon.c
index c123f87e92..f1a252a26f 100644
--- a/cumulus/start-stop-daemon.c
+++ b/tools/start-stop-daemon.c
@@ -811,6 +811,7 @@ run_stop_schedule(void)
anykilled = 0;
retry_nr = 0;
+ n_killed = 0;
if (schedule == NULL) {
do_stop(signal_nr, quietmode, &n_killed, &n_notkilled, 0);
diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am
index 9b81f99607..bb6bbbe87e 100644
--- a/vtysh/Makefile.am
+++ b/vtysh/Makefile.am
@@ -112,6 +112,16 @@ if NHRPD
vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c
endif
+if EIGRPD
+vtysh_scan += $(top_srcdir)/eigrpd/eigrp_dump.c
+#vtysh_scan += $(top_srcdir)/eigrpd/eigrp_routemap.c
+vtysh_scan += $(top_srcdir)/eigrpd/eigrp_vty.c
+endif
+
+if SNMP
+vtysh_scan += $(top_srcdir)/lib/agentx.c
+endif
+
vtysh_cmd_FILES = $(vtysh_scan) \
$(top_srcdir)/lib/keychain.c $(top_srcdir)/lib/routemap.c \
$(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \
diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in
index 5510482485..0ca1451ff5 100755
--- a/vtysh/extract.pl.in
+++ b/vtysh/extract.pl.in
@@ -82,14 +82,17 @@ foreach (@ARGV) {
$protocol = "VTYSH_RIPD";
}
elsif ($file =~ /lib\/routemap\.c$/) {
- $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD";
+ $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD";
}
elsif ($file =~ /lib\/vrf\.c$/) {
- $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA";
+ $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_EIGRPD";
}
elsif ($file =~ /lib\/filter\.c$/) {
$protocol = "VTYSH_ALL";
}
+ elsif ($file =~ /lib\/agentx\.c$/) {
+ $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA";
+ }
elsif ($file =~ /lib\/ns\.c$/) {
$protocol = "VTYSH_ZEBRA";
}
@@ -97,7 +100,7 @@ foreach (@ARGV) {
if ($defun_array[1] =~ m/ipv6/) {
$protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA";
} else {
- $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD";
+ $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD";
}
}
elsif ($file =~ /lib\/distribute\.c$/) {
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 5c39e1ee90..19b8f2fd8b 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -75,6 +74,7 @@ struct vtysh_client vtysh_client[] =
{ .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .next = NULL},
{ .fd = -1, .name = "pimd", .flag = VTYSH_PIMD, .next = NULL},
{ .fd = -1, .name = "nhrpd", .flag = VTYSH_NHRPD, .next = NULL},
+ { .fd = -1, .name = "eigrpd", .flag = VTYSH_EIGRPD, .next = NULL},
{ .fd = -1, .name = "watchfrr", .flag = VTYSH_WATCHFRR, .next = NULL},
};
@@ -106,12 +106,9 @@ begins_with(const char *str, const char *prefix)
return strncmp(str, prefix, lenprefix) == 0;
}
-/* NB: multiplexed function:
- * if fp == NULL, this calls vtysh_config_parse_line
- * if fp != NULL, this prints lines to fp
- */
static int
-vtysh_client_run (struct vtysh_client *vclient, const char *line, FILE *fp)
+vtysh_client_run (struct vtysh_client *vclient, const char *line, FILE *fp,
+ void (*callback)(void *, const char *), void *cbarg)
{
int ret;
char stackbuf[4096];
@@ -177,8 +174,8 @@ vtysh_client_run (struct vtysh_client *vclient, const char *line, FILE *fp)
fputs (buf, fp);
fputc ('\n', fp);
}
- else
- vtysh_config_parse_line (buf);
+ if (callback)
+ callback(cbarg, buf);
if (eol == end)
/* \n\0\0\0 */
@@ -222,14 +219,15 @@ out:
static int
vtysh_client_run_all (struct vtysh_client *head_client, const char *line,
- int continue_on_err, FILE *fp)
+ int continue_on_err, FILE *fp,
+ void (*callback)(void *, const char *), void *cbarg)
{
struct vtysh_client *client;
int rc, rc_all = CMD_SUCCESS;
for (client = head_client; client; client = client->next)
{
- rc = vtysh_client_run(client, line, fp);
+ rc = vtysh_client_run(client, line, fp, callback, cbarg);
if (rc != CMD_SUCCESS)
{
if (!continue_on_err)
@@ -244,13 +242,13 @@ static int
vtysh_client_execute (struct vtysh_client *head_client, const char *line,
FILE *fp)
{
- return vtysh_client_run_all (head_client, line, 0, fp);
+ return vtysh_client_run_all (head_client, line, 0, fp, NULL, NULL);
}
static void
vtysh_client_config (struct vtysh_client *head_client, char *line)
{
- vtysh_client_run_all (head_client, line, 1, NULL);
+ vtysh_client_run_all (head_client, line, 1, NULL, vtysh_config_parse_line, NULL);
}
void
@@ -263,7 +261,7 @@ vtysh_pager_init (void)
if (pager_defined)
vtysh_pager_name = strdup (pager_defined);
else
- vtysh_pager_name = strdup ("more");
+ vtysh_pager_name = strdup (VTYSH_PAGER);
}
/* Command execution over the vty interface. */
@@ -309,7 +307,8 @@ vtysh_execute_func (const char *line, int pager)
|| saved_node == BGP_ENCAP_NODE || saved_node == BGP_ENCAPV6_NODE
|| saved_node == BGP_IPV4_NODE
|| saved_node == BGP_IPV6_NODE || saved_node == BGP_IPV4M_NODE
- || saved_node == BGP_IPV6M_NODE || saved_node == BGP_EVPN_NODE)
+ || saved_node == BGP_IPV4L_NODE || saved_node == BGP_IPV6L_NODE
+ || saved_node == BGP_IPV6M_NODE || saved_node == BGP_EVPN_NODE)
&& (tried == 1))
{
vtysh_execute("exit-address-family");
@@ -646,7 +645,7 @@ vtysh_mark_file (const char *filename)
}
}
/* This is the end */
- fprintf(stdout, "end\n");
+ fprintf(stdout, "\nend\n");
vty_close(vty);
XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
@@ -798,6 +797,27 @@ vtysh_rl_describe (void)
width,
token->text,
token->desc);
+
+ if (IS_VARYING_TOKEN(token->type))
+ {
+ const char *ref = vector_slot(vline, vector_active(vline) - 1);
+
+ vector varcomps = vector_init (VECTOR_MIN_SIZE);
+ cmd_variable_complete (token, ref, varcomps);
+
+ if (vector_active (varcomps) > 0)
+ {
+ fprintf(stdout, " ");
+ for (size_t j = 0; j < vector_active (varcomps); j++)
+ {
+ char *item = vector_slot (varcomps, j);
+ fprintf (stdout, " %s", item);
+ XFREE (MTYPE_COMPLETION, item);
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+ }
+ vector_free (varcomps);
+ }
}
cmd_free_strvec (vline);
@@ -840,6 +860,7 @@ command_generator (const char *text, int state)
}
if (matched && matched[index])
+ /* this is free()'d by readline, but we leak 1 count of MTYPE_COMPLETION */
return matched[index++];
XFREE (MTYPE_TMP, matched);
@@ -951,6 +972,12 @@ static struct cmd_node bgp_ipv4m_node =
"%s(config-router-af)# "
};
+static struct cmd_node bgp_ipv4l_node =
+{
+ BGP_IPV4L_NODE,
+ "%s(config-router-af)# "
+};
+
static struct cmd_node bgp_ipv6_node =
{
BGP_IPV6_NODE,
@@ -969,6 +996,12 @@ static struct cmd_node bgp_evpn_node =
"%s(config-router-af)# "
};
+static struct cmd_node bgp_ipv6l_node =
+{
+ BGP_IPV6L_NODE,
+ "%s(config-router-af)# "
+};
+
static struct cmd_node bgp_vnc_defaults_node =
{
BGP_VNC_DEFAULTS_NODE,
@@ -998,6 +1031,12 @@ static struct cmd_node ospf_node =
"%s(config-router)# "
};
+static struct cmd_node eigrp_node =
+{
+ EIGRP_NODE,
+ "%s(config-router)# "
+};
+
static struct cmd_node ripng_node =
{
RIPNG_NODE,
@@ -1119,7 +1158,7 @@ DEFUNSH (VTYSH_BGPD,
"address-family vpnv4 [unicast]",
"Enter Address Family command mode\n"
"Address Family\n"
- "Address Family Modifier\n")
+ "Address Family modifier\n")
{
vty->node = BGP_VPNV4_NODE;
return CMD_SUCCESS;
@@ -1131,7 +1170,7 @@ DEFUNSH (VTYSH_BGPD,
"address-family vpnv6 [unicast]",
"Enter Address Family command mode\n"
"Address Family\n"
- "Address Family Modifier\n")
+ "Address Family modifier\n")
{
vty->node = BGP_VPNV6_NODE;
return CMD_SUCCESS;
@@ -1199,6 +1238,18 @@ DEFUNSH (VTYSH_BGPD,
}
DEFUNSH (VTYSH_BGPD,
+ address_family_ipv4_labeled_unicast,
+ address_family_ipv4_labeled_unicast_cmd,
+ "address-family ipv4 labeled-unicast",
+ "Enter Address Family command mode\n"
+ "Address Family\n"
+ "Address Family modifier\n")
+{
+ vty->node = BGP_IPV4L_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUNSH (VTYSH_BGPD,
address_family_ipv6,
address_family_ipv6_cmd,
"address-family ipv6 [unicast]",
@@ -1235,6 +1286,18 @@ DEFUNSH (VTYSH_BGPD,
}
DEFUNSH (VTYSH_BGPD,
+ address_family_ipv6_labeled_unicast,
+ address_family_ipv6_labeled_unicast_cmd,
+ "address-family ipv6 labeled-unicast",
+ "Enter Address Family command mode\n"
+ "Address Family\n"
+ "Address Family modifier\n")
+{
+ vty->node = BGP_IPV6L_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUNSH (VTYSH_BGPD,
address_family_evpn,
address_family_evpn_cmd,
"address-family <l2vpn evpn>",
@@ -1352,6 +1415,18 @@ DEFUNSH (VTYSH_OSPFD,
return CMD_SUCCESS;
}
+DEFUNSH (VTYSH_EIGRPD,
+ router_eigrp,
+ router_eigrp_cmd,
+ "router eigrp (1-65535)",
+ "Enable a routing process\n"
+ "Start EIGRP configuration\n"
+ "AS number to use\n")
+{
+ vty->node = EIGRP_NODE;
+ return CMD_SUCCESS;
+}
+
DEFUNSH (VTYSH_OSPF6D,
router_ospf6,
router_ospf6_cmd,
@@ -1535,6 +1610,7 @@ vtysh_exit (struct vty *vty)
case RIPNG_NODE:
case OSPF_NODE:
case OSPF6_NODE:
+ case EIGRP_NODE:
case LDP_NODE:
case LDP_L2VPN_NODE:
case ISIS_NODE:
@@ -1552,8 +1628,10 @@ vtysh_exit (struct vty *vty)
case BGP_ENCAPV6_NODE:
case BGP_IPV4_NODE:
case BGP_IPV4M_NODE:
+ case BGP_IPV4L_NODE:
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
+ case BGP_IPV6L_NODE:
case BGP_VRF_POLICY_NODE:
case BGP_EVPN_NODE:
case BGP_VNC_DEFAULTS_NODE:
@@ -1612,11 +1690,13 @@ DEFUNSH (VTYSH_BGPD,
{
if (vty->node == BGP_IPV4_NODE
|| vty->node == BGP_IPV4M_NODE
+ || vty->node == BGP_IPV4L_NODE
|| vty->node == BGP_VPNV4_NODE
|| vty->node == BGP_VPNV6_NODE
|| vty->node == BGP_ENCAP_NODE
|| vty->node == BGP_ENCAPV6_NODE
|| vty->node == BGP_IPV6_NODE
+ || vty->node == BGP_IPV6L_NODE
|| vty->node == BGP_IPV6M_NODE)
vty->node = BGP_NODE;
return CMD_SUCCESS;
@@ -1736,6 +1816,24 @@ DEFUNSH (VTYSH_OSPFD,
return vtysh_exit_ospfd (self, vty, argc, argv);
}
+DEFUNSH (VTYSH_EIGRPD,
+ vtysh_exit_eigrpd,
+ vtysh_exit_eigrpd_cmd,
+ "exit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit (vty);
+}
+
+DEFUNSH (VTYSH_EIGRPD,
+ vtysh_quit_eigrpd,
+ vtysh_quit_eigrpd_cmd,
+ "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit (vty);
+}
+
DEFUNSH (VTYSH_OSPF6D,
vtysh_exit_ospf6d,
vtysh_exit_ospf6d_cmd,
@@ -1819,7 +1917,7 @@ DEFUNSH (VTYSH_INTERFACE,
}
/* TODO Implement "no interface command in isisd. */
-DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,
+DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_EIGRPD,
vtysh_no_interface_cmd,
"no interface IFNAME",
NO_STR
@@ -1903,13 +2001,13 @@ DEFUNSH (VTYSH_VRF,
/* TODO Implement interface description commands in ripngd, ospf6d
* and isisd. */
-DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
- vtysh_interface_desc_cmd,
+DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_EIGRPD,
+ vtysh_interface_desc_cmd,
"description LINE...",
"Interface specific description\n"
"Characters describing this interface\n")
-DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
+DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_EIGRPD,
vtysh_no_interface_desc_cmd,
"no description",
NO_STR
@@ -3118,6 +3216,36 @@ vtysh_prompt (void)
return buf;
}
+static void vtysh_ac_line(void *arg, const char *line)
+{
+ vector comps = arg;
+ size_t i;
+ for (i = 0; i < vector_active(comps); i++)
+ if (!strcmp(line, (char *)vector_slot(comps, i)))
+ return;
+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION, line));
+}
+
+static void vtysh_autocomplete(vector comps, struct cmd_token *token)
+{
+ char accmd[256];
+ size_t i;
+
+ snprintf(accmd, sizeof(accmd), "autocomplete %d %s %s", token->type,
+ token->text, token->varname ? token->varname : "-");
+
+ for (i = 0; i < array_size(vtysh_client); i++)
+ vtysh_client_run_all (&vtysh_client[i], accmd, 1, NULL,
+ vtysh_ac_line, comps);
+}
+
+static const struct cmd_variable_handler vtysh_var_handler = {
+ /* match all */
+ .tokenname = NULL,
+ .varname = NULL,
+ .completions = vtysh_autocomplete
+};
+
void
vtysh_init_vty (void)
{
@@ -3128,6 +3256,7 @@ vtysh_init_vty (void)
/* Initialize commands. */
cmd_init (0);
+ cmd_variable_handler_register(&vtysh_var_handler);
/* Install nodes. */
install_node (&bgp_node, NULL);
@@ -3144,14 +3273,17 @@ vtysh_init_vty (void)
install_node (&bgp_encapv6_node, NULL);
install_node (&bgp_ipv4_node, NULL);
install_node (&bgp_ipv4m_node, NULL);
+ install_node (&bgp_ipv4l_node, NULL);
install_node (&bgp_ipv6_node, NULL);
install_node (&bgp_ipv6m_node, NULL);
+ install_node (&bgp_ipv6l_node, NULL);
install_node (&bgp_vrf_policy_node, NULL);
install_node (&bgp_evpn_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);
install_node (&ospf_node, NULL);
+ install_node (&eigrp_node, NULL);
install_node (&ripng_node, NULL);
install_node (&ospf6_node, NULL);
install_node (&ldp_node, NULL);
@@ -3182,9 +3314,11 @@ vtysh_init_vty (void)
vtysh_install_default (BGP_ENCAPV6_NODE);
vtysh_install_default (BGP_IPV4_NODE);
vtysh_install_default (BGP_IPV4M_NODE);
+ vtysh_install_default (BGP_IPV4L_NODE);
vtysh_install_default (BGP_IPV6_NODE);
vtysh_install_default (BGP_IPV6M_NODE);
vtysh_install_default (BGP_EVPN_NODE);
+ vtysh_install_default (BGP_IPV6L_NODE);
#if ENABLE_BGP_VNC
vtysh_install_default (BGP_VRF_POLICY_NODE);
vtysh_install_default (BGP_VNC_DEFAULTS_NODE);
@@ -3192,6 +3326,7 @@ vtysh_init_vty (void)
vtysh_install_default (BGP_VNC_L2_GROUP_NODE);
#endif
vtysh_install_default (OSPF_NODE);
+ vtysh_install_default (EIGRP_NODE);
vtysh_install_default (RIPNG_NODE);
vtysh_install_default (OSPF6_NODE);
vtysh_install_default (LDP_NODE);
@@ -3221,6 +3356,8 @@ vtysh_init_vty (void)
install_element (RIPNG_NODE, &vtysh_quit_ripngd_cmd);
install_element (OSPF_NODE, &vtysh_exit_ospfd_cmd);
install_element (OSPF_NODE, &vtysh_quit_ospfd_cmd);
+ install_element (EIGRP_NODE, &vtysh_exit_eigrpd_cmd);
+ install_element (EIGRP_NODE, &vtysh_quit_eigrpd_cmd);
install_element (OSPF6_NODE, &vtysh_exit_ospf6d_cmd);
install_element (OSPF6_NODE, &vtysh_quit_ospf6d_cmd);
#if defined (HAVE_LDPD)
@@ -3253,11 +3390,15 @@ vtysh_init_vty (void)
install_element (BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);
install_element (BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);
install_element (BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd);
+ install_element (BGP_IPV4L_NODE, &vtysh_exit_bgpd_cmd);
+ install_element (BGP_IPV4L_NODE, &vtysh_quit_bgpd_cmd);
install_element (BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd);
install_element (BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd);
install_element (BGP_IPV6M_NODE, &vtysh_exit_bgpd_cmd);
install_element (BGP_IPV6M_NODE, &vtysh_quit_bgpd_cmd);
install_element (BGP_EVPN_NODE, &vtysh_quit_bgpd_cmd);
+ install_element (BGP_IPV6L_NODE, &vtysh_exit_bgpd_cmd);
+ install_element (BGP_IPV6L_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);
@@ -3285,6 +3426,7 @@ vtysh_init_vty (void)
install_element (RIP_NODE, &vtysh_end_all_cmd);
install_element (RIPNG_NODE, &vtysh_end_all_cmd);
install_element (OSPF_NODE, &vtysh_end_all_cmd);
+ install_element (EIGRP_NODE, &vtysh_end_all_cmd);
install_element (OSPF6_NODE, &vtysh_end_all_cmd);
install_element (LDP_NODE, &vtysh_end_all_cmd);
install_element (LDP_IPV4_NODE, &vtysh_end_all_cmd);
@@ -3296,12 +3438,14 @@ vtysh_init_vty (void)
install_element (BGP_NODE, &vtysh_end_all_cmd);
install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd);
install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd);
+ install_element (BGP_IPV4L_NODE, &vtysh_end_all_cmd);
install_element (BGP_VPNV4_NODE, &vtysh_end_all_cmd);
install_element (BGP_VPNV6_NODE, &vtysh_end_all_cmd);
install_element (BGP_ENCAP_NODE, &vtysh_end_all_cmd);
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_IPV6L_NODE, &vtysh_end_all_cmd);
install_element (BGP_VRF_POLICY_NODE, &vtysh_end_all_cmd);
install_element (BGP_EVPN_NODE, &vtysh_end_all_cmd);
install_element (BGP_VNC_DEFAULTS_NODE, &vtysh_end_all_cmd);
@@ -3332,6 +3476,7 @@ vtysh_init_vty (void)
install_element (VRF_NODE, &vtysh_exit_vrf_cmd);
install_element (VRF_NODE, &vtysh_quit_vrf_cmd);
+ install_element (CONFIG_NODE, &router_eigrp_cmd);
install_element (CONFIG_NODE, &router_rip_cmd);
install_element (CONFIG_NODE, &router_ripng_cmd);
install_element (CONFIG_NODE, &router_ospf_cmd);
@@ -3360,9 +3505,11 @@ vtysh_init_vty (void)
install_element (BGP_NODE, &address_family_ipv4_cmd);
install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);
install_element (BGP_NODE, &address_family_ipv4_vpn_cmd);
+ install_element (BGP_NODE, &address_family_ipv4_labeled_unicast_cmd);
install_element (BGP_NODE, &address_family_ipv6_cmd);
install_element (BGP_NODE, &address_family_ipv6_multicast_cmd);
install_element (BGP_NODE, &address_family_ipv6_vpn_cmd);
+ install_element (BGP_NODE, &address_family_ipv6_labeled_unicast_cmd);
install_element (BGP_NODE, &address_family_evpn_cmd);
install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);
install_element (BGP_VPNV6_NODE, &exit_address_family_cmd);
@@ -3370,9 +3517,11 @@ vtysh_init_vty (void)
install_element (BGP_ENCAPV6_NODE, &exit_address_family_cmd);
install_element (BGP_IPV4_NODE, &exit_address_family_cmd);
install_element (BGP_IPV4M_NODE, &exit_address_family_cmd);
+ install_element (BGP_IPV4L_NODE, &exit_address_family_cmd);
install_element (BGP_IPV6_NODE, &exit_address_family_cmd);
install_element (BGP_IPV6M_NODE, &exit_address_family_cmd);
install_element (BGP_EVPN_NODE, &exit_address_family_cmd);
+ install_element (BGP_IPV6L_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);
diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
index 6d9e21d8a0..d3c7a4def9 100644
--- a/vtysh/vtysh.h
+++ b/vtysh/vtysh.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 VTYSH_H
@@ -36,15 +35,16 @@ DECLARE_MGROUP(MVTYSH)
#define VTYSH_LDPD 0x200
#define VTYSH_WATCHFRR 0x400
#define VTYSH_NHRPD 0x800
+#define VTYSH_EIGRPD 0x1000
/* commands in REALLYALL are crucial to correct vtysh operation */
#define VTYSH_REALLYALL ~0U
/* watchfrr is not in ALL since library CLI functions should not be
* run on it (logging & co. should stay in a fixed/frozen config, and
* things like prefix lists are not even initialised) */
-#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD
+#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_PIMD
-#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD
+#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD
#define VTYSH_NS VTYSH_ZEBRA
#define VTYSH_VRF VTYSH_ZEBRA
@@ -84,7 +84,7 @@ int vtysh_mark_file(const char *filename);
int vtysh_read_config (const char *);
int vtysh_write_config_integrated (void);
-void vtysh_config_parse_line (const char *);
+void vtysh_config_parse_line (void *, const char *);
void vtysh_config_dump (FILE *);
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 94c4042dd4..f25b5f26f7 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -1,22 +1,22 @@
/* Configuration generator.
- Copyright (C) 2000 Kunihiro Ishiguro
-
-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. */
+ * Copyright (C) 2000 Kunihiro Ishiguro
+ *
+ * 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 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>
@@ -145,7 +145,7 @@ config_add_line_uniq (struct list *config, const char *line)
}
void
-vtysh_config_parse_line (const char *line)
+vtysh_config_parse_line (void *arg, const char *line)
{
char c;
static struct config *config = NULL;
@@ -206,6 +206,8 @@ vtysh_config_parse_line (const char *line)
config = config_get (RIP_NODE, line);
else if (strncmp (line, "router ripng", strlen ("router ripng")) == 0)
config = config_get (RIPNG_NODE, line);
+ else if (strncmp (line, "router eigrp", strlen ("router eigrp")) == 0)
+ config = config_get (EIGRP_NODE, line);
else if (strncmp (line, "router ospf", strlen ("router ospf")) == 0)
config = config_get (OSPF_NODE, line);
else if (strncmp (line, "router ospf6", strlen ("router ospf6")) == 0)
@@ -275,6 +277,7 @@ vtysh_config_parse_line (const char *line)
if (strncmp (line, "log", strlen ("log")) == 0
|| strncmp (line, "hostname", strlen ("hostname")) == 0
|| strncmp (line, "frr", strlen ("frr")) == 0
+ || strncmp (line, "agentx", strlen ("agentx")) == 0
)
config_add_line_uniq (config_top, line);
else
@@ -415,12 +418,12 @@ vtysh_config_write ()
if (host.name)
{
sprintf (line, "hostname %s", host.name);
- vtysh_config_parse_line(line);
+ vtysh_config_parse_line(NULL, line);
}
if (vtysh_write_integrated == WRITE_INTEGRATED_NO)
- vtysh_config_parse_line ("no service integrated-vtysh-config");
+ vtysh_config_parse_line (NULL, "no service integrated-vtysh-config");
if (vtysh_write_integrated == WRITE_INTEGRATED_YES)
- vtysh_config_parse_line ("service integrated-vtysh-config");
+ vtysh_config_parse_line (NULL, "service integrated-vtysh-config");
user_config_write ();
}
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index bf62850e22..d2ac56c366 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/vtysh/vtysh_user.c b/vtysh/vtysh_user.c
index cce797c932..97720e9fd6 100644
--- a/vtysh/vtysh_user.c
+++ b/vtysh/vtysh_user.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/vtysh/vtysh_user.h b/vtysh/vtysh_user.h
index 16fcdd03a5..9d8f4ae62c 100644
--- a/vtysh/vtysh_user.h
+++ b/vtysh/vtysh_user.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _VTYSH_USER_H
diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c
index 6edce242b3..0b19a2ad23 100644
--- a/watchfrr/watchfrr.c
+++ b/watchfrr/watchfrr.c
@@ -1,21 +1,21 @@
/*
- Monitor status of frr daemons and restart if necessary.
-
- Copyright (C) 2004 Andrew J. Schorr
-
- 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
+ * Monitor status of frr daemons and restart if necessary.
+ *
+ * Copyright (C) 2004 Andrew J. Schorr
+ *
+ * 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>
@@ -373,8 +373,9 @@ static int restart_kill(struct thread *t_kill)
(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);
+ restart->t_kill = NULL;
+ thread_add_timer(master, restart_kill, restart, gs.restart_timeout,
+ &restart->t_kill);
return 0;
}
@@ -487,9 +488,9 @@ run_job(struct restart_info *restart, const char *cmdtype, const char *command,
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->t_kill = NULL;
+ thread_add_timer(master, restart_kill, restart, gs.restart_timeout,
+ &restart->t_kill);
restart->what = cmdtype;
gs.numpids++;
} else
@@ -510,19 +511,31 @@ run_job(struct restart_info *restart, const char *cmdtype, const char *command,
}
#define SET_READ_HANDLER(DMN) \
- (DMN)->t_read = thread_add_read(master,handle_read,(DMN),(DMN)->fd)
-
-#define SET_WAKEUP_DOWN(DMN) \
- (DMN)->t_wakeup = thread_add_timer_msec(master,wakeup_down,(DMN), \
- FUZZY(gs.period))
-
-#define SET_WAKEUP_UNRESPONSIVE(DMN) \
- (DMN)->t_wakeup = thread_add_timer_msec(master,wakeup_unresponsive,(DMN), \
- FUZZY(gs.period))
+ do { \
+ (DMN)->t_read = NULL; \
+ thread_add_read (master, handle_read, (DMN), (DMN)->fd, &(DMN)->t_read); \
+ } while (0);
+
+#define SET_WAKEUP_DOWN(DMN) \
+ do { \
+ (DMN)->t_wakeup = NULL; \
+ thread_add_timer_msec (master, wakeup_down, (DMN), FUZZY(gs.period), \
+ &(DMN)->t_wakeup); \
+ } while (0);
+
+#define SET_WAKEUP_UNRESPONSIVE(DMN) \
+ do { \
+ (DMN)->t_wakeup = NULL; \
+ thread_add_timer_msec (master, wakeup_unresponsive, (DMN), \
+ FUZZY(gs.period), &(DMN)->t_wakeup); \
+ } while (0);
#define SET_WAKEUP_ECHO(DMN) \
- (DMN)->t_wakeup = thread_add_timer_msec(master,wakeup_send_echo,(DMN), \
- FUZZY(gs.period))
+ do { \
+ (DMN)->t_wakeup = NULL; \
+ thread_add_timer_msec (master, wakeup_send_echo, (DMN), \
+ FUZZY(gs.period), &(DMN)->t_wakeup); \
+ } while (0);
static int wakeup_down(struct thread *t_wakeup)
{
@@ -775,11 +788,11 @@ static int try_connect(struct daemon *dmn)
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);
+ dmn->t_write = NULL;
+ thread_add_write(master, check_connect, dmn, dmn->fd,
+ &dmn->t_write);dmn->t_wakeup = NULL;
+ thread_add_timer(master, wakeup_connect_hanging, dmn, gs.timeout,
+ &dmn->t_wakeup);
SET_READ_HANDLER(dmn);
return 0;
}
@@ -804,8 +817,9 @@ 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.t_phase_hanging = NULL;
+ thread_add_timer(master, phase_hanging, NULL, PHASE_TIMEOUT,
+ &gs.t_phase_hanging);
}
static void phase_check(void)
@@ -962,8 +976,9 @@ static int wakeup_send_echo(struct thread *t_wakeup)
daemon_down(dmn, why);
} else {
gettimeofday(&dmn->echo_sent, NULL);
- dmn->t_wakeup =
- thread_add_timer(master, wakeup_no_answer, dmn, gs.timeout);
+ dmn->t_wakeup = NULL;
+ thread_add_timer(master, wakeup_no_answer, dmn, gs.timeout,
+ &dmn->t_wakeup);
}
return 0;
}
@@ -1310,9 +1325,9 @@ int main(int argc, char **argv)
gs.numdaemons++;
gs.numdown++;
dmn->fd = -1;
- dmn->t_wakeup =
- thread_add_timer_msec(master, wakeup_init, dmn,
- 100 + (random() % 900));
+ dmn->t_wakeup = NULL;
+ thread_add_timer_msec(master, wakeup_init, dmn, 100 + (random() % 900),
+ &dmn->t_wakeup);
dmn->restart.interval = gs.min_restart_interval;
if (tail)
tail->next = dmn;
diff --git a/watchfrr/watchfrr.h b/watchfrr/watchfrr.h
index 719ad4dfd8..e7aba643d6 100644
--- a/watchfrr/watchfrr.h
+++ b/watchfrr/watchfrr.h
@@ -1,21 +1,21 @@
/*
- Common definitions for watchfrr API socket.
-
- Copyright (C) 2016 David Lamparter for NetDEF, 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; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Common definitions for watchfrr API socket.
+ *
+ * Copyright (C) 2016 David Lamparter for NetDEF, 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 FRR_WATCHFRR_H
diff --git a/watchfrr/watchfrr_vty.c b/watchfrr/watchfrr_vty.c
index 64af7d7f4a..3501dd57ea 100644
--- a/watchfrr/watchfrr_vty.c
+++ b/watchfrr/watchfrr_vty.c
@@ -1,21 +1,21 @@
/*
- watchfrr CLI functions.
-
- Copyright (C) 2016 David Lamparter for NetDEF, 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; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * watchfrr CLI functions.
+ *
+ * Copyright (C) 2016 David Lamparter for NetDEF, 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>
diff --git a/zebra/Makefile.am b/zebra/Makefile.am
index 3e0de3b463..6c5e069064 100644
--- a/zebra/Makefile.am
+++ b/zebra/Makefile.am
@@ -31,7 +31,7 @@ zebra_SOURCES = \
redistribute.c debug.c rtadv.c zebra_vty.c \
irdp_main.c irdp_interface.c irdp_packet.c router-id.c \
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 \
+ zebra_ns.c zebra_vrf.c zebra_static.c zebra_mpls_vty.c \
zebra_mroute.c \
label_manager.c \
# end
@@ -40,7 +40,7 @@ testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c zebra_vrf.c \
kernel_null.c redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c \
zebra_ptm_null.c rtadv_null.c if_null.c zserv_null.c zebra_static.c \
- zebra_memory.c zebra_mpls.c zebra_mpls_vty.c zebra_mpls_null.c
+ zebra_memory.c zebra_mpls_vty.c zebra_mpls_null.c
noinst_HEADERS = \
zebra_memory.h \
@@ -88,7 +88,7 @@ EXTRA_DIST = if_ioctl.c if_ioctl_solaris.c if_netlink.c \
rt_socket.c rtread_netlink.c rtread_sysctl.c \
rtread_getmsg.c kernel_socket.c kernel_netlink.c \
ioctl.c ioctl_solaris.c \
- zebra_mpls_netlink.c zebra_mpls_openbsd.c \
+ zebra_mpls_netlink.c zebra_mpls_openbsd.c zebra_mpls.c \
GNOME-SMI GNOME-PRODUCT-ZEBRA-MIB
client : client_main.o ../lib/libfrr.la
diff --git a/zebra/client_main.c b/zebra/client_main.c
index 178184d463..cf423ad25f 100644
--- a/zebra/client_main.c
+++ b/zebra/client_main.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/connected.c b/zebra/connected.c
index 0ceaddc8e3..4d8fe9f6d6 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/connected.h b/zebra/connected.h
index bdcf6085e4..3e37346853 100644
--- a/zebra/connected.h
+++ b/zebra/connected.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_CONNECTED_H
diff --git a/zebra/debug.c b/zebra/debug.c
index a42d5aa3ef..98770371d8 100644
--- a/zebra/debug.c
+++ b/zebra/debug.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -384,6 +383,16 @@ config_write_debug (struct vty *vty)
vty_out (vty, "debug zebra kernel%s", VTY_NEWLINE);
write++;
}
+ if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV)
+ {
+ vty_out (vty, "debug zebra kernel msgdump recv%s", VTY_NEWLINE);
+ write++;
+ }
+ if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND)
+ {
+ vty_out (vty, "debug zebra kernel msgdump send%s", VTY_NEWLINE);
+ write++;
+ }
/* Check here using flags as the 'macro' does an OR */
if (CHECK_FLAG (zebra_debug_rib, ZEBRA_DEBUG_RIB))
{
diff --git a/zebra/debug.h b/zebra/debug.h
index f8ebf3d616..0a50da8176 100644
--- a/zebra/debug.h
+++ b/zebra/debug.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_DEBUG_H
diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c
index 5333f0331e..73da049655 100644
--- a/zebra/if_ioctl.c
+++ b/zebra/if_ioctl.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c
index dbc4109913..08af2aa350 100644
--- a/zebra/if_ioctl_solaris.c
+++ b/zebra/if_ioctl_solaris.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 006fcf16f4..edfb564a6c 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -38,6 +37,7 @@
#include "privs.h"
#include "nexthop.h"
#include "vrf.h"
+#include "vrf_int.h"
#include "mpls.h"
#include "vty.h"
diff --git a/zebra/if_netlink.h b/zebra/if_netlink.h
index 6fa39ccab2..0c1b488fb1 100644
--- a/zebra/if_netlink.h
+++ b/zebra/if_netlink.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_IF_NETLINK_H
diff --git a/zebra/if_null.c b/zebra/if_null.c
index 2ccea56c81..7cba0a4ee2 100644
--- a/zebra/if_null.c
+++ b/zebra/if_null.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/if_sysctl.c b/zebra/if_sysctl.c
index c62d9926a2..dbf5abd12b 100644
--- a/zebra/if_sysctl.c
+++ b/zebra/if_sysctl.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/interface.c b/zebra/interface.c
index 78ac0258ca..7b0d31338d 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -709,6 +708,11 @@ if_delete_update (struct interface *ifp)
for setting ifindex to IFINDEX_INTERNAL after processing the
interface deletion message. */
ifp->ifindex = IFINDEX_INTERNAL;
+ ifp->node = NULL;
+
+ /* if the ifp is in a vrf, move it to default so vrf can be deleted if desired */
+ if (ifp->vrf_id)
+ if_handle_vrf_change (ifp, VRF_DEFAULT);
}
/* VRF change for an interface */
diff --git a/zebra/interface.h b/zebra/interface.h
index 9f108760d6..b276edc353 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_INTERFACE_H
diff --git a/zebra/ioctl.c b/zebra/ioctl.c
index dfd69300f9..25aeea18f5 100644
--- a/zebra/ioctl.c
+++ b/zebra/ioctl.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/ioctl.h b/zebra/ioctl.h
index 9e3fd5b3fb..b11a90f193 100644
--- a/zebra/ioctl.h
+++ b/zebra/ioctl.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_IOCTL_H
diff --git a/zebra/ioctl_null.c b/zebra/ioctl_null.c
index c2060e90a1..9cc2daedbe 100644
--- a/zebra/ioctl_null.c
+++ b/zebra/ioctl_null.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/zebra/ioctl_solaris.c b/zebra/ioctl_solaris.c
index 78796a8a28..4bdbdaa584 100644
--- a/zebra/ioctl_solaris.c
+++ b/zebra/ioctl_solaris.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/ioctl_solaris.h b/zebra/ioctl_solaris.h
index 188986be16..dbf93bdcaa 100644
--- a/zebra/ioctl_solaris.h
+++ b/zebra/ioctl_solaris.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_IF_IOCTL_SOLARIS_H
diff --git a/zebra/ipforward.h b/zebra/ipforward.h
index a75073cb36..5401ed08ad 100644
--- a/zebra/ipforward.h
+++ b/zebra/ipforward.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_IPFORWARD_H
diff --git a/zebra/ipforward_proc.c b/zebra/ipforward_proc.c
index 910fd61d06..200c50c0ad 100644
--- a/zebra/ipforward_proc.c
+++ b/zebra/ipforward_proc.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/ipforward_solaris.c b/zebra/ipforward_solaris.c
index 8eccfe133c..09f145e818 100644
--- a/zebra/ipforward_solaris.c
+++ b/zebra/ipforward_solaris.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/ipforward_sysctl.c b/zebra/ipforward_sysctl.c
index 28894f4e0a..a381eb2d72 100644
--- a/zebra/ipforward_sysctl.c
+++ b/zebra/ipforward_sysctl.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/zebra/irdp.h b/zebra/irdp.h
index 9ce55e5876..975e378b72 100644
--- a/zebra/irdp.h
+++ b/zebra/irdp.h
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/*
diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c
index 5cabe7e62f..d3c471e753 100644
--- a/zebra/irdp_interface.c
+++ b/zebra/irdp_interface.c
@@ -15,10 +15,9 @@
* 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.
+ * 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
*/
/*
@@ -259,10 +258,9 @@ irdp_if_start(struct interface *ifp, int multicast, int set_defaults)
ifp->name,
timer);
- irdp->t_advertise = thread_add_timer(zebrad.master,
- irdp_send_thread,
- ifp,
- timer);
+ irdp->t_advertise = NULL;
+ thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer,
+ &irdp->t_advertise);
}
static void
diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c
index 7fa4ad4cbe..8e4ebfda60 100644
--- a/zebra/irdp_main.c
+++ b/zebra/irdp_main.c
@@ -15,10 +15,9 @@
* 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.
+ * 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
*/
/*
@@ -114,7 +113,8 @@ irdp_sock_init (void)
return ret;
};
- t_irdp_raw = thread_add_read (zebrad.master, irdp_read_raw, NULL, sock);
+ t_irdp_raw = NULL;
+ thread_add_read(zebrad.master, irdp_read_raw, NULL, sock, &t_irdp_raw);
return sock;
}
@@ -244,7 +244,9 @@ int irdp_send_thread(struct thread *t_advert)
if(irdp->flags & IF_DEBUG_MISC)
zlog_debug("IRDP: New timer for %s set to %u\n", ifp->name, timer);
- irdp->t_advertise = thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer);
+ irdp->t_advertise = NULL;
+ thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer,
+ &irdp->t_advertise);
return 0;
}
@@ -296,10 +298,9 @@ void process_solicit (struct interface *ifp)
timer = (random () % MAX_RESPONSE_DELAY) + 1;
- irdp->t_advertise = thread_add_timer(zebrad.master,
- irdp_send_thread,
- ifp,
- timer);
+ irdp->t_advertise = NULL;
+ thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer,
+ &irdp->t_advertise);
}
void irdp_finish()
diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c
index 4c58b6b35d..20982b31a1 100644
--- a/zebra/irdp_packet.c
+++ b/zebra/irdp_packet.c
@@ -15,10 +15,9 @@
* 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.
+ * 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
*/
/*
@@ -232,7 +231,8 @@ int irdp_read_raw(struct thread *r)
int ret, ifindex = 0;
int irdp_sock = THREAD_FD (r);
- t_irdp_raw = thread_add_read (zebrad.master, irdp_read_raw, NULL, irdp_sock);
+ t_irdp_raw = NULL;
+ thread_add_read(zebrad.master, irdp_read_raw, NULL, irdp_sock, &t_irdp_raw);
ret = irdp_recvmsg (irdp_sock, (u_char *) buf, IRDP_RX_BUF, &ifindex);
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 49394bd6f8..3efad44acb 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -100,6 +99,11 @@ static const struct message rtproto_str[] = {
{RTPROT_BIRD, "BIRD"},
#endif /* RTPROT_BIRD */
{RTPROT_MROUTED, "mroute"},
+ {RTPROT_BGP, "BGP"},
+ {RTPROT_OSPF, "OSPF"},
+ {RTPROT_ISIS, "IS-IS"},
+ {RTPROT_RIP, "RIP"},
+ {RTPROT_RIPNG, "RIPNG"},
{0, NULL}
};
@@ -278,8 +282,9 @@ kernel_read (struct thread *thread)
{
struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG (thread);
netlink_parse_info (netlink_information_fetch, &zns->netlink, zns, 5, 0);
- zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns,
- zns->netlink.sock);
+ zns->t_netlink = NULL;
+ thread_add_read(zebrad.master, kernel_read, zns, zns->netlink.sock,
+ &zns->t_netlink);
return 0;
}
@@ -516,7 +521,7 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV)
{
zlog_debug("%s: << netlink message dump [recv]", __func__);
- zlog_hexdump(&msg, sizeof(msg));
+ zlog_hexdump(buf, status);
}
read_in++;
@@ -699,7 +704,7 @@ netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND)
{
zlog_debug("%s: >> netlink message dump [sent]", __func__);
- zlog_hexdump(&msg, sizeof(msg));
+ zlog_hexdump(n, n->nlmsg_len);
}
if (status < 0)
@@ -808,8 +813,9 @@ kernel_init (struct zebra_ns *zns)
netlink_recvbuf (&zns->netlink, nl_rcvbufsize);
netlink_install_filter (zns->netlink.sock, zns->netlink_cmd.snl.nl_pid);
- zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns,
- zns->netlink.sock);
+ zns->t_netlink = NULL;
+ thread_add_read(zebrad.master, kernel_read, zns, zns->netlink.sock,
+ &zns->t_netlink);
}
}
diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h
index adbcf71f63..36ab5c3254 100644
--- a/zebra/kernel_netlink.h
+++ b/zebra/kernel_netlink.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_KERNEL_NETLINK_H
diff --git a/zebra/kernel_null.c b/zebra/kernel_null.c
index fea79ffe8c..ad96ce41ca 100644
--- a/zebra/kernel_null.c
+++ b/zebra/kernel_null.c
@@ -1,6 +1,5 @@
-/* NULL kernel methods for testing. */
-
-/*
+/*
+ * NULL kernel methods for testing.
* Copyright (C) 2006 Sun Microsystems, Inc.
*
* This file is part of Quagga.
@@ -15,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 7212ed6f26..25c11e578b 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -1282,7 +1281,7 @@ kernel_read (struct thread *thread)
return 0;
}
- thread_add_read (zebrad.master, kernel_read, NULL, sock);
+ thread_add_read(zebrad.master, kernel_read, NULL, sock, NULL);
if (IS_ZEBRA_DEBUG_KERNEL)
rtmsg_debug (&buf.r.rtm);
@@ -1355,7 +1354,7 @@ routing_socket (struct zebra_ns *zns)
zlog_err ("routing_socket: Can't lower privileges");
/* kernel_read needs rewrite. */
- thread_add_read (zebrad.master, kernel_read, NULL, routing_sock);
+ thread_add_read(zebrad.master, kernel_read, NULL, routing_sock, NULL);
}
/* Exported interface function. This function simply calls
diff --git a/zebra/kernel_socket.h b/zebra/kernel_socket.h
index 04e3054312..26cd6127f8 100644
--- a/zebra/kernel_socket.h
+++ b/zebra/kernel_socket.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 __ZEBRA_KERNEL_SOCKET_H
diff --git a/zebra/label_manager.c b/zebra/label_manager.c
index 7dbb36edb8..cbb35631ac 100644
--- a/zebra/label_manager.c
+++ b/zebra/label_manager.c
@@ -16,10 +16,9 @@
* 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.
+ * 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 <stdio.h>
@@ -141,9 +140,8 @@ static int zclient_connect(struct thread *t)
if (zclient_socket_connect(zclient) < 0) {
zlog_err("Error connecting synchronous zclient!");
- THREAD_TIMER_ON(zebrad.master, zclient->t_connect,
- zclient_connect,
- zclient, CONNECTION_DELAY);
+ thread_add_timer(zebrad.master, zclient_connect, zclient,
+ CONNECTION_DELAY, &zclient->t_connect);
return -1;
}
diff --git a/zebra/label_manager.h b/zebra/label_manager.h
index 0c6a5ebc7d..a68c301f16 100644
--- a/zebra/label_manager.h
+++ b/zebra/label_manager.h
@@ -16,10 +16,9 @@
* 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.
+ * 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 _LABEL_MANAGER_H
diff --git a/zebra/main.c b/zebra/main.c
index 459e6148d8..b136f8ae93 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/zebra/misc_null.c b/zebra/misc_null.c
index 49cb92bd7d..b125becdc9 100644
--- a/zebra/misc_null.c
+++ b/zebra/misc_null.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index c7ed209d3c..1493bd9cb6 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -107,45 +106,41 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
/* Redistribute routes. */
static void
-zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id)
+zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id, int afi)
{
struct rib *newrib;
struct route_table *table;
struct route_node *rn;
- int afi;
- for (afi = AFI_IP; afi <= AFI_IP6; afi++)
- {
- table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id);
- if (! table)
- continue;
+ table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id);
+ if (! table)
+ return;
- 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 (dst_p));
-
- if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED))
- continue;
- if ((type != ZEBRA_ROUTE_ALL &&
- (newrib->type != type || newrib->instance != instance)))
- continue;
- if (newrib->distance == DISTANCE_INFINITY)
- continue;
- if (! zebra_check_addr (dst_p))
- continue;
-
- zsend_redistribute_route (1, client, dst_p, src_p, newrib);
- }
- }
+ 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 (dst_p));
+
+ if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED))
+ continue;
+ if ((type != ZEBRA_ROUTE_ALL &&
+ (newrib->type != type || newrib->instance != instance)))
+ continue;
+ if (newrib->distance == DISTANCE_INFINITY)
+ continue;
+ if (! zebra_check_addr (dst_p))
+ continue;
+
+ zsend_redistribute_route (1, client, dst_p, src_p, newrib);
+ }
}
/* Either advertise a route for redistribution to registered clients or */
@@ -265,13 +260,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length,
if (! redist_check_instance (&client->mi_redist[afi][type], instance))
{
redist_add_instance (&client->mi_redist[afi][type], instance);
- zebra_redistribute (client, type, instance, zvrf_id (zvrf));
+ zebra_redistribute (client, type, instance, zvrf_id (zvrf), afi);
}
} else {
if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf)))
{
vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf));
- zebra_redistribute (client, type, 0, zvrf_id (zvrf));
+ zebra_redistribute (client, type, 0, zvrf_id (zvrf), afi);
}
}
}
@@ -498,6 +493,7 @@ int
zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char *rmap_name)
{
struct rib *newrib;
+ struct rib *same;
struct prefix p;
struct nexthop *nhop;
union g_addr *gate;
@@ -515,6 +511,21 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
p.prefixlen = rn->p.prefixlen;
p.u.prefix4 = rn->p.u.prefix4;
+ RNODE_FOREACH_RIB (rn, same)
+ {
+ if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
+ continue;
+
+ if (same->type == rib->type && same->instance == rib->instance
+ && same->table == rib->table
+ && same->type != ZEBRA_ROUTE_CONNECT)
+ break;
+ }
+
+ if (same)
+ zebra_del_import_table_entry (rn, same);
+
+
if (rib->nexthop_num == 1)
{
nhop = rib->nexthop;
diff --git a/zebra/redistribute.h b/zebra/redistribute.h
index 06afc726d1..8a78574980 100644
--- a/zebra/redistribute.h
+++ b/zebra/redistribute.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_REDISTRIBUTE_H
diff --git a/zebra/redistribute_null.c b/zebra/redistribute_null.c
index ffde8ed773..7f40c21782 100644
--- a/zebra/redistribute_null.c
+++ b/zebra/redistribute_null.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/zebra/rib.h b/zebra/rib.h
index 5381d76b98..7bcbf56bde 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_RIB_H
@@ -372,7 +371,7 @@ extern void rib_init (void);
extern unsigned long rib_score_proto (u_char proto, u_short instance);
extern void rib_queue_add (struct route_node *rn);
extern void meta_queue_free (struct meta_queue *mq);
-
+extern int zebra_rib_labeled_unicast (struct rib *rib);
extern struct route_table *rib_table_ipv6;
extern void rib_unlink (struct route_node *, struct rib *);
diff --git a/zebra/router-id.c b/zebra/router-id.c
index b1e786d0c8..318986c1b7 100644
--- a/zebra/router-id.c
+++ b/zebra/router-id.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
diff --git a/zebra/router-id.h b/zebra/router-id.h
index 46d300eeac..6b15159fdb 100644
--- a/zebra/router-id.h
+++ b/zebra/router-id.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 _ROUTER_ID_H_
diff --git a/zebra/rt.h b/zebra/rt.h
index 75d234ce83..5f2441a9ce 100644
--- a/zebra/rt.h
+++ b/zebra/rt.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_RT_H
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index a544593dd6..3c4f3171ff 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -103,6 +102,47 @@ struct gw_family_t
union g_addr gate;
};
+static inline int is_selfroute(int proto)
+{
+ if ((proto == RTPROT_BGP) || (proto == RTPROT_OSPF) ||
+ (proto == RTPROT_STATIC) || (proto == RTPROT_ZEBRA) ||
+ (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static inline int get_rt_proto(int proto)
+{
+ switch (proto) {
+ case ZEBRA_ROUTE_BGP:
+ proto = RTPROT_BGP;
+ break;
+ case ZEBRA_ROUTE_OSPF:
+ case ZEBRA_ROUTE_OSPF6:
+ proto = RTPROT_OSPF;
+ break;
+ case ZEBRA_ROUTE_STATIC:
+ proto = RTPROT_STATIC;
+ break;
+ case ZEBRA_ROUTE_ISIS:
+ proto = RTPROT_ISIS;
+ break;
+ case ZEBRA_ROUTE_RIP:
+ proto = RTPROT_RIP;
+ break;
+ case ZEBRA_ROUTE_RIPNG:
+ proto = RTPROT_RIPNG;
+ break;
+ default:
+ proto = RTPROT_ZEBRA;
+ break;
+ }
+
+ return proto;
+}
+
/*
Pending: create an efficient table_id (in a tree/hash) based lookup)
*/
@@ -171,7 +211,7 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
return 0;
if (!startup &&
- rtm->rtm_protocol == RTPROT_ZEBRA &&
+ is_selfroute (rtm->rtm_protocol) &&
h->nlmsg_type == RTM_NEWROUTE)
return 0;
@@ -196,7 +236,7 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
}
/* Route which inserted by Zebra. */
- if (rtm->rtm_protocol == RTPROT_ZEBRA)
+ if (is_selfroute(rtm->rtm_protocol))
flags |= ZEBRA_FLAG_SELFROUTE;
if (tb[RTA_OIF])
@@ -1137,7 +1177,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
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_protocol = get_rt_proto(rib->type);
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h
index 93ee622e35..0e305beb37 100644
--- a/zebra/rt_netlink.h
+++ b/zebra/rt_netlink.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_RT_NETLINK_H
@@ -28,6 +27,14 @@
#define NL_DEFAULT_ROUTE_METRIC 20
+/* Additional protocol strings to push into routes */
+#define RTPROT_BGP 186
+#define RTPROT_ISIS 187
+#define RTPROT_OSPF 188
+#define RTPROT_RIP 189
+#define RTPROT_RIPNG 190
+
+
extern void
clear_nhlfe_installed (zebra_lsp_t *lsp);
extern int
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index de8cc69a8e..3e4833016a 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 12e4873adf..7f46066a63 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
@@ -1574,11 +1573,8 @@ rtadv_event (struct zebra_ns *zns, enum rtadv_event event, int val)
switch (event)
{
case RTADV_START:
- if (! rtadv->ra_read)
- rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
- if (! rtadv->ra_timer)
- rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
- zns, 0);
+ thread_add_read(zebrad.master, rtadv_read, zns, val, &rtadv->ra_read);
+ thread_add_event(zebrad.master, rtadv_timer, zns, 0, &rtadv->ra_timer);
break;
case RTADV_STOP:
if (rtadv->ra_timer)
@@ -1593,18 +1589,14 @@ rtadv_event (struct zebra_ns *zns, enum rtadv_event event, int val)
}
break;
case RTADV_TIMER:
- if (! rtadv->ra_timer)
- rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zns,
- val);
+ thread_add_timer(zebrad.master, rtadv_timer, zns, val, &rtadv->ra_timer);
break;
case RTADV_TIMER_MSEC:
- if (! rtadv->ra_timer)
- rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
- zns, val);
+ thread_add_timer_msec(zebrad.master, rtadv_timer, zns, val,
+ &rtadv->ra_timer);
break;
case RTADV_READ:
- if (! rtadv->ra_read)
- rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
+ thread_add_read(zebrad.master, rtadv_read, zns, val, &rtadv->ra_read);
break;
default:
break;
diff --git a/zebra/rtadv.h b/zebra/rtadv.h
index e4c2c6b36d..5f389b30a2 100644
--- a/zebra/rtadv.h
+++ b/zebra/rtadv.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_RTADV_H
diff --git a/zebra/rtadv_null.c b/zebra/rtadv_null.c
index ee6eda6bdd..ccb1a39e02 100644
--- a/zebra/rtadv_null.c
+++ b/zebra/rtadv_null.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c
index 4d491f3200..1fb2984ddf 100644
--- a/zebra/rtread_getmsg.c
+++ b/zebra/rtread_getmsg.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/rtread_netlink.c b/zebra/rtread_netlink.c
index 1d41861bbd..d59883445d 100644
--- a/zebra/rtread_netlink.c
+++ b/zebra/rtread_netlink.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/rtread_sysctl.c b/zebra/rtread_sysctl.c
index b68e1cb74a..cabb1f7714 100644
--- a/zebra/rtread_sysctl.c
+++ b/zebra/rtread_sysctl.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/test_main.c b/zebra/test_main.c
index f3ef3df96a..83c1ebb178 100644
--- a/zebra/test_main.c
+++ b/zebra/test_main.c
@@ -11,10 +11,9 @@
* 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.
+ * 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>
diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c
index 405b2e9f79..2a23ff1027 100644
--- a/zebra/zebra_fpm.c
+++ b/zebra/zebra_fpm.c
@@ -16,10 +16,9 @@
* 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.
+ * 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>
@@ -487,8 +486,8 @@ zfpm_read_on (void)
assert (!zfpm_g->t_read);
assert (zfpm_g->sock >= 0);
- THREAD_READ_ON (zfpm_g->master, zfpm_g->t_read, zfpm_read_cb, 0,
- zfpm_g->sock);
+ thread_add_read(zfpm_g->master, zfpm_read_cb, 0, zfpm_g->sock,
+ &zfpm_g->t_read);
}
/*
@@ -500,8 +499,8 @@ zfpm_write_on (void)
assert (!zfpm_g->t_write);
assert (zfpm_g->sock >= 0);
- THREAD_WRITE_ON (zfpm_g->master, zfpm_g->t_write, zfpm_write_cb, 0,
- zfpm_g->sock);
+ thread_add_write(zfpm_g->master, zfpm_write_cb, 0, zfpm_g->sock,
+ &zfpm_g->t_write);
}
/*
@@ -535,7 +534,6 @@ zfpm_conn_up_thread_cb (struct thread *thread)
zfpm_rnodes_iter_t *iter;
rib_dest_t *dest;
- assert (zfpm_g->t_conn_up);
zfpm_g->t_conn_up = NULL;
iter = &zfpm_g->t_conn_up_state.iter;
@@ -565,9 +563,9 @@ zfpm_conn_up_thread_cb (struct thread *thread)
zfpm_g->stats.t_conn_up_yields++;
zfpm_rnodes_iter_pause (iter);
- zfpm_g->t_conn_up = thread_add_background (zfpm_g->master,
- zfpm_conn_up_thread_cb,
- 0, 0);
+ zfpm_g->t_conn_up = NULL;
+ thread_add_background(zfpm_g->master, zfpm_conn_up_thread_cb, 0, 0,
+ &zfpm_g->t_conn_up);
return 0;
}
@@ -599,8 +597,9 @@ zfpm_connection_up (const char *detail)
zfpm_rnodes_iter_init (&zfpm_g->t_conn_up_state.iter);
zfpm_debug ("Starting conn_up thread");
- zfpm_g->t_conn_up = thread_add_background (zfpm_g->master,
- zfpm_conn_up_thread_cb, 0, 0);
+ zfpm_g->t_conn_up = NULL;
+ thread_add_background(zfpm_g->master, zfpm_conn_up_thread_cb, 0, 0,
+ &zfpm_g->t_conn_up);
zfpm_g->stats.t_conn_up_starts++;
}
@@ -654,7 +653,6 @@ zfpm_conn_down_thread_cb (struct thread *thread)
assert (zfpm_g->state == ZFPM_STATE_IDLE);
- assert (zfpm_g->t_conn_down);
zfpm_g->t_conn_down = NULL;
iter = &zfpm_g->t_conn_down_state.iter;
@@ -689,9 +687,9 @@ zfpm_conn_down_thread_cb (struct thread *thread)
zfpm_g->stats.t_conn_down_yields++;
zfpm_rnodes_iter_pause (iter);
- zfpm_g->t_conn_down = thread_add_background (zfpm_g->master,
- zfpm_conn_down_thread_cb,
- 0, 0);
+ zfpm_g->t_conn_down = NULL;
+ thread_add_background(zfpm_g->master, zfpm_conn_down_thread_cb, 0, 0,
+ &zfpm_g->t_conn_down);
return 0;
}
@@ -737,8 +735,9 @@ zfpm_connection_down (const char *detail)
assert (!zfpm_g->t_conn_down);
zfpm_debug ("Starting conn_down thread");
zfpm_rnodes_iter_init (&zfpm_g->t_conn_down_state.iter);
- zfpm_g->t_conn_down = thread_add_background (zfpm_g->master,
- zfpm_conn_down_thread_cb, 0, 0);
+ zfpm_g->t_conn_down = NULL;
+ thread_add_background(zfpm_g->master, zfpm_conn_down_thread_cb, 0, 0,
+ &zfpm_g->t_conn_down);
zfpm_g->stats.t_conn_down_starts++;
zfpm_set_state (ZFPM_STATE_IDLE, detail);
@@ -756,7 +755,6 @@ zfpm_read_cb (struct thread *thread)
fpm_msg_hdr_t *hdr;
zfpm_g->stats.read_cb_calls++;
- assert (zfpm_g->t_read);
zfpm_g->t_read = NULL;
/*
@@ -1045,7 +1043,6 @@ zfpm_write_cb (struct thread *thread)
int num_writes;
zfpm_g->stats.write_cb_calls++;
- assert (zfpm_g->t_write);
zfpm_g->t_write = NULL;
/*
@@ -1137,7 +1134,6 @@ zfpm_connect_cb (struct thread *t)
int sock, ret;
struct sockaddr_in serv;
- assert (zfpm_g->t_connect);
zfpm_g->t_connect = NULL;
assert (zfpm_g->state == ZFPM_STATE_ACTIVE);
@@ -1294,8 +1290,8 @@ zfpm_start_connect_timer (const char *reason)
delay_secs = zfpm_calc_connect_delay();
zfpm_debug ("scheduling connect in %ld seconds", delay_secs);
- THREAD_TIMER_ON (zfpm_g->master, zfpm_g->t_connect, zfpm_connect_cb, 0,
- delay_secs);
+ thread_add_timer(zfpm_g->master, zfpm_connect_cb, 0, delay_secs,
+ &zfpm_g->t_connect);
zfpm_set_state (ZFPM_STATE_ACTIVE, reason);
}
@@ -1388,7 +1384,6 @@ zfpm_trigger_update (struct route_node *rn, const char *reason)
static int
zfpm_stats_timer_cb (struct thread *t)
{
- assert (zfpm_g->t_stats);
zfpm_g->t_stats = NULL;
/*
@@ -1434,8 +1429,8 @@ zfpm_start_stats_timer (void)
{
assert (!zfpm_g->t_stats);
- THREAD_TIMER_ON (zfpm_g->master, zfpm_g->t_stats, zfpm_stats_timer_cb, 0,
- ZFPM_STATS_IVL_SECS);
+ thread_add_timer(zfpm_g->master, zfpm_stats_timer_cb, 0,
+ ZFPM_STATS_IVL_SECS, &zfpm_g->t_stats);
}
/*
diff --git a/zebra/zebra_fpm_dt.c b/zebra/zebra_fpm_dt.c
index 7b4e1b90dc..db28b6f0e4 100644
--- a/zebra/zebra_fpm_dt.c
+++ b/zebra/zebra_fpm_dt.c
@@ -17,10 +17,9 @@
* 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.
+ * 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
*/
/*
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index 92ab5df2c3..4ca7b59726 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -17,10 +17,9 @@
* 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.
+ * 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>
diff --git a/zebra/zebra_fpm_private.h b/zebra/zebra_fpm_private.h
index 1c4fd4c22f..49650541e7 100644
--- a/zebra/zebra_fpm_private.h
+++ b/zebra/zebra_fpm_private.h
@@ -16,10 +16,9 @@
* 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.
+ * 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 _ZEBRA_FPM_PRIVATE_H
diff --git a/zebra/zebra_fpm_protobuf.c b/zebra/zebra_fpm_protobuf.c
index 11869d8a2b..312d4cd3ed 100644
--- a/zebra/zebra_fpm_protobuf.c
+++ b/zebra/zebra_fpm_protobuf.c
@@ -17,10 +17,9 @@
* 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.
+ * 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>
diff --git a/zebra/zebra_memory.c b/zebra/zebra_memory.c
index 728051c34b..51c240ae28 100644
--- a/zebra/zebra_memory.c
+++ b/zebra/zebra_memory.c
@@ -14,10 +14,9 @@
* 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.
+ * 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
*/
#ifdef HAVE_CONFIG_H
diff --git a/zebra/zebra_memory.h b/zebra/zebra_memory.h
index c1ac4fe955..35d70d81ee 100644
--- a/zebra/zebra_memory.h
+++ b/zebra/zebra_memory.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _QUAGGA_ZEBRA_MEMORY_H
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 5a3ed7545d..d7589fda73 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -47,6 +46,7 @@
#include "zebra/zebra_mpls.h"
DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object")
+DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object")
DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config")
DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object")
DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object")
@@ -58,6 +58,32 @@ int mpls_enabled;
extern struct zebra_t zebrad;
/* static function declarations */
+
+static void
+fec_evaluate (struct zebra_vrf *zvrf, int add);
+static u_int32_t
+fec_derive_label_from_index (struct zebra_vrf *vrf, zebra_fec_t *fec);
+static int
+lsp_install (struct zebra_vrf *zvrf, mpls_label_t label,
+ struct route_node *rn, struct rib *rib);
+static int
+lsp_uninstall (struct zebra_vrf *zvrf, mpls_label_t label);
+static int
+fec_change_update_lsp (struct zebra_vrf *zvrf, zebra_fec_t *fec, mpls_label_t old_label);
+static int
+fec_send (zebra_fec_t *fec, struct zserv *client);
+static void
+fec_update_clients (zebra_fec_t *fec);
+static void
+fec_print (zebra_fec_t *fec, struct vty *vty);
+static zebra_fec_t *
+fec_find (struct route_table *table, struct prefix *p);
+static zebra_fec_t *
+fec_add (struct route_table *table, struct prefix *p, mpls_label_t label,
+ u_int32_t flags, u_int32_t label_index);
+static int
+fec_del (zebra_fec_t *fec);
+
static unsigned int
label_hash (void *p);
static int
@@ -68,6 +94,7 @@ static int
nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop);
static int
nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe);
+
static void
lsp_select_best_nhlfe (zebra_lsp_t *lsp);
static void
@@ -84,21 +111,24 @@ static int
lsp_processq_add (zebra_lsp_t *lsp);
static void *
lsp_alloc (void *p);
+
static char *
nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size);
static int
nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex);
+ union g_addr *gate, ifindex_t ifindex);
static zebra_nhlfe_t *
nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
enum nexthop_types_t gtype, union g_addr *gate,
- char *ifname, ifindex_t ifindex);
+ ifindex_t ifindex);
static zebra_nhlfe_t *
nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
enum nexthop_types_t gtype, union g_addr *gate,
- char *ifname, ifindex_t ifindex, mpls_label_t out_label);
+ ifindex_t ifindex, mpls_label_t out_label);
static int
nhlfe_del (zebra_nhlfe_t *snhlfe);
+static void
+nhlfe_out_label_update (zebra_nhlfe_t *nhlfe, struct nexthop_label *nh_label);
static int
mpls_lsp_uninstall_all (struct hash *lsp_table, zebra_lsp_t *lsp,
enum lsp_types_t type);
@@ -112,21 +142,20 @@ static void *
slsp_alloc (void *p);
static int
snhlfe_match (zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex);
+ union g_addr *gate, ifindex_t ifindex);
static zebra_snhlfe_t *
snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex);
+ union g_addr *gate, ifindex_t ifindex);
static zebra_snhlfe_t *
snhlfe_add (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex,
- mpls_label_t out_label);
+ union g_addr *gate, ifindex_t ifindex, mpls_label_t out_label);
static int
snhlfe_del (zebra_snhlfe_t *snhlfe);
static int
snhlfe_del_all (zebra_slsp_t *slsp);
static char *
snhlfe2str (zebra_snhlfe_t *snhlfe, char *buf, int size);
-static void
+static int
mpls_processq_init (struct zebra_t *zebra);
@@ -135,6 +164,465 @@ mpls_processq_init (struct zebra_t *zebra);
/* Static functions */
/*
+ * Install label forwarding entry based on labeled-route entry.
+ */
+static int
+lsp_install (struct zebra_vrf *zvrf, mpls_label_t label,
+ struct route_node *rn, struct rib *rib)
+{
+ struct hash *lsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe;
+ struct nexthop *nexthop;
+ enum lsp_types_t lsp_type;
+ char buf[BUFSIZ];
+ int added, changed;
+
+ /* Lookup table. */
+ lsp_table = zvrf->lsp_table;
+ if (!lsp_table)
+ return -1;
+
+ lsp_type = lsp_type_from_rib_type (rib->type);
+ added = changed = 0;
+
+ /* Locate or allocate LSP entry. */
+ tmp_ile.in_label = label;
+ lsp = hash_get (lsp_table, &tmp_ile, lsp_alloc);
+ if (!lsp)
+ return -1;
+
+ /* For each active nexthop, create NHLFE. Note that we deliberately skip
+ * recursive nexthops right now, because intermediate hops won't understand
+ * the label advertised by the recursive nexthop (plus we don't have the
+ * logic yet to push multiple labels).
+ */
+ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
+ {
+ /* Skip inactive and recursive entries. */
+ if (!CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ continue;
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ continue;
+
+ nhlfe = nhlfe_find (lsp, lsp_type, nexthop->type, &nexthop->gate,
+ nexthop->ifindex);
+ if (nhlfe)
+ {
+ /* Clear deleted flag (in case it was set) */
+ UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED);
+ if (nexthop_labels_match (nhlfe->nexthop, nexthop))
+ /* No change */
+ continue;
+
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ {
+ nhlfe2str (nhlfe, buf, BUFSIZ);
+ zlog_debug ("LSP in-label %u type %d nexthop %s "
+ "out-label changed",
+ lsp->ile.in_label, lsp_type, buf);
+ }
+
+ /* Update out label, trigger processing. */
+ nhlfe_out_label_update (nhlfe, nexthop->nh_label);
+ SET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED);
+ changed++;
+ }
+ else
+ {
+ /* Add LSP entry to this nexthop */
+ nhlfe = nhlfe_add (lsp, lsp_type, nexthop->type,
+ &nexthop->gate, nexthop->ifindex,
+ nexthop->nh_label->label[0]);
+ if (!nhlfe)
+ return -1;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ {
+ nhlfe2str (nhlfe, buf, BUFSIZ);
+ zlog_debug ("Add LSP in-label %u type %d nexthop %s "
+ "out-label %u",
+ lsp->ile.in_label, lsp_type, buf,
+ nexthop->nh_label->label[0]);
+ }
+
+ lsp->addr_family = NHLFE_FAMILY (nhlfe);
+
+ /* Mark NHLFE as changed. */
+ SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
+ added++;
+ }
+ }
+
+ /* Queue LSP for processing if necessary. If no NHLFE got added (special
+ * case), delete the LSP entry; this case results in somewhat ugly logging.
+ */
+ if (added || changed)
+ {
+ if (lsp_processq_add (lsp))
+ return -1;
+ }
+ else if (!lsp->nhlfe_list &&
+ !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED))
+ {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug ("Free LSP in-label %u flags 0x%x",
+ lsp->ile.in_label, lsp->flags);
+
+ lsp = hash_release(lsp_table, &lsp->ile);
+ if (lsp)
+ XFREE(MTYPE_LSP, lsp);
+ }
+
+ return 0;
+}
+
+/*
+ * Uninstall all non-static NHLFEs of a label forwarding entry. If all
+ * NHLFEs are removed, the entire entry is deleted.
+ */
+static int
+lsp_uninstall (struct zebra_vrf *zvrf, mpls_label_t label)
+{
+ struct hash *lsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe, *nhlfe_next;
+ char buf[BUFSIZ];
+
+ /* Lookup table. */
+ lsp_table = zvrf->lsp_table;
+ if (!lsp_table)
+ return -1;
+
+ /* If entry is not present, exit. */
+ tmp_ile.in_label = label;
+ lsp = hash_lookup (lsp_table, &tmp_ile);
+ if (!lsp || !lsp->nhlfe_list)
+ return 0;
+
+ /* Mark NHLFEs for delete or directly delete, as appropriate. */
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next)
+ {
+ nhlfe_next = nhlfe->next;
+
+ /* Skip static NHLFEs */
+ if (nhlfe->type == ZEBRA_LSP_STATIC)
+ continue;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ {
+ nhlfe2str (nhlfe, buf, BUFSIZ);
+ zlog_debug ("Del LSP in-label %u type %d nexthop %s flags 0x%x",
+ label, nhlfe->type, buf, nhlfe->flags);
+ }
+
+ if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED))
+ {
+ UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED);
+ SET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED);
+ }
+ else
+ {
+ nhlfe_del (nhlfe);
+ }
+ }
+
+ /* Queue LSP for processing, if needed, else delete. */
+ if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
+ {
+ if (lsp_processq_add (lsp))
+ return -1;
+ }
+ else if (!lsp->nhlfe_list &&
+ !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED))
+ {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug ("Del LSP in-label %u flags 0x%x",
+ lsp->ile.in_label, lsp->flags);
+
+ lsp = hash_release(lsp_table, &lsp->ile);
+ if (lsp)
+ XFREE(MTYPE_LSP, lsp);
+ }
+
+ return 0;
+}
+
+/*
+ * This function is invoked upon change to label block configuration; it
+ * will walk all registered FECs with label-index and appropriately update
+ * their local labels and trigger client updates.
+ */
+static void
+fec_evaluate (struct zebra_vrf *zvrf, int add)
+{
+ struct route_node *rn;
+ zebra_fec_t *fec;
+ u_int32_t old_label, new_label;
+ int af;
+ char buf[BUFSIZ];
+
+ for (af = AFI_IP; af < AFI_MAX; af++)
+ {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
+
+ for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
+ {
+ if ((fec = rn->info) == NULL)
+ continue;
+
+ /* Skip configured FECs and those without a label index. */
+ if (fec->flags & FEC_FLAG_CONFIGURED ||
+ fec->label_index == MPLS_INVALID_LABEL_INDEX)
+ continue;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ prefix2str(&rn->p, buf, BUFSIZ);
+
+ /* Save old label, determine new label. */
+ old_label = fec->label;
+ if (add)
+ {
+ new_label = zvrf->mpls_srgb.start_label + fec->label_index;
+ if (new_label >= zvrf->mpls_srgb.end_label)
+ new_label = MPLS_INVALID_LABEL;
+ }
+ else
+ new_label = MPLS_INVALID_LABEL;
+
+ /* If label has changed, update FEC and clients. */
+ if (new_label == old_label)
+ continue;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug ("Update fec %s new label %u upon label block %s",
+ buf, new_label, add ? "ADD" : "DEL");
+
+ fec->label = new_label;
+ fec_update_clients (fec);
+
+ /* Update label forwarding entries appropriately */
+ fec_change_update_lsp (zvrf, fec, old_label);
+ }
+ }
+}
+
+/*
+ * Derive (if possible) and update the local label for the FEC based on
+ * its label index. The index is "acceptable" if it falls within the
+ * globally configured label block (SRGB).
+ */
+static u_int32_t
+fec_derive_label_from_index (struct zebra_vrf *zvrf, zebra_fec_t *fec)
+{
+ u_int32_t label;
+
+ if (fec->label_index != MPLS_INVALID_LABEL_INDEX &&
+ zvrf->mpls_srgb.start_label &&
+ ((label = zvrf->mpls_srgb.start_label + fec->label_index) <
+ zvrf->mpls_srgb.end_label))
+ fec->label = label;
+ else
+ fec->label = MPLS_INVALID_LABEL;
+
+ return fec->label;
+}
+
+/*
+ * There is a change for this FEC. Install or uninstall label forwarding
+ * entries, as appropriate.
+ */
+static int
+fec_change_update_lsp (struct zebra_vrf *zvrf, zebra_fec_t *fec, mpls_label_t old_label)
+{
+ struct route_table *table;
+ struct route_node *rn;
+ struct rib *rib;
+ afi_t afi;
+
+ /* Uninstall label forwarding entry, if previously installed. */
+ if (old_label != MPLS_INVALID_LABEL &&
+ old_label != MPLS_IMP_NULL_LABEL)
+ lsp_uninstall (zvrf, old_label);
+
+ /* Install label forwarding entry corr. to new label, if needed. */
+ if (fec->label == MPLS_INVALID_LABEL ||
+ fec->label == MPLS_IMP_NULL_LABEL)
+ return 0;
+
+ afi = family2afi(PREFIX_FAMILY(&fec->rn->p));
+ table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf_id (zvrf));
+ if (!table)
+ return 0;
+
+ /* See if labeled route exists. */
+ rn = route_node_lookup (table, &fec->rn->p);
+ if (!rn)
+ return 0;
+
+ RNODE_FOREACH_RIB (rn, rib)
+ {
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
+
+ if (!rib || !zebra_rib_labeled_unicast (rib))
+ return 0;
+
+ if (lsp_install (zvrf, fec->label, rn, rib))
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Inform about FEC to a registered client.
+ */
+static int
+fec_send (zebra_fec_t *fec, struct zserv *client)
+{
+ struct stream *s;
+ struct route_node *rn;
+
+ rn = fec->rn;
+
+ /* Get output stream. */
+ s = client->obuf;
+ stream_reset (s);
+
+ zserv_create_header (s, ZEBRA_FEC_UPDATE, VRF_DEFAULT);
+
+ stream_putw(s, rn->p.family);
+ stream_put_prefix (s, &rn->p);
+ stream_putl(s, fec->label);
+ stream_putw_at(s, 0, stream_get_endp(s));
+ return zebra_server_send_message(client);
+}
+
+/*
+ * Update all registered clients about this FEC. Caller should've updated
+ * FEC and ensure no duplicate updates.
+ */
+static void
+fec_update_clients (zebra_fec_t *fec)
+{
+ struct listnode *node;
+ struct zserv *client;
+
+ for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, client))
+ {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug ("Update client %s", zebra_route_string(client->proto));
+ fec_send(fec, client);
+ }
+}
+
+
+/*
+ * Print a FEC-label binding entry.
+ */
+static void
+fec_print (zebra_fec_t *fec, struct vty *vty)
+{
+ struct route_node *rn;
+ struct listnode *node;
+ struct zserv *client;
+ char buf[BUFSIZ];
+
+ rn = fec->rn;
+ prefix2str(&rn->p, buf, BUFSIZ);
+ vty_out(vty, "%s%s", buf, VTY_NEWLINE);
+ vty_out(vty, " Label: %s", label2str(fec->label, buf, BUFSIZ));
+ if (fec->label_index != MPLS_INVALID_LABEL_INDEX)
+ vty_out(vty, ", Label Index: %u", fec->label_index);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ if (!list_isempty(fec->client_list))
+ {
+ vty_out(vty, " Client list:");
+ for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, client))
+ vty_out(vty, " %s(fd %d)",
+ zebra_route_string(client->proto), client->sock);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+}
+
+/*
+ * Locate FEC-label binding that matches with passed info.
+ */
+static zebra_fec_t *
+fec_find (struct route_table *table, struct prefix *p)
+{
+ struct route_node *rn;
+
+ apply_mask (p);
+ rn = route_node_lookup(table, p);
+ if (!rn)
+ return NULL;
+
+ route_unlock_node(rn);
+ return (rn->info);
+}
+
+/*
+ * Add a FEC. This may be upon a client registering for a binding
+ * or when a binding is configured.
+ */
+static zebra_fec_t *
+fec_add (struct route_table *table, struct prefix *p,
+ mpls_label_t label, u_int32_t flags, u_int32_t label_index)
+{
+ struct route_node *rn;
+ zebra_fec_t *fec;
+
+ apply_mask (p);
+
+ /* Lookup (or add) route node.*/
+ rn = route_node_get (table, p);
+ if (!rn)
+ return NULL;
+
+ fec = rn->info;
+
+ if (!fec)
+ {
+ fec = XCALLOC (MTYPE_FEC, sizeof(zebra_fec_t));
+ if (!fec)
+ return NULL;
+
+ rn->info = fec;
+ fec->rn = rn;
+ fec->label = label;
+ fec->client_list = list_new();
+ }
+ else
+ route_unlock_node (rn); /* for the route_node_get */
+
+ fec->label_index = label_index;
+ fec->flags = flags;
+
+ return fec;
+}
+
+/*
+ * Delete a FEC. This may be upon the last client deregistering for
+ * a FEC and no binding exists or when the binding is deleted and there
+ * are no registered clients.
+ */
+static int
+fec_del (zebra_fec_t *fec)
+{
+ list_free (fec->client_list);
+ fec->rn->info = NULL;
+ route_unlock_node (fec->rn);
+ XFREE (MTYPE_FEC, fec);
+ return 0;
+}
+
+/*
* Hash function for label.
*/
static unsigned int
@@ -548,6 +1036,12 @@ lsp_processq_add (zebra_lsp_t *lsp)
if (CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED))
return 0;
+ if (zebrad.lsp_process_q == NULL)
+ {
+ zlog_err ("%s: work_queue does not exist!", __func__);
+ return -1;
+ }
+
work_queue_add (zebrad.lsp_process_q, lsp);
SET_FLAG (lsp->flags, LSP_FLAG_SCHEDULED);
return 0;
@@ -602,7 +1096,7 @@ nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size)
*/
static int
nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex)
+ union g_addr *gate, ifindex_t ifindex)
{
struct nexthop *nhop;
int cmp = 1;
@@ -644,7 +1138,7 @@ nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
static zebra_nhlfe_t *
nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
enum nexthop_types_t gtype, union g_addr *gate,
- char *ifname, ifindex_t ifindex)
+ ifindex_t ifindex)
{
zebra_nhlfe_t *nhlfe;
@@ -655,7 +1149,7 @@ nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
{
if (nhlfe->type != lsp_type)
continue;
- if (!nhlfe_nhop_match (nhlfe, gtype, gate, ifname, ifindex))
+ if (!nhlfe_nhop_match (nhlfe, gtype, gate, ifindex))
break;
}
@@ -669,7 +1163,7 @@ nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
static zebra_nhlfe_t *
nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
enum nexthop_types_t gtype, union g_addr *gate,
- char *ifname, ifindex_t ifindex, mpls_label_t out_label)
+ ifindex_t ifindex, mpls_label_t out_label)
{
zebra_nhlfe_t *nhlfe;
struct nexthop *nexthop;
@@ -759,6 +1253,15 @@ nhlfe_del (zebra_nhlfe_t *nhlfe)
return 0;
}
+/*
+ * Update label for NHLFE entry.
+ */
+static void
+nhlfe_out_label_update (zebra_nhlfe_t *nhlfe, struct nexthop_label *nh_label)
+{
+ nhlfe->nexthop->nh_label->label[0] = nh_label->label[0];
+}
+
static int
mpls_lsp_uninstall_all (struct hash *lsp_table, zebra_lsp_t *lsp,
enum lsp_types_t type)
@@ -1026,7 +1529,7 @@ slsp_cmp (zebra_slsp_t *slsp1, zebra_slsp_t *slsp2)
*/
static int
snhlfe_match (zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex)
+ union g_addr *gate, ifindex_t ifindex)
{
int cmp = 1;
@@ -1058,7 +1561,7 @@ snhlfe_match (zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
*/
static zebra_snhlfe_t *
snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex)
+ union g_addr *gate, ifindex_t ifindex)
{
zebra_snhlfe_t *snhlfe;
@@ -1067,7 +1570,7 @@ snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next)
{
- if (!snhlfe_match (snhlfe, gtype, gate, ifname, ifindex))
+ if (!snhlfe_match (snhlfe, gtype, gate, ifindex))
break;
}
@@ -1081,7 +1584,7 @@ snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
*/
static zebra_snhlfe_t *
snhlfe_add (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex,
+ union g_addr *gate, ifindex_t ifindex,
mpls_label_t out_label)
{
zebra_snhlfe_t *snhlfe;
@@ -1195,14 +1698,14 @@ snhlfe2str (zebra_snhlfe_t *snhlfe, char *buf, int size)
/*
* Initialize work queue for processing changed LSPs.
*/
-static void
+static int
mpls_processq_init (struct zebra_t *zebra)
{
zebra->lsp_process_q = work_queue_new (zebra->master, "LSP processing");
if (!zebra->lsp_process_q)
{
zlog_err ("%s: could not initialise work queue!", __func__);
- return;
+ return -1;
}
zebra->lsp_process_q->spec.workfunc = &lsp_process;
@@ -1211,6 +1714,8 @@ mpls_processq_init (struct zebra_t *zebra)
zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete;
zebra->lsp_process_q->spec.max_retries = 0;
zebra->lsp_process_q->spec.hold = 10;
+
+ return 0;
}
@@ -1230,7 +1735,7 @@ mpls_str2label (const char *label_str, u_int8_t *num_labels,
*num_labels = 0;
for (i = 0; i < MPLS_MAX_LABELS; i++)
{
- u_int32_t label;
+ mpls_label_t label;
label = strtoul(label_str, &endp, 0);
@@ -1264,17 +1769,513 @@ mpls_str2label (const char *label_str, u_int8_t *num_labels,
*/
char *
mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
- char *buf, int len)
+ char *buf, int len, int pretty)
{
+ char *buf_ptr = buf;
buf[0] = '\0';
- if (num_labels == 1)
- snprintf (buf, len, "%u", labels[0]);
- else if (num_labels == 2)
- snprintf (buf, len, "%u/%u", labels[0], labels[1]);
+
+ if (pretty) {
+ if (num_labels == 1) {
+ label2str(labels[0], buf, len);
+ } else if (num_labels == 2) {
+ label2str(labels[0], buf, len);
+ buf_ptr += strlen(buf);
+
+ snprintf (buf_ptr, len, "/");
+ buf_ptr++;
+
+ label2str(labels[1], buf_ptr, len);
+ }
+ } else {
+ if (num_labels == 1)
+ snprintf (buf, len, "%u", labels[0]);
+ else if (num_labels == 2)
+ snprintf (buf, len, "%u/%u", labels[0], labels[1]);
+ }
return buf;
}
/*
+ * Install dynamic LSP entry.
+ */
+int
+zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib)
+{
+ struct route_table *table;
+ zebra_fec_t *fec;
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(&rn->p))];
+ if (!table)
+ return -1;
+
+ /* See if there is a configured label binding for this FEC. */
+ fec = fec_find (table, &rn->p);
+ if (!fec || fec->label == MPLS_INVALID_LABEL)
+ return 0;
+
+ /* We cannot install a label forwarding entry if local label is the
+ * implicit-null label.
+ */
+ if (fec->label == MPLS_IMP_NULL_LABEL)
+ return 0;
+
+ if (lsp_install (zvrf, fec->label, rn, rib))
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Uninstall dynamic LSP entry, if any.
+ */
+int
+zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib)
+{
+ struct route_table *table;
+ zebra_fec_t *fec;
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(&rn->p))];
+ if (!table)
+ return -1;
+
+ /* See if there is a configured label binding for this FEC. */
+ fec = fec_find (table, &rn->p);
+ if (!fec || fec->label == MPLS_INVALID_LABEL)
+ return 0;
+
+ /* Uninstall always removes all dynamic NHLFEs. */
+ return lsp_uninstall (zvrf, fec->label);
+}
+
+/*
+ * Registration from a client for the label binding for a FEC. If a binding
+ * already exists, it is informed to the client.
+ * NOTE: If there is a manually configured label binding, that is used.
+ * Otherwise, if aa label index is specified, it means we have to allocate the
+ * label from a locally configured label block (SRGB), if one exists and index
+ * is acceptable.
+ */
+int
+zebra_mpls_fec_register (struct zebra_vrf *zvrf, struct prefix *p,
+ u_int32_t label_index, struct zserv *client)
+{
+ struct route_table *table;
+ zebra_fec_t *fec;
+ char buf[BUFSIZ];
+ int new_client;
+ int label_change = 0;
+ u_int32_t old_label;
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return -1;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ prefix2str(p, buf, BUFSIZ);
+
+ /* Locate FEC */
+ fec = fec_find (table, p);
+ if (!fec)
+ {
+ fec = fec_add (table, p, MPLS_INVALID_LABEL, 0, label_index);
+ if (!fec)
+ {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_err("Failed to add FEC %s upon register, client %s",
+ buf, zebra_route_string(client->proto));
+ return -1;
+ }
+
+ old_label = MPLS_INVALID_LABEL;
+ new_client = 1;
+ }
+ else
+ {
+ /* Client may register same FEC with different label index. */
+ new_client = (listnode_lookup(fec->client_list, client) == NULL);
+ if (!new_client && fec->label_index == label_index)
+ /* Duplicate register */
+ return 0;
+
+ /* Save current label, update label index */
+ old_label = fec->label;
+ fec->label_index = label_index;
+ }
+
+ if (new_client)
+ listnode_add (fec->client_list, client);
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("FEC %s Label Index %u %s by client %s",
+ buf, label_index, new_client ? "registered" : "updated",
+ zebra_route_string(client->proto));
+
+ /* If not a configured FEC, derive the local label (from label index)
+ * or reset it.
+ */
+ if (!(fec->flags & FEC_FLAG_CONFIGURED))
+ {
+ fec_derive_label_from_index (zvrf, fec);
+
+ /* If no label change, exit. */
+ if (fec->label == old_label)
+ return 0;
+
+ label_change = 1;
+ }
+
+ /* If new client or label change, update client and install or uninstall
+ * label forwarding entry as needed.
+ */
+ /* Inform client of label, if needed. */
+ if ((new_client && fec->label != MPLS_INVALID_LABEL) ||
+ label_change)
+ {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug ("Update client label %u", fec->label);
+ fec_send (fec, client);
+ }
+
+ if (new_client || label_change)
+ return fec_change_update_lsp (zvrf, fec, old_label);
+
+ return 0;
+}
+
+/*
+ * Deregistration from a client for the label binding for a FEC. The FEC
+ * itself is deleted if no other registered clients exist and there is no
+ * label bound to the FEC.
+ */
+int
+zebra_mpls_fec_unregister (struct zebra_vrf *zvrf, struct prefix *p,
+ struct zserv *client)
+{
+ struct route_table *table;
+ zebra_fec_t *fec;
+ char buf[BUFSIZ];
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return -1;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ prefix2str(p, buf, BUFSIZ);
+
+ fec = fec_find (table, p);
+ if (!fec)
+ {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_err("Failed to find FEC %s upon unregister, client %s",
+ buf, zebra_route_string(client->proto));
+ return -1;
+ }
+
+ listnode_delete(fec->client_list, client);
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("FEC %s unregistered by client %s",
+ buf, zebra_route_string(client->proto));
+
+ /* If not a configured entry, delete the FEC if no other clients. Before
+ * deleting, see if any LSP needs to be uninstalled.
+ */
+ if (!(fec->flags & FEC_FLAG_CONFIGURED) &&
+ list_isempty(fec->client_list))
+ {
+ mpls_label_t old_label = fec->label;
+ fec->label = MPLS_INVALID_LABEL; /* reset */
+ fec_change_update_lsp (zvrf, fec, old_label);
+ fec_del (fec);
+ }
+
+ return 0;
+}
+
+/*
+ * Cleanup any FECs registered by this client.
+ */
+int
+zebra_mpls_cleanup_fecs_for_client (struct zebra_vrf *zvrf, struct zserv *client)
+{
+ struct route_node *rn;
+ zebra_fec_t *fec;
+ struct listnode *node;
+ struct zserv *fec_client;
+ int af;
+
+ for (af = AFI_IP; af < AFI_MAX; af++)
+ {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
+
+ for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
+ {
+ fec = rn->info;
+ if (!fec || list_isempty(fec->client_list))
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, fec_client))
+ {
+ if (fec_client == client)
+ {
+ listnode_delete(fec->client_list, fec_client);
+ if (!(fec->flags & FEC_FLAG_CONFIGURED) &&
+ list_isempty(fec->client_list))
+ fec_del (fec);
+ break;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Return FEC (if any) to which this label is bound.
+ * Note: Only works for per-prefix binding and when the label is not
+ * implicit-null.
+ * TODO: Currently walks entire table, can optimize later with another
+ * hash..
+ */
+zebra_fec_t *
+zebra_mpls_fec_for_label (struct zebra_vrf *zvrf, mpls_label_t label)
+{
+ struct route_node *rn;
+ zebra_fec_t *fec;
+ int af;
+
+ for (af = AFI_IP; af < AFI_MAX; af++)
+ {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
+
+ for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
+ {
+ if (!rn->info)
+ continue;
+ fec = rn->info;
+ if (fec->label == label)
+ return fec;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Inform if specified label is currently bound to a FEC or not.
+ */
+int
+zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label)
+{
+ return (zebra_mpls_fec_for_label (zvrf, label) ? 1 : 0);
+}
+
+/*
+ * Add static FEC to label binding. If there are clients registered for this
+ * FEC, notify them. If there are labeled routes for this FEC, install the
+ * label forwarding entry.
+*/
+int
+zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
+ mpls_label_t in_label)
+{
+ struct route_table *table;
+ zebra_fec_t *fec;
+ char buf[BUFSIZ];
+ mpls_label_t old_label;
+ int ret = 0;
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return -1;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ prefix2str(p, buf, BUFSIZ);
+
+ /* Update existing FEC or create a new one. */
+ fec = fec_find (table, p);
+ if (!fec)
+ {
+ fec = fec_add (table, p, in_label, FEC_FLAG_CONFIGURED,
+ MPLS_INVALID_LABEL_INDEX);
+ if (!fec)
+ {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_err ("Failed to add FEC %s upon config", buf);
+ return -1;
+ }
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug ("Add fec %s label %u", buf, in_label);
+ }
+ else
+ {
+ fec->flags |= FEC_FLAG_CONFIGURED;
+ if (fec->label == in_label)
+ /* Duplicate config */
+ return 0;
+
+ /* Label change, update clients. */
+ old_label = fec->label;
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug ("Update fec %s new label %u", buf, in_label);
+
+ fec->label = in_label;
+ fec_update_clients (fec);
+
+ /* Update label forwarding entries appropriately */
+ ret = fec_change_update_lsp (zvrf, fec, old_label);
+ }
+
+ return ret;
+}
+
+/*
+ * Remove static FEC to label binding. If there are no clients registered
+ * for this FEC, delete the FEC; else notify clients
+ * Note: Upon delete of static binding, if label index exists for this FEC,
+ * client may need to be updated with derived label.
+ */
+int
+zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p)
+{
+ struct route_table *table;
+ zebra_fec_t *fec;
+ mpls_label_t old_label;
+ char buf[BUFSIZ];
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return -1;
+
+ fec = fec_find (table, p);
+ if (!fec)
+ {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_err("Failed to find FEC %s upon delete", buf);
+ return -1;
+ }
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_debug ("Delete fec %s label index %u",
+ buf, fec->label_index);
+ }
+
+ old_label = fec->label;
+ fec->flags &= ~FEC_FLAG_CONFIGURED;
+ fec->label = MPLS_INVALID_LABEL;
+
+ /* If no client exists, just delete the FEC. */
+ if (list_isempty(fec->client_list))
+ {
+ fec_del (fec);
+ return 0;
+ }
+
+ /* Derive the local label (from label index) or reset it. */
+ fec_derive_label_from_index (zvrf, fec);
+
+ /* If there is a label change, update clients. */
+ if (fec->label == old_label)
+ return 0;
+ fec_update_clients (fec);
+
+ /* Update label forwarding entries appropriately */
+ return fec_change_update_lsp (zvrf, fec, old_label);
+}
+
+/*
+ * Display MPLS FEC to label binding configuration (VTY command handler).
+ */
+int
+zebra_mpls_write_fec_config (struct vty *vty, struct zebra_vrf *zvrf)
+{
+ struct route_node *rn;
+ int af;
+ zebra_fec_t *fec;
+ char buf[BUFSIZ];
+ int write = 0;
+
+ for (af = AFI_IP; af < AFI_MAX; af++)
+ {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
+
+ for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
+ {
+ if (!rn->info)
+ continue;
+
+ char lstr[BUFSIZ];
+ fec = rn->info;
+
+ if (!(fec->flags & FEC_FLAG_CONFIGURED))
+ continue;
+
+ write = 1;
+ prefix2str(&rn->p, buf, BUFSIZ);
+ vty_out(vty, "mpls label bind %s %s%s", buf,
+ label2str(fec->label, lstr, BUFSIZ), VTY_NEWLINE);
+ }
+ }
+
+ return write;
+}
+
+/*
+ * Display MPLS FEC to label binding (VTY command handler).
+ */
+void
+zebra_mpls_print_fec_table (struct vty *vty, struct zebra_vrf *zvrf)
+{
+ struct route_node *rn;
+ int af;
+
+ for (af = AFI_IP; af < AFI_MAX; af++)
+ {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
+
+ for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
+ {
+ if (!rn->info)
+ continue;
+ fec_print (rn->info, vty);
+ }
+ }
+}
+
+/*
+ * Display MPLS FEC to label binding for a specific FEC (VTY command handler).
+ */
+void
+zebra_mpls_print_fec (struct vty *vty, struct zebra_vrf *zvrf, struct prefix *p)
+{
+ struct route_table *table;
+ struct route_node *rn;
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return;
+
+ apply_mask (p);
+ rn = route_node_lookup(table, p);
+ if (!rn)
+ return;
+
+ route_unlock_node(rn);
+ if (!rn->info)
+ return;
+
+ fec_print (rn->info, vty);
+}
+
+/*
* Install/uninstall a FEC-To-NHLFE (FTN) binding.
*/
int
@@ -1361,7 +2362,7 @@ int
mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type,
mpls_label_t in_label, mpls_label_t out_label,
enum nexthop_types_t gtype, union g_addr *gate,
- char *ifname, ifindex_t ifindex)
+ ifindex_t ifindex)
{
struct hash *lsp_table;
zebra_ile_t tmp_ile;
@@ -1379,7 +2380,7 @@ mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type,
lsp = hash_get (lsp_table, &tmp_ile, lsp_alloc);
if (!lsp)
return -1;
- nhlfe = nhlfe_find (lsp, type, gtype, gate, ifname, ifindex);
+ nhlfe = nhlfe_find (lsp, type, gtype, gate, ifindex);
if (nhlfe)
{
struct nexthop *nh = nhlfe->nexthop;
@@ -1408,8 +2409,7 @@ mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type,
else
{
/* Add LSP entry to this nexthop */
- nhlfe = nhlfe_add (lsp, type, gtype, gate,
- ifname, ifindex, out_label);
+ nhlfe = nhlfe_add (lsp, type, gtype, gate, ifindex, out_label);
if (!nhlfe)
return -1;
@@ -1438,7 +2438,7 @@ mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type,
int
mpls_lsp_uninstall (struct zebra_vrf *zvrf, enum lsp_types_t type,
mpls_label_t in_label, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex)
+ union g_addr *gate, ifindex_t ifindex)
{
struct hash *lsp_table;
zebra_ile_t tmp_ile;
@@ -1456,7 +2456,7 @@ mpls_lsp_uninstall (struct zebra_vrf *zvrf, enum lsp_types_t type,
lsp = hash_lookup (lsp_table, &tmp_ile);
if (!lsp)
return 0;
- nhlfe = nhlfe_find (lsp, type, gtype, gate, ifname, ifindex);
+ nhlfe = nhlfe_find (lsp, type, gtype, gate, ifindex);
if (!nhlfe)
return 0;
@@ -1561,7 +2561,7 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
int
zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
mpls_label_t out_label, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex)
+ union g_addr *gate, ifindex_t ifindex)
{
struct hash *slsp_table;
zebra_ile_t tmp_ile;
@@ -1579,7 +2579,7 @@ zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
if (!slsp)
return 1;
- snhlfe = snhlfe_find (slsp, gtype, gate, ifname, ifindex);
+ snhlfe = snhlfe_find (slsp, gtype, gate, ifindex);
if (snhlfe)
{
if (snhlfe->out_label == out_label)
@@ -1619,7 +2619,7 @@ zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
int
zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
mpls_label_t out_label, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex)
+ union g_addr *gate, ifindex_t ifindex)
{
struct hash *slsp_table;
zebra_ile_t tmp_ile;
@@ -1637,7 +2637,7 @@ zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
slsp = hash_get (slsp_table, &tmp_ile, slsp_alloc);
if (!slsp)
return -1;
- snhlfe = snhlfe_find (slsp, gtype, gate, ifname, ifindex);
+ snhlfe = snhlfe_find (slsp, gtype, gate, ifindex);
if (snhlfe)
{
if (snhlfe->out_label == out_label)
@@ -1656,7 +2656,7 @@ zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
else
{
/* Add static LSP entry to this nexthop */
- snhlfe = snhlfe_add (slsp, gtype, gate, ifname, ifindex, out_label);
+ snhlfe = snhlfe_add (slsp, gtype, gate, ifindex, out_label);
if (!snhlfe)
return -1;
@@ -1670,7 +2670,7 @@ zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
/* (Re)Install LSP in the main table. */
if (mpls_lsp_install (zvrf, ZEBRA_LSP_STATIC, in_label, out_label, gtype,
- gate, ifname, ifindex))
+ gate, ifindex))
return -1;
return 0;
@@ -1686,7 +2686,7 @@ zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
int
zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,
enum nexthop_types_t gtype, union g_addr *gate,
- char *ifname, ifindex_t ifindex)
+ ifindex_t ifindex)
{
struct hash *slsp_table;
zebra_ile_t tmp_ile;
@@ -1719,7 +2719,7 @@ zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,
else
{
/* Find specific NHLFE, exit if not found. */
- snhlfe = snhlfe_find (slsp, gtype, gate, ifname, ifindex);
+ snhlfe = snhlfe_find (slsp, gtype, gate, ifindex);
if (!snhlfe)
return 0;
@@ -1733,7 +2733,7 @@ zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,
/* Uninstall LSP from the main table. */
mpls_lsp_uninstall (zvrf, ZEBRA_LSP_STATIC, in_label, gtype, gate,
- ifname, ifindex);
+ ifindex);
/* Delete static LSP NHLFE */
snhlfe_del (snhlfe);
@@ -1902,6 +2902,51 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)
}
/*
+ * Add/update global label block.
+ */
+int
+zebra_mpls_label_block_add (struct zebra_vrf *zvrf, u_int32_t start_label,
+ u_int32_t end_label)
+{
+ zvrf->mpls_srgb.start_label = start_label;
+ zvrf->mpls_srgb.end_label = end_label;
+
+ /* Evaluate registered FECs to see if any get a label or not. */
+ fec_evaluate (zvrf, 1);
+ return 0;
+}
+
+/*
+ * Delete global label block.
+ */
+int
+zebra_mpls_label_block_del (struct zebra_vrf *zvrf)
+{
+ zvrf->mpls_srgb.start_label = 0;
+ zvrf->mpls_srgb.end_label = 0;
+
+ /* Process registered FECs to clear their local label, if needed. */
+ fec_evaluate (zvrf, 0);
+ return 0;
+}
+
+/*
+ * Display MPLS global label block configuration (VTY command handler).
+ */
+int
+zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *zvrf)
+{
+ if (zvrf->mpls_srgb.start_label == 0)
+ return 0;
+
+ vty_out(vty, "mpls label global-block %u %u%s",
+ zvrf->mpls_srgb.start_label, zvrf->mpls_srgb.end_label,
+ VTY_NEWLINE);
+
+ return 1;
+}
+
+/*
* Called upon process exiting, need to delete LSP forwarding
* entries from the kernel.
* NOTE: Currently supported only for default VRF.
@@ -1927,7 +2972,11 @@ zebra_mpls_init_tables (struct zebra_vrf *zvrf)
return;
zvrf->slsp_table = hash_create(label_hash, label_cmp);
zvrf->lsp_table = hash_create(label_hash, label_cmp);
+ zvrf->fec_table[AFI_IP] = route_table_init();
+ zvrf->fec_table[AFI_IP6] = route_table_init();
zvrf->mpls_flags = 0;
+ zvrf->mpls_srgb.start_label = 0;
+ zvrf->mpls_srgb.end_label = 0;
}
/*
@@ -1936,12 +2985,14 @@ zebra_mpls_init_tables (struct zebra_vrf *zvrf)
void
zebra_mpls_init (void)
{
+ mpls_enabled = 0;
+
if (mpls_kernel_init () < 0)
{
zlog_warn ("Disabling MPLS support (no kernel support)");
return;
}
- mpls_enabled = 1;
- mpls_processq_init (&zebrad);
+ if (! mpls_processq_init (&zebrad))
+ mpls_enabled = 1;
}
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index a871fac651..1f17de67a3 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_MPLS_H
@@ -52,6 +51,7 @@ typedef struct zebra_snhlfe_t_ zebra_snhlfe_t;
typedef struct zebra_slsp_t_ zebra_slsp_t;
typedef struct zebra_nhlfe_t_ zebra_nhlfe_t;
typedef struct zebra_lsp_t_ zebra_lsp_t;
+typedef struct zebra_fec_t_ zebra_fec_t;
/*
* (Outgoing) nexthop label forwarding entry configuration
@@ -147,6 +147,27 @@ struct zebra_lsp_t_
u_char addr_family;
};
+/*
+ * FEC to label binding.
+ */
+struct zebra_fec_t_
+{
+ /* FEC (prefix) */
+ struct route_node *rn;
+
+ /* In-label - either statically bound or derived from label block. */
+ mpls_label_t label;
+
+ /* Label index (into global label block), if valid */
+ u_int32_t label_index;
+
+ /* Flags. */
+ u_int32_t flags;
+#define FEC_FLAG_CONFIGURED (1 << 0)
+
+ /* Clients interested in this FEC. */
+ struct list *client_list;
+};
/* Function declarations. */
@@ -162,7 +183,117 @@ mpls_str2label (const char *label_str, u_int8_t *num_labels,
*/
char *
mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
- char *buf, int len);
+ char *buf, int len, int pretty);
+
+/*
+ * Add/update global label block.
+ */
+int
+zebra_mpls_label_block_add (struct zebra_vrf *zvrf, u_int32_t start_label,
+ u_int32_t end_label);
+
+/*
+ * Delete global label block.
+ */
+int
+zebra_mpls_label_block_del (struct zebra_vrf *vrf);
+
+/*
+ * Display MPLS global label block configuration (VTY command handler).
+ */
+int
+zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *vrf);
+
+/*
+ * Install dynamic LSP entry.
+ */
+int
+zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib);
+
+/*
+ * Uninstall dynamic LSP entry, if any.
+ */
+int
+zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib);
+
+/*
+ * Registration from a client for the label binding for a FEC. If a binding
+ * already exists, it is informed to the client.
+ * NOTE: If there is a manually configured label binding, that is used.
+ * Otherwise, if aa label index is specified, it means we have to allocate the
+ * label from a locally configured label block (SRGB), if one exists and index
+ * is acceptable.
+ */
+int
+zebra_mpls_fec_register (struct zebra_vrf *zvrf, struct prefix *p,
+ u_int32_t label_index, struct zserv *client);
+
+/*
+ * Deregistration from a client for the label binding for a FEC. The FEC
+ * itself is deleted if no other registered clients exist and there is no
+ * label bound to the FEC.
+ */
+int
+zebra_mpls_fec_unregister (struct zebra_vrf *zvrf, struct prefix *p,
+ struct zserv *client);
+
+/*
+ * Cleanup any FECs registered by this client.
+ */
+int
+zebra_mpls_cleanup_fecs_for_client (struct zebra_vrf *zvrf, struct zserv *client);
+
+/*
+ * Return FEC (if any) to which this label is bound.
+ * Note: Only works for per-prefix binding and when the label is not
+ * implicit-null.
+ * TODO: Currently walks entire table, can optimize later with another
+ * hash..
+ */
+zebra_fec_t *
+zebra_mpls_fec_for_label (struct zebra_vrf *zvrf, mpls_label_t label);
+
+/*
+ * Inform if specified label is currently bound to a FEC or not.
+ */
+int
+zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label);
+
+/*
+ * Add static FEC to label binding. If there are clients registered for this
+ * FEC, notify them. If there are labeled routes for this FEC, install the
+ * label forwarding entry.
+ */
+int
+zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
+ mpls_label_t in_label);
+
+/*
+ * Remove static FEC to label binding. If there are no clients registered
+ * for this FEC, delete the FEC; else notify clients.
+ * Note: Upon delete of static binding, if label index exists for this FEC,
+ * client may need to be updated with derived label.
+ */
+int
+zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p);
+
+/*
+ * Display MPLS FEC to label binding configuration (VTY command handler).
+ */
+int
+zebra_mpls_write_fec_config (struct vty *vty, struct zebra_vrf *zvrf);
+
+/*
+ * Display MPLS FEC to label binding (VTY command handler).
+ */
+void
+zebra_mpls_print_fec_table (struct vty *vty, struct zebra_vrf *zvrf);
+
+/*
+ * Display MPLS FEC to label binding for a specific FEC (VTY command handler).
+ */
+void
+zebra_mpls_print_fec (struct vty *vty, struct zebra_vrf *zvrf, struct prefix *p);
/*
* Install/uninstall a FEC-To-NHLFE (FTN) binding.
@@ -182,7 +313,7 @@ int
mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type,
mpls_label_t in_label, mpls_label_t out_label,
enum nexthop_types_t gtype, union g_addr *gate,
- char *ifname, ifindex_t ifindex);
+ ifindex_t ifindex);
/*
* Uninstall a particular NHLFE in the forwarding table. If this is
@@ -191,7 +322,7 @@ mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type,
int
mpls_lsp_uninstall (struct zebra_vrf *zvrf, enum lsp_types_t type,
mpls_label_t in_label, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex);
+ union g_addr *gate, ifindex_t ifindex);
/*
* Uninstall all LDP NHLFEs for a particular LSP forwarding entry.
@@ -216,7 +347,7 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi);
int
zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
mpls_label_t out_label, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex);
+ union g_addr *gate, ifindex_t ifindex);
#endif /* HAVE_CUMULUS */
/*
@@ -229,7 +360,7 @@ zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
int
zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
mpls_label_t out_label, enum nexthop_types_t gtype,
- union g_addr *gate, char *ifname, ifindex_t ifindex);
+ union g_addr *gate, ifindex_t ifindex);
/*
* Delete static LSP entry. This may be the delete of one particular
@@ -241,7 +372,7 @@ zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
int
zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,
enum nexthop_types_t gtype, union g_addr *gate,
- char *ifname, ifindex_t ifindex);
+ ifindex_t ifindex);
/*
* Schedule all MPLS label forwarding entries for processing.
@@ -324,6 +455,8 @@ lsp_type_from_rib_type (int rib_type)
{
case ZEBRA_ROUTE_STATIC:
return ZEBRA_LSP_STATIC;
+ case ZEBRA_ROUTE_BGP:
+ return ZEBRA_LSP_BGP;
default:
return ZEBRA_LSP_NONE;
}
@@ -339,6 +472,8 @@ nhlfe_type2str(enum lsp_types_t lsp_type)
return "Static";
case ZEBRA_LSP_LDP:
return "LDP";
+ case ZEBRA_LSP_BGP:
+ return "BGP";
default:
return "Unknown";
}
diff --git a/zebra/zebra_mpls_netlink.c b/zebra/zebra_mpls_netlink.c
index 045bee2b91..d0c4acb370 100644
--- a/zebra/zebra_mpls_netlink.c
+++ b/zebra/zebra_mpls_netlink.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/zebra/zebra_mpls_null.c b/zebra/zebra_mpls_null.c
index 23f5e72956..c69b06085d 100644
--- a/zebra/zebra_mpls_null.c
+++ b/zebra/zebra_mpls_null.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -27,3 +26,209 @@ int kernel_add_lsp (zebra_lsp_t *lsp) { return 0; }
int kernel_upd_lsp (zebra_lsp_t *lsp) { return 0; }
int kernel_del_lsp (zebra_lsp_t *lsp) { return 0; }
int mpls_kernel_init (void) { return -1; };
+
+int mpls_enabled;
+
+char *
+mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
+ char *buf, int len, int pretty)
+{
+ return NULL;
+}
+
+int
+mpls_str2label (const char *label_str, u_int8_t *num_labels,
+ mpls_label_t *labels)
+{
+ return 0;
+}
+
+int
+zebra_mpls_label_block_add (struct zebra_vrf *vrf, u_int32_t start_label,
+ u_int32_t end_label)
+{
+ return 0;
+}
+
+int
+zebra_mpls_label_block_del (struct zebra_vrf *zvrf)
+{
+ return 0;
+}
+
+int
+zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *zvrf)
+{
+ return 0;
+}
+
+int
+zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib)
+{
+ return 0;
+}
+
+int
+zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct rib *rib)
+{
+ return 0;
+}
+
+void
+zebra_mpls_init_tables (struct zebra_vrf *zvrf)
+{
+}
+
+void
+zebra_mpls_print_lsp (struct vty *vty, struct zebra_vrf *zvrf, mpls_label_t label,
+ u_char use_json)
+{
+}
+
+void
+zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf,
+ u_char use_json)
+{
+}
+
+int
+zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)
+{
+ return 0;
+}
+
+#ifdef HAVE_CUMULUS
+int
+zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
+ mpls_label_t out_label, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex)
+{
+ return 0;
+}
+#endif
+
+int
+zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
+ mpls_label_t out_label, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex)
+{
+ return 0;
+}
+
+int
+zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,
+ enum nexthop_types_t gtype, union g_addr *gate,
+ ifindex_t ifindex)
+{
+ return 0;
+}
+
+void
+zebra_mpls_lsp_schedule (struct zebra_vrf *zvrf)
+{
+}
+
+void
+zebra_mpls_close_tables (struct zebra_vrf *zvrf)
+{
+}
+
+zebra_fec_t *
+zebra_mpls_fec_for_label (struct zebra_vrf *zvrf, mpls_label_t label)
+{
+ return NULL;
+}
+
+int
+zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label)
+{
+ return 0;
+}
+
+int
+zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
+ mpls_label_t in_label)
+{
+ return 0;
+}
+
+int
+zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p)
+{
+ return 0;
+}
+
+int
+zebra_mpls_write_fec_config (struct vty *vty, struct zebra_vrf *zvrf)
+{
+ return 0;
+}
+
+void
+zebra_mpls_print_fec_table (struct vty *vty, struct zebra_vrf *zvrf)
+{
+}
+
+void
+zebra_mpls_print_fec (struct vty *vty, struct zebra_vrf *zvrf, struct prefix *p)
+{
+}
+
+int
+zebra_mpls_fec_register (struct zebra_vrf *zvrf, struct prefix *p,
+ u_int32_t label_index, struct zserv *client)
+{
+ return 0;
+}
+
+int
+zebra_mpls_fec_unregister (struct zebra_vrf *zvrf, struct prefix *p,
+ struct zserv *client)
+{
+ return 0;
+}
+
+int
+zebra_mpls_cleanup_fecs_for_client (struct zebra_vrf *zvrf, struct zserv *client)
+{
+ return 0;
+}
+
+void mpls_ldp_lsp_uninstall_all (struct hash_backet *backet, void *ctxt)
+{
+ return;
+}
+
+void mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
+{
+ return;
+}
+
+void zebra_mpls_init (void)
+{
+ return;
+}
+
+int mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type,
+ mpls_label_t in_label, mpls_label_t out_label,
+ enum nexthop_types_t gtype, union g_addr *gate,
+ ifindex_t ifindex)
+{
+ return 0;
+}
+
+int mpls_lsp_uninstall (struct zebra_vrf *zvrf, enum lsp_types_t type,
+ mpls_label_t in_label, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex)
+{
+ return 0;
+}
+
+int mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
+ struct prefix *prefix, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex, u_int8_t distance,
+ mpls_label_t out_label)
+{
+ return 0;
+}
+
diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c
index eaa80ac558..bca73898c5 100644
--- a/zebra/zebra_mpls_openbsd.c
+++ b/zebra/zebra_mpls_openbsd.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c
index dd381723c5..3010a3bd8a 100644
--- a/zebra/zebra_mpls_vty.c
+++ b/zebra/zebra_mpls_vty.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -133,7 +132,7 @@ zebra_mpls_transit_lsp (struct vty *vty, int add_cmd, const char *inlabel_str,
#if defined(HAVE_CUMULUS)
/* Check that label value is consistent. */
if (!zebra_mpls_lsp_label_consistent (zvrf, in_label, out_label, gtype,
- &gate, NULL, 0))
+ &gate, 0))
{
vty_out (vty, "%% Label value not consistent%s",
VTY_NEWLINE);
@@ -142,10 +141,10 @@ zebra_mpls_transit_lsp (struct vty *vty, int add_cmd, const char *inlabel_str,
#endif /* HAVE_CUMULUS */
ret = zebra_mpls_static_lsp_add (zvrf, in_label, out_label, gtype,
- &gate, NULL, 0);
+ &gate, 0);
}
else
- ret = zebra_mpls_static_lsp_del (zvrf, in_label, gtype, &gate, NULL, 0);
+ ret = zebra_mpls_static_lsp_del (zvrf, in_label, gtype, &gate, 0);
if (ret)
{
@@ -209,6 +208,109 @@ DEFUN (no_mpls_transit_lsp_all,
return zebra_mpls_transit_lsp (vty, 0, argv[3]->arg, NULL, NULL, NULL);
}
+static int
+zebra_mpls_bind (struct vty *vty, int add_cmd, const char *prefix,
+ const char *label_str)
+{
+ struct zebra_vrf *zvrf;
+ struct prefix p;
+ u_int32_t label;
+ int ret;
+
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ if (!zvrf)
+ {
+ vty_out (vty, "%% Default VRF does not exist%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ memset(&p, 0, sizeof(struct prefix));
+ ret = str2prefix(prefix, &p);
+ if (ret <= 0)
+ {
+ vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (add_cmd)
+ {
+ if (!label_str)
+ {
+ vty_out (vty, "%% No label binding specified%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (!strcmp(label_str, "implicit-null"))
+ label = MPLS_IMP_NULL_LABEL;
+ else if (!strcmp(label_str, "explicit-null"))
+ {
+ if (p.family == AF_INET)
+ label = MPLS_V4_EXP_NULL_LABEL;
+ else
+ label = MPLS_V6_EXP_NULL_LABEL;
+ }
+ else
+ {
+ label = atoi(label_str);
+ if (!IS_MPLS_UNRESERVED_LABEL(label))
+ {
+ vty_out (vty, "%% Invalid label%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (zebra_mpls_label_already_bound (zvrf, label))
+ {
+ vty_out (vty, "%% Label already bound to a FEC%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ ret = zebra_mpls_static_fec_add (zvrf, &p, label);
+ }
+ else
+ ret = zebra_mpls_static_fec_del (zvrf, &p);
+
+ if (ret)
+ {
+ vty_out (vty, "%% FEC to label binding cannot be %s%s",
+ add_cmd ? "added" : "deleted", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (mpls_label_bind,
+ mpls_label_bind_cmd,
+ "mpls label bind <A.B.C.D/M|X:X::X:X/M> <(16-1048575)|implicit-null|explicit-null>",
+ MPLS_STR
+ "Label configuration\n"
+ "Establish FEC to label binding\n"
+ "IPv4 prefix\n"
+ "IPv6 prefix\n"
+ "MPLS Label to bind\n"
+ "Use Implicit-Null Label\n"
+ "Use Explicit-Null Label\n")
+{
+ return zebra_mpls_bind (vty, 1, argv[3]->arg, argv[4]->arg);
+}
+
+DEFUN (no_mpls_label_bind,
+ no_mpls_label_bind_cmd,
+ "no mpls label bind <A.B.C.D/M|X:X::X:X/M> [<(16-1048575)|implicit-null>]",
+ NO_STR
+ MPLS_STR
+ "Label configuration\n"
+ "Establish FEC to label binding\n"
+ "IPv4 prefix\n"
+ "IPv6 prefix\n"
+ "MPLS Label to bind\n"
+ "Use Implicit-Null Label\n")
+
+{
+ return zebra_mpls_bind (vty, 0, argv[4]->arg, NULL);
+}
+
/* Static route configuration. */
DEFUN (ip_route_label,
ip_route_label_cmd,
@@ -777,9 +879,45 @@ zebra_mpls_config (struct vty *vty)
return 0;
write += zebra_mpls_write_lsp_config(vty, zvrf);
+ write += zebra_mpls_write_fec_config(vty, zvrf);
+ write += zebra_mpls_write_label_block_config (vty, zvrf);
return write;
}
+DEFUN (show_mpls_fec,
+ show_mpls_fec_cmd,
+ "show mpls fec [<A.B.C.D/M|X:X::X:X/M>]",
+ SHOW_STR
+ MPLS_STR
+ "MPLS FEC table\n"
+ "FEC to display information about\n"
+ "FEC to display information about\n")
+{
+ struct zebra_vrf *zvrf;
+ struct prefix p;
+ int ret;
+
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ if (!zvrf)
+ return 0;
+
+ if (argc == 3)
+ zebra_mpls_print_fec_table(vty, zvrf);
+ else
+ {
+ memset(&p, 0, sizeof(struct prefix));
+ ret = str2prefix(argv[3]->arg, &p);
+ if (ret <= 0)
+ {
+ vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ zebra_mpls_print_fec (vty, zvrf, &p);
+ }
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_mpls_table,
show_mpls_table_cmd,
"show mpls table [json]",
@@ -827,6 +965,85 @@ DEFUN (show_mpls_status,
return CMD_SUCCESS;
}
+static int
+zebra_mpls_global_block (struct vty *vty, int add_cmd,
+ const char *start_label_str, const char *end_label_str)
+{
+ int ret;
+ u_int32_t start_label;
+ u_int32_t end_label;
+ struct zebra_vrf *zvrf;
+
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
+ if (!zvrf)
+ {
+ vty_out (vty, "%% Default VRF does not exist%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (add_cmd)
+ {
+ if (!start_label_str || !end_label_str)
+ {
+ vty_out (vty, "%% Labels not specified%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ start_label = atoi(start_label_str);
+ end_label = atoi(end_label_str);
+ if (!IS_MPLS_UNRESERVED_LABEL(start_label) ||
+ !IS_MPLS_UNRESERVED_LABEL(end_label))
+ {
+ vty_out (vty, "%% Invalid label%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (end_label < start_label)
+ {
+ vty_out (vty, "%% End label is less than Start label%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ret = zebra_mpls_label_block_add (zvrf, start_label, end_label);
+ }
+ else
+ ret = zebra_mpls_label_block_del (zvrf);
+
+ if (ret)
+ {
+ vty_out (vty, "%% Global label block could not be %s%s",
+ add_cmd ? "added" : "deleted", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (mpls_label_global_block,
+ mpls_label_global_block_cmd,
+ "mpls label global-block (16-1048575) (16-1048575)",
+ MPLS_STR
+ "Label configuration\n"
+ "Configure global label block\n"
+ "Start label\n"
+ "End label\n")
+{
+ return zebra_mpls_global_block (vty, 1, argv[3]->arg, argv[4]->arg);
+}
+
+DEFUN (no_mpls_label_global_block,
+ no_mpls_label_global_block_cmd,
+ "no mpls label global-block [(16-1048575) (16-1048575)]",
+ NO_STR
+ MPLS_STR
+ "Label configuration\n"
+ "Configure global label block\n"
+ "Start label\n"
+ "End label\n")
+{
+ return zebra_mpls_global_block (vty, 0, NULL, NULL);
+}
+
/* MPLS node for MPLS LSP. */
static struct cmd_node mpls_node = { MPLS_NODE, "", 1 };
@@ -876,7 +1093,13 @@ zebra_mpls_vty_init (void)
install_element (CONFIG_NODE, &no_mpls_transit_lsp_cmd);
install_element (CONFIG_NODE, &no_mpls_transit_lsp_out_label_cmd);
install_element (CONFIG_NODE, &no_mpls_transit_lsp_all_cmd);
+ install_element (CONFIG_NODE, &mpls_label_bind_cmd);
+ install_element (CONFIG_NODE, &no_mpls_label_bind_cmd);
+
+ install_element (CONFIG_NODE, &mpls_label_global_block_cmd);
+ install_element (CONFIG_NODE, &no_mpls_label_global_block_cmd);
install_element (VIEW_NODE, &show_mpls_table_cmd);
install_element (VIEW_NODE, &show_mpls_table_lsp_cmd);
+ install_element (VIEW_NODE, &show_mpls_fec_cmd);
}
diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c
index 86356104bd..82c7f404b7 100644
--- a/zebra/zebra_mroute.c
+++ b/zebra/zebra_mroute.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
diff --git a/zebra/zebra_mroute.h b/zebra/zebra_mroute.h
index c0bac43a81..eeaf9caf1a 100644
--- a/zebra/zebra_mroute.h
+++ b/zebra/zebra_mroute.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 __ZEBRA_MROUTE_H__
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 642d2700a4..a5869585d5 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -14,10 +14,9 @@
* 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.
+ * 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"
diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h
index c50f9249d2..721b6c818b 100644
--- a/zebra/zebra_ns.h
+++ b/zebra/zebra_ns.h
@@ -15,10 +15,9 @@
* 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.
+ * 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
*/
#if !defined(__ZEBRA_NS_H__)
#define __ZEBRA_NS_H__
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index bc924842d4..68d2bff718 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -182,12 +181,14 @@ zebra_ptm_flush_messages (struct thread *thread)
close(ptm_cb.ptm_sock);
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
- ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect,
- NULL, ptm_cb.reconnect_time);
+ ptm_cb.t_timer = NULL;
+ thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time,
+ &ptm_cb.t_timer);
return (-1);
case BUFFER_PENDING:
- ptm_cb.t_write = thread_add_write(zebrad.master, zebra_ptm_flush_messages,
- NULL, ptm_cb.ptm_sock);
+ ptm_cb.t_write = NULL;
+ thread_add_write(zebrad.master, zebra_ptm_flush_messages, NULL, ptm_cb.ptm_sock,
+ &ptm_cb.t_write);
break;
case BUFFER_EMPTY:
break;
@@ -207,15 +208,16 @@ zebra_ptm_send_message(char *data, int size)
close(ptm_cb.ptm_sock);
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
- ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect,
- NULL, ptm_cb.reconnect_time);
+ ptm_cb.t_timer = NULL;
+ thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time,
+ &ptm_cb.t_timer);
return -1;
case BUFFER_EMPTY:
THREAD_OFF(ptm_cb.t_write);
break;
case BUFFER_PENDING:
- THREAD_WRITE_ON(zebrad.master, ptm_cb.t_write,
- zebra_ptm_flush_messages, NULL, ptm_cb.ptm_sock);
+ thread_add_write(zebrad.master, zebra_ptm_flush_messages, NULL,
+ ptm_cb.ptm_sock, &ptm_cb.t_write);
break;
}
@@ -234,8 +236,9 @@ zebra_ptm_connect (struct thread *t)
if (ptm_cb.ptm_sock != -1) {
if (init) {
- ptm_cb.t_read = thread_add_read (zebrad.master, zebra_ptm_sock_read,
- NULL, ptm_cb.ptm_sock);
+ ptm_cb.t_read = NULL;
+ thread_add_read(zebrad.master, zebra_ptm_sock_read, NULL, ptm_cb.ptm_sock,
+ &ptm_cb.t_read);
zebra_bfd_peer_replay_req();
}
zebra_ptm_send_status_req();
@@ -245,8 +248,9 @@ zebra_ptm_connect (struct thread *t)
if (ptm_cb.reconnect_time > ZEBRA_PTM_RECONNECT_TIME_MAX)
ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_MAX;
- ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, NULL,
- ptm_cb.reconnect_time);
+ ptm_cb.t_timer = NULL;
+ thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time,
+ &ptm_cb.t_timer);
} else if (ptm_cb.reconnect_time >= ZEBRA_PTM_RECONNECT_TIME_MAX){
ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL;
}
@@ -653,14 +657,16 @@ zebra_ptm_sock_read (struct thread *thread)
close (ptm_cb.ptm_sock);
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
- ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect,
- NULL, ptm_cb.reconnect_time);
+ ptm_cb.t_timer = NULL;
+ thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time,
+ &ptm_cb.t_timer);
return (-1);
}
}
- ptm_cb.t_read = thread_add_read (zebrad.master, zebra_ptm_sock_read,
- NULL, ptm_cb.ptm_sock);
+ ptm_cb.t_read = NULL;
+ thread_add_read(zebrad.master, zebra_ptm_sock_read, NULL, ptm_cb.ptm_sock,
+ &ptm_cb.t_read);
return 0;
}
@@ -697,8 +703,9 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
if (ptm_cb.ptm_sock == -1)
{
- ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect,
- NULL, ptm_cb.reconnect_time);
+ ptm_cb.t_timer = NULL;
+ thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time,
+ &ptm_cb.t_timer);
return -1;
}
@@ -854,8 +861,9 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length,
if (ptm_cb.ptm_sock == -1)
{
- ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect,
- NULL, ptm_cb.reconnect_time);
+ ptm_cb.t_timer = NULL;
+ thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time,
+ &ptm_cb.t_timer);
return -1;
}
@@ -976,8 +984,9 @@ zebra_ptm_bfd_client_register (struct zserv *client, int sock, u_short length)
if (ptm_cb.ptm_sock == -1)
{
- ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect,
- NULL, ptm_cb.reconnect_time);
+ ptm_cb.t_timer = NULL;
+ thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time,
+ &ptm_cb.t_timer);
return -1;
}
@@ -1026,8 +1035,9 @@ zebra_ptm_bfd_client_deregister (int proto)
if (ptm_cb.ptm_sock == -1)
{
- ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect,
- NULL, ptm_cb.reconnect_time);
+ ptm_cb.t_timer = NULL;
+ thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time,
+ &ptm_cb.t_timer);
return;
}
diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h
index 71c85d9094..28fe9c1de7 100644
--- a/zebra/zebra_ptm.h
+++ b/zebra/zebra_ptm.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_PTM_H
diff --git a/zebra/zebra_ptm_null.c b/zebra/zebra_ptm_null.c
index 4afa2ce522..576ea17327 100644
--- a/zebra/zebra_ptm_null.c
+++ b/zebra/zebra_ptm_null.c
@@ -13,10 +13,9 @@
* 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.
+ * 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 "prefix.h"
diff --git a/zebra/zebra_ptm_redistribute.c b/zebra/zebra_ptm_redistribute.c
index 396857bc1f..efa29989e1 100644
--- a/zebra/zebra_ptm_redistribute.c
+++ b/zebra/zebra_ptm_redistribute.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
diff --git a/zebra/zebra_ptm_redistribute.h b/zebra/zebra_ptm_redistribute.h
index d5aa37d5f8..ac3873f248 100644
--- a/zebra/zebra_ptm_redistribute.h
+++ b/zebra/zebra_ptm_redistribute.h
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index b3e70e46fa..12ee9961d5 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -1084,7 +1083,25 @@ nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
return rib->nexthop_active_num;
}
+/*
+ * Is this RIB labeled-unicast? It must be of type BGP and all paths
+ * (nexthops) must have a label.
+ */
+int
+zebra_rib_labeled_unicast (struct rib *rib)
+{
+ struct nexthop *nexthop = NULL, *tnexthop;
+ int recursing;
+ if (rib->type != ZEBRA_ROUTE_BGP)
+ return 0;
+
+ for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
+ if (!nexthop->nh_label || !nexthop->nh_label->num_labels)
+ return 0;
+
+ return 1;
+}
/* Update flag indicates whether this is a "replace" or not. Currently, this
* is only used for IPv4.
@@ -1177,7 +1194,12 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
if (! RIB_SYSTEM_ROUTE (rib))
rib_uninstall_kernel (rn, rib);
- UNSET_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB);
+
+ /* If labeled-unicast route, uninstall transit LSP. */
+ if (zebra_rib_labeled_unicast (rib))
+ zebra_mpls_lsp_uninstall (info->zvrf, rn, rib);
+
+ UNSET_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB);
}
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
@@ -1272,6 +1294,10 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
zvrf_id (zvrf), buf, rn, new, new->type);
}
+ /* If labeled-unicast route, install transit LSP. */
+ if (zebra_rib_labeled_unicast (new))
+ zebra_mpls_lsp_install (zvrf, rn, new);
+
if (!RIB_SYSTEM_ROUTE (new))
{
if (rib_install_kernel (rn, new, NULL))
@@ -1301,6 +1327,10 @@ rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
zvrf_id (zvrf), buf, rn, old, old->type);
}
+ /* If labeled-unicast route, uninstall transit LSP. */
+ if (zebra_rib_labeled_unicast (old))
+ zebra_mpls_lsp_uninstall (zvrf, rn, old);
+
if (!RIB_SYSTEM_ROUTE (old))
rib_uninstall_kernel (rn, old);
@@ -1351,9 +1381,18 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
zlog_debug ("%u:%s: Updating route rn %p, rib %p (type %d)",
zvrf_id (zvrf), buf, rn, new, new->type);
}
+
+ /* If labeled-unicast route, uninstall transit LSP. */
+ if (zebra_rib_labeled_unicast (old))
+ zebra_mpls_lsp_uninstall (zvrf, rn, old);
+
/* Non-system route should be installed. */
if (!RIB_SYSTEM_ROUTE (new))
{
+ /* If labeled-unicast route, install transit LSP. */
+ if (zebra_rib_labeled_unicast (new))
+ zebra_mpls_lsp_install (zvrf, rn, new);
+
if (rib_install_kernel (rn, new, old))
{
char buf[SRCDEST2STR_BUFFER];
@@ -1404,6 +1443,10 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
nh_active ? "install failed" : "nexthop inactive");
}
+ /* If labeled-unicast route, uninstall transit LSP. */
+ if (zebra_rib_labeled_unicast (old))
+ zebra_mpls_lsp_uninstall (zvrf, rn, old);
+
if (!RIB_SYSTEM_ROUTE (old))
rib_uninstall_kernel (rn, old);
UNSET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB);
@@ -2934,8 +2977,10 @@ rib_tables_iter_next (rib_tables_iter_t *iter)
} afi_safis[] = {
{ AFI_IP, SAFI_UNICAST },
{ AFI_IP, SAFI_MULTICAST },
+ { AFI_IP, SAFI_LABELED_UNICAST },
{ AFI_IP6, SAFI_UNICAST },
{ AFI_IP6, SAFI_MULTICAST },
+ { AFI_IP6, SAFI_LABELED_UNICAST },
};
table = NULL;
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 67859fd46b..16c157e307 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -555,7 +554,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
{
RNODE_FOREACH_RIB(static_rn, srib)
{
- if (srib->type == ZEBRA_ROUTE_STATIC)
+ if (srib->type != ZEBRA_ROUTE_STATIC)
continue;
/* Set the filter flag for the correct nexthop - static route may
diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h
index 4394fde4f3..a75674d0cb 100644
--- a/zebra/zebra_rnh.h
+++ b/zebra/zebra_rnh.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 _ZEBRA_RNH_H
diff --git a/zebra/zebra_rnh_null.c b/zebra/zebra_rnh_null.c
index 286290a52b..0a3620bbe8 100644
--- a/zebra/zebra_rnh_null.c
+++ b/zebra/zebra_rnh_null.c
@@ -13,10 +13,9 @@
* 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.
+ * 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 "vty.h"
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 847da52952..4a81cb635d 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -1403,10 +1402,11 @@ static void
zebra_route_map_mark_update (const char *rmap_name)
{
/* rmap_update_timer of 0 means don't do route updates */
- if (zebra_rmap_update_timer && !zebra_t_rmap_update)
- zebra_t_rmap_update =
- thread_add_timer(zebrad.master, zebra_route_map_update_timer, NULL,
- zebra_rmap_update_timer);
+ if (zebra_rmap_update_timer && !zebra_t_rmap_update) {
+ zebra_t_rmap_update = NULL;
+ thread_add_timer(zebrad.master, zebra_route_map_update_timer, NULL, zebra_rmap_update_timer,
+ &zebra_t_rmap_update);
+ }
}
static void
diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h
index bf418ccacc..94981a3cd6 100644
--- a/zebra/zebra_routemap.h
+++ b/zebra/zebra_routemap.h
@@ -14,10 +14,9 @@
* 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.
+ * 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 __ZEBRA_ROUTEMAP_H__
diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c
index 8adb8873dc..7c2e6697ce 100644
--- a/zebra/zebra_snmp.c
+++ b/zebra/zebra_snmp.c
@@ -13,10 +13,9 @@
* 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.
+ * 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
*/
/*
diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c
index 4628d11091..b218eb5210 100644
--- a/zebra/zebra_static.c
+++ b/zebra/zebra_static.c
@@ -15,10 +15,9 @@
* 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.
+ * 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>
diff --git a/zebra/zebra_static.h b/zebra/zebra_static.h
index adc2efff58..9f76ab5f55 100644
--- a/zebra/zebra_static.h
+++ b/zebra/zebra_static.h
@@ -15,10 +15,9 @@
* 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.
+ * 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 __ZEBRA_STATIC_H__
#define __ZEBRA_STATIC_H__
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 6b36891056..94e2506186 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>
@@ -536,11 +535,10 @@ vrf_config_write (struct vty *vty)
void
zebra_vrf_init (void)
{
- vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
- vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
- vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
- vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete);
+ vrf_init (zebra_vrf_new,
+ zebra_vrf_enable,
+ zebra_vrf_disable,
+ zebra_vrf_delete);
- vrf_init ();
vrf_cmd_init (vrf_config_write);
}
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index 96d631d646..df25fad947 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -15,16 +15,22 @@
* 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.
+ * 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
*/
#if !defined(__ZEBRA_RIB_H__)
#define __ZEBRA_RIB_H__
#include <zebra/zebra_ns.h>
+/* MPLS (Segment Routing) global block */
+typedef struct mpls_srgb_t_
+{
+ u_int32_t start_label;
+ u_int32_t end_label;
+} mpls_srgb_t;
+
/* Routing table instance. */
struct zebra_vrf
{
@@ -79,6 +85,12 @@ struct zebra_vrf
/* MPLS label forwarding table */
struct hash *lsp_table;
+ /* MPLS FEC binding table */
+ struct route_table *fec_table[AFI_MAX];
+
+ /* MPLS Segment Routing Global block */
+ mpls_srgb_t mpls_srgb;
+
/* MPLS processing flags */
u_int16_t mpls_flags;
#define MPLS_FLAG_SCHEDULE_LSPS (1 << 0)
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 1708138d83..eedd38f3f9 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -46,7 +45,7 @@
extern int allow_delete;
static int do_show_ip_route(struct vty *vty, const char *vrf_name,
- safi_t safi, u_char use_json);
+ safi_t safi, bool use_fib, u_char use_json);
static void vty_show_ip_route_detail (struct vty *vty, struct route_node *rn,
int mcast);
@@ -304,7 +303,7 @@ DEFUN (show_ip_rpf,
IP_STR
"Display RPF information for multicast source\n")
{
- return do_show_ip_route(vty, VRF_DEFAULT_NAME, SAFI_MULTICAST, 0);
+ return do_show_ip_route(vty, VRF_DEFAULT_NAME, SAFI_MULTICAST, false, 0);
}
DEFUN (show_ip_rpf_addr,
@@ -781,9 +780,9 @@ 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",
+ vty_out (vty, ", label %s",
mpls_label2str (nexthop->nh_label->num_labels,
- nexthop->nh_label->label, buf, BUFSIZ));
+ nexthop->nh_label->label, buf, BUFSIZ, 1));
}
vty_out (vty, "%s", VTY_NEWLINE);
@@ -803,6 +802,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
json_object *json_nexthops = NULL;
json_object *json_nexthop = NULL;
json_object *json_route = NULL;
+ json_object *json_labels = NULL;
if (json)
{
@@ -932,6 +932,16 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
break;
}
+ if (nexthop->nh_label && nexthop->nh_label->num_labels)
+ {
+ json_labels = json_object_new_array();
+
+ for (int label_index = 0; label_index < nexthop->nh_label->num_labels; label_index++)
+ json_object_array_add(json_labels, json_object_new_int(nexthop->nh_label->label[label_index]));
+
+ json_object_object_add(json_nexthop, "labels", json_labels);
+ }
+
json_object_array_add(json_nexthops, json_nexthop);
}
@@ -1030,9 +1040,9 @@ 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",
+ vty_out (vty, ", label %s",
mpls_label2str (nexthop->nh_label->num_labels,
- nexthop->nh_label->label, buf, BUFSIZ));
+ nexthop->nh_label->label, buf, BUFSIZ, 1));
}
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
@@ -1069,20 +1079,28 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
}
}
+static bool
+use_fib (struct cmd_token *token)
+{
+ return strncmp(token->arg, "route", strlen(token->arg));
+}
+
DEFUN (show_ip_route,
show_ip_route_cmd,
- "show ip route [json]",
+ "show ip <fib|route> [json]",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
JSON_STR)
{
- return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST, use_json(argc, argv));
+ return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST,
+ use_fib(argv[2]), use_json(argc, argv));
}
static int
do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
- u_char use_json)
+ bool use_fib, u_char use_json)
{
struct route_table *table;
struct route_node *rn;
@@ -1128,6 +1146,8 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
{
RNODE_FOREACH_RIB (rn, rib)
{
+ if (use_fib && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (!json_prefix)
json_prefix = json_object_new_array();
vty_show_ip_route (vty, rn, rib, json_prefix);
@@ -1151,6 +1171,8 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
{
RNODE_FOREACH_RIB (rn, rib)
{
+ if (use_fib && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V4_HEADER);
@@ -1166,17 +1188,19 @@ 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 NAME [json]",
+ "show ip <fib|route> vrf NAME [json]",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_CMD_HELP_STR
JSON_STR)
{
int idx_vrf = 4;
+ bool uf = use_fib(argv[2]);
u_char uj = use_json(argc, argv);
- return do_show_ip_route (vty, argv[idx_vrf]->arg, SAFI_UNICAST, uj);
+ return do_show_ip_route (vty, argv[idx_vrf]->arg, SAFI_UNICAST, uf, uj);
}
DEFUN (show_ip_nht,
@@ -1323,14 +1347,16 @@ DEFUN (no_ipv6_nht_default_route,
DEFUN (show_ip_route_tag,
show_ip_route_tag_cmd,
- "show ip route [vrf NAME] tag (1-4294967295)",
+ "show ip <fib|route> [vrf NAME] tag (1-4294967295)",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_CMD_HELP_STR
"Show only routes with tag\n"
"Tag value\n")
{
+ bool uf = use_fib(argv[2]);
int idx_vrf = 3;
int idx_name = 4;
int idx_tag = 6;
@@ -1360,6 +1386,8 @@ DEFUN (show_ip_route_tag,
for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (rib->tag != tag)
continue;
@@ -1375,9 +1403,10 @@ DEFUN (show_ip_route_tag,
DEFUN (show_ip_route_prefix_longer,
show_ip_route_prefix_longer_cmd,
- "show ip route [vrf NAME] A.B.C.D/M longer-prefixes",
+ "show ip <fib|route> [vrf NAME] A.B.C.D/M longer-prefixes",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_CMD_HELP_STR
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
@@ -1389,6 +1418,7 @@ DEFUN (show_ip_route_prefix_longer,
struct prefix p;
int ret;
int first = 1;
+ bool uf = use_fib(argv[2]);
vrf_id_t vrf_id = VRF_DEFAULT;
if (strmatch(argv[3]->text, "vrf"))
@@ -1416,6 +1446,8 @@ DEFUN (show_ip_route_prefix_longer,
RNODE_FOREACH_RIB (rn, rib)
if (prefix_match (&p, &rn->p))
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V4_HEADER);
@@ -1428,9 +1460,10 @@ DEFUN (show_ip_route_prefix_longer,
DEFUN (show_ip_route_supernets,
show_ip_route_supernets_cmd,
- "show ip route [vrf NAME] supernets-only",
+ "show ip <fib|route> [vrf NAME] supernets-only",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_CMD_HELP_STR
"Show supernet entries only\n")
@@ -1441,6 +1474,7 @@ DEFUN (show_ip_route_supernets,
u_int32_t addr;
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
+ bool uf = use_fib(argv[2]);
if (strmatch(argv[3]->text, "vrf"))
VRF_GET_ID (vrf_id, argv[4]->arg);
@@ -1453,6 +1487,8 @@ DEFUN (show_ip_route_supernets,
for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
addr = ntohl (rn->p.u.prefix4.s_addr);
if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
@@ -1472,9 +1508,10 @@ DEFUN (show_ip_route_supernets,
DEFUN (show_ip_route_protocol,
show_ip_route_protocol_cmd,
- "show ip route [vrf NAME] " FRR_IP_REDIST_STR_ZEBRA,
+ "show ip <fib|route> [vrf NAME] " FRR_IP_REDIST_STR_ZEBRA,
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_CMD_HELP_STR
FRR_IP_REDIST_HELP_STR_ZEBRA)
@@ -1485,6 +1522,7 @@ DEFUN (show_ip_route_protocol,
struct rib *rib;
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
+ bool uf = use_fib(argv[2]);
int idx = 0;
if (argv_find (argv, argc, "NAME", &idx))
@@ -1508,6 +1546,8 @@ DEFUN (show_ip_route_protocol,
RNODE_FOREACH_RIB (rn, rib)
if (rib->type == type)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V4_HEADER);
@@ -1521,9 +1561,10 @@ DEFUN (show_ip_route_protocol,
DEFUN (show_ip_route_ospf_instance,
show_ip_route_ospf_instance_cmd,
- "show ip route ospf (1-65535)",
+ "show ip <fib|route> ospf (1-65535)",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
"Open Shortest Path First (OSPFv2)\n"
"Instance ID\n")
@@ -1534,6 +1575,7 @@ DEFUN (show_ip_route_ospf_instance,
struct rib *rib;
int first = 1;
u_short instance = 0;
+ bool uf = use_fib(argv[2]);
VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
@@ -1546,6 +1588,8 @@ DEFUN (show_ip_route_ospf_instance,
RNODE_FOREACH_RIB (rn, rib)
if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V4_HEADER);
@@ -1858,9 +1902,10 @@ DEFUN (show_ip_route_summary_prefix,
DEFUN (show_ip_route_vrf_all,
show_ip_route_vrf_all_cmd,
- "show ip route vrf all",
+ "show ip <fib|route> vrf all",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_ALL_CMD_HELP_STR)
{
@@ -1871,6 +1916,7 @@ DEFUN (show_ip_route_vrf_all,
struct zebra_vrf *zvrf;
int first = 1;
int vrf_header = 1;
+ bool uf = use_fib(argv[2]);
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
@@ -1882,6 +1928,8 @@ DEFUN (show_ip_route_vrf_all,
for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V4_HEADER);
@@ -1903,9 +1951,10 @@ 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 tag (1-4294967295)",
+ "show ip <fib|route> vrf all tag (1-4294967295)",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_ALL_CMD_HELP_STR
"Show only routes with tag\n"
@@ -1920,6 +1969,7 @@ DEFUN (show_ip_route_vrf_all_tag,
int first = 1;
int vrf_header = 1;
route_tag_t tag = 0;
+ bool uf = use_fib(argv[2]);
if (argv[idx_number]->arg)
VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
@@ -1934,6 +1984,8 @@ DEFUN (show_ip_route_vrf_all_tag,
for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (rib->tag != tag)
continue;
@@ -1957,9 +2009,10 @@ 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 A.B.C.D/M longer-prefixes",
+ "show ip <fib|route> vrf all A.B.C.D/M longer-prefixes",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_ALL_CMD_HELP_STR
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
@@ -1975,6 +2028,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
int ret;
int first = 1;
int vrf_header = 1;
+ bool uf = use_fib(argv[2]);
ret = str2prefix (argv[idx_ipv4_prefixlen]->arg, &p);
if (! ret)
@@ -1994,6 +2048,8 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
RNODE_FOREACH_RIB (rn, rib)
if (prefix_match (&p, &rn->p))
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V4_HEADER);
@@ -2015,9 +2071,10 @@ 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 supernets-only",
+ "show ip <fib|route> vrf all supernets-only",
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_ALL_CMD_HELP_STR
"Show supernet entries only\n")
@@ -2030,6 +2087,7 @@ DEFUN (show_ip_route_vrf_all_supernets,
u_int32_t addr;
int first = 1;
int vrf_header = 1;
+ bool uf = use_fib(argv[2]);
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
@@ -2041,6 +2099,9 @@ DEFUN (show_ip_route_vrf_all_supernets,
for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
+
addr = ntohl (rn->p.u.prefix4.s_addr);
if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
@@ -2068,9 +2129,10 @@ 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 " FRR_IP_REDIST_STR_ZEBRA,
+ "show ip <fib|route> vrf all " FRR_IP_REDIST_STR_ZEBRA,
SHOW_STR
IP_STR
+ "IP forwarding table\n"
"IP routing table\n"
VRF_ALL_CMD_HELP_STR
FRR_IP_REDIST_HELP_STR_ZEBRA"\n")
@@ -2083,6 +2145,7 @@ DEFUN (show_ip_route_vrf_all_protocol,
struct zebra_vrf *zvrf;
int first = 1;
int vrf_header = 1;
+ bool uf = use_fib(argv[2]);
char *proto = argv[argc - 1]->text;
type = proto_redistnum (AFI_IP, proto);
@@ -2104,6 +2167,8 @@ DEFUN (show_ip_route_vrf_all_protocol,
RNODE_FOREACH_RIB (rn, rib)
if (rib->type == type)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V4_HEADER);
@@ -2251,49 +2316,49 @@ DEFUN (show_ip_route_vrf_all_summary_prefix,
return CMD_SUCCESS;
}
-/* Write IPv4 static route configuration. */
+/* Write static route configuration. */
static int
-static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
+static_config (struct vty *vty, afi_t afi, safi_t safi, const char *cmd)
{
struct route_node *rn;
struct static_route *si;
struct route_table *stable;
struct vrf *vrf;
struct zebra_vrf *zvrf;
- char buf[BUFSIZ];
+ char buf[SRCDEST2STR_BUFFER];
int write =0;
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
if (!(zvrf = vrf->info))
continue;
- if ((stable = zvrf->stable[AFI_IP][safi]) == NULL)
+ if ((stable = zvrf->stable[afi][safi]) == 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, "%s %s", cmd, prefix2str (&rn->p, buf, sizeof buf));
+ vty_out (vty, "%s %s", cmd, 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;
case STATIC_IFINDEX:
vty_out (vty, " %s", si->ifname);
break;
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 (si->ifindex, si->vrf_id));
- break;
+ case STATIC_IPV6_GATEWAY_IFINDEX:
+ vty_out (vty, " %s %s",
+ inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ),
+ ifindex2ifname (si->ifindex, si->vrf_id));
+ break;
}
/* flags are incompatible with STATIC_BLACKHOLE */
@@ -2313,13 +2378,13 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
vty_out (vty, " %d", si->distance);
if (si->vrf_id != VRF_DEFAULT)
- vty_out (vty, " vrf %s", zvrf ? zvrf_name (zvrf) : "");
+ vty_out (vty, " vrf %s", zvrf_name (zvrf));
/* Label information */
if (si->snh_label.num_labels)
vty_out (vty, " label %s",
mpls_label2str (si->snh_label.num_labels,
- si->snh_label.label, buf, sizeof buf));
+ si->snh_label.label, buf, sizeof buf, 0));
vty_out (vty, "%s", VTY_NEWLINE);
@@ -2915,9 +2980,10 @@ DEFUN (no_ipv6_route_ifname_flags,
DEFUN (show_ipv6_route,
show_ipv6_route_cmd,
- "show ipv6 route [vrf NAME] [json]",
+ "show ipv6 <fib|route> [vrf NAME] [json]",
SHOW_STR
IP_STR
+ "IPv6 forwarding table\n"
"IPv6 routing table\n"
VRF_CMD_HELP_STR
"Output JSON\n")
@@ -2931,6 +2997,7 @@ DEFUN (show_ipv6_route,
char buf[SRCDEST2STR_BUFFER];
json_object *json = NULL;
json_object *json_prefix = NULL;
+ bool uf = use_fib(argv[2]);
int vrf = (argc > 3 && strmatch (argv[3]->text, "vrf"));
int uj = vrf ? argc == 6 : argc == 4;
@@ -2976,6 +3043,8 @@ DEFUN (show_ipv6_route,
{
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (!json_prefix)
json_prefix = json_object_new_array();
vty_show_ip_route (vty, rn, rib, json_prefix);
@@ -2999,6 +3068,8 @@ DEFUN (show_ipv6_route,
{
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V6_HEADER);
@@ -3014,9 +3085,10 @@ DEFUN (show_ipv6_route,
DEFUN (show_ipv6_route_tag,
show_ipv6_route_tag_cmd,
- "show ipv6 route [vrf NAME] tag (1-4294967295)",
+ "show ipv6 <fib|route> [vrf NAME] tag (1-4294967295)",
SHOW_STR
IP_STR
+ "IPv6 forwarding table\n"
"IPv6 routing table\n"
VRF_CMD_HELP_STR
"Show only routes with tag\n"
@@ -3031,6 +3103,7 @@ DEFUN (show_ipv6_route_tag,
int first = 1;
route_tag_t tag = 0;
vrf_id_t vrf_id = VRF_DEFAULT;
+ bool uf = use_fib(argv[2]);
if (strmatch(argv[idx_vrf]->text, "vrf"))
{
@@ -3051,6 +3124,8 @@ DEFUN (show_ipv6_route_tag,
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (rib->tag != tag)
continue;
@@ -3066,9 +3141,10 @@ DEFUN (show_ipv6_route_tag,
DEFUN (show_ipv6_route_prefix_longer,
show_ipv6_route_prefix_longer_cmd,
- "show ipv6 route [vrf NAME] X:X::X:X/M longer-prefixes",
+ "show ipv6 <fib|route> [vrf NAME] X:X::X:X/M longer-prefixes",
SHOW_STR
IP_STR
+ "IPv6 forwarding table\n"
"IPv6 routing table\n"
VRF_CMD_HELP_STR
"IPv6 prefix\n"
@@ -3081,6 +3157,7 @@ DEFUN (show_ipv6_route_prefix_longer,
int ret;
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
+ bool uf = use_fib(argv[2]);
if (strmatch(argv[3]->text, "vrf"))
{
@@ -3109,6 +3186,8 @@ DEFUN (show_ipv6_route_prefix_longer,
struct prefix *p, *src_p;
srcdest_rnode_prefixes(rn, &p, &src_p);
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (prefix_match (p, &rn->p))
{
if (first)
@@ -3124,10 +3203,11 @@ DEFUN (show_ipv6_route_prefix_longer,
DEFUN (show_ipv6_route_protocol,
show_ipv6_route_protocol_cmd,
- "show ipv6 route [vrf NAME] " FRR_IP6_REDIST_STR_ZEBRA,
+ "show ipv6 <fib|route> [vrf NAME] " FRR_IP6_REDIST_STR_ZEBRA,
SHOW_STR
IP_STR
- "IP routing table\n"
+ "IPv6 forwarding table\n"
+ "IPv6 routing table\n"
VRF_CMD_HELP_STR
FRR_IP6_REDIST_HELP_STR_ZEBRA)
{
@@ -3137,6 +3217,7 @@ DEFUN (show_ipv6_route_protocol,
struct rib *rib;
int first = 1;
vrf_id_t vrf_id = VRF_DEFAULT;
+ bool uf = use_fib(argv[2]);
int idx = 0;
if (argv_find (argv, argc, "NAME", &idx))
@@ -3160,6 +3241,8 @@ DEFUN (show_ipv6_route_protocol,
RNODE_FOREACH_RIB (rn, rib)
if (rib->type == type)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V6_HEADER);
@@ -3362,9 +3445,10 @@ DEFUN (show_ipv6_mroute,
DEFUN (show_ipv6_route_vrf_all,
show_ipv6_route_vrf_all_cmd,
- "show ipv6 route vrf all",
+ "show ipv6 <fib|route> vrf all",
SHOW_STR
IP_STR
+ "IPv6 forwarding table\n"
"IPv6 routing table\n"
VRF_ALL_CMD_HELP_STR)
{
@@ -3375,6 +3459,7 @@ DEFUN (show_ipv6_route_vrf_all,
struct zebra_vrf *zvrf;
int first = 1;
int vrf_header = 1;
+ bool uf = use_fib(argv[2]);
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
@@ -3386,6 +3471,8 @@ DEFUN (show_ipv6_route_vrf_all,
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V6_HEADER);
@@ -3407,9 +3494,10 @@ 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 tag (1-4294967295)",
+ "show ipv6 <fib|route> vrf all tag (1-4294967295)",
SHOW_STR
IP_STR
+ "IPv6 forwarding table\n"
"IPv6 routing table\n"
VRF_ALL_CMD_HELP_STR
"Show only routes with tag\n"
@@ -3424,6 +3512,7 @@ DEFUN (show_ipv6_route_vrf_all_tag,
int first = 1;
int vrf_header = 1;
route_tag_t tag = 0;
+ bool uf = use_fib(argv[2]);
if (argv[idx_number]->arg)
VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
@@ -3438,6 +3527,8 @@ DEFUN (show_ipv6_route_vrf_all_tag,
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (rib->tag != tag)
continue;
@@ -3462,9 +3553,10 @@ 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 X:X::X:X/M longer-prefixes",
+ "show ipv6 <fib|route> vrf all X:X::X:X/M longer-prefixes",
SHOW_STR
IP_STR
+ "IPv6 forwarding table\n"
"IPv6 routing table\n"
VRF_ALL_CMD_HELP_STR
"IPv6 prefix\n"
@@ -3480,6 +3572,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
int ret;
int first = 1;
int vrf_header = 1;
+ bool uf = use_fib(argv[2]);
ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &p);
if (! ret)
@@ -3500,6 +3593,8 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
{
struct prefix *p, *src_p;
srcdest_rnode_prefixes(rn, &p, &src_p);
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (prefix_match (p, &rn->p))
{
if (first)
@@ -3524,10 +3619,11 @@ 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 " FRR_IP6_REDIST_STR_ZEBRA,
+ "show ipv6 <fib|route> vrf all " FRR_IP6_REDIST_STR_ZEBRA,
SHOW_STR
IP_STR
- "IP routing table\n"
+ "IPv6 forwarding table\n"
+ "IPv6 routing table\n"
VRF_ALL_CMD_HELP_STR
FRR_IP6_REDIST_HELP_STR_ZEBRA)
{
@@ -3539,6 +3635,7 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
struct zebra_vrf *zvrf;
int first = 1;
int vrf_header = 1;
+ bool uf = use_fib(argv[2]);
char *proto = argv[argc - 1]->text;
type = proto_redistnum (AFI_IP6, proto);
@@ -3560,6 +3657,8 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
RNODE_FOREACH_RIB (rn, rib)
if (rib->type == type)
{
+ if (uf && !CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
+ continue;
if (first)
{
vty_out (vty, SHOW_ROUTE_V6_HEADER);
@@ -3743,85 +3842,6 @@ DEFUN (show_ipv6_route_vrf_all_summary_prefix,
return CMD_SUCCESS;
}
-/* Write IPv6 static route configuration. */
-static int
-static_config_ipv6 (struct vty *vty)
-{
- struct route_node *rn;
- struct static_route *si;
- int write = 0;
- char buf[SRCDEST2STR_BUFFER];
- struct route_table *stable;
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
- {
- if (!(zvrf = vrf->info))
- continue;
- if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
- continue;
-
- 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", 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;
- case STATIC_IFINDEX:
- vty_out (vty, " %s", si->ifname);
- break;
- case STATIC_BLACKHOLE:
- vty_out (vty, " Null0" );
- break;
- case STATIC_IPV6_GATEWAY_IFINDEX:
- vty_out (vty, " %s %s",
- inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ),
- ifindex2ifname (si->ifindex, si->vrf_id));
- break;
- }
-
- /* flags are incompatible with STATIC_BLACKHOLE */
- if (si->type != STATIC_BLACKHOLE)
- {
- if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
- vty_out (vty, " %s", "reject");
- if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
- vty_out (vty, " %s", "blackhole");
- }
-
- if (si->tag)
- vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag);
-
- if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
- vty_out (vty, " %d", si->distance);
-
- if (si->vrf_id != VRF_DEFAULT)
- {
- vty_out (vty, " vrf %s", zvrf_name (zvrf));
- }
-
- /* Label information */
- if (si->snh_label.num_labels)
- vty_out (vty, " label %s",
- mpls_label2str (si->snh_label.num_labels,
- si->snh_label.label, buf, sizeof buf));
-
- vty_out (vty, "%s", VTY_NEWLINE);
-
- write = 1;
- }
- }
- return write;
-}
-
DEFUN (allow_external_route_update,
allow_external_route_update_cmd,
"allow-external-route-update",
@@ -3878,9 +3898,9 @@ zebra_ip_config (struct vty *vty)
{
int write = 0;
- write += static_config_ipv4 (vty, SAFI_UNICAST, "ip route");
- write += static_config_ipv4 (vty, SAFI_MULTICAST, "ip mroute");
- write += static_config_ipv6 (vty);
+ write += static_config (vty, AFI_IP, SAFI_UNICAST, "ip route");
+ write += static_config (vty, AFI_IP, SAFI_MULTICAST, "ip mroute");
+ write += static_config (vty, AFI_IP6, SAFI_UNICAST, "ipv6 route");
write += zebra_import_table_config (vty);
return write;
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 3477dc36d2..a59ef3031d 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -13,10 +13,9 @@
* 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.
+ * 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>
@@ -95,8 +94,9 @@ zserv_flush_data(struct thread *thread)
client = NULL;
break;
case BUFFER_PENDING:
- client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
- client, client->sock);
+ client->t_write = NULL;
+ thread_add_write(zebrad.master, zserv_flush_data, client, client->sock,
+ &client->t_write);
break;
case BUFFER_EMPTY:
break;
@@ -128,15 +128,16 @@ zebra_server_send_message(struct zserv *client)
one do not check the return code. They do not allow for the
possibility that an I/O error may have caused the client to be
deleted. */
- client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
- client, 0);
+ client->t_suicide = NULL;
+ thread_add_event(zebrad.master, zserv_delayed_close, client, 0,
+ &client->t_suicide);
return -1;
case BUFFER_EMPTY:
THREAD_OFF(client->t_write);
break;
case BUFFER_PENDING:
- THREAD_WRITE_ON(zebrad.master, client->t_write,
- zserv_flush_data, client, client->sock);
+ thread_add_write(zebrad.master, zserv_flush_data, client, client->sock,
+ &client->t_write);
break;
}
@@ -934,6 +935,109 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
return 0;
}
+#define ZEBRA_MIN_FEC_LENGTH 5
+
+/* FEC register */
+static int
+zserv_fec_register (struct zserv *client, int sock, u_short length)
+{
+ struct stream *s;
+ struct zebra_vrf *zvrf;
+ u_short l = 0;
+ struct prefix p;
+ u_int16_t flags;
+ u_int32_t label_index = MPLS_INVALID_LABEL_INDEX;
+
+ s = client->ibuf;
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ if (!zvrf)
+ return 0; // unexpected
+
+ /*
+ * The minimum amount of data that can be sent for one fec
+ * registration
+ */
+ if (length < ZEBRA_MIN_FEC_LENGTH)
+ {
+ zlog_err ("fec_register: Received a fec register of length %d, it is of insufficient size to properly decode",
+ length);
+ return -1;
+ }
+
+ while (l < length)
+ {
+ flags = stream_getw(s);
+ p.family = stream_getw(s);
+ if (p.family != AF_INET &&
+ p.family != AF_INET6)
+ {
+ zlog_err ("fec_register: Received unknown family type %d\n",
+ p.family);
+ return -1;
+ }
+ p.prefixlen = stream_getc(s);
+ l += 5;
+ stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
+ l += PSIZE(p.prefixlen);
+ if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX)
+ {
+ label_index = stream_getl(s);
+ l += 4;
+ }
+ zebra_mpls_fec_register (zvrf, &p, label_index, client);
+ }
+
+ return 0;
+}
+
+/* FEC unregister */
+static int
+zserv_fec_unregister (struct zserv *client, int sock, u_short length)
+{
+ struct stream *s;
+ struct zebra_vrf *zvrf;
+ u_short l = 0;
+ struct prefix p;
+ //u_int16_t flags;
+
+ s = client->ibuf;
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ if (!zvrf)
+ return 0; // unexpected
+
+ /*
+ * The minimum amount of data that can be sent for one
+ * fec unregistration
+ */
+ if (length < ZEBRA_MIN_FEC_LENGTH)
+ {
+ zlog_err ("fec_unregister: Received a fec unregister of length %d, it is of insufficient size to properly decode",
+ length);
+ return -1;
+ }
+
+ while (l < length)
+ {
+ //flags = stream_getw(s);
+ (void)stream_getw(s);
+ p.family = stream_getw(s);
+ if (p.family != AF_INET &&
+ p.family != AF_INET6)
+ {
+ zlog_err ("fec_unregister: Received unknown family type %d\n",
+ p.family);
+ return -1;
+ }
+ p.prefixlen = stream_getc(s);
+ l += 5;
+ stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
+ l += PSIZE(p.prefixlen);
+ zebra_mpls_fec_unregister (zvrf, &p, client);
+ }
+
+ return 0;
+}
+
/*
Modified version of zsend_ipv4_nexthop_lookup():
Query unicast rib if nexthop is not found on mrib.
@@ -1075,13 +1179,15 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
struct rib *rib;
struct prefix p;
u_char message;
- struct in_addr nexthop;
+ struct in_addr nhop_addr;
u_char nexthop_num;
u_char nexthop_type;
struct stream *s;
ifindex_t ifindex;
safi_t safi;
int ret;
+ mpls_label_t label;
+ struct nexthop *nexthop;
/* Get input stream. */
s = client->ibuf;
@@ -1123,13 +1229,19 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
rib_nexthop_ifindex_add (rib, ifindex);
break;
case NEXTHOP_TYPE_IPV4:
- nexthop.s_addr = stream_get_ipv4 (s);
- rib_nexthop_ipv4_add (rib, &nexthop, NULL);
+ nhop_addr.s_addr = stream_get_ipv4 (s);
+ nexthop = rib_nexthop_ipv4_add (rib, &nhop_addr, NULL);
+ /* For labeled-unicast, each nexthop is followed by label. */
+ if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
+ {
+ label = (mpls_label_t)stream_getl (s);
+ nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &label);
+ }
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
- nexthop.s_addr = stream_get_ipv4 (s);
+ nhop_addr.s_addr = stream_get_ipv4 (s);
ifindex = stream_getl (s);
- rib_nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
+ rib_nexthop_ipv4_ifindex_add (rib, &nhop_addr, NULL, ifindex);
break;
case NEXTHOP_TYPE_IPV6:
stream_forward_getp (s, IPV6_MAX_BYTELEN);
@@ -1222,6 +1334,11 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
break;
case NEXTHOP_TYPE_IPV4:
nexthop.s_addr = stream_get_ipv4 (s);
+ /* For labeled-unicast, each nexthop is followed by label, but
+ * we don't care for delete.
+ */
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_LABEL))
+ stream_forward_getp (s, sizeof(u_int32_t));
nexthop_p = (union g_addr *)&nexthop;
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
@@ -1407,7 +1524,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{
unsigned int i;
struct stream *s;
- struct in6_addr nexthop;
+ struct in6_addr nhop_addr;
struct rib *rib;
u_char message;
u_char nexthop_num;
@@ -1418,11 +1535,14 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
static struct in6_addr nexthops[MULTIPATH_NUM];
static unsigned int ifindices[MULTIPATH_NUM];
int ret;
+ static mpls_label_t labels[MULTIPATH_NUM];
+ mpls_label_t label;
+ struct nexthop *nexthop;
/* Get input stream. */
s = client->ibuf;
- memset (&nexthop, 0, sizeof (struct in6_addr));
+ memset (&nhop_addr, 0, sizeof (struct in6_addr));
/* Allocate new rib. */
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
@@ -1471,10 +1591,17 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
switch (nexthop_type)
{
case NEXTHOP_TYPE_IPV6:
- stream_get (&nexthop, s, 16);
- if (nh_count < multipath_num) {
- nexthops[nh_count++] = nexthop;
- }
+ stream_get (&nhop_addr, s, 16);
+ if (nh_count < MULTIPATH_NUM)
+ {
+ /* For labeled-unicast, each nexthop is followed by label. */
+ if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
+ {
+ label = (mpls_label_t)stream_getl (s);
+ labels[nh_count++] = label;
+ }
+ nexthops[nh_count++] = nhop_addr;
+ }
break;
case NEXTHOP_TYPE_IFINDEX:
if (if_count < multipath_num) {
@@ -1492,9 +1619,11 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{
if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
if ((i < if_count) && ifindices[i])
- rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
+ nexthop = rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
else
- rib_nexthop_ipv6_add (rib, &nexthops[i]);
+ nexthop = rib_nexthop_ipv6_add (rib, &nexthops[i]);
+ if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
+ nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]);
}
else {
if ((i < if_count) && ifindices[i])
@@ -1591,6 +1720,11 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{
case NEXTHOP_TYPE_IPV6:
stream_get (&nexthop, s, 16);
+ /* For labeled-unicast, each nexthop is followed by label, but
+ * we don't care for delete.
+ */
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_LABEL))
+ stream_forward_getp (s, sizeof(u_int32_t));
pnexthop = (union g_addr *)&nexthop;
break;
case NEXTHOP_TYPE_IFINDEX:
@@ -1761,14 +1895,14 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
if (command == ZEBRA_MPLS_LABELS_ADD)
{
mpls_lsp_install (zvrf, type, in_label, out_label, gtype, &gate,
- NULL, ifindex);
+ ifindex);
if (out_label != MPLS_IMP_NULL_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, ifindex);
+ mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, ifindex);
if (out_label != MPLS_IMP_NULL_LABEL)
mpls_ftn_update (0, zvrf, type, &prefix, gtype, &gate, ifindex,
distance, out_label);
@@ -1975,6 +2109,9 @@ zebra_client_close (struct zserv *client)
/* Release Label Manager chunks */
release_daemon_chunks (client->proto, client->instance);
+ /* Cleanup any FECs registered by this client. */
+ zebra_mpls_cleanup_fecs_for_client (vrf_info_lookup(VRF_DEFAULT), client);
+
/* Close file descriptor. */
if (client->sock)
{
@@ -2263,6 +2400,12 @@ zebra_client_read (struct thread *thread)
case ZEBRA_RELEASE_LABEL_CHUNK:
zread_label_manager_request (command, client, vrf_id);
break;
+ case ZEBRA_FEC_REGISTER:
+ zserv_fec_register (client, sock, length);
+ break;
+ case ZEBRA_FEC_UNREGISTER:
+ zserv_fec_unregister (client, sock, length);
+ break;
default:
zlog_info ("Zebra received unknown command %d", command);
break;
@@ -2446,11 +2589,12 @@ zebra_event (enum event event, int sock, struct zserv *client)
switch (event)
{
case ZEBRA_SERV:
- thread_add_read (zebrad.master, zebra_accept, client, sock);
+ thread_add_read(zebrad.master, zebra_accept, client, sock, NULL);
break;
case ZEBRA_READ:
- client->t_read =
- thread_add_read (zebrad.master, zebra_client_read, client, sock);
+ client->t_read = NULL;
+ thread_add_read(zebrad.master, zebra_client_read, client, sock,
+ &client->t_read);
break;
case ZEBRA_WRITE:
/**/
diff --git a/zebra/zserv.h b/zebra/zserv.h
index cd1948373a..2fafd040cf 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -13,10 +13,9 @@
* 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.
+ * 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 _ZEBRA_ZSERV_H
diff --git a/zebra/zserv_null.c b/zebra/zserv_null.c
index 4b52abb222..972caaeed4 100644
--- a/zebra/zserv_null.c
+++ b/zebra/zserv_null.c
@@ -14,10 +14,9 @@
* 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.
+ * 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>