Skip to content

Commit

Permalink
[DHCP Relay]: Support Multiple VLANs (Separate DHCP Relay Agents, One…
Browse files Browse the repository at this point in the history
… 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
  • Loading branch information
jleveque authored and lguohan committed Oct 5, 2017
1 parent 1cd9818 commit 1d16a37
Show file tree
Hide file tree
Showing 17 changed files with 307 additions and 143 deletions.
8 changes: 3 additions & 5 deletions dockers/docker-dhcp-relay/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
67 changes: 67 additions & 0 deletions dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
[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 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 } -%}
{%- 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 }}
{%- endif %}
{% endfor %}


{# Create a program entry for each DHCP relay agent instance #}
{% for vlan_name in VLAN -%}
{%- if VLAN[vlan_name]['dhcp_servers'] -%}
[program:isc-dhcp-relay-{{ 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 -%}
{%- for (name, prefix) in PORTCHANNEL_INTERFACE -%}
{%- if prefix | ipv4 %} -i {{ name }}{% endif -%}
{%- endfor -%}
{%- for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} {{ dhcp_server }}{% endfor %}

priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog

{% endif %}
{% endfor %}
{% endif %}
{% endif %}
18 changes: 18 additions & 0 deletions dockers/docker-dhcp-relay/docker_init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash

# Generate supervisord config file
mkdir -p /etc/supervisor/conf.d/
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
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 "<name> <alias>"
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
exec /usr/bin/supervisord
28 changes: 0 additions & 28 deletions dockers/docker-dhcp-relay/isc-dhcp-relay.j2

This file was deleted.

18 changes: 0 additions & 18 deletions dockers/docker-dhcp-relay/isc-dhcp-relay.sh

This file was deleted.

13 changes: 5 additions & 8 deletions dockers/docker-dhcp-relay/start.sh
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
#!/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

# 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
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
# Wait for all interfaces to come up before starting the DHCP relay agent(s)
/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:*
28 changes: 0 additions & 28 deletions dockers/docker-dhcp-relay/supervisord.conf

This file was deleted.

1 change: 0 additions & 1 deletion dockers/docker-dhcp-relay/wait_for_intf.sh.j2
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,3 @@ wait_until_iface_exists {{ name }}
{% for (name, prefix) in PORTCHANNEL_INTERFACE %}
wait_until_iface_exists {{ name }}
{% endfor %}

Loading

0 comments on commit 1d16a37

Please sign in to comment.