Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify dhcp relay to pick primary address #17012

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions dockers/docker-dhcp-relay/dhcpv4-relay.agents.j2
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /t
{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
{% endfor %}
{% for (name, gateway) in VLAN_INTERFACE|get_primary_addr %}
shbalaku-microsoft marked this conversation as resolved.
Show resolved Hide resolved
{% if gateway | ipv4 %} -pg {{ gateway }}{% endif -%}
{% endfor %}
{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
{%- if dhcp_server | ipv4 %} {{ dhcp_server }}{% endif -%}
{% endfor %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
diff --git a/common/discover.c b/common/discover.c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kellyyeh , could you please review this?

index ab50234..40e13f5 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -1614,3 +1614,16 @@ void interface_snorf (struct interface_info *tmp, int ir)
}
interface_reference (&interfaces, tmp, MDL);
}
+
+void set_primary_addr_in_intf (struct in_addr primary_addr) {
+ for (struct interface_info *tmp = interfaces; tmp; tmp = tmp->next) {
+ for (int i = 0; i < tmp->address_count; i++) {
+ if (tmp->addresses[i].s_addr == primary_addr.s_addr) {
+ struct in_addr tmp_ip = tmp->addresses[0];
+ tmp->addresses[0] = primary_addr;
+ tmp->addresses[i] = tmp_ip;
+ break;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index 257b31e..e7f9f06 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -2873,6 +2873,7 @@ extern int interface_count;
extern int interface_max;
isc_result_t interface_initialize(omapi_object_t *, const char *, int);
void discover_interfaces(int);
+void set_primary_addr_in_intf (struct in_addr );
int setup_fallback (struct interface_info **, const char *, int);
int if_readsocket (omapi_object_t *);
void reinitialize_interfaces (void);
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index ff0ad17..31fe61b 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -92,6 +92,11 @@ struct downstream_intf_list {
struct interface_info *interface;
} *downstream_intfs = NULL;

+struct primary_gw_list {
+ struct primary_gw_list *next;
+ struct in_addr gateway_addr;
+} *primary_gws = NULL;
+
#ifdef DHCPv6
/* Force use of DHCPv6 interface-id option. */
isc_boolean_t use_if_id = ISC_FALSE;
@@ -199,6 +204,7 @@ char *progname;
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
+" [-pg ip-address0 [ ... -pg ip-addressN]]\n" \
" [-U interface]\n" \
" [-dt]\n"\
" server0 [ ... serverN]\n\n" \
@@ -221,6 +227,7 @@ char *progname;
" [-i interface0 [ ... -i interfaceN]\n" \
" [-iu interface0 [ ... -iu interfaceN]\n" \
" [-id interface0 [ ... -id interfaceN]\n" \
+" [-pg ip-address0 [ ... -pg ip-addressN]]\n" \
" [-U interface]\n" \
" [-dt]\n"\
" server0 [ ... serverN]\n\n" \
@@ -649,6 +656,34 @@ main(int argc, char **argv) {
usage(use_noarg, argv[i-1]);
path_dhcrelay_pid = argv[i];
no_dhcrelay_pid = ISC_TRUE;
+ } else if (!strcmp(argv[i], "-pg")) {
+ if (++i == argc)
+ usage(use_noarg, argv[i-1]);
+#ifdef DHCPv6
+ if (local_family_set && (local_family == AF_INET6)) {
+ usage(use_v4command, argv[i]);
+ }
+ local_family_set = 1;
+ local_family = AF_INET;
+#endif
+ struct in_addr gw = {0};
+ if (inet_pton(AF_INET, argv[i], &gw) <= 0) {
+ usage("Invalid gateway address '%s'", argv[i]);
+ } else {
+ struct primary_gw_list *pg = ((struct primary_gw_list *)dmalloc(sizeof(struct primary_gw_list), MDL));
+ pg->gateway_addr = gw;
+ pg->next = NULL;
+
+ if (primary_gws == NULL) {
+ primary_gws = pg;
+ } else {
+ struct primary_gw_list *tmp = primary_gws;
+ while (tmp->next != NULL) {
+ tmp = tmp->next;
+ }
+ tmp->next = pg;
+ }
+ }
} else if (!strcmp(argv[i], "--no-pid")) {
no_pid_file = ISC_TRUE;
} else if (!strcmp(argv[i], "--name-alias-map-file")) {
@@ -818,6 +853,12 @@ main(int argc, char **argv) {
/* Discover all the network interfaces. */
discover_interfaces(DISCOVER_RELAY);

+ struct primary_gw_list *tmp = primary_gws;
+ while (tmp != NULL) {
+ set_primary_addr_in_intf(tmp->gateway_addr);
+ tmp = tmp->next;
+ }
+
#ifdef DHCPv6
if (local_family == AF_INET6)
setup_streams();
1 change: 1 addition & 0 deletions src/isc-dhcp/patch/series
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
0012-add-option-si-to-support-using-src-intf-ip-in-relay.patch
0013-Fix-dhcrelay-agent-option-buffer-pointer-logic.patch
0014-enable-parallel-build.patch
0015-option-to-set-primary-address-in-interface.patch
23 changes: 23 additions & 0 deletions src/sonic-config-engine/sonic-cfggen
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import netaddr
import os
import sys
import yaml
import ipaddress

from collections import OrderedDict
from config_samples import generate_sample_config, get_available_config
Expand Down Expand Up @@ -137,6 +138,27 @@ def ip_network(value):
return "Invalid ip address %s" % value
return r_v.network

def get_primary_addr(value):
if not value:
return ""
table = pfx_filter(value)
returnTable = OrderedDict()
shbalaku-microsoft marked this conversation as resolved.
Show resolved Hide resolved
intf_with_secondary = set()
for key, val in table.items():
name, prefix = key
if "secondary" in val:
intf_with_secondary.add(name)
for key, val in table.items():
name, prefix = key
if name in intf_with_secondary and "secondary" not in val:
if PY3x:
network_def = ipaddress.ip_network(prefix, strict=False)
else:
network_def = ipaddress.ip_network(unicode(prefix), strict=False)
returnTable[(name, network_def[1])] = {}
intf_with_secondary.remove(name)
return returnTable

def load_namespace_config(asic_name):
if not SonicDBConfig.isInit():
if is_multi_asic():
Expand Down Expand Up @@ -247,6 +269,7 @@ def _get_jinja2_env(paths):
env.filters['unique_name'] = unique_name
env.filters['pfx_filter'] = pfx_filter
env.filters['ip_network'] = ip_network
env.filters['get_primary_addr'] = get_primary_addr
for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']:
env.filters[attr] = partial(prefix_attr, attr)

Expand Down
1 change: 1 addition & 0 deletions src/sonic-config-engine/tests/test_j2files.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def setUp(self):
self.ztp_ip = os.path.join(self.test_dir, "sample-ztp-ip.json")
self.ztp_inband_ip = os.path.join(self.test_dir, "sample-ztp-inband-ip.json")
self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml')
self.t0_minigraph_secondary_subnets = os.path.join(self.test_dir, 't0-sample-graph-secondary-subnets.xml')
shbalaku-microsoft marked this conversation as resolved.
Show resolved Hide resolved
self.t0_mvrf_minigraph = os.path.join(self.test_dir, 't0-sample-graph-mvrf.xml')
self.t0_minigraph_nomgmt = os.path.join(self.test_dir, 't0-sample-graph-nomgmt.xml')
self.t0_minigraph_two_mgmt = os.path.join(self.test_dir, 't0-sample-graph-two-mgmt.xml')
Expand Down