1 #ifndef _IPXE_NDP_H
2 #define _IPXE_NDP_H
3
4 /** @file
5 *
6 * Neighbour discovery protocol
7 *
8 */
9
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
12 #include <stdint.h>
13 #include <ipxe/in.h>
14 #include <ipxe/ipv6.h>
15 #include <ipxe/icmpv6.h>
16 #include <ipxe/neighbour.h>
17
18 /** An NDP option header */
19 struct ndp_option_header {
20 /** Type */
21 uint8_t type;
22 /** Length (in blocks of 8 bytes) */
23 uint8_t blocks;
24 } __attribute__ (( packed ));
25
26 /** NDP option block size */
27 #define NDP_OPTION_BLKSZ 8U
28
29 /** NDP source link-layer address option */
30 #define NDP_OPT_LL_SOURCE 1
31
32 /** NDP target link-layer address option */
33 #define NDP_OPT_LL_TARGET 2
34
35 /** NDP source or target link-layer address option */
36 struct ndp_ll_addr_option {
37 /** NDP option header */
38 struct ndp_option_header header;
39 /** Link-layer address */
40 uint8_t ll_addr[0];
41 } __attribute__ (( packed ));
42
43 /** NDP prefix information option */
44 #define NDP_OPT_PREFIX 3
45
46 /** NDP prefix information */
47 struct ndp_prefix_information_option {
48 /** NDP option header */
49 struct ndp_option_header header;
50 /** Prefix length */
51 uint8_t prefix_len;
52 /** Flags */
53 uint8_t flags;
54 /** Valid lifetime */
55 uint32_t valid;
56 /** Preferred lifetime */
57 uint32_t preferred;
58 /** Reserved */
59 uint32_t reserved;
60 /** Prefix */
61 struct in6_addr prefix;
62 } __attribute__ (( packed ));
63
64 /** NDP on-link flag */
65 #define NDP_PREFIX_ON_LINK 0x80
66
67 /** NDP autonomous address configuration flag */
68 #define NDP_PREFIX_AUTONOMOUS 0x40
69
70 /** NDP recursive DNS server option */
71 #define NDP_OPT_RDNSS 25
72
73 /** NDP recursive DNS server */
74 struct ndp_rdnss_option {
75 /** NDP option header */
76 struct ndp_option_header header;
77 /** Reserved */
78 uint16_t reserved;
79 /** Lifetime */
80 uint32_t lifetime;
81 /** Addresses */
82 struct in6_addr addresses[0];
83 } __attribute__ (( packed ));
84
85 /** NDP DNS search list option */
86 #define NDP_OPT_DNSSL 31
87
88 /** NDP DNS search list */
89 struct ndp_dnssl_option {
90 /** NDP option header */
91 struct ndp_option_header header;
92 /** Reserved */
93 uint16_t reserved;
94 /** Lifetime */
95 uint32_t lifetime;
96 /** Domain names */
97 uint8_t names[0];
98 } __attribute__ (( packed ));
99
100 /** An NDP option */
101 union ndp_option {
102 /** Option header */
103 struct ndp_option_header header;
104 /** Source or target link-layer address option */
105 struct ndp_ll_addr_option ll_addr;
106 /** Prefix information option */
107 struct ndp_prefix_information_option prefix;
108 /** Recursive DNS server option */
109 struct ndp_rdnss_option rdnss;
110 /** DNS search list option */
111 struct ndp_dnssl_option dnssl;
112 } __attribute__ (( packed ));
113
114 /** An NDP neighbour solicitation or advertisement header */
115 struct ndp_neighbour_header {
116 /** ICMPv6 header */
117 struct icmp_header icmp;
118 /** Flags */
119 uint8_t flags;
120 /** Reserved */
121 uint8_t reserved[3];
122 /** Target address */
123 struct in6_addr target;
124 /** Options */
125 union ndp_option option[0];
126 } __attribute__ (( packed ));
127
128 /** NDP router flag */
129 #define NDP_NEIGHBOUR_ROUTER 0x80
130
131 /** NDP solicited flag */
132 #define NDP_NEIGHBOUR_SOLICITED 0x40
133
134 /** NDP override flag */
135 #define NDP_NEIGHBOUR_OVERRIDE 0x20
136
137 /** An NDP router advertisement header */
138 struct ndp_router_advertisement_header {
139 /** ICMPv6 header */
140 struct icmp_header icmp;
141 /** Current hop limit */
142 uint8_t hop_limit;
143 /** Flags */
144 uint8_t flags;
145 /** Router lifetime */
146 uint16_t lifetime;
147 /** Reachable time */
148 uint32_t reachable;
149 /** Retransmission timer */
150 uint32_t retransmit;
151 /** Options */
152 union ndp_option option[0];
153 } __attribute__ (( packed ));
154
155 /** NDP managed address configuration */
156 #define NDP_ROUTER_MANAGED 0x80
157
158 /** NDP other configuration */
159 #define NDP_ROUTER_OTHER 0x40
160
161 /** An NDP router solicitation header */
162 struct ndp_router_solicitation_header {
163 /** ICMPv6 header */
164 struct icmp_header icmp;
165 /** Reserved */
166 uint32_t reserved;
167 /** Options */
168 union ndp_option option[0];
169 } __attribute__ (( packed ));
170
171 /** An NDP header */
172 union ndp_header {
173 /** ICMPv6 header */
174 struct icmp_header icmp;
175 /** Neighbour solicitation or advertisement header */
176 struct ndp_neighbour_header neigh;
177 /** Router solicitation header */
178 struct ndp_router_solicitation_header rsol;
179 /** Router advertisement header */
180 struct ndp_router_advertisement_header radv;
181 } __attribute__ (( packed ));
182
183 extern struct neighbour_discovery ndp_discovery;
184
185 /**
186 * Transmit packet, determining link-layer address via NDP
187 *
188 * @v iobuf I/O buffer
189 * @v netdev Network device
190 * @v net_dest Destination network-layer address
191 * @v net_source Source network-layer address
192 * @v ll_source Source link-layer address
193 * @ret rc Return status code
194 */
ndp_tx(struct io_buffer * iobuf,struct net_device * netdev,const void * net_dest,const void * net_source,const void * ll_source)195 static inline int ndp_tx ( struct io_buffer *iobuf, struct net_device *netdev,
196 const void *net_dest, const void *net_source,
197 const void *ll_source ) {
198
199 return neighbour_tx ( iobuf, netdev, &ipv6_protocol, net_dest,
200 &ndp_discovery, net_source, ll_source );
201 }
202
203 /** NDP settings block name */
204 #define NDP_SETTINGS_NAME "ndp"
205
206 #endif /* _IPXE_NDP_H */
207