Hi, comments inline. > RFC3527 link selection sub-option is used to select the "uplink" interface of > dhcrelay in cases where the DHCP server does not know how to reach the > dhcrelay > based on the DHCP range. This can happen in weird network configurations like > Mesh networks. > > Signed-off-by: Bruno Randolf <b...@einfach.org> > --- > net/isc-dhcp/files/dhcrelay4.init | 8 ++ > net/isc-dhcp/files/etc/config/dhcrelay | 3 + > .../patches/100-relay-rfc3527-link-selection.patch | 100 > +++++++++++++++++++++ > 3 files changed, 111 insertions(+) > create mode 100644 > net/isc-dhcp/patches/100-relay-rfc3527-link-selection.patch > > diff --git a/net/isc-dhcp/files/dhcrelay4.init > b/net/isc-dhcp/files/dhcrelay4.init > index 0f87b37..d03722f 100644 > --- a/net/isc-dhcp/files/dhcrelay4.init > +++ b/net/isc-dhcp/files/dhcrelay4.init > @@ -29,6 +29,14 @@ start() { > done > fi > > + # link selection sub-option (RFC3527) > + local link_selection > + config_get link_selection ipv4 link_selection > + if [ -n "$link_selection" ]; then > + config_get ifname "$link_selection" ifname
This relies on state vars which will get deprecated soon. Should be converted to use "network_get_device" from /lib/functions/network.sh. Example: if network_get_device ifname "$link_selection"; then append args "-l $ifname" fi > + append args "-l $ifname" > + fi > + > # relay mode > local relay_mode > config_get relay_mode ipv4 relay_mode > diff --git a/net/isc-dhcp/files/etc/config/dhcrelay > b/net/isc-dhcp/files/etc/config/dhcrelay > index 1b89782..b3b53b5 100644 > --- a/net/isc-dhcp/files/etc/config/dhcrelay > +++ b/net/isc-dhcp/files/etc/config/dhcrelay > @@ -15,6 +15,9 @@ config dhcrelay ipv4 > # 'discard': Don't forward > option 'relay_mode' '' > > + # enable RFC3527 link selection sub-option and use the IP address of > + # the specified network interface as "uplink" IP address (e.g. wan) > + option 'link_selection' '' > > config dhcrelay ipv6 > # option dhcpserver '2001:db8:1::1' > diff --git a/net/isc-dhcp/patches/100-relay-rfc3527-link-selection.patch > b/net/isc-dhcp/patches/100-relay-rfc3527-link-selection.patch > new file mode 100644 > index 0000000..1f593ee > --- /dev/null > +++ b/net/isc-dhcp/patches/100-relay-rfc3527-link-selection.patch Can you elaborate on the origin of this patch? Was it written by you? > @@ -0,0 +1,100 @@ > +--- a/relay/dhcrelay.c > ++++ b/relay/dhcrelay.c > +@@ -65,6 +65,7 @@ int server_packets_relayed = 0; /* Packe > + int client_packet_errors = 0; /* Errors sending packets to clients. */ > + > + int add_agent_options = 0; /* If nonzero, add relay agent options. */ > ++int add_rfc3527_suboption = 0; /* If nonzero, add RFC3527 link > selection sub-option. */ > + > + int agent_option_errors = 0; /* Number of packets forwarded without > + agent options because there was no room. */ > +@@ -104,6 +105,8 @@ struct server_list { > + struct sockaddr_in to; > + } *servers; > + > ++struct interface_info *uplink; > ++ > + #ifdef DHCPv6 > + struct stream_list { > + struct stream_list *next; > +@@ -144,6 +147,7 @@ static const char url[] = > + " [-pf <pid-file>] [--no-pid]\n"\ > + " [-m append|replace|forward|discard]\n" \ > + " [-i interface0 [ ... -i interfaceN]\n" \ > ++" [-l interface]\n" \ > + " server0 [ ... serverN]\n\n" \ > + " dhcrelay -6 [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \ > + " [-pf <pid-file>] [--no-pid]\n"\ > +@@ -157,6 +161,7 @@ static const char url[] = > + " [-pf <pid-file>] [--no-pid]\n"\ > + " [-m append|replace|forward|discard]\n" \ > + " [-i interface0 [ ... -i interfaceN]\n" \ > ++" [-l interface]\n" \ > + " server0 [ ... serverN]\n\n" > + #endif > + > +@@ -314,6 +319,20 @@ main(int argc, char **argv) { > + agent_relay_mode = discard; > + } else > + usage(); > ++ } else if (!strcmp (argv [i], "-l")) { > ++ add_agent_options = 1; > ++ add_rfc3527_suboption = 1; > ++ if (++i == argc) > ++ usage(); > ++ > ++ status = interface_allocate(&uplink, MDL); > ++ if (status != ISC_R_SUCCESS) > ++ log_fatal("%s: interface_allocate: %s", > ++ argv[i], > ++ isc_result_totext(status)); > ++ strcpy(uplink->name, argv[i]); > ++ interface_snorf(uplink, INTERFACE_REQUESTED); > ++ //interface_dereference(&uplink, MDL); > + } else if (!strcmp(argv[i], "-D")) { > + #ifdef DHCPv6 > + if (local_family_set && (local_family == AF_INET6)) { > +@@ -685,12 +704,17 @@ do_relay4(struct interface_info *ip, str > + ip->addresses[0]))) > + return; > + > ++ /* RFC3527: Replace giaddr address by uplink address. The original > ++ * giaddr will be used in the link selection sub-option */ > ++ if (add_rfc3527_suboption) > ++ packet->giaddr = uplink->addresses[0]; > ++ > + /* If giaddr is not already set, Set it so the server can > + figure out what net it's from and so that we can later > + forward the response to the correct net. If it's already > + set, the response will be sent directly to the relay agent > + that set giaddr, so we won't see it. */ > +- if (!packet->giaddr.s_addr) > ++ else if (!packet->giaddr.s_addr) > + packet->giaddr = ip->addresses[0]; > + if (packet->hops < max_hop_count) > + packet->hops = packet->hops + 1; > +@@ -1062,6 +1086,9 @@ add_relay_agent_options(struct interface > + optlen += ip->remote_id_len + 2; /* RAI_REMOTE_ID + len */ > + } > + > ++ if (add_rfc3527_suboption) > ++ optlen += 6; > ++ > + /* We do not support relay option fragmenting(multiple options to > + * support an option data exceeding 255 bytes). > + */ > +@@ -1093,6 +1120,14 @@ add_relay_agent_options(struct interface > + memcpy(sp, ip->remote_id, ip->remote_id_len); > + sp += ip->remote_id_len; > + } > ++ > ++ if (add_rfc3527_suboption) { > ++ *sp++ = RAI_LINK_SELECT; > ++ *sp++ = 4u; > ++ memcpy(sp, &giaddr.s_addr, 4); > ++ sp += 4; > ++ log_debug ("RFC3527 link selection sub-option added: > %s", inet_ntoa(giaddr)); > ++ } > + } else { > + ++agent_option_errors; > + log_error("No room in packet (used %d of %d) " > ~ Jow
signature.asc
Description: OpenPGP digital signature
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel