First Commit
[librecmc/package-feed.git] / net / isc-dhcp / patches / 100-relay-rfc3527-link-selection.patch
1 --- a/relay/dhcrelay.c
2 +++ b/relay/dhcrelay.c
3 @@ -60,6 +60,7 @@
4  int client_packet_errors = 0;  /* Errors sending packets to clients. */
5  
6  int add_agent_options = 0;     /* If nonzero, add relay agent options. */
7 +int add_rfc3527_suboption = 0; /* If nonzero, add RFC3527 link selection sub-option. */
8  
9  int agent_option_errors = 0;    /* Number of packets forwarded without
10                                    agent options because there was no room. */
11 @@ -99,6 +100,8 @@
12         struct sockaddr_in to;
13  } *servers;
14  
15 +struct interface_info *uplink;
16 +
17  #ifdef DHCPv6
18  struct stream_list {
19         struct stream_list *next;
20 @@ -147,6 +150,7 @@
21  "                     [-pf <pid-file>] [--no-pid]\n"\
22  "                     [-m append|replace|forward|discard]\n" \
23  "                     [-i interface0 [ ... -i interfaceN]\n" \
24 +"                     [-l interface]\n" \
25  "                     server0 [ ... serverN]\n\n" \
26  "       dhcrelay -6   [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
27  "                     [-pf <pid-file>] [--no-pid]\n" \
28 @@ -161,6 +165,7 @@
29  "                [-pf <pid-file>] [--no-pid]\n" \
30  "                [-m append|replace|forward|discard]\n" \
31  "                [-i interface0 [ ... -i interfaceN]\n" \
32 +"                [-l interface]\n" \
33  "                server0 [ ... serverN]\n\n"
34  #endif
35  
36 @@ -325,6 +330,20 @@
37                                 agent_relay_mode = discard;
38                         } else
39                                 usage();
40 +               } else if (!strcmp (argv [i], "-l")) {
41 +                       add_agent_options = 1;
42 +                       add_rfc3527_suboption = 1;
43 +                       if (++i == argc)
44 +                               usage();
45 +
46 +                       status = interface_allocate(&uplink, MDL);
47 +                       if (status != ISC_R_SUCCESS)
48 +                               log_fatal("%s: interface_allocate: %s",
49 +                                         argv[i],
50 +                                         isc_result_totext(status));
51 +                       strcpy(uplink->name, argv[i]);
52 +                       interface_snorf(uplink, INTERFACE_REQUESTED);
53 +                       //interface_dereference(&uplink, MDL);
54                 } else if (!strcmp(argv[i], "-D")) {
55  #ifdef DHCPv6
56                         if (local_family_set && (local_family == AF_INET6)) {
57 @@ -711,12 +730,17 @@
58                                                ip->addresses[0])))
59                 return;
60  
61 +       /* RFC3527: Replace giaddr address by uplink address. The original
62 +        * giaddr will be used in the link selection sub-option */
63 +       if (add_rfc3527_suboption)
64 +               packet->giaddr = uplink->addresses[0];
65 +
66         /* If giaddr is not already set, Set it so the server can
67            figure out what net it's from and so that we can later
68            forward the response to the correct net.    If it's already
69            set, the response will be sent directly to the relay agent
70            that set giaddr, so we won't see it. */
71 -       if (!packet->giaddr.s_addr)
72 +       else if (!packet->giaddr.s_addr)
73                 packet->giaddr = ip->addresses[0];
74         if (packet->hops < max_hop_count)
75                 packet->hops = packet->hops + 1;
76 @@ -1090,6 +1114,9 @@
77                 optlen += ip->remote_id_len + 2;    /* RAI_REMOTE_ID + len */
78         }
79  
80 +       if (add_rfc3527_suboption)
81 +               optlen += 6;
82 +
83         /* We do not support relay option fragmenting(multiple options to
84          * support an option data exceeding 255 bytes).
85          */
86 @@ -1121,6 +1148,14 @@
87                         memcpy(sp, ip->remote_id, ip->remote_id_len);
88                         sp += ip->remote_id_len;
89                 }
90 +
91 +               if (add_rfc3527_suboption) {
92 +                       *sp++ = RAI_LINK_SELECT;
93 +                       *sp++ = 4u;
94 +                       memcpy(sp, &giaddr.s_addr, 4);
95 +                       sp += 4;
96 +                       log_debug ("RFC3527 link selection sub-option added: %s", inet_ntoa(giaddr));
97 +               }
98         } else {
99                 ++agent_option_errors;
100                 log_error("No room in packet (used %d of %d) "