From 5a8f2e368ff5a2372523c83c28e471e4434d8b2b Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 25 Aug 2017 01:07:40 +0000 Subject: [PATCH 01/16] [DHCP Relay]: Support new minigraph tag; support multiple VLANs --- dockers/docker-dhcp-relay/Dockerfile.j2 | 8 +-- .../docker-dhcp-relay.supervisord.conf.j2 | 55 +++++++++++++++++++ dockers/docker-dhcp-relay/docker_init.sh | 10 ++++ dockers/docker-dhcp-relay/isc-dhcp-relay.j2 | 28 ---------- dockers/docker-dhcp-relay/isc-dhcp-relay.sh | 18 ------ dockers/docker-dhcp-relay/start.sh | 23 ++++++-- dockers/docker-dhcp-relay/supervisord.conf | 28 ---------- src/sonic-config-engine/minigraph.py | 4 +- 8 files changed, 89 insertions(+), 85 deletions(-) create mode 100644 dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 create mode 100755 dockers/docker-dhcp-relay/docker_init.sh delete mode 100644 dockers/docker-dhcp-relay/isc-dhcp-relay.j2 delete mode 100755 dockers/docker-dhcp-relay/isc-dhcp-relay.sh delete mode 100644 dockers/docker-dhcp-relay/supervisord.conf diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2 index 3c6614c4921f..2c2bdcaecbf7 100644 --- a/dockers/docker-dhcp-relay/Dockerfile.j2 +++ b/dockers/docker-dhcp-relay/Dockerfile.j2 @@ -22,9 +22,7 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -COPY ["start.sh", "isc-dhcp-relay.sh", "/usr/bin/"] -COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["isc-dhcp-relay.j2", "/usr/share/sonic/templates/"] -COPY ["wait_for_intf.sh.j2", "/usr/share/sonic/templates/"] +COPY ["docker_init.sh", "start.sh", "/usr/bin/"] +COPY ["docker-dhcp-relay.supervisord.conf.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 new file mode 100644 index 000000000000..c937dc466136 --- /dev/null +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -0,0 +1,55 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +{# If our configuration has VLANs... #} +{% if minigraph_vlans | length > 0 %} +[group:isc-dhcp-relay] +programs= +{%- set add_preceding_comma = { 'flag': False } -%} +{%- for vlan in minigraph_vlans.values() -%} +{%- if vlan['dhcp_servers'] | length > 0 -%} +{%- if add_preceding_comma.flag %},{% endif -%} +{%- set _dummy = add_preceding_comma.update({'flag': True}) -%} +isc-dhcp-relay-{{ vlan['name'] }} +{%- endif %} +{% endfor %} + + +{# Create a program entry for each DHCP relay agent instance #} +{% for vlan in minigraph_vlans.values() %} +[program:isc-dhcp-relay-{{ vlan['name'] }}] +command=/usr/sbin/dhcrelay -d -q -a %%h:%%p %%P -i {{ vlan['name'] }} +{%- for interface in minigraph_interfaces -%} +{%- if interface['addr'] | ipv4 %} -i {{ interface['attachto'] }}{% endif -%} +{%- endfor -%} +{%- for pc_interface in minigraph_portchannel_interfaces -%} +{%- if pc_interface['addr'] | ipv4 %} -i {{ pc_interface['attachto'] }}{% endif -%} +{%- endfor -%} +{%- for dhcp_server in vlan['dhcp_servers'] %} {{ dhcp_server }}{% endfor %} + +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +{% endfor %} +{% endif %} diff --git a/dockers/docker-dhcp-relay/docker_init.sh b/dockers/docker-dhcp-relay/docker_init.sh new file mode 100755 index 000000000000..ab3ea0c18b44 --- /dev/null +++ b/dockers/docker-dhcp-relay/docker_init.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +# Generate supervisord config file +mkdir -p /etc/supervisor/conf.d/ +sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/docker-dhcp-relay.supervisord.conf.j2 > /etc/supervisor/conf.d/docker-dhcp-relay.supervisord.conf + +# The docker container should start this script as PID 1, so now that supervisord is +# properly configured, we exec supervisord so that it runs as PID 1 for the +# duration of the container's lifetime +exec /usr/bin/supervisord diff --git a/dockers/docker-dhcp-relay/isc-dhcp-relay.j2 b/dockers/docker-dhcp-relay/isc-dhcp-relay.j2 deleted file mode 100644 index cdedfcf9692b..000000000000 --- a/dockers/docker-dhcp-relay/isc-dhcp-relay.j2 +++ /dev/null @@ -1,28 +0,0 @@ -SERVERS="{{ DHCP_SERVER | join(' ') }}" - -INTERFACES=" -{%- set add_preceding_space = { 'flag': False } %} -{%- for (name, prefix) in INTERFACE %} -{%- if prefix | ipv4 %} -{%- if add_preceding_space.flag %} {% endif %} -{{ name }} -{%- set _dummy = add_preceding_space.update({'flag': True}) %} -{%- endif %} -{%- endfor %} -{%- for (name, prefix) in VLAN_INTERFACE %} -{%- if prefix | ipv4 %} -{%- if add_preceding_space.flag %} {% endif %} -{{ name }} -{%- set _dummy = add_preceding_space.update({'flag': True}) %} -{%- endif %} -{%- endfor %} -{%- for (name, prefix) in PORTCHANNEL_INTERFACE %} -{%- if prefix | ipv4 %} -{%- if add_preceding_space.flag %} {% endif %} -{{ name }} -{%- set _dummy = add_preceding_space.update({'flag': True}) %} -{%- endif %} -{%- endfor %}" - -# '-a' option provides option 82 circuit_id and remote_id information -OPTIONS="-a %h:%p %P" diff --git a/dockers/docker-dhcp-relay/isc-dhcp-relay.sh b/dockers/docker-dhcp-relay/isc-dhcp-relay.sh deleted file mode 100755 index 2224b8a0fe00..000000000000 --- a/dockers/docker-dhcp-relay/isc-dhcp-relay.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -# -# Based off /etc/init.d/isc-dhcp-relay -# - -# Read init script configuration (interfaces the daemon should listen on -# and the DHCP server we should forward requests to.) -[ -f /etc/default/isc-dhcp-relay ] && . /etc/default/isc-dhcp-relay - -# Build command line for interfaces (will be passed to dhrelay below.) -IFCMD="" -if test "$INTERFACES" != ""; then - for I in $INTERFACES; do - IFCMD=${IFCMD}"-i "${I}" " - done -fi - -exec /usr/sbin/dhcrelay -d -q ${OPTIONS} ${IFCMD} ${SERVERS} diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 37c3f488a5c7..4647da20c14b 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -1,16 +1,29 @@ #!/usr/bin/env bash -# Create isc-dhcp-relay config file -sonic-cfggen -d -t /usr/share/sonic/templates/isc-dhcp-relay.j2 > /etc/default/isc-dhcp-relay +function wait_until_iface_exists +{ + IFACE=$1 + echo "Waiting for interface ${IFACE}..." + + # Wait for the interface to come up (i.e., 'ip link show' returns 0) + until ip link show $IFACE > /dev/null 2>&1; do + sleep 1 + done + + echo "Interface ${IFACE} is created" +} + +# Remove stale rsyslog PID file if it exists rm -f /var/run/rsyslogd.pid +# Start rsyslog supervisorctl start rsyslogd -# Wait for all interfaces to come up before starting the DHCP relay +# Wait for all interfaces to come up before starting the DHCP relay agent(s) sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh chmod +x /usr/bin/wait_for_intf.sh /usr/bin/wait_for_intf.sh -# Start the DHCP relay -supervisorctl start isc-dhcp-relay +# Start the DHCP relay agent(s) +supervisorctl start isc-dhcp-relay:* diff --git a/dockers/docker-dhcp-relay/supervisord.conf b/dockers/docker-dhcp-relay/supervisord.conf deleted file mode 100644 index ed1f75d1aed6..000000000000 --- a/dockers/docker-dhcp-relay/supervisord.conf +++ /dev/null @@ -1,28 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[program:start.sh] -command=/usr/bin/start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:isc-dhcp-relay] -command=/usr/bin/isc-dhcp-relay.sh -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 95a45b8530de..204248215cf4 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -178,7 +178,9 @@ def parse_dpg(dpg, hname): vmbr_list = vintfmbr.split(';') for i, member in enumerate(vmbr_list): vmbr_list[i] = port_alias_map.get(member, member) - vlan_attributes = {'members': vmbr_list, 'vlanid': vlanid} + vintfdhcpservers = vintf.find(str(QName(ns, "DhcpRelays"))).text + vdhcpserver_list = vintfdhcpservers.split(';') + vlan_attributes = {'members': vmbr_list, 'vlanid': vlanid, 'dhcp_servers': vdhcpserver_list} sonic_vlan_name = "Vlan%s" % vlanid vlans[sonic_vlan_name] = vlan_attributes From 36a0b65e94b7e829e92e05c3ca6152a2a92f3bc6 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 30 Aug 2017 00:35:48 +0000 Subject: [PATCH 02/16] Don't start dhcrelay in quiet mode so as to get startup output in syslog --- dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index c937dc466136..b82fdbefaff4 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -36,7 +36,7 @@ isc-dhcp-relay-{{ vlan['name'] }} {# Create a program entry for each DHCP relay agent instance #} {% for vlan in minigraph_vlans.values() %} [program:isc-dhcp-relay-{{ vlan['name'] }}] -command=/usr/sbin/dhcrelay -d -q -a %%h:%%p %%P -i {{ vlan['name'] }} +command=/usr/sbin/dhcrelay -d -a %%h:%%p %%P -i {{ vlan['name'] }} {%- for interface in minigraph_interfaces -%} {%- if interface['addr'] | ipv4 %} -i {{ interface['attachto'] }}{% endif -%} {%- endfor -%} From 4e76084ed5e3a1ef0249f723a04f5f0d377cc23b Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 30 Aug 2017 19:02:52 +0000 Subject: [PATCH 03/16] Update sonic-cfggen tests to support new '' tag --- src/sonic-config-engine/tests/pc-test-graph.xml | 1 + src/sonic-config-engine/tests/simple-sample-graph.xml | 1 + src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml | 1 + src/sonic-config-engine/tests/t0-sample-graph-everflow.xml | 1 + src/sonic-config-engine/tests/t0-sample-graph.xml | 1 + src/sonic-config-engine/tests/test_cfggen.py | 2 +- 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sonic-config-engine/tests/pc-test-graph.xml b/src/sonic-config-engine/tests/pc-test-graph.xml index 7d7ec74a8631..aeeb88805734 100644 --- a/src/sonic-config-engine/tests/pc-test-graph.xml +++ b/src/sonic-config-engine/tests/pc-test-graph.xml @@ -108,6 +108,7 @@ False 0.0.0.0/0 + 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index 7daae24f49a6..76fe346adde8 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -130,6 +130,7 @@ Vlan1000 fortyGigE0/8 + 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml b/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml index 8a21c041c80e..cd2d411d1731 100644 --- a/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml +++ b/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml @@ -203,6 +203,7 @@ False 0.0.0.0/0 + 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml b/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml index 355f01122f0d..828d5ba125b4 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml @@ -198,6 +198,7 @@ False 0.0.0.0/0 + 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 62a41105f937..0acf614693f7 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -206,6 +206,7 @@ False 0.0.0.0/0 + 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 4303f5a2492d..52317ac2997c 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -83,7 +83,7 @@ def test_minigraph_interfaces(self): def test_minigraph_vlans(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'Vlan1000': {'members': ['Ethernet8'], 'vlanid': '1000'}}") + self.assertEqual(output.strip(), "{'Vlan1000': {'dhcp_servers': ['192.0.0.1', '192.0.0.2', '192.0.0.3', '192.0.0.4'], 'members': ['Ethernet8'], 'vlanid': '1000'}}") def test_minigraph_vlan_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' From afa2fb39342641efe6b422b2a28035f9315895c0 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 31 Aug 2017 19:42:17 +0000 Subject: [PATCH 04/16] tag is only present for VLANs which require a DHCP relay agent -- only parse if present --- src/sonic-config-engine/minigraph.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 204248215cf4..93f170a23b86 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -178,9 +178,15 @@ def parse_dpg(dpg, hname): vmbr_list = vintfmbr.split(';') for i, member in enumerate(vmbr_list): vmbr_list[i] = port_alias_map.get(member, member) - vintfdhcpservers = vintf.find(str(QName(ns, "DhcpRelays"))).text - vdhcpserver_list = vintfdhcpservers.split(';') - vlan_attributes = {'members': vmbr_list, 'vlanid': vlanid, 'dhcp_servers': vdhcpserver_list} + vlan_attributes = {'members': vmbr_list, 'vlanid': vlanid} + + # If this VLAN requires a DHCP relay agent, it will contain a element + # containing a list of DHCP server IPs + if vintf.find(str(QName(ns, "DhcpRelays"))) is not None: + vintfdhcpservers = vintf.find(str(QName(ns, "DhcpRelays"))).text + vdhcpserver_list = vintfdhcpservers.split(';') + vlan_attributes['dhcp_servers'] = vdhcpserver_list + sonic_vlan_name = "Vlan%s" % vlanid vlans[sonic_vlan_name] = vlan_attributes From 06f903d69bdd375c86055c21c89eeed79c4f1bcb Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 31 Aug 2017 23:52:06 +0000 Subject: [PATCH 05/16] Don't attempt to configure a DHCP relay agent for VLANs without specified DHCP servers --- .../docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index b82fdbefaff4..1ef5c3f88108 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -20,12 +20,12 @@ stdout_logfile=syslog stderr_logfile=syslog {# If our configuration has VLANs... #} -{% if minigraph_vlans | length > 0 %} +{% if minigraph_vlans is defined and minigraph_vlans | length > 0 %} [group:isc-dhcp-relay] programs= {%- set add_preceding_comma = { 'flag': False } -%} {%- for vlan in minigraph_vlans.values() -%} -{%- if vlan['dhcp_servers'] | length > 0 -%} +{%- if vlan['dhcp_servers'] is defined and vlan['dhcp_servers'] | length > 0 -%} {%- if add_preceding_comma.flag %},{% endif -%} {%- set _dummy = add_preceding_comma.update({'flag': True}) -%} isc-dhcp-relay-{{ vlan['name'] }} @@ -35,6 +35,7 @@ isc-dhcp-relay-{{ vlan['name'] }} {# Create a program entry for each DHCP relay agent instance #} {% for vlan in minigraph_vlans.values() %} +{%- if vlan['dhcp_servers'] is defined and vlan['dhcp_servers'] | length > 0 -%} [program:isc-dhcp-relay-{{ vlan['name'] }}] command=/usr/sbin/dhcrelay -d -a %%h:%%p %%P -i {{ vlan['name'] }} {%- for interface in minigraph_interfaces -%} @@ -51,5 +52,6 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog +{% endif %} {% endfor %} {% endif %} From 57101fbb77e04b9abdb57c2eefb4a9656109b888 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 12 Sep 2017 23:45:15 +0000 Subject: [PATCH 06/16] Modify to work with Taoyu's minigraph/DB changes (#942) --- .../docker-dhcp-relay.supervisord.conf.j2 | 26 +++++++++---------- dockers/docker-dhcp-relay/docker_init.sh | 4 +++ dockers/docker-dhcp-relay/start.sh | 16 ------------ dockers/docker-dhcp-relay/wait_for_intf.sh.j2 | 1 - 4 files changed, 17 insertions(+), 30 deletions(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 1ef5c3f88108..0f288d95b12d 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -20,31 +20,31 @@ stdout_logfile=syslog stderr_logfile=syslog {# If our configuration has VLANs... #} -{% if minigraph_vlans is defined and minigraph_vlans | length > 0 %} +{% if VLAN %} [group:isc-dhcp-relay] programs= {%- set add_preceding_comma = { 'flag': False } -%} -{%- for vlan in minigraph_vlans.values() -%} -{%- if vlan['dhcp_servers'] is defined and vlan['dhcp_servers'] | length > 0 -%} +{%- for vlan_name in VLAN -%} +{%- if VLAN[vlan_name]['dhcp_servers'] -%} {%- if add_preceding_comma.flag %},{% endif -%} {%- set _dummy = add_preceding_comma.update({'flag': True}) -%} -isc-dhcp-relay-{{ vlan['name'] }} +isc-dhcp-relay-{{ vlan_name }} {%- endif %} {% endfor %} {# Create a program entry for each DHCP relay agent instance #} -{% for vlan in minigraph_vlans.values() %} -{%- if vlan['dhcp_servers'] is defined and vlan['dhcp_servers'] | length > 0 -%} -[program:isc-dhcp-relay-{{ vlan['name'] }}] -command=/usr/sbin/dhcrelay -d -a %%h:%%p %%P -i {{ vlan['name'] }} -{%- for interface in minigraph_interfaces -%} -{%- if interface['addr'] | ipv4 %} -i {{ interface['attachto'] }}{% endif -%} +{% for vlan_name in VLAN -%} +{%- if VLAN[vlan_name]['dhcp_servers'] -%} +[program:isc-dhcp-relay-{{ vlan_name }}] +command=/usr/sbin/dhcrelay -d -a %%h:%%p %%P -i {{ vlan_name }} +{%- for (name, prefix) in INTERFACE -%} +{%- if prefix | ipv4 %} -i {{ name }}{% endif -%} {%- endfor -%} -{%- for pc_interface in minigraph_portchannel_interfaces -%} -{%- if pc_interface['addr'] | ipv4 %} -i {{ pc_interface['attachto'] }}{% endif -%} +{%- for (name, prefix) in PORTCHANNEL_INTERFACE -%} +{%- if prefix | ipv4 %} -i {{ name }}{% endif -%} {%- endfor -%} -{%- for dhcp_server in vlan['dhcp_servers'] %} {{ dhcp_server }}{% endfor %} +{%- for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} {{ dhcp_server }}{% endfor %} priority=3 autostart=false diff --git a/dockers/docker-dhcp-relay/docker_init.sh b/dockers/docker-dhcp-relay/docker_init.sh index ab3ea0c18b44..78574c1049de 100755 --- a/dockers/docker-dhcp-relay/docker_init.sh +++ b/dockers/docker-dhcp-relay/docker_init.sh @@ -4,6 +4,10 @@ mkdir -p /etc/supervisor/conf.d/ sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/docker-dhcp-relay.supervisord.conf.j2 > /etc/supervisor/conf.d/docker-dhcp-relay.supervisord.conf +# Generate the script that waits for all interfaces to come up and make it executable +sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh +chmod +x /usr/bin/wait_for_intf.sh + # The docker container should start this script as PID 1, so now that supervisord is # properly configured, we exec supervisord so that it runs as PID 1 for the # duration of the container's lifetime diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 4647da20c14b..b53d7e4e238a 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -1,19 +1,5 @@ #!/usr/bin/env bash -function wait_until_iface_exists -{ - IFACE=$1 - - echo "Waiting for interface ${IFACE}..." - - # Wait for the interface to come up (i.e., 'ip link show' returns 0) - until ip link show $IFACE > /dev/null 2>&1; do - sleep 1 - done - - echo "Interface ${IFACE} is created" -} - # Remove stale rsyslog PID file if it exists rm -f /var/run/rsyslogd.pid @@ -21,8 +7,6 @@ rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd # Wait for all interfaces to come up before starting the DHCP relay agent(s) -sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh -chmod +x /usr/bin/wait_for_intf.sh /usr/bin/wait_for_intf.sh # Start the DHCP relay agent(s) diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 index b859a43b07b1..1524b3221312 100755 --- a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 +++ b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 @@ -25,4 +25,3 @@ wait_until_iface_exists {{ name }} {% for (name, prefix) in PORTCHANNEL_INTERFACE %} wait_until_iface_exists {{ name }} {% endfor %} - From 39b4c604f4620b065ca01e1fdc5642f3ade4c257 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 12 Sep 2017 23:51:27 +0000 Subject: [PATCH 07/16] Reduce number of DHCP servers in sonic-cfggen unit tests from 4 to 2 --- src/sonic-config-engine/tests/pc-test-graph.xml | 2 +- src/sonic-config-engine/tests/simple-sample-graph.xml | 2 +- src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml | 2 +- src/sonic-config-engine/tests/t0-sample-graph-everflow.xml | 2 +- src/sonic-config-engine/tests/t0-sample-graph.xml | 2 +- src/sonic-config-engine/tests/test_cfggen.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sonic-config-engine/tests/pc-test-graph.xml b/src/sonic-config-engine/tests/pc-test-graph.xml index aeeb88805734..9c346c09a462 100644 --- a/src/sonic-config-engine/tests/pc-test-graph.xml +++ b/src/sonic-config-engine/tests/pc-test-graph.xml @@ -108,7 +108,7 @@ False 0.0.0.0/0 - 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index 76fe346adde8..bbf5995809c9 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -130,7 +130,7 @@ Vlan1000 fortyGigE0/8 - 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml b/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml index cd2d411d1731..e187b9a1c96b 100644 --- a/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml +++ b/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml @@ -203,7 +203,7 @@ False 0.0.0.0/0 - 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml b/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml index 828d5ba125b4..167999216164 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml @@ -198,7 +198,7 @@ False 0.0.0.0/0 - 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 0acf614693f7..23da26b9a860 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -206,7 +206,7 @@ False 0.0.0.0/0 - 192.0.0.1;192.0.0.2;192.0.0.3;192.0.0.4 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 52317ac2997c..70e37b7461e9 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -83,7 +83,7 @@ def test_minigraph_interfaces(self): def test_minigraph_vlans(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'Vlan1000': {'dhcp_servers': ['192.0.0.1', '192.0.0.2', '192.0.0.3', '192.0.0.4'], 'members': ['Ethernet8'], 'vlanid': '1000'}}") + self.assertEqual(output.strip(), "{'Vlan1000': {'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'members': ['Ethernet8'], 'vlanid': '1000'}}") def test_minigraph_vlan_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' From 9893597bd6ce82c45e05c7bfb97735d737a2ec47 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 12 Sep 2017 23:52:37 +0000 Subject: [PATCH 08/16] Remove isc-dhcp-relay sample output file from sonic-cfggen test, as we no longer generate that file --- src/sonic-config-engine/tests/sample_output/isc-dhcp-relay | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/sonic-config-engine/tests/sample_output/isc-dhcp-relay diff --git a/src/sonic-config-engine/tests/sample_output/isc-dhcp-relay b/src/sonic-config-engine/tests/sample_output/isc-dhcp-relay deleted file mode 100644 index 4a851af34eb9..000000000000 --- a/src/sonic-config-engine/tests/sample_output/isc-dhcp-relay +++ /dev/null @@ -1,7 +0,0 @@ -SERVERS="192.0.0.1 192.0.0.2 192.0.0.3 192.0.0.4 192.0.0.5 192.0.0.6 192.0.0.7 192.0.0.8 192.0.0.9 192.0.0.10 192.0.0.11 192.0.0.12 192.0.0.13 192.0.0.14 192.0.0.15 192.0.0.16 192.0.0.17 192.0.0.18 192.0.0.19 192.0.0.20 192.0.0.21 192.0.0.22 192.0.0.23 192.0.0.24 192.0.0.25 192.0.0.26 192.0.0.27 192.0.0.28 192.0.0.29 192.0.0.30 192.0.0.31 192.0.0.32 192.0.0.33 192.0.0.34 192.0.0.35 192.0.0.36 192.0.0.37 192.0.0.38 192.0.0.39 192.0.0.40 192.0.0.41 192.0.0.42 192.0.0.43 192.0.0.44 192.0.0.45 192.0.0.46 192.0.0.47 192.0.0.48" - -INTERFACES="Vlan1000 PortChannel01 PortChannel02 PortChannel03 PortChannel04" - -# '-a' option provides option 82 circuit id information -OPTIONS="-a" - From ef93c68e0641924c09926cb4b31e550340923d67 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 20 Sep 2017 21:15:56 +0000 Subject: [PATCH 09/16] Update Option 82 isc-dhcp-relay patch to load all interface name-alias maps into memory once at start instead of calling sonic-cfggen on each packet we relay --- ...d-remote_id-and-bridge-iface-support.patch | 323 +++++++++++++++--- 1 file changed, 278 insertions(+), 45 deletions(-) diff --git a/src/isc-dhcp/isc-dhcp-4.3.1_dhcrelay-custom-circuit_id-remote_id-and-bridge-iface-support.patch b/src/isc-dhcp/isc-dhcp-4.3.1_dhcrelay-custom-circuit_id-remote_id-and-bridge-iface-support.patch index 8d28751da63c..c47cea3695c1 100644 --- a/src/isc-dhcp/isc-dhcp-4.3.1_dhcrelay-custom-circuit_id-remote_id-and-bridge-iface-support.patch +++ b/src/isc-dhcp/isc-dhcp-4.3.1_dhcrelay-custom-circuit_id-remote_id-and-bridge-iface-support.patch @@ -1,10 +1,10 @@ This patch adds the following functionality to dhcrelay in isc-dhcp v4.3.1-6: * Add customizable Circuit ID and Remote ID fields -* Support for obtaining name of physical interface of interfaces that are part of a bridge interface +* Support for obtaining name of physical interfaces that are part of a bridge interface diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c ---- a/isc-dhcp/relay/dhcrelay.c 2014-08-06 22:35:02.000000000 +0000 -+++ b/isc-dhcp/relay/dhcrelay.c 2017-06-08 21:39:53.856192546 +0000 +--- a/isc-dhcp/relay/dhcrelay.c 2017-09-28 23:12:25.755524700 +0000 ++++ b/isc-dhcp/relay/dhcrelay.c 2017-09-28 23:12:17.179524700 +0000 @@ -73,6 +73,8 @@ did not match any known circuit ID. */ int missing_circuit_id = 0; /* Circuit ID option in matching RAI option @@ -14,7 +14,33 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c int max_hop_count = 10; /* Maximum hop count */ #ifdef DHCPv6 -@@ -140,9 +142,19 @@ +@@ -120,6 +122,14 @@ + char *dhcrelay_sub_id = NULL; + #endif + ++struct interface_name_alias_tuple { ++ char if_name[IFNAMSIZ + 1]; ++ char if_alias[IFNAMSIZ + 1]; ++}; ++ ++static struct interface_name_alias_tuple *g_interface_name_alias_map = NULL; ++static size_t g_interface_name_alias_map_size = 0; ++ + static void do_relay4(struct interface_info *, struct dhcp_packet *, + unsigned int, unsigned int, struct iaddr, + struct hardware *); +@@ -132,6 +142,10 @@ + struct interface_info **, + struct dhcp_packet *, unsigned); + ++static int load_interface_alias_map(void); ++static int get_interface_alias_by_name(const char *if_name, char *if_alias_out); ++static void free_interface_alias_map(void); ++ + static const char copyright[] = + "Copyright 2004-2014 Internet Systems Consortium."; + static const char arr[] = "All rights reserved."; +@@ -140,9 +154,19 @@ static const char url[] = "For info, please visit https://www.isc.org/software/dhcp/"; @@ -35,7 +61,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c " [-A ] [-c ] [-p ]\n" \ " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ -@@ -154,14 +166,15 @@ +@@ -154,14 +178,15 @@ " -l lower0 [ ... -l lowerN]\n" \ " -u upper0 [ ... -u upperN]\n" \ " lower (client link): [address%%]interface[#index]\n" \ @@ -55,7 +81,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c #endif static void usage() { -@@ -287,6 +300,15 @@ +@@ -287,6 +312,15 @@ local_family_set = 1; local_family = AF_INET; #endif @@ -71,7 +97,81 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c add_agent_options = 1; } else if (!strcmp(argv[i], "-A")) { #ifdef DHCPv6 -@@ -937,6 +959,166 @@ +@@ -454,6 +488,10 @@ + } else + log_perror = 0; + ++ /* Load our interface name-alias map */ ++ if (load_interface_alias_map() != 0) ++ log_fatal("Failed to load interface name-alias map."); ++ + /* Set default port */ + if (local_family == AF_INET) { + service_local = "bootps"; +@@ -602,6 +640,8 @@ + dispatch(); + + /* In fact dispatch() never returns. */ ++ free_interface_alias_map(); ++ + return (0); + } + +@@ -690,10 +730,9 @@ + &to, htop) < 0) { + ++server_packet_errors; + } else { +- log_debug("Forwarded BOOTREPLY for %s to %s", +- print_hw_addr(packet->htype, packet->hlen, +- packet->chaddr), +- inet_ntoa(to.sin_addr)); ++ //log_debug("Forwarded BOOTREPLY for %s to %s", ++ // print_hw_addr(packet->htype, packet->hlen, packet->chaddr), ++ // inet_ntoa(to.sin_addr)); + + ++server_packets_relayed; + } +@@ -705,6 +744,13 @@ + if (out) + return; + ++ // If the packet's hop count >= max_hop_count, drop the packet. ++ // Otherwise, increment the hop count ++ if (packet->hops < max_hop_count) ++ packet->hops = packet->hops + 1; ++ else ++ return; ++ + /* Add relay agent options if indicated. If something goes wrong, + drop the packet. */ + if (!(length = add_relay_agent_options(ip, packet, length, +@@ -718,10 +764,6 @@ + that set giaddr, so we won't see it. */ + if (!packet->giaddr.s_addr) + packet->giaddr = ip->addresses[0]; +- if (packet->hops < max_hop_count) +- packet->hops = packet->hops + 1; +- else +- return; + + /* Otherwise, it's a BOOTREQUEST, so forward it to all the + servers. */ +@@ -732,10 +774,10 @@ + &sp->to, NULL) < 0) { + ++client_packet_errors; + } else { +- log_debug("Forwarded BOOTREQUEST for %s to %s", +- print_hw_addr(packet->htype, packet->hlen, +- packet->chaddr), +- inet_ntoa(sp->to.sin_addr)); ++ //log_debug("Forwarded BOOTREQUEST for %s to %s", ++ // print_hw_addr(packet->htype, packet->hlen, packet->chaddr), ++ // inet_ntoa(sp->to.sin_addr)); ++ + ++client_packets_relayed; + } + } +@@ -937,6 +979,152 @@ return (-1); } @@ -106,9 +206,8 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c + if (cmd != NULL) { + while (fgets(buf, sizeof(buf), cmd)) { + sscanf(buf, FDB_LINE_FORMAT, macAddr, interface, vlanid); -+ log_debug ("bridgefdbquery: macAddr:%s interface: %s vlanid %d", -+ macAddr, -+ interface, *vlanid); ++ //log_debug("bridgefdbquery: macAddr:%s interface: %s vlanid %d", ++ // macAddr, interface, *vlanid); + } + pclose(cmd); + return 0; @@ -160,42 +259,29 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c + &vlanid); + + if (ret < 0) { -+ log_debug("MAC Address: %s (interface:%s vlan:%d) not found in bridge fdb show", -+ print_hw_addr (packet->htype, packet->hlen, packet->chaddr), -+ ip->name, -+ vlanid); ++ //log_debug("MAC Address: %s (interface:%s vlan:%d) not found in bridge fdb show", ++ // print_hw_addr (packet->htype, packet->hlen, packet->chaddr), ++ // ip->name, ++ // vlanid); ++ + strncpy(ifname, ip->name, IFNAMSIZ); + } + else if (strlen(ip->name) > 0) { -+ char cmdstr[256] = { 0 }; -+ char cmdout[256] = { 0 }; -+ -+ log_debug("Adding option 82 interface name for MAC Address: %s as %s", -+ print_hw_addr (packet->htype, packet->hlen, packet->chaddr), -+ ip->name); -+ -+ // Translate SONiC interface name to vendor alias -+ sprintf(cmdstr, "sonic-cfggen -m /etc/sonic/minigraph.xml -v \"minigraph_ports['%s'].alias\"", ip->name); -+ -+ FILE *cmd = popen(cmdstr, "r"); -+ -+ if (cmd != NULL) { -+ while (fgets(cmdout, sizeof(cmdout), cmd)) { -+ // Strip any trailing newline -+ if (cmdout[strlen(cmdout) - 1] == '\n') -+ cmdout[strlen(cmdout) - 1] = '\0'; -+ -+ log_debug ("Retrieved alias %s for interface %s", buf, ip->name); ++ // Translate SONiC interface name to vendor alias ++ if (get_interface_alias_by_name(ip->name, ifname) < 0) { ++ log_error("Failed to retrieve alias for interface name '%s'. Defaulting to interface name.", ip->name); ++ strncpy(ifname, ip->name, IFNAMSIZ); + } + -+ pclose(cmd); ++ //log_debug("Mapped interface name '%s' to alias '%s'", ip->name, ifname); ++ ++ //log_debug("Adding option 82 interface alias for MAC Address %s as '%s'", ++ // print_hw_addr (packet->htype, packet->hlen, packet->chaddr), ++ // ifname); + } + -+ strncpy(ifname, cmdout, IFNAMSIZ); ++ str = ifname; + } -+ -+ str = ifname; -+ } + break; + + case 'P': /* Physical address of interface that we received the request from */ @@ -238,7 +324,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c /* * Examine a packet to see if it's a candidate to have a Relay * Agent Information option tacked onto its tail. If it is, tack -@@ -948,6 +1130,8 @@ +@@ -948,6 +1136,8 @@ int is_dhcp = 0, mms; unsigned optlen; u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; @@ -247,7 +333,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c /* If we're not adding agent options to packets, we can skip this. */ -@@ -1077,6 +1261,38 @@ +@@ -1077,6 +1267,38 @@ op = sp; #endif @@ -262,8 +348,8 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c + ip->circuit_id = (uint8_t *)circuit_id_buf; + ip->circuit_id_len = len; + -+ log_debug("sending on %s option82:circuit_id='%s'(%d)", -+ ip->name, (char *)ip->circuit_id, ip->circuit_id_len); ++ //log_debug("Sending on %s option82:circuit_id='%s' (%d)", ++ // ip->name, (char *)ip->circuit_id, ip->circuit_id_len); + } + } + @@ -278,12 +364,159 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c + ip->remote_id = (uint8_t *)remote_id_buf; + ip->remote_id_len = len; + -+ log_debug("sending on %s option82:remote_id='%s'(%d)", -+ ip->name, (char *)ip->remote_id, ip->remote_id_len); ++ //log_debug("Sending on %s option82:remote_id='%s' (%d)", ++ // ip->name, (char *)ip->remote_id, ip->remote_id_len); + } + } + /* Sanity check. Had better not ever happen. */ if ((ip->circuit_id_len > 255) ||(ip->circuit_id_len < 1)) log_fatal("Circuit ID length %d out of range [1-255] on " - +@@ -1102,7 +1324,7 @@ + * If not, forward without adding the option. + */ + if (max - sp >= optlen + 3) { +- log_debug("Adding %d-byte relay agent option", optlen + 3); ++ //log_debug("Adding %d-byte relay agent option", optlen + 3); + + /* Okay, cons up *our* Relay Agent Information option. */ + *sp++ = DHO_DHCP_AGENT_OPTIONS; +@@ -1726,3 +1948,138 @@ + + exit(0); + } ++ ++#define MAX_PORT_CONFIG_LINE_LEN 1024 ++ ++// Allocates and loads global map g_interface_name_alias_map ++// Also sets global g_interface_name_alias_map_size ++static int ++load_interface_alias_map(void) { ++ int i = 0; ++ FILE *fp = NULL; ++ char line[MAX_PORT_CONFIG_LINE_LEN] = { 0 }; ++ char port_config_file_path[] = "/usr/share/sonic/hwsku/port_config.ini"; ++ int name_column = -1; ++ int alias_column = -1; ++ char *pch = NULL; ++ ++ fp = fopen(port_config_file_path,"r"); ++ if (fp == NULL) { ++ log_error("Unable to open %s", port_config_file_path); ++ return -1; ++ } ++ ++ g_interface_name_alias_map_size = 0; ++ ++ // Count the number of interfaces listed in the file ++ while (fgets(line, sizeof(line), fp)) { ++ // Ignore comments ++ if (*line == '#') ++ continue; ++ ++ g_interface_name_alias_map_size++; ++ } ++ ++ // Allocate our map accordingly ++ g_interface_name_alias_map = ((struct interface_name_alias_tuple *) ++ dmalloc((sizeof(struct interface_name_alias_tuple) * g_interface_name_alias_map_size), ++ MDL)); ++ ++ // Reset file position indicator to beginning of file ++ fseek(fp, 0, SEEK_SET); ++ ++ // We expect the first line of port_config.ini to be a comment that defines the order of the columns ++ fgets(line, sizeof(line), fp); ++ if (*line != '#') { ++ log_error("Improper format of port_config.ini file - missing header row"); ++ return -1; ++ } ++ ++ // Remove the initial '#' and following whitespace so that the first token is our first column title ++ pch = strtok(line, "# \t"); ++ ++ while (pch != NULL) { ++ if (strncmp(pch, "name", 4) == 0) ++ name_column = i; ++ else if (strncmp(pch, "alias", 5) == 0) ++ alias_column = i; ++ ++ i++; ++ ++ // Split the line by whitespace ++ pch = strtok(NULL, " \t"); ++ } ++ ++ // Ensure we found a "name" column. Note that "alias" column is optional. If there is no ++ // "alias" column present, we reuse the name as the alias ++ if (name_column == -1) { ++ log_error("Improper format of port_config.ini file - no 'name' field in header row"); ++ return -1; ++ } ++ ++ i = 0; ++ ++ // For the remainder of the file, we parse the fields of each line according to our header ++ while (fgets(line, sizeof(line), fp)) { ++ int column = 0; ++ ++ // Ignore comments ++ if (*line == '#') ++ continue; ++ ++ // Split the line by whitespace ++ pch = strtok(line, " \t"); ++ ++ while (pch != NULL) { ++ // If this is the index of the "name" column, save it as this interface's name ++ if (column == name_column) { ++ strncpy(g_interface_name_alias_map[i].if_name, pch, IFNAMSIZ); ++ ++ // If there was no "alias" column in the file, save the interface name as the alias ++ if (alias_column == -1) ++ strncpy(g_interface_name_alias_map[i].if_alias, pch, IFNAMSIZ); ++ } ++ else if (column == alias_column) { ++ strncpy(g_interface_name_alias_map[i].if_alias, pch, IFNAMSIZ); ++ } ++ ++ column++; ++ ++ // Split the line by whitespace ++ pch = strtok(NULL, " \t"); ++ } ++ ++ i++; ++ } ++ ++ fclose(fp); ++ ++ log_info("Loaded %d interface name-alias mappings", i); ++ ++ return 0; ++} ++ ++// Locates alias for port named if_name, copies alias into if_alias_out, up to a ++// max of IFNAMSIZ bytes. ++// Returns 0 on success, -1 on failure ++static int ++get_interface_alias_by_name(const char *if_name, char *if_alias_out) { ++ int i = 0; ++ ++ for (i = 0; i < g_interface_name_alias_map_size; i++) { ++ if (strncmp(if_name, g_interface_name_alias_map[i].if_name, IFNAMSIZ) == 0) { ++ strncpy(if_alias_out, g_interface_name_alias_map[i].if_alias, IFNAMSIZ); ++ return 0; ++ } ++ } ++ ++ return -1; ++} ++ ++// Frees global map g_interface_name_alias_map ++// Sets g_interface_name_alias_map_size to 0 ++static void ++free_interface_alias_map(void) { ++ free(g_interface_name_alias_map); ++ g_interface_name_alias_map_size = 0; ++} From 69d6fa648cf25071c5cb27ae6ba95e7df3d3a3c5 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 25 Sep 2017 23:26:47 +0000 Subject: [PATCH 10/16] Remove executable permission from Jinja2 template --- dockers/docker-dhcp-relay/wait_for_intf.sh.j2 | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 dockers/docker-dhcp-relay/wait_for_intf.sh.j2 diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 old mode 100755 new mode 100644 From 39d03013d868be964dc6a37c5bdbecee928ce9bc Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 25 Sep 2017 23:28:10 +0000 Subject: [PATCH 11/16] Set max hop count to 1 so that DHCP relay will only relay packets with a hop count of zero --- dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 0f288d95b12d..2a6f5cdb28d8 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -37,7 +37,7 @@ isc-dhcp-relay-{{ vlan_name }} {% for vlan_name in VLAN -%} {%- if VLAN[vlan_name]['dhcp_servers'] -%} [program:isc-dhcp-relay-{{ vlan_name }}] -command=/usr/sbin/dhcrelay -d -a %%h:%%p %%P -i {{ vlan_name }} +command=/usr/sbin/dhcrelay -d -c 1 -a %%h:%%p %%P -i {{ vlan_name }} {%- for (name, prefix) in INTERFACE -%} {%- if prefix | ipv4 %} -i {{ name }}{% endif -%} {%- endfor -%} From bc1550f3fc2bdfb61adf0d225d92962f805e997b Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 29 Sep 2017 00:31:12 +0000 Subject: [PATCH 12/16] Replace tabs with spaces --- src/sonic-config-engine/tests/pc-test-graph.xml | 2 +- src/sonic-config-engine/tests/simple-sample-graph.xml | 2 +- src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml | 2 +- src/sonic-config-engine/tests/t0-sample-graph-everflow.xml | 2 +- src/sonic-config-engine/tests/t0-sample-graph.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sonic-config-engine/tests/pc-test-graph.xml b/src/sonic-config-engine/tests/pc-test-graph.xml index 9c346c09a462..2cb281b879cb 100644 --- a/src/sonic-config-engine/tests/pc-test-graph.xml +++ b/src/sonic-config-engine/tests/pc-test-graph.xml @@ -108,7 +108,7 @@ False 0.0.0.0/0 - 192.0.0.1;192.0.0.2 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index bbf5995809c9..89f53af83e41 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -130,7 +130,7 @@ Vlan1000 fortyGigE0/8 - 192.0.0.1;192.0.0.2 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml b/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml index e187b9a1c96b..18a8baccdae2 100644 --- a/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml +++ b/src/sonic-config-engine/tests/t0-sample-bgp-speaker.xml @@ -203,7 +203,7 @@ False 0.0.0.0/0 - 192.0.0.1;192.0.0.2 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml b/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml index 167999216164..6a078b48cf99 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph-everflow.xml @@ -198,7 +198,7 @@ False 0.0.0.0/0 - 192.0.0.1;192.0.0.2 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 23da26b9a860..fe0b1a1e2500 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -206,7 +206,7 @@ False 0.0.0.0/0 - 192.0.0.1;192.0.0.2 + 192.0.0.1;192.0.0.2 1000 1000 192.168.0.0/27 From a97fff2176e104dd850e0c9473191fee3f27007a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 29 Sep 2017 18:09:09 +0000 Subject: [PATCH 13/16] Modify overlooked sonic-cfggen call, use Config DB instead of minigraph --- dockers/docker-dhcp-relay/docker_init.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-dhcp-relay/docker_init.sh b/dockers/docker-dhcp-relay/docker_init.sh index 78574c1049de..08b20e94aada 100755 --- a/dockers/docker-dhcp-relay/docker_init.sh +++ b/dockers/docker-dhcp-relay/docker_init.sh @@ -2,7 +2,7 @@ # Generate supervisord config file mkdir -p /etc/supervisor/conf.d/ -sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/docker-dhcp-relay.supervisord.conf.j2 > /etc/supervisor/conf.d/docker-dhcp-relay.supervisord.conf +sonic-cfggen -d -t /usr/share/sonic/templates/docker-dhcp-relay.supervisord.conf.j2 > /etc/supervisor/conf.d/docker-dhcp-relay.supervisord.conf # Generate the script that waits for all interfaces to come up and make it executable sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh From ba4a06b0598a8bae34bbaf1cb5b0bd061a60bb31 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 29 Sep 2017 18:53:52 +0000 Subject: [PATCH 14/16] Also ensure > 1 VLAN requires a DHCP relay agent before outputting to template --- .../docker-dhcp-relay.supervisord.conf.j2 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 2a6f5cdb28d8..069a8e96dce4 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -21,6 +21,15 @@ stderr_logfile=syslog {# If our configuration has VLANs... #} {% if VLAN %} +{# Count how many VLANs require a DHCP relay agent... #} +{% set num_relays = { 'count': 0 } %} +{% for vlan_name in VLAN %} +{% if VLAN[vlan_name]['dhcp_servers'] %} +{% set _dummy = num_relays.update({'count': num_relays.count + 1}) %} +{% endif %} +{% endfor %} +{# If one or more of the VLANs require a DHCP relay agent... #} +{% if num_relays.count > 0 %} [group:isc-dhcp-relay] programs= {%- set add_preceding_comma = { 'flag': False } -%} @@ -55,3 +64,4 @@ stderr_logfile=syslog {% endif %} {% endfor %} {% endif %} +{% endif %} From 7bb46d11bf197f78321bdc2df6f4f1623c160340 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 3 Oct 2017 17:57:06 +0000 Subject: [PATCH 15/16] Generate port name-alias map file using sonic-cfggen and parse that in lieu of parsing port_config.ini directly --- .../docker-dhcp-relay.supervisord.conf.j2 | 2 +- dockers/docker-dhcp-relay/docker_init.sh | 4 + ...d-remote_id-and-bridge-iface-support.patch | 168 +++++------------- 3 files changed, 49 insertions(+), 125 deletions(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 069a8e96dce4..c5b366684e50 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -46,7 +46,7 @@ isc-dhcp-relay-{{ vlan_name }} {% for vlan_name in VLAN -%} {%- if VLAN[vlan_name]['dhcp_servers'] -%} [program:isc-dhcp-relay-{{ vlan_name }}] -command=/usr/sbin/dhcrelay -d -c 1 -a %%h:%%p %%P -i {{ vlan_name }} +command=/usr/sbin/dhcrelay -d -c 1 -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -i {{ vlan_name }} {%- for (name, prefix) in INTERFACE -%} {%- if prefix | ipv4 %} -i {{ name }}{% endif -%} {%- endfor -%} diff --git a/dockers/docker-dhcp-relay/docker_init.sh b/dockers/docker-dhcp-relay/docker_init.sh index 08b20e94aada..f6d402e6f780 100755 --- a/dockers/docker-dhcp-relay/docker_init.sh +++ b/dockers/docker-dhcp-relay/docker_init.sh @@ -8,6 +8,10 @@ sonic-cfggen -d -t /usr/share/sonic/templates/docker-dhcp-relay.supervisord.conf sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh chmod +x /usr/bin/wait_for_intf.sh +# Generate port name-alias map for isc-dhcp-relay to parse. Each line contains one +# name-alias pair of the form " " +sonic-cfggen -d --var-json "PORT" | python -c "import sys, json, os; [sys.stdout.write('%s %s\n' % (k, v['alias'] if 'alias' in v else k)) for (k, v) in json.load(sys.stdin).iteritems()]" > /tmp/port-name-alias-map.txt + # The docker container should start this script as PID 1, so now that supervisord is # properly configured, we exec supervisord so that it runs as PID 1 for the # duration of the container's lifetime diff --git a/src/isc-dhcp/isc-dhcp-4.3.1_dhcrelay-custom-circuit_id-remote_id-and-bridge-iface-support.patch b/src/isc-dhcp/isc-dhcp-4.3.1_dhcrelay-custom-circuit_id-remote_id-and-bridge-iface-support.patch index c47cea3695c1..4dee30238acd 100644 --- a/src/isc-dhcp/isc-dhcp-4.3.1_dhcrelay-custom-circuit_id-remote_id-and-bridge-iface-support.patch +++ b/src/isc-dhcp/isc-dhcp-4.3.1_dhcrelay-custom-circuit_id-remote_id-and-bridge-iface-support.patch @@ -3,8 +3,8 @@ This patch adds the following functionality to dhcrelay in isc-dhcp v4.3.1-6: * Support for obtaining name of physical interfaces that are part of a bridge interface diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c ---- a/isc-dhcp/relay/dhcrelay.c 2017-09-28 23:12:25.755524700 +0000 -+++ b/isc-dhcp/relay/dhcrelay.c 2017-09-28 23:12:17.179524700 +0000 +--- a/isc-dhcp/relay/dhcrelay.c 2017-10-03 01:46:19.811524700 +0000 ++++ b/isc-dhcp/relay/dhcrelay.c 2017-10-03 01:45:50.699524700 +0000 @@ -73,6 +73,8 @@ did not match any known circuit ID. */ int missing_circuit_id = 0; /* Circuit ID option in matching RAI option @@ -33,14 +33,14 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c struct interface_info **, struct dhcp_packet *, unsigned); -+static int load_interface_alias_map(void); ++static int load_interface_alias_map(const char *port_alias_map_file_path); +static int get_interface_alias_by_name(const char *if_name, char *if_alias_out); +static void free_interface_alias_map(void); + static const char copyright[] = "Copyright 2004-2014 Internet Systems Consortium."; static const char arr[] = "All rights reserved."; -@@ -140,9 +154,19 @@ +@@ -140,28 +154,42 @@ static const char url[] = "For info, please visit https://www.isc.org/software/dhcp/"; @@ -49,7 +49,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c +"\n" \ +" %%%% A single %%\n" \ +" %%h Hostname of device\n" \ -+" %%p Name of interface that generated the request\n" \ ++" %%p Alias of interface that generated the request\n" \ +" %%P Hardware address of interface that generated the request\n" \ +" %%C Client hardware address\n" \ +" %%I DHCP relay agent IP Address\n" \ @@ -61,7 +61,13 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c " [-A ] [-c ] [-p ]\n" \ " [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ -@@ -154,14 +178,15 @@ ++" [--name-alias-map-file ]\n" \ + " [-i interface0 [ ... -i interfaceN]\n" \ + " server0 [ ... serverN]\n\n" \ + " dhcrelay -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n" \ ++" [--name-alias-map-file ]\n" \ + " [-s ]\n" \ " -l lower0 [ ... -l lowerN]\n" \ " -u upper0 [ ... -u upperN]\n" \ " lower (client link): [address%%]interface[#index]\n" \ @@ -75,13 +81,14 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c +" [-A ] [-c ] [-p ]\n" \ +" [-pf ] [--no-pid]\n"\ " [-m append|replace|forward|discard]\n" \ ++" [--name-alias-map-file ]\n" \ " [-i interface0 [ ... -i interfaceN]\n" \ -" server0 [ ... serverN]\n\n" +" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE #endif static void usage() { -@@ -287,6 +312,15 @@ +@@ -287,6 +315,15 @@ local_family_set = 1; local_family = AF_INET; #endif @@ -97,18 +104,21 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c add_agent_options = 1; } else if (!strcmp(argv[i], "-A")) { #ifdef DHCPv6 -@@ -454,6 +488,10 @@ - } else - log_perror = 0; - -+ /* Load our interface name-alias map */ -+ if (load_interface_alias_map() != 0) -+ log_fatal("Failed to load interface name-alias map."); -+ - /* Set default port */ - if (local_family == AF_INET) { - service_local = "bootps"; -@@ -602,6 +640,8 @@ +@@ -383,6 +420,13 @@ + no_dhcrelay_pid = ISC_TRUE; + } else if (!strcmp(argv[i], "--no-pid")) { + no_pid_file = ISC_TRUE; ++ } else if (!strcmp(argv[i], "--name-alias-map-file")) { ++ if (++i == argc) ++ usage(); ++ if (load_interface_alias_map(argv[i]) != 0) ++ log_fatal("Failed to load interface name-alias map."); ++ path_dhcrelay_pid = argv[i]; ++ no_dhcrelay_pid = ISC_TRUE; + } else if (!strcmp(argv[i], "--version")) { + log_info("isc-dhcrelay-%s", PACKAGE_VERSION); + exit(0); +@@ -602,6 +646,8 @@ dispatch(); /* In fact dispatch() never returns. */ @@ -117,7 +127,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c return (0); } -@@ -690,10 +730,9 @@ +@@ -690,10 +736,9 @@ &to, htop) < 0) { ++server_packet_errors; } else { @@ -131,32 +141,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c ++server_packets_relayed; } -@@ -705,6 +744,13 @@ - if (out) - return; - -+ // If the packet's hop count >= max_hop_count, drop the packet. -+ // Otherwise, increment the hop count -+ if (packet->hops < max_hop_count) -+ packet->hops = packet->hops + 1; -+ else -+ return; -+ - /* Add relay agent options if indicated. If something goes wrong, - drop the packet. */ - if (!(length = add_relay_agent_options(ip, packet, length, -@@ -718,10 +764,6 @@ - that set giaddr, so we won't see it. */ - if (!packet->giaddr.s_addr) - packet->giaddr = ip->addresses[0]; -- if (packet->hops < max_hop_count) -- packet->hops = packet->hops + 1; -- else -- return; - - /* Otherwise, it's a BOOTREQUEST, so forward it to all the - servers. */ -@@ -732,10 +774,10 @@ +@@ -732,10 +777,10 @@ &sp->to, NULL) < 0) { ++client_packet_errors; } else { @@ -171,7 +156,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c ++client_packets_relayed; } } -@@ -937,6 +979,152 @@ +@@ -937,6 +982,152 @@ return (-1); } @@ -248,7 +233,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c + + case 'p': /* Name of interface that we received the request from */ + /* -+ * Query FDB to identify the exact physical interface only when source MAC address ++ * Query FDB to identify the exact physical interface only when source MAC address + * is present and '20: DHCP relay agent IP address' (giaddr) is not present + */ + if (packet->htype && !packet->giaddr.s_addr) { @@ -324,7 +309,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c /* * Examine a packet to see if it's a candidate to have a Relay * Agent Information option tacked onto its tail. If it is, tack -@@ -948,6 +1136,8 @@ +@@ -948,6 +1139,8 @@ int is_dhcp = 0, mms; unsigned optlen; u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; @@ -333,7 +318,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c /* If we're not adding agent options to packets, we can skip this. */ -@@ -1077,6 +1267,38 @@ +@@ -1077,6 +1270,38 @@ op = sp; #endif @@ -372,7 +357,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c /* Sanity check. Had better not ever happen. */ if ((ip->circuit_id_len > 255) ||(ip->circuit_id_len < 1)) log_fatal("Circuit ID length %d out of range [1-255] on " -@@ -1102,7 +1324,7 @@ +@@ -1102,7 +1327,7 @@ * If not, forward without adding the option. */ if (max - sp >= optlen + 3) { @@ -381,7 +366,7 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c /* Okay, cons up *our* Relay Agent Information option. */ *sp++ = DHO_DHCP_AGENT_OPTIONS; -@@ -1726,3 +1948,138 @@ +@@ -1726,3 +1951,73 @@ exit(0); } @@ -391,18 +376,14 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c +// Allocates and loads global map g_interface_name_alias_map +// Also sets global g_interface_name_alias_map_size +static int -+load_interface_alias_map(void) { ++load_interface_alias_map(const char *port_alias_map_file_path) { + int i = 0; + FILE *fp = NULL; + char line[MAX_PORT_CONFIG_LINE_LEN] = { 0 }; -+ char port_config_file_path[] = "/usr/share/sonic/hwsku/port_config.ini"; -+ int name_column = -1; -+ int alias_column = -1; -+ char *pch = NULL; + -+ fp = fopen(port_config_file_path,"r"); ++ fp = fopen(port_alias_map_file_path,"r"); + if (fp == NULL) { -+ log_error("Unable to open %s", port_config_file_path); ++ log_error("Unable to open %s", port_alias_map_file_path); + return -1; + } + @@ -410,82 +391,21 @@ diff -ruN a/isc-dhcp/relay/dhcrelay.c b/isc-dhcp/relay/dhcrelay.c + + // Count the number of interfaces listed in the file + while (fgets(line, sizeof(line), fp)) { -+ // Ignore comments -+ if (*line == '#') -+ continue; -+ + g_interface_name_alias_map_size++; + } + + // Allocate our map accordingly + g_interface_name_alias_map = ((struct interface_name_alias_tuple *) -+ dmalloc((sizeof(struct interface_name_alias_tuple) * g_interface_name_alias_map_size), ++ dmalloc((sizeof(struct interface_name_alias_tuple) * g_interface_name_alias_map_size), + MDL)); + + // Reset file position indicator to beginning of file + fseek(fp, 0, SEEK_SET); + -+ // We expect the first line of port_config.ini to be a comment that defines the order of the columns -+ fgets(line, sizeof(line), fp); -+ if (*line != '#') { -+ log_error("Improper format of port_config.ini file - missing header row"); -+ return -1; -+ } -+ -+ // Remove the initial '#' and following whitespace so that the first token is our first column title -+ pch = strtok(line, "# \t"); -+ -+ while (pch != NULL) { -+ if (strncmp(pch, "name", 4) == 0) -+ name_column = i; -+ else if (strncmp(pch, "alias", 5) == 0) -+ alias_column = i; -+ -+ i++; -+ -+ // Split the line by whitespace -+ pch = strtok(NULL, " \t"); -+ } -+ -+ // Ensure we found a "name" column. Note that "alias" column is optional. If there is no -+ // "alias" column present, we reuse the name as the alias -+ if (name_column == -1) { -+ log_error("Improper format of port_config.ini file - no 'name' field in header row"); -+ return -1; -+ } -+ -+ i = 0; -+ -+ // For the remainder of the file, we parse the fields of each line according to our header ++ // Every line should contain exactly one name-alias pair + while (fgets(line, sizeof(line), fp)) { -+ int column = 0; -+ -+ // Ignore comments -+ if (*line == '#') -+ continue; -+ -+ // Split the line by whitespace -+ pch = strtok(line, " \t"); -+ -+ while (pch != NULL) { -+ // If this is the index of the "name" column, save it as this interface's name -+ if (column == name_column) { -+ strncpy(g_interface_name_alias_map[i].if_name, pch, IFNAMSIZ); -+ -+ // If there was no "alias" column in the file, save the interface name as the alias -+ if (alias_column == -1) -+ strncpy(g_interface_name_alias_map[i].if_alias, pch, IFNAMSIZ); -+ } -+ else if (column == alias_column) { -+ strncpy(g_interface_name_alias_map[i].if_alias, pch, IFNAMSIZ); -+ } -+ -+ column++; -+ -+ // Split the line by whitespace -+ pch = strtok(NULL, " \t"); -+ } -+ ++ // Each line should read as "" ++ sscanf(line, "%s %s", g_interface_name_alias_map[i].if_name, g_interface_name_alias_map[i].if_alias); + i++; + } + From 486d0a5f2e2ea204f72ffe1b57467a00875225a3 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 3 Oct 2017 23:40:57 +0000 Subject: [PATCH 16/16] No longer drop packets with hop count > 0; Instead, drop packets which already contain agent info --- dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index c5b366684e50..747f65a3aaf6 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -46,7 +46,7 @@ isc-dhcp-relay-{{ vlan_name }} {% for vlan_name in VLAN -%} {%- if VLAN[vlan_name]['dhcp_servers'] -%} [program:isc-dhcp-relay-{{ vlan_name }}] -command=/usr/sbin/dhcrelay -d -c 1 -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -i {{ vlan_name }} +command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -i {{ vlan_name }} {%- for (name, prefix) in INTERFACE -%} {%- if prefix | ipv4 %} -i {{ name }}{% endif -%} {%- endfor -%}