Skip to content

Commit 1d16a37

Browse files
jlevequelguohan
authored andcommitted
[DHCP Relay]: Support Multiple VLANs (Separate DHCP Relay Agents, One Per VLAN) (#999)
* [DHCP Relay]: Support new <DhcpRelays> minigraph tag; support multiple VLANs * Don't start dhcrelay in quiet mode so as to get startup output in syslog * Update sonic-cfggen tests to support new '<DhcpRelays>' tag * <DhcpRelays> tag is only present for VLANs which require a DHCP relay agent -- only parse if present * Don't attempt to configure a DHCP relay agent for VLANs without specified DHCP servers * Modify to work with Taoyu's minigraph/DB changes (#942) * Reduce number of DHCP servers in sonic-cfggen unit tests from 4 to 2 * Remove isc-dhcp-relay sample output file from sonic-cfggen test, as we no longer generate that file * 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 * Remove executable permission from Jinja2 template * Set max hop count to 1 so that DHCP relay will only relay packets with a hop count of zero * Replace tabs with spaces * Modify overlooked sonic-cfggen call, use Config DB instead of minigraph * Also ensure > 1 VLAN requires a DHCP relay agent before outputting to template * Generate port name-alias map file using sonic-cfggen and parse that in lieu of parsing port_config.ini directly * No longer drop packets with hop count > 0; Instead, drop packets which already contain agent info
1 parent 1cd9818 commit 1d16a37

17 files changed

+307
-143
lines changed

dockers/docker-dhcp-relay/Dockerfile.j2

+3-5
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return
2222
RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y
2323
RUN rm -rf /debs
2424

25-
COPY ["start.sh", "isc-dhcp-relay.sh", "/usr/bin/"]
26-
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
27-
COPY ["isc-dhcp-relay.j2", "/usr/share/sonic/templates/"]
28-
COPY ["wait_for_intf.sh.j2", "/usr/share/sonic/templates/"]
25+
COPY ["docker_init.sh", "start.sh", "/usr/bin/"]
26+
COPY ["docker-dhcp-relay.supervisord.conf.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"]
2927

30-
ENTRYPOINT ["/usr/bin/supervisord"]
28+
ENTRYPOINT ["/usr/bin/docker_init.sh"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
[supervisord]
2+
logfile_maxbytes=1MB
3+
logfile_backups=2
4+
nodaemon=true
5+
6+
[program:start.sh]
7+
command=/usr/bin/start.sh
8+
priority=1
9+
autostart=true
10+
autorestart=false
11+
stdout_logfile=syslog
12+
stderr_logfile=syslog
13+
14+
[program:rsyslogd]
15+
command=/usr/sbin/rsyslogd -n
16+
priority=2
17+
autostart=false
18+
autorestart=false
19+
stdout_logfile=syslog
20+
stderr_logfile=syslog
21+
22+
{# If our configuration has VLANs... #}
23+
{% if VLAN %}
24+
{# Count how many VLANs require a DHCP relay agent... #}
25+
{% set num_relays = { 'count': 0 } %}
26+
{% for vlan_name in VLAN %}
27+
{% if VLAN[vlan_name]['dhcp_servers'] %}
28+
{% set _dummy = num_relays.update({'count': num_relays.count + 1}) %}
29+
{% endif %}
30+
{% endfor %}
31+
{# If one or more of the VLANs require a DHCP relay agent... #}
32+
{% if num_relays.count > 0 %}
33+
[group:isc-dhcp-relay]
34+
programs=
35+
{%- set add_preceding_comma = { 'flag': False } -%}
36+
{%- for vlan_name in VLAN -%}
37+
{%- if VLAN[vlan_name]['dhcp_servers'] -%}
38+
{%- if add_preceding_comma.flag %},{% endif -%}
39+
{%- set _dummy = add_preceding_comma.update({'flag': True}) -%}
40+
isc-dhcp-relay-{{ vlan_name }}
41+
{%- endif %}
42+
{% endfor %}
43+
44+
45+
{# Create a program entry for each DHCP relay agent instance #}
46+
{% for vlan_name in VLAN -%}
47+
{%- if VLAN[vlan_name]['dhcp_servers'] -%}
48+
[program:isc-dhcp-relay-{{ vlan_name }}]
49+
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -i {{ vlan_name }}
50+
{%- for (name, prefix) in INTERFACE -%}
51+
{%- if prefix | ipv4 %} -i {{ name }}{% endif -%}
52+
{%- endfor -%}
53+
{%- for (name, prefix) in PORTCHANNEL_INTERFACE -%}
54+
{%- if prefix | ipv4 %} -i {{ name }}{% endif -%}
55+
{%- endfor -%}
56+
{%- for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} {{ dhcp_server }}{% endfor %}
57+
58+
priority=3
59+
autostart=false
60+
autorestart=false
61+
stdout_logfile=syslog
62+
stderr_logfile=syslog
63+
64+
{% endif %}
65+
{% endfor %}
66+
{% endif %}
67+
{% endif %}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env bash
2+
3+
# Generate supervisord config file
4+
mkdir -p /etc/supervisor/conf.d/
5+
sonic-cfggen -d -t /usr/share/sonic/templates/docker-dhcp-relay.supervisord.conf.j2 > /etc/supervisor/conf.d/docker-dhcp-relay.supervisord.conf
6+
7+
# Generate the script that waits for all interfaces to come up and make it executable
8+
sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh
9+
chmod +x /usr/bin/wait_for_intf.sh
10+
11+
# Generate port name-alias map for isc-dhcp-relay to parse. Each line contains one
12+
# name-alias pair of the form "<name> <alias>"
13+
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
14+
15+
# The docker container should start this script as PID 1, so now that supervisord is
16+
# properly configured, we exec supervisord so that it runs as PID 1 for the
17+
# duration of the container's lifetime
18+
exec /usr/bin/supervisord

dockers/docker-dhcp-relay/isc-dhcp-relay.j2

-28
This file was deleted.

dockers/docker-dhcp-relay/isc-dhcp-relay.sh

-18
This file was deleted.

dockers/docker-dhcp-relay/start.sh

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
#!/usr/bin/env bash
22

3-
# Create isc-dhcp-relay config file
4-
sonic-cfggen -d -t /usr/share/sonic/templates/isc-dhcp-relay.j2 > /etc/default/isc-dhcp-relay
5-
3+
# Remove stale rsyslog PID file if it exists
64
rm -f /var/run/rsyslogd.pid
75

6+
# Start rsyslog
87
supervisorctl start rsyslogd
98

10-
# Wait for all interfaces to come up before starting the DHCP relay
11-
sonic-cfggen -d -t /usr/share/sonic/templates/wait_for_intf.sh.j2 > /usr/bin/wait_for_intf.sh
12-
chmod +x /usr/bin/wait_for_intf.sh
9+
# Wait for all interfaces to come up before starting the DHCP relay agent(s)
1310
/usr/bin/wait_for_intf.sh
1411

15-
# Start the DHCP relay
16-
supervisorctl start isc-dhcp-relay
12+
# Start the DHCP relay agent(s)
13+
supervisorctl start isc-dhcp-relay:*

dockers/docker-dhcp-relay/supervisord.conf

-28
This file was deleted.

dockers/docker-dhcp-relay/wait_for_intf.sh.j2

100755100644
-1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,3 @@ wait_until_iface_exists {{ name }}
2525
{% for (name, prefix) in PORTCHANNEL_INTERFACE %}
2626
wait_until_iface_exists {{ name }}
2727
{% endfor %}
28-

0 commit comments

Comments
 (0)