Commit d3a9b96c by Juliusz Chroboczek

Implement interface configuration keyword "type".

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