iPXE
netdev_settings.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <string.h>
27 #include <errno.h>
28 #include <byteswap.h>
29 #include <ipxe/dhcp.h>
30 #include <ipxe/dhcpopts.h>
31 #include <ipxe/settings.h>
32 #include <ipxe/device.h>
33 #include <ipxe/netdevice.h>
34 #include <ipxe/init.h>
35 
36 /** @file
37  *
38  * Network device configuration settings
39  *
40  */
41 
42 /** Network device predefined settings */
43 const struct setting mac_setting __setting ( SETTING_NETDEV, mac ) = {
44  .name = "mac",
45  .description = "MAC address",
46  .type = &setting_type_hex,
47 };
48 const struct setting hwaddr_setting __setting ( SETTING_NETDEV, hwaddr ) = {
49  .name = "hwaddr",
50  .description = "Hardware address",
51  .type = &setting_type_hex,
52 };
53 const struct setting bustype_setting __setting ( SETTING_NETDEV, bustype ) = {
54  .name = "bustype",
55  .description = "Bus type",
56  .type = &setting_type_string,
57 };
58 const struct setting busloc_setting __setting ( SETTING_NETDEV, busloc ) = {
59  .name = "busloc",
60  .description = "Bus location",
61  .type = &setting_type_uint32,
62 };
63 const struct setting busid_setting __setting ( SETTING_NETDEV, busid ) = {
64  .name = "busid",
65  .description = "Bus ID",
66  .type = &setting_type_hex,
67 };
68 const struct setting linktype_setting __setting ( SETTING_NETDEV, linktype ) = {
69  .name = "linktype",
70  .description = "Link-layer type",
71  .type = &setting_type_string,
72 };
73 const struct setting chip_setting __setting ( SETTING_NETDEV, chip ) = {
74  .name = "chip",
75  .description = "Chip",
76  .type = &setting_type_string,
77 };
78 const struct setting ifname_setting __setting ( SETTING_NETDEV, ifname ) = {
79  .name = "ifname",
80  .description = "Interface name",
81  .type = &setting_type_string,
82 };
83 const struct setting mtu_setting __setting ( SETTING_NETDEV, mtu ) = {
84  .name = "mtu",
85  .description = "MTU",
86  .type = &setting_type_int16,
87  .tag = DHCP_MTU,
88 };
89 
90 /**
91  * Store link-layer address setting
92  *
93  * @v netdev Network device
94  * @v data Setting data, or NULL to clear setting
95  * @v len Length of setting data
96  * @ret rc Return status code
97  */
98 static int netdev_store_mac ( struct net_device *netdev,
99  const void *data, size_t len ) {
101 
102  /* Record new MAC address */
103  if ( data ) {
104  if ( len != netdev->ll_protocol->ll_addr_len )
105  return -EINVAL;
106  memcpy ( netdev->ll_addr, data, len );
107  } else {
108  /* Reset MAC address if clearing setting */
110  }
111 
112  return 0;
113 }
114 
115 /**
116  * Fetch link-layer address setting
117  *
118  * @v netdev Network device
119  * @v data Buffer to fill with setting data
120  * @v len Length of buffer
121  * @ret len Length of setting data, or negative error
122  */
123 static int netdev_fetch_mac ( struct net_device *netdev, void *data,
124  size_t len ) {
126 
127  if ( len > max_len )
128  len = max_len;
129  memcpy ( data, netdev->ll_addr, len );
130  return max_len;
131 }
132 
133 /**
134  * Fetch hardware address setting
135  *
136  * @v netdev Network device
137  * @v data Buffer to fill with setting data
138  * @v len Length of buffer
139  * @ret len Length of setting data, or negative error
140  */
141 static int netdev_fetch_hwaddr ( struct net_device *netdev, void *data,
142  size_t len ) {
144 
145  if ( len > max_len )
146  len = max_len;
147  memcpy ( data, netdev->hw_addr, len );
148  return max_len;
149 }
150 
151 /**
152  * Fetch bus type setting
153  *
154  * @v netdev Network device
155  * @v data Buffer to fill with setting data
156  * @v len Length of buffer
157  * @ret len Length of setting data, or negative error
158  */
159 static int netdev_fetch_bustype ( struct net_device *netdev, void *data,
160  size_t len ) {
161  static const char *bustypes[] = {
162  [BUS_TYPE_PCI] = "PCI",
163  [BUS_TYPE_ISAPNP] = "ISAPNP",
164  [BUS_TYPE_EISA] = "EISA",
165  [BUS_TYPE_MCA] = "MCA",
166  [BUS_TYPE_ISA] = "ISA",
167  [BUS_TYPE_TAP] = "TAP",
168  [BUS_TYPE_EFI] = "EFI",
169  [BUS_TYPE_XEN] = "XEN",
170  [BUS_TYPE_HV] = "HV",
171  [BUS_TYPE_USB] = "USB",
172  };
173  struct device_description *desc = &netdev->dev->desc;
174  const char *bustype;
175 
176  assert ( desc->bus_type < ( sizeof ( bustypes ) /
177  sizeof ( bustypes[0] ) ) );
178  bustype = bustypes[desc->bus_type];
179  if ( ! bustype )
180  return -ENOENT;
181  strncpy ( data, bustype, len );
182  return strlen ( bustype );
183 }
184 
185 /**
186  * Fetch bus location setting
187  *
188  * @v netdev Network device
189  * @v data Buffer to fill with setting data
190  * @v len Length of buffer
191  * @ret len Length of setting data, or negative error
192  */
193 static int netdev_fetch_busloc ( struct net_device *netdev, void *data,
194  size_t len ) {
195  struct device_description *desc = &netdev->dev->desc;
196  uint32_t busloc;
197 
198  busloc = cpu_to_be32 ( desc->location );
199  if ( len > sizeof ( busloc ) )
200  len = sizeof ( busloc );
201  memcpy ( data, &busloc, len );
202  return sizeof ( busloc );
203 }
204 
205 /**
206  * Fetch bus ID setting
207  *
208  * @v netdev Network device
209  * @v data Buffer to fill with setting data
210  * @v len Length of buffer
211  * @ret len Length of setting data, or negative error
212  */
213 static int netdev_fetch_busid ( struct net_device *netdev, void *data,
214  size_t len ) {
215  struct device_description *desc = &netdev->dev->desc;
216  struct dhcp_netdev_desc dhcp_desc;
217 
218  dhcp_desc.type = desc->bus_type;
219  dhcp_desc.vendor = htons ( desc->vendor );
220  dhcp_desc.device = htons ( desc->device );
221  if ( len > sizeof ( dhcp_desc ) )
222  len = sizeof ( dhcp_desc );
223  memcpy ( data, &dhcp_desc, len );
224  return sizeof ( dhcp_desc );
225 }
226 
227 /**
228  * Fetch link layer type setting
229  *
230  * @v netdev Network device
231  * @v data Buffer to fill with setting data
232  * @v len Length of buffer
233  * @ret len Length of setting data, or negative error
234  */
235 static int netdev_fetch_linktype ( struct net_device *netdev, void *data,
236  size_t len ) {
237  const char *linktype = netdev->ll_protocol->name;
238 
239  strncpy ( data, linktype, len );
240  return strlen ( linktype );
241 }
242 
243 /**
244  * Fetch chip setting
245  *
246  * @v netdev Network device
247  * @v data Buffer to fill with setting data
248  * @v len Length of buffer
249  * @ret len Length of setting data, or negative error
250  */
251 static int netdev_fetch_chip ( struct net_device *netdev, void *data,
252  size_t len ) {
253  const char *chip = netdev->dev->driver_name;
254 
255  strncpy ( data, chip, len );
256  return strlen ( chip );
257 }
258 
259 /**
260  * Fetch ifname setting
261  *
262  * @v netdev Network device
263  * @v data Buffer to fill with setting data
264  * @v len Length of buffer
265  * @ret len Length of setting data, or negative error
266  */
267 static int netdev_fetch_ifname ( struct net_device *netdev, void *data,
268  size_t len ) {
269  const char *ifname = netdev->name;
270 
271  strncpy ( data, ifname, len );
272  return strlen ( ifname );
273 }
274 
275 /** A network device setting operation */
277  /** Setting */
278  const struct setting *setting;
279  /** Store setting (or NULL if not supported)
280  *
281  * @v netdev Network device
282  * @v data Setting data, or NULL to clear setting
283  * @v len Length of setting data
284  * @ret rc Return status code
285  */
286  int ( * store ) ( struct net_device *netdev, const void *data,
287  size_t len );
288  /** Fetch setting
289  *
290  * @v netdev Network device
291  * @v data Buffer to fill with setting data
292  * @v len Length of buffer
293  * @ret len Length of setting data, or negative error
294  */
295  int ( * fetch ) ( struct net_device *netdev, void *data, size_t len );
296 };
297 
298 /** Network device settings */
300  { &mac_setting, netdev_store_mac, netdev_fetch_mac },
301  { &hwaddr_setting, NULL, netdev_fetch_hwaddr },
302  { &bustype_setting, NULL, netdev_fetch_bustype },
303  { &busloc_setting, NULL, netdev_fetch_busloc },
304  { &busid_setting, NULL, netdev_fetch_busid },
305  { &linktype_setting, NULL, netdev_fetch_linktype },
306  { &chip_setting, NULL, netdev_fetch_chip },
307  { &ifname_setting, NULL, netdev_fetch_ifname },
308 };
309 
310 /**
311  * Store value of network device setting
312  *
313  * @v settings Settings block
314  * @v setting Setting to store
315  * @v data Setting data, or NULL to clear setting
316  * @v len Length of setting data
317  * @ret rc Return status code
318  */
319 static int netdev_store ( struct settings *settings,
320  const struct setting *setting,
321  const void *data, size_t len ) {
322  struct net_device *netdev = container_of ( settings, struct net_device,
323  settings.settings );
325  unsigned int i;
326 
327  /* Handle network device-specific settings */
328  for ( i = 0 ; i < ( sizeof ( netdev_setting_operations ) /
329  sizeof ( netdev_setting_operations[0] ) ) ; i++ ) {
331  if ( setting_cmp ( setting, op->setting ) == 0 ) {
332  if ( op->store ) {
333  return op->store ( netdev, data, len );
334  } else {
335  return -ENOTSUP;
336  }
337  }
338  }
339 
341 }
342 
343 /**
344  * Fetch value of network device setting
345  *
346  * @v settings Settings block
347  * @v setting Setting to fetch
348  * @v data Buffer to fill with setting data
349  * @v len Length of buffer
350  * @ret len Length of setting data, or negative error
351  */
352 static int netdev_fetch ( struct settings *settings, struct setting *setting,
353  void *data, size_t len ) {
354  struct net_device *netdev = container_of ( settings, struct net_device,
355  settings.settings );
357  unsigned int i;
358 
359  /* Handle network device-specific settings */
360  for ( i = 0 ; i < ( sizeof ( netdev_setting_operations ) /
361  sizeof ( netdev_setting_operations[0] ) ) ; i++ ) {
363  if ( setting_cmp ( setting, op->setting ) == 0 )
364  return op->fetch ( netdev, data, len );
365  }
366 
368 }
369 
370 /**
371  * Clear network device settings
372  *
373  * @v settings Settings block
374  */
375 static void netdev_clear ( struct settings *settings ) {
377 }
378 
379 /** Network device configuration settings operations */
381  .store = netdev_store,
382  .fetch = netdev_fetch,
383  .clear = netdev_clear,
384 };
385 
386 /**
387  * Redirect "netX" settings block
388  *
389  * @v settings Settings block
390  * @ret settings Underlying settings block
391  */
392 static struct settings * netdev_redirect ( struct settings *settings ) {
393  struct net_device *netdev;
394 
395  /* Redirect to "netX" network device */
397  if ( netdev ) {
398  return netdev_settings ( netdev );
399  } else {
400  return settings;
401  }
402 }
403 
404 /** "netX" settings operations */
407 };
408 
409 /** "netX" settings */
411  .refcnt = NULL,
415 };
416 
417 /** Initialise "netX" settings */
418 static void netdev_redirect_settings_init ( void ) {
419  int rc;
420 
422  "netX" ) ) != 0 ) {
423  DBG ( "Could not register netX settings: %s\n",
424  strerror ( rc ) );
425  return;
426  }
427 }
428 
429 /** "netX" settings initialiser */
430 struct init_fn netdev_redirect_settings_init_fn __init_fn ( INIT_LATE ) = {
432 };
433 
434 /**
435  * Apply network device settings
436  *
437  * @ret rc Return status code
438  */
439 static int apply_netdev_settings ( void ) {
440  struct net_device *netdev;
441  struct settings *settings;
442  struct ll_protocol *ll_protocol;
443  size_t max_mtu;
444  size_t old_mtu;
445  size_t mtu;
446  int rc;
447 
448  /* Process settings for each network device */
449  for_each_netdev ( netdev ) {
450 
451  /* Get network device settings */
453 
454  /* Get MTU */
455  mtu = fetch_uintz_setting ( settings, &mtu_setting );
456 
457  /* Do nothing unless MTU is specified */
458  if ( ! mtu )
459  continue;
460 
461  /* Limit MTU to maximum supported by hardware */
463  max_mtu = ( netdev->max_pkt_len - ll_protocol->ll_header_len );
464  if ( mtu > max_mtu ) {
465  DBGC ( netdev, "NETDEV %s cannot support MTU %zd (max "
466  "%zd)\n", netdev->name, mtu, max_mtu );
467  mtu = max_mtu;
468  }
469 
470  /* Update maximum packet length */
471  old_mtu = netdev->mtu;
472  netdev->mtu = mtu;
473  if ( mtu != old_mtu ) {
474  DBGC ( netdev, "NETDEV %s MTU is %zd\n",
475  netdev->name, mtu );
476  }
477 
478  /* Close and reopen network device if MTU has increased */
479  if ( netdev_is_open ( netdev ) && ( mtu > old_mtu ) ) {
480  netdev_close ( netdev );
481  if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
482  DBGC ( netdev, "NETDEV %s could not reopen: "
483  "%s\n", netdev->name, strerror ( rc ) );
484  return rc;
485  }
486  }
487  }
488 
489  return 0;
490 }
491 
492 /** Network device settings applicator */
493 struct settings_applicator netdev_applicator __settings_applicator = {
495 };
static int netdev_fetch_mac(struct net_device *netdev, void *data, size_t len)
Fetch link-layer address setting.
#define EINVAL
Invalid argument.
Definition: errno.h:428
static struct settings netdev_redirect_settings
"netX" settings
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Dynamic Host Configuration Protocol.
int(* fetch)(struct net_device *netdev, void *data, size_t len)
Fetch setting.
uint8_t ll_header_len
Link-layer header length.
Definition: netdevice.h:200
uint8_t type
Bus type ID.
Definition: dhcp.h:448
static struct netdev_setting_operation netdev_setting_operations[]
Network device settings.
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
static struct settings * netdev_redirect(struct settings *settings)
Redirect "netX" settings block.
void(* initialise)(void)
Definition: init.h:15
static struct settings_operations netdev_redirect_settings_operations
"netX" settings operations
const struct setting * setting
Setting.
Error codes.
uint16_t max_len
Maximum length (in bytes)
Definition: ntlm.h:18
const struct setting mac_setting __setting(SETTING_NETDEV, mac)
Network device predefined settings.
size_t mtu
Maximum transmission unit length.
Definition: netdevice.h:415
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
A settings applicator.
Definition: settings.h:251
void generic_settings_clear(struct settings *settings)
Clear generic settings block.
Definition: settings.c:207
static int apply_netdev_settings(void)
Apply network device settings.
int generic_settings_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of generic setting.
Definition: settings.c:178
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
void(* init_addr)(const void *hw_addr, void *ll_addr)
Initialise link-layer address.
Definition: netdevice.h:150
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
A link-layer protocol.
Definition: netdevice.h:114
static void netdev_clear(struct settings *settings)
Clear network device settings.
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A hardware device description.
Definition: device.h:19
#define BUS_TYPE_MCA
MCA bus type.
Definition: device.h:52
const char * name
Name.
Definition: settings.h:28
const char * name
Protocol name.
Definition: netdevice.h:116
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
Definition: string.c:347
static int netdev_fetch_chip(struct net_device *netdev, void *data, size_t len)
Fetch chip setting.
#define BUS_TYPE_ISA
ISA bus type.
Definition: device.h:55
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define SETTING_NETDEV
Network device settings.
Definition: settings.h:63
static int netdev_fetch_busid(struct net_device *netdev, void *data, size_t len)
Fetch bus ID setting.
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:658
An initialisation function.
Definition: init.h:14
#define BUS_TYPE_PCI
PCI bus type.
Definition: device.h:43
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
uint8_t hw_addr_len
Hardware address length.
Definition: netdevice.h:196
static struct net_device * netdev
Definition: gdbudp.c:52
const char * driver_name
Driver name.
Definition: device.h:77
static int netdev_store(struct settings *settings, const struct setting *setting, const void *data, size_t len)
Store value of network device setting.
#define DHCP_MTU
Maximum transmission unit.
Definition: dhcp.h:87
struct settings_applicator netdev_applicator __settings_applicator
Network device settings applicator.
Configuration settings.
struct settings *(* redirect)(struct settings *settings)
Redirect to underlying settings block (if applicable)
Definition: settings.h:91
#define BUS_TYPE_EISA
EISA bus type.
Definition: device.h:49
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A network device setting operation.
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:543
uint16_t device
Device ID.
Definition: dhcp.h:452
A network device.
Definition: netdevice.h:352
Network device descriptor.
Definition: dhcp.h:446
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
Settings block operations.
Definition: settings.h:85
A settings block.
Definition: settings.h:132
static int netdev_fetch_linktype(struct net_device *netdev, void *data, size_t len)
Fetch link layer type setting.
unsigned long fetch_uintz_setting(struct settings *settings, const struct setting *setting)
Fetch value of unsigned integer setting, or zero.
Definition: settings.c:1068
const char * name
Name.
Definition: settings.h:136
static int netdev_fetch_hwaddr(struct net_device *netdev, void *data, size_t len)
Fetch hardware address setting.
#define BUS_TYPE_EFI
EFI bus type.
Definition: device.h:61
unsigned int uint32_t
Definition: stdint.h:12
DHCP options.
struct list_head siblings
Sibling settings blocks.
Definition: settings.h:140
A setting.
Definition: settings.h:23
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
void netdev_close(struct net_device *netdev)
Close network device.
Definition: netdevice.c:895
Network device management.
#define BUS_TYPE_TAP
TAP bus type.
Definition: device.h:58
#define cpu_to_be32(value)
Definition: byteswap.h:110
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
uint32_t len
Length.
Definition: ena.h:14
static int netdev_fetch_bustype(struct net_device *netdev, void *data, size_t len)
Fetch bus type setting.
struct settings_operations netdev_settings_operations
Network device configuration settings operations.
int generic_settings_store(struct settings *settings, const struct setting *setting, const void *data, size_t len)
Store value of generic setting.
Definition: settings.c:126
uint32_t mtu
Maximum MTU.
Definition: ena.h:28
struct net_device * find_netdev(const char *name)
Get network device by name.
Definition: netdevice.c:988
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static int netdev_fetch_ifname(struct net_device *netdev, void *data, size_t len)
Fetch ifname setting.
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct device_description desc
Device description.
Definition: device.h:79
static void netdev_redirect_settings_init(void)
Initialise "netX" settings.
int(* apply)(void)
Apply updated settings.
Definition: settings.h:256
Device model.
struct init_fn netdev_redirect_settings_init_fn __init_fn(INIT_LATE)
"netX" settings initialiser
struct list_head children
Child settings blocks.
Definition: settings.h:142
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:475
static int netdev_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of network device setting.
uint16_t vendor
Vendor ID.
Definition: dhcp.h:450
#define BUS_TYPE_XEN
Xen bus type.
Definition: device.h:64
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
size_t max_pkt_len
Maximum packet length.
Definition: netdevice.h:409
#define INIT_LATE
Late initialisation.
Definition: init.h:31
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
#define BUS_TYPE_USB
USB bus type.
Definition: device.h:70
struct generic_settings settings
Configuration settings applicable to this device.
Definition: netdevice.h:428
linktype
Definition: 3c90x.h:240
static int netdev_store_mac(struct net_device *netdev, const void *data, size_t len)
Store link-layer address setting.
int(* store)(struct net_device *netdev, const void *data, size_t len)
Store setting (or NULL if not supported)
int(* store)(struct settings *settings, const struct setting *setting, const void *data, size_t len)
Store value of setting.
Definition: settings.h:108
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
Definition: settings.c:1120
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:381
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:861
#define htons(value)
Definition: byteswap.h:135
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
struct refcnt * refcnt
Reference counter.
Definition: settings.h:134
static int netdev_fetch_busloc(struct net_device *netdev, void *data, size_t len)
Fetch bus location setting.
#define BUS_TYPE_HV
Hyper-V bus type.
Definition: device.h:67
#define BUS_TYPE_ISAPNP
ISAPnP bus type.
Definition: device.h:46