Commit d3a9b96c authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Implement interface configuration keyword "type".

parent 05dc01dd
...@@ -350,30 +350,32 @@ Each ...@@ -350,30 +350,32 @@ Each
.I parameter .I parameter
can be one of: can be one of:
.TP .TP
.BR wired " {" true | false | auto } .BR type " {" auto | wired | wireless | tunnel }
This specifies whether to enable optimisations specific to wired interfaces.
By default, this is determined automatically unless the The default is
.B auto
unless the
.B \-w .B \-w
command-line flag was specified. command-line flag was specified.
.TP .TP
.BR link\-quality " {" true | false | auto } .BR link\-quality " {" true | false | auto }
This specifies whether link quality estimation should be performed on this This specifies whether link quality estimation should be performed on this
interface. The default is to perform link quality estimation on wireless interface. The default is to perform link quality estimation on wireless
interfaces but not on wired interfaces. interfaces only.
.TP .TP
.BR split\-horizon " {" true | false | auto } .BR split\-horizon " {" true | false | auto }
This specifies whether to perform split-horizon processing on this This specifies whether to perform split-horizon processing on this
interface. The default is to never perform split-horizon processing on interface. The default is to perform split-horizon processing on
wireless interfaces; on wired interfaces, the default depends on the on wired interfaces, unless the
.B \-s .B \-s
flag. flag was set.
.TP .TP
.BI rxcost " cost" .BI rxcost " cost"
This defines the cost of receiving frames on the given interface under This defines the cost of receiving frames on the given interface under
ideal conditions (no packet loss); how this relates to the actual cost used ideal conditions (no packet loss); how this relates to the actual cost
for computing metrics of routes going through this interface depends on used for computing metrics of routes going through this interface depends
whether link quality estimation is being done. The default is 96 for wired on whether link quality estimation is being done. The default is 256 if
interfaces, and 256 for wireless ones. the interface is wireless, and 96 otherwise.
.TP .TP
.BI channel " channel" .BI channel " channel"
Sets the channel for this interface. The value Sets the channel for this interface. The value
...@@ -385,7 +387,7 @@ or ...@@ -385,7 +387,7 @@ or
The default is to autodetect the channel number for wireless interfaces, The default is to autodetect the channel number for wireless interfaces,
and and
.B noninterfering .B noninterfering
for wired interfaces. for other interfaces.
.TP .TP
.BR faraway " {" true | false } .BR faraway " {" true | false }
This specifies whether the network is "far away", in the sense that This specifies whether the network is "far away", in the sense that
...@@ -410,9 +412,7 @@ packet loss is expected. The default is four times the hello interval. ...@@ -410,9 +412,7 @@ packet loss is expected. The default is four times the hello interval.
Enable sending timestamps with each Hello and IHU message in order to Enable sending timestamps with each Hello and IHU message in order to
compute RTT values. The default is compute RTT values. The default is
.B true .B true
if for tunnel interfaces, and
.B max\-rtt\-penalty
is non-zero (see below), and
.B false .B false
otherwise. otherwise.
.TP .TP
......
...@@ -295,6 +295,32 @@ getnet(int c, unsigned char **p_r, unsigned char *plen_r, int *af_r, ...@@ -295,6 +295,32 @@ getnet(int c, unsigned char **p_r, unsigned char *plen_r, int *af_r,
return c; return c;
} }
static int
get_interface_type(int c, int *type_r, gnc_t gnc, void *closure)
{
char *t;
int i;
c = getword(c, &t, gnc, closure);
if(c < -1)
return c;
if(strcmp(t, "default") == 0 || strcmp(t, "auto") == 0) {
i = IF_TYPE_DEFAULT;
} else if(strcmp(t, "wired") == 0) {
i = IF_TYPE_WIRED;
} else if(strcmp(t, "wireless") == 0) {
i = IF_TYPE_WIRELESS;
} else if(strcmp(t, "tunnel") == 0) {
i = IF_TYPE_TUNNEL;
} else {
free(t);
return -2;
}
free(t);
*type_r = i;
return c;
}
static int static int
parse_filter(int c, gnc_t gnc, void *closure, struct filter **filter_return) parse_filter(int c, gnc_t gnc, void *closure, struct filter **filter_return)
{ {
...@@ -498,12 +524,21 @@ parse_anonymous_ifconf(int c, gnc_t gnc, void *closure, ...@@ -498,12 +524,21 @@ parse_anonymous_ifconf(int c, gnc_t gnc, void *closure,
if(c < -1 || interval <= 0 || interval > 10 * 0xFFFF) if(c < -1 || interval <= 0 || interval > 10 * 0xFFFF)
goto error; goto error;
if_conf->update_interval = interval; if_conf->update_interval = interval;
} else if(strcmp(token, "type") == 0) {
int type = IF_TYPE_DEFAULT;
c = get_interface_type(c, &type, gnc, closure);
if(c < -1)
goto error;
if_conf->type = type;
} else if(strcmp(token, "wired") == 0) { } else if(strcmp(token, "wired") == 0) {
int v; int v;
fprintf(stderr, "Warning: keyword \"wired\" is deprecated -- "
"please use \"type\" instead.\n");
c = getbool(c, &v, gnc, closure); c = getbool(c, &v, gnc, closure);
if(c < -1) if(c < -1)
goto error; goto error;
if_conf->wired = v; if_conf->type = (v == CONFIG_YES) ?
IF_TYPE_WIRED : IF_TYPE_WIRELESS;
} else if(strcmp(token, "faraway") == 0) { } else if(strcmp(token, "faraway") == 0) {
int v; int v;
c = getbool(c, &v, gnc, closure); c = getbool(c, &v, gnc, closure);
...@@ -569,11 +604,11 @@ parse_anonymous_ifconf(int c, gnc_t gnc, void *closure, ...@@ -569,11 +604,11 @@ parse_anonymous_ifconf(int c, gnc_t gnc, void *closure,
goto error; goto error;
if_conf->rtt_max = rtt; if_conf->rtt_max = rtt;
} else if(strcmp(token, "max-rtt-penalty") == 0) { } else if(strcmp(token, "max-rtt-penalty") == 0) {
int cost; int penalty;
c = getint(c, &cost, gnc, closure); c = getint(c, &penalty, gnc, closure);
if(c < -1 || cost <= 0 || cost > 0xFFFF) if(c < -1 || penalty <= 0 || penalty > 0xFFFF)
goto error; goto error;
if_conf->max_rtt_penalty = cost; if_conf->max_rtt_penalty = penalty;
} else { } else {
goto error; goto error;
} }
...@@ -649,7 +684,7 @@ merge_ifconf(struct interface_conf *dest, ...@@ -649,7 +684,7 @@ merge_ifconf(struct interface_conf *dest,
MERGE(hello_interval); MERGE(hello_interval);
MERGE(update_interval); MERGE(update_interval);
MERGE(cost); MERGE(cost);
MERGE(wired); MERGE(type);
MERGE(split_horizon); MERGE(split_horizon);
MERGE(lq); MERGE(lq);
MERGE(faraway); MERGE(faraway);
......
...@@ -198,24 +198,23 @@ static int ...@@ -198,24 +198,23 @@ static int
check_interface_channel(struct interface *ifp) check_interface_channel(struct interface *ifp)
{ {
int channel = IF_CONF(ifp, channel); int channel = IF_CONF(ifp, channel);
int rc = 1;
if(channel == IF_CHANNEL_UNKNOWN) { if(channel == IF_CHANNEL_UNKNOWN) {
if((ifp->flags & IF_WIRED)) { /* IF_WIRELESS merely means that we know for sure that the
channel = IF_CHANNEL_NONINTERFERING; interface is wireless, so check unconditionally. */
} else { channel = kernel_interface_channel(ifp->name, ifp->ifindex);
channel = kernel_interface_channel(ifp->name, ifp->ifindex); if(channel < 0) {
if(channel < 0) if((ifp->flags & IF_WIRELESS))
fprintf(stderr, rc = -1;
"Couldn't determine channel of interface %s: %s.\n", channel = (ifp->flags & IF_WIRELESS) ?
ifp->name, strerror(errno)); IF_CHANNEL_INTERFERING : IF_CHANNEL_NONINTERFERING;
if(channel <= 0)
channel = IF_CHANNEL_INTERFERING;
} }
} }
if(ifp->channel != channel) { if(ifp->channel != channel) {
ifp->channel = channel; ifp->channel = channel;
return 1; return rc;
} }
return 0; return 0;
} }
...@@ -278,7 +277,7 @@ check_link_local_addresses(struct interface *ifp) ...@@ -278,7 +277,7 @@ check_link_local_addresses(struct interface *ifp)
int int
interface_up(struct interface *ifp, int up) interface_up(struct interface *ifp, int up)
{ {
int mtu, rc, wired; int mtu, rc, type;
struct ipv6_mreq mreq; struct ipv6_mreq mreq;
if((!!up) == if_up(ifp)) if((!!up) == if_up(ifp))
...@@ -338,64 +337,63 @@ interface_up(struct interface *ifp, int up) ...@@ -338,64 +337,63 @@ interface_up(struct interface *ifp, int up)
"receive buffer for interface %s (%d) (%d bytes).\n", "receive buffer for interface %s (%d) (%d bytes).\n",
ifp->name, ifp->ifindex, mtu); ifp->name, ifp->ifindex, mtu);
if(IF_CONF(ifp, wired) == CONFIG_NO) { type = IF_CONF(ifp, type);
wired = 0; if(type == IF_TYPE_DEFAULT) {
} else if(IF_CONF(ifp, wired) == CONFIG_YES) { if(all_wireless) {
wired = 1; type = IF_TYPE_WIRELESS;
} else if(all_wireless) {
wired = 0;
} else {
rc = kernel_interface_wireless(ifp->name, ifp->ifindex);
if(rc < 0) {
fprintf(stderr,
"Warning: couldn't determine whether %s (%d) "
"is a wireless interface.\n",
ifp->name, ifp->ifindex);
wired = 0;
} else { } else {
wired = !rc; rc = kernel_interface_wireless(ifp->name, ifp->ifindex);
if(rc < 0) {
fprintf(stderr,
"Warning: couldn't determine whether %s (%d) "
"is a wireless interface.\n",
ifp->name, ifp->ifindex);
} else if(rc) {
type = IF_TYPE_WIRELESS;
}
} }
} }
printf("Type: %d\n", type);
if(wired) { /* Type is CONFIG_TYPE_AUTO if interface is not known to be
ifp->flags |= IF_WIRED; wireless, so provide sane defaults for that case. */
ifp->cost = IF_CONF(ifp, cost);
if(ifp->cost <= 0) ifp->cost = 96; if(type == IF_TYPE_WIRELESS)
if(IF_CONF(ifp, split_horizon) == CONFIG_NO) ifp->flags |= IF_WIRELESS;
ifp->flags &= ~IF_SPLIT_HORIZON; else
else if(IF_CONF(ifp, split_horizon) == CONFIG_YES) ifp->flags &= ~IF_WIRELESS;
ifp->flags |= IF_SPLIT_HORIZON;
else if(split_horizon) ifp->cost = IF_CONF(ifp, cost);
ifp->flags |= IF_SPLIT_HORIZON; if(ifp->cost <= 0)
else ifp->cost = type == IF_TYPE_WIRELESS ? 256 : 96;
ifp->flags &= ~IF_SPLIT_HORIZON;
if(IF_CONF(ifp, lq) == CONFIG_YES) if(IF_CONF(ifp, split_horizon) == CONFIG_YES)
ifp->flags |= IF_LQ; ifp->flags |= IF_SPLIT_HORIZON;
else else if(IF_CONF(ifp, split_horizon) == CONFIG_NO)
ifp->flags &= ~IF_LQ; ifp->flags &= ~IF_SPLIT_HORIZON;
} else { else if(type == IF_TYPE_WIRED)
ifp->flags &= ~IF_WIRED; ifp->flags |= IF_SPLIT_HORIZON;
ifp->cost = IF_CONF(ifp, cost); else
if(ifp->cost <= 0) ifp->cost = 256; ifp->flags &= ~IF_SPLIT_HORIZON;
if(IF_CONF(ifp, split_horizon) == CONFIG_YES)
ifp->flags |= IF_SPLIT_HORIZON; if(IF_CONF(ifp, lq) == CONFIG_YES)
else ifp->flags |= IF_LQ;
ifp->flags &= ~IF_SPLIT_HORIZON; else if(IF_CONF(ifp, lq) == CONFIG_NO)
if(IF_CONF(ifp, lq) == CONFIG_NO) ifp->flags &= ~IF_LQ;
ifp->flags &= ~IF_LQ; else if(type == IF_TYPE_WIRELESS)
else ifp->flags |= IF_LQ;
ifp->flags |= IF_LQ; else
} ifp->flags &= ~IF_LQ;
if(IF_CONF(ifp, faraway) == CONFIG_YES) if(IF_CONF(ifp, faraway) == CONFIG_YES)
ifp->flags |= IF_FARAWAY; ifp->flags |= IF_FARAWAY;
if(IF_CONF(ifp, hello_interval) > 0) if(IF_CONF(ifp, hello_interval) > 0)
ifp->hello_interval = IF_CONF(ifp, hello_interval); ifp->hello_interval = IF_CONF(ifp, hello_interval);
else if((ifp->flags & IF_WIRED)) else if(type == IF_TYPE_WIRELESS)
ifp->hello_interval = default_wired_hello_interval;
else
ifp->hello_interval = default_wireless_hello_interval; ifp->hello_interval = default_wireless_hello_interval;
else
ifp->hello_interval = default_wired_hello_interval;
ifp->update_interval = ifp->update_interval =
IF_CONF(ifp, update_interval) > 0 ? IF_CONF(ifp, update_interval) > 0 ?
...@@ -420,11 +418,22 @@ interface_up(struct interface *ifp, int up) ...@@ -420,11 +418,22 @@ interface_up(struct interface *ifp, int up)
ifp->rtt_max = ifp->rtt_min + 10000; ifp->rtt_max = ifp->rtt_min + 10000;
} }
ifp->max_rtt_penalty = IF_CONF(ifp, max_rtt_penalty); ifp->max_rtt_penalty = IF_CONF(ifp, max_rtt_penalty);
if(ifp->max_rtt_penalty == 0 && type == IF_TYPE_TUNNEL)
ifp->max_rtt_penalty = 96;
if(IF_CONF(ifp, enable_timestamps) == CONFIG_YES || if(IF_CONF(ifp, enable_timestamps) == CONFIG_YES)
(IF_CONF(ifp, enable_timestamps) == CONFIG_DEFAULT && ifp->flags |= IF_TIMESTAMPS;
ifp->max_rtt_penalty > 0)) else if(IF_CONF(ifp, enable_timestamps) == CONFIG_NO)
ifp->flags &= ~IF_TIMESTAMPS;
else if(type == IF_TYPE_TUNNEL)
ifp->flags |= IF_TIMESTAMPS; ifp->flags |= IF_TIMESTAMPS;
else
ifp->flags &= ~IF_TIMESTAMPS;
if(ifp->max_rtt_penalty > 0 && !(ifp->flags & IF_TIMESTAMPS))
fprintf(stderr,
"Warning: max_rtt_penalty is set "
"but timestamps are disabled on interface %s.\n",
ifp->name);
rc = check_link_local_addresses(ifp); rc = check_link_local_addresses(ifp);
if(rc < 0) { if(rc < 0) {
...@@ -440,13 +449,16 @@ interface_up(struct interface *ifp, int up) ...@@ -440,13 +449,16 @@ interface_up(struct interface *ifp, int up)
goto fail; goto fail;
} }
check_interface_channel(ifp); rc = check_interface_channel(ifp);
if(rc < 0)
fprintf(stderr,
"Warning: couldn't determine channel of interface %s.\n",
ifp->name);
update_interface_metric(ifp); update_interface_metric(ifp);
rc = check_interface_ipv4(ifp); rc = check_interface_ipv4(ifp);
debugf("Upped interface %s (%s, cost=%d, channel=%d%s).\n", debugf("Upped interface %s (cost=%d, channel=%d%s).\n",
ifp->name, ifp->name,
(ifp->flags & IF_WIRED) ? "wired" : "wireless",
ifp->cost, ifp->cost,
ifp->channel, ifp->channel,
ifp->ipv4 ? ", IPv4" : ""); ifp->ipv4 ? ", IPv4" : "");
......
...@@ -29,12 +29,19 @@ struct buffered_update { ...@@ -29,12 +29,19 @@ struct buffered_update {
unsigned char pad[2]; unsigned char pad[2];
}; };
#define IF_TYPE_DEFAULT 0
#define IF_TYPE_WIRED 1
#define IF_TYPE_WIRELESS 2
#define IF_TYPE_TUNNEL 3
/* If you modify this structure, also modify the merge_ifconf function. */
struct interface_conf { struct interface_conf {
char *ifname; char *ifname;
unsigned hello_interval; unsigned hello_interval;
unsigned update_interval; unsigned update_interval;
unsigned short cost; unsigned short cost;
char wired; char type;
char split_horizon; char split_horizon;
char lq; char lq;
char faraway; char faraway;
...@@ -51,11 +58,17 @@ struct interface_conf { ...@@ -51,11 +58,17 @@ struct interface_conf {
#define CONFIG_NO 1 #define CONFIG_NO 1
#define CONFIG_YES 2 #define CONFIG_YES 2
#define IF_UP (1 << 0) /* Interface is up. */
#define IF_WIRED (1<<1) # define IF_UP (1 << 0)
/* Interface known to be wireless, unknown otherwise. */
#define IF_WIRELESS (1<<1)
/* Apply split horizon. */
#define IF_SPLIT_HORIZON (1 << 2) #define IF_SPLIT_HORIZON (1 << 2)
/* Perform link-quality estimation. */
#define IF_LQ (1 << 3) #define IF_LQ (1 << 3)
/* Nodes on the far end don't interfere with nodes on the near end. */
#define IF_FARAWAY (1 << 4) #define IF_FARAWAY (1 << 4)
/* Send timestamps in Hello and IHU. */
#define IF_TIMESTAMPS (1 << 5) #define IF_TIMESTAMPS (1 << 5)
/* Only INTERFERING can appear on the wire. */ /* Only INTERFERING can appear on the wire. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment