Added new parametr 'rx buffer <num>'. BIRD is able to receive
very large packets (if configured).
This commit is contained in:
parent
e6ea2e375e
commit
94c42054ea
7 changed files with 94 additions and 47 deletions
|
@ -120,6 +120,7 @@ protocol static {
|
||||||
# password "pass";
|
# password "pass";
|
||||||
# };
|
# };
|
||||||
# interface "arc0" {
|
# interface "arc0" {
|
||||||
|
# rx buffer large;
|
||||||
# type nonbroadcast;
|
# type nonbroadcast;
|
||||||
# poll 14;
|
# poll 14;
|
||||||
# dead 75;
|
# dead 75;
|
||||||
|
|
|
@ -1026,6 +1026,7 @@ protocol ospf <name> {
|
||||||
wait <num>;
|
wait <num>;
|
||||||
dead count <num>;
|
dead count <num>;
|
||||||
dead <num>;
|
dead <num>;
|
||||||
|
rx buffer [normal|large|<num>];
|
||||||
type [broadcast|nonbroadcast|pointopoint];
|
type [broadcast|nonbroadcast|pointopoint];
|
||||||
strict nonbroadcast <switch>;
|
strict nonbroadcast <switch>;
|
||||||
authentication [none|simple];
|
authentication [none|simple];
|
||||||
|
@ -1134,6 +1135,11 @@ protocol ospf <name> {
|
||||||
<m/dead/ seconds, it will consider the neighbor down. If both directives
|
<m/dead/ seconds, it will consider the neighbor down. If both directives
|
||||||
<m/dead count/ and <m/dead/ are used, <m/dead/ has precendence.
|
<m/dead count/ and <m/dead/ are used, <m/dead/ has precendence.
|
||||||
|
|
||||||
|
<tag>rx buffer <M>num</M></tag>
|
||||||
|
This sets the size of buffer used for receiving packets. The buffer should
|
||||||
|
be bigger than maximal size of any packets. Value NORMAL (default)
|
||||||
|
means 2*MTU, value LARGE means maximal allowed packet - 65536.
|
||||||
|
|
||||||
<tag>type broadcast</tag>
|
<tag>type broadcast</tag>
|
||||||
BIRD detects a type of a connected network automatically, but sometimes it's
|
BIRD detects a type of a connected network automatically, but sometimes it's
|
||||||
convenient to force use of a different type manually.
|
convenient to force use of a different type manually.
|
||||||
|
|
|
@ -26,6 +26,7 @@ CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
|
||||||
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
|
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
|
||||||
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
|
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
|
||||||
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK)
|
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK)
|
||||||
|
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL)
|
||||||
|
|
||||||
%type <t> opttext
|
%type <t> opttext
|
||||||
|
|
||||||
|
@ -142,6 +143,9 @@ ospf_iface_item:
|
||||||
| AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE ; }
|
| AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE ; }
|
||||||
| AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE ; }
|
| AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE ; }
|
||||||
| AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT ; }
|
| AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT ; }
|
||||||
|
| RX BUFFER LARGE { OSPF_PATT->rxbuf = OSPF_RXBUF_LARGE ; }
|
||||||
|
| RX BUFFER NORMAL { OSPF_PATT->rxbuf = OSPF_RXBUF_NORMAL ; }
|
||||||
|
| RX BUFFER expr { OSPF_PATT->rxbuf = $3 ; if ($3 < OSPF_RXBUF_MINSIZE) cf_error("Buffer size is too small") ; }
|
||||||
| password_list {OSPF_PATT->passwords = (list *) $1; }
|
| password_list {OSPF_PATT->passwords = (list *) $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,23 @@ wait_timer_hook(timer * timer)
|
||||||
ospf_iface_sm(ifa, ISM_WAITF);
|
ospf_iface_sm(ifa, ISM_WAITF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32
|
||||||
|
rxbufsize(struct ospf_iface *ifa)
|
||||||
|
{
|
||||||
|
switch(ifa->rxbuf)
|
||||||
|
{
|
||||||
|
case OSPF_RXBUF_NORMAL:
|
||||||
|
return (ifa->iface->mtu * 2);
|
||||||
|
break;
|
||||||
|
case OSPF_RXBUF_LARGE:
|
||||||
|
return OSPF_MAX_PKT_SIZE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ifa->rxbuf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static sock *
|
static sock *
|
||||||
ospf_open_ip_socket(struct ospf_iface *ifa)
|
ospf_open_ip_socket(struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
|
@ -59,7 +76,7 @@ ospf_open_ip_socket(struct ospf_iface *ifa)
|
||||||
ipsk->tx_hook = ospf_tx_hook;
|
ipsk->tx_hook = ospf_tx_hook;
|
||||||
ipsk->err_hook = ospf_err_hook;
|
ipsk->err_hook = ospf_err_hook;
|
||||||
ipsk->iface = ifa->iface;
|
ipsk->iface = ifa->iface;
|
||||||
ipsk->rbsize = OSPF_MAX_PKT_SIZE;
|
ipsk->rbsize = rxbufsize(ifa);
|
||||||
ipsk->tbsize = ifa->iface->mtu;
|
ipsk->tbsize = ifa->iface->mtu;
|
||||||
ipsk->data = (void *) ifa;
|
ipsk->data = (void *) ifa;
|
||||||
if (sk_open(ipsk) != 0)
|
if (sk_open(ipsk) != 0)
|
||||||
|
@ -126,7 +143,7 @@ ospf_iface_chstate(struct ospf_iface *ifa, u8 state)
|
||||||
ifa->dr_sk->tx_hook = ospf_tx_hook;
|
ifa->dr_sk->tx_hook = ospf_tx_hook;
|
||||||
ifa->dr_sk->err_hook = ospf_err_hook;
|
ifa->dr_sk->err_hook = ospf_err_hook;
|
||||||
ifa->dr_sk->iface = ifa->iface;
|
ifa->dr_sk->iface = ifa->iface;
|
||||||
ifa->dr_sk->rbsize = OSPF_MAX_PKT_SIZE;
|
ifa->dr_sk->rbsize = rxbufsize(ifa);
|
||||||
ifa->dr_sk->tbsize = ifa->iface->mtu;
|
ifa->dr_sk->tbsize = ifa->iface->mtu;
|
||||||
ifa->dr_sk->data = (void *) ifa;
|
ifa->dr_sk->data = (void *) ifa;
|
||||||
if (sk_open(ifa->dr_sk) != 0)
|
if (sk_open(ifa->dr_sk) != 0)
|
||||||
|
@ -299,7 +316,7 @@ ospf_open_mc_socket(struct ospf_iface *ifa)
|
||||||
mcsk->tx_hook = ospf_tx_hook;
|
mcsk->tx_hook = ospf_tx_hook;
|
||||||
mcsk->err_hook = ospf_err_hook;
|
mcsk->err_hook = ospf_err_hook;
|
||||||
mcsk->iface = ifa->iface;
|
mcsk->iface = ifa->iface;
|
||||||
mcsk->rbsize = OSPF_MAX_PKT_SIZE;
|
mcsk->rbsize = rxbufsize(ifa);
|
||||||
mcsk->tbsize = ifa->iface->mtu;
|
mcsk->tbsize = ifa->iface->mtu;
|
||||||
mcsk->data = (void *) ifa;
|
mcsk->data = (void *) ifa;
|
||||||
if (sk_open(mcsk) != 0)
|
if (sk_open(mcsk) != 0)
|
||||||
|
@ -397,6 +414,7 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface,
|
||||||
ifa->stub = ip->stub;
|
ifa->stub = ip->stub;
|
||||||
ifa->autype = ip->autype;
|
ifa->autype = ip->autype;
|
||||||
ifa->passwords = ip->passwords;
|
ifa->passwords = ip->passwords;
|
||||||
|
ifa->rxbuf = ip->rxbuf;
|
||||||
|
|
||||||
if (ip->type == OSPF_IT_UNDEF)
|
if (ip->type == OSPF_IT_UNDEF)
|
||||||
ifa->type = ospf_iface_clasify(ifa->iface);
|
ifa->type = ospf_iface_clasify(ifa->iface);
|
||||||
|
@ -476,6 +494,44 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface,
|
||||||
olock_acquire(lock);
|
olock_acquire(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ospf_iface_change_mtu(struct proto_ospf *po, struct ospf_iface *ifa)
|
||||||
|
{
|
||||||
|
struct proto *p = &po->proto;
|
||||||
|
struct ospf_packet *op;
|
||||||
|
struct ospf_neighbor *n;
|
||||||
|
OSPF_TRACE(D_EVENTS, "Changing MTU on interface %s.", ifa->iface->name);
|
||||||
|
if (ifa->hello_sk)
|
||||||
|
{
|
||||||
|
ifa->hello_sk->rbsize = rxbufsize(ifa);
|
||||||
|
ifa->hello_sk->tbsize = ifa->iface->mtu;
|
||||||
|
sk_reallocate(ifa->hello_sk);
|
||||||
|
}
|
||||||
|
if (ifa->dr_sk)
|
||||||
|
{
|
||||||
|
ifa->dr_sk->rbsize = rxbufsize(ifa);
|
||||||
|
ifa->dr_sk->tbsize = ifa->iface->mtu;
|
||||||
|
sk_reallocate(ifa->dr_sk);
|
||||||
|
}
|
||||||
|
if (ifa->ip_sk)
|
||||||
|
{
|
||||||
|
ifa->ip_sk->rbsize = rxbufsize(ifa);
|
||||||
|
ifa->ip_sk->tbsize = ifa->iface->mtu;
|
||||||
|
sk_reallocate(ifa->ip_sk);
|
||||||
|
}
|
||||||
|
|
||||||
|
WALK_LIST(n, ifa->neigh_list)
|
||||||
|
{
|
||||||
|
op = (struct ospf_packet *) n->ldbdes;
|
||||||
|
n->ldbdes = mb_allocz(n->pool, ifa->iface->mtu);
|
||||||
|
|
||||||
|
if (ntohs(op->length) <= ifa->iface->mtu) /* If the packet in old buffer is bigger, let it filled by zeros */
|
||||||
|
memcpy(n->ldbdes, op, ifa->iface->mtu); /* If the packet is old is same or smaller, copy it */
|
||||||
|
|
||||||
|
rfree(op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface)
|
ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface)
|
||||||
{
|
{
|
||||||
|
@ -517,40 +573,7 @@ ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface)
|
||||||
if (flags & IF_CHANGE_MTU)
|
if (flags & IF_CHANGE_MTU)
|
||||||
{
|
{
|
||||||
if ((ifa = ospf_iface_find((struct proto_ospf *) p, iface)) != NULL)
|
if ((ifa = ospf_iface_find((struct proto_ospf *) p, iface)) != NULL)
|
||||||
{
|
ospf_iface_change_mtu(po, ifa);
|
||||||
struct ospf_packet *op;
|
|
||||||
struct ospf_neighbor *n;
|
|
||||||
OSPF_TRACE(D_EVENTS, "Changing MTU on interface %s.", iface->name);
|
|
||||||
if (ifa->hello_sk)
|
|
||||||
{
|
|
||||||
ifa->hello_sk->rbsize = OSPF_MAX_PKT_SIZE;
|
|
||||||
ifa->hello_sk->tbsize = ifa->iface->mtu;
|
|
||||||
sk_reallocate(ifa->hello_sk);
|
|
||||||
}
|
|
||||||
if (ifa->dr_sk)
|
|
||||||
{
|
|
||||||
ifa->dr_sk->rbsize = OSPF_MAX_PKT_SIZE;
|
|
||||||
ifa->dr_sk->tbsize = ifa->iface->mtu;
|
|
||||||
sk_reallocate(ifa->dr_sk);
|
|
||||||
}
|
|
||||||
if (ifa->ip_sk)
|
|
||||||
{
|
|
||||||
ifa->ip_sk->rbsize = OSPF_MAX_PKT_SIZE;
|
|
||||||
ifa->ip_sk->tbsize = ifa->iface->mtu;
|
|
||||||
sk_reallocate(ifa->ip_sk);
|
|
||||||
}
|
|
||||||
|
|
||||||
WALK_LIST(n, ifa->neigh_list)
|
|
||||||
{
|
|
||||||
op = (struct ospf_packet *) n->ldbdes;
|
|
||||||
n->ldbdes = mb_allocz(n->pool, iface->mtu);
|
|
||||||
|
|
||||||
if (ntohs(op->length) <= iface->mtu) /* If the packet in old buffer is bigger, let it filled by zeros */
|
|
||||||
memcpy(n->ldbdes, op, iface->mtu); /* If the packet is old is same or smaller, copy it */
|
|
||||||
|
|
||||||
rfree(op);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* BIRD -- OSPF
|
* BIRD -- OSPF
|
||||||
*
|
*
|
||||||
* (c) 1999 - 2004 Ondrej Filip <feela@network.cz>
|
* (c) 1999--2005 Ondrej Filip <feela@network.cz>
|
||||||
*
|
*
|
||||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
*
|
*
|
||||||
|
@ -17,5 +17,9 @@ void ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface);
|
||||||
void ospf_iface_info(struct ospf_iface *ifa);
|
void ospf_iface_info(struct ospf_iface *ifa);
|
||||||
void ospf_iface_shutdown(struct ospf_iface *ifa);
|
void ospf_iface_shutdown(struct ospf_iface *ifa);
|
||||||
void ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ospf_area_config *ac, struct ospf_iface_patt *ip);
|
void ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ospf_area_config *ac, struct ospf_iface_patt *ip);
|
||||||
|
void ospf_iface_change_mtu(struct proto_ospf *po, struct ospf_iface *ifa);
|
||||||
|
void ospf_set_rxbuf_size(struct ospf_iface *ifa, u32 rxbuf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _BIRD_OSPF_IFACE_H_ */
|
#endif /* _BIRD_OSPF_IFACE_H_ */
|
||||||
|
|
|
@ -637,7 +637,7 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
|
||||||
{
|
{
|
||||||
/* Now reconfigure interface */
|
/* Now reconfigure interface */
|
||||||
if (!(newip = (struct ospf_iface_patt *)
|
if (!(newip = (struct ospf_iface_patt *)
|
||||||
iface_patt_match(&oldac->patt_list, ifa->iface)))
|
iface_patt_match(&newac->patt_list, ifa->iface)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* HELLO TIMER */
|
/* HELLO TIMER */
|
||||||
|
@ -672,6 +672,16 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
|
||||||
schedule_rt_lsa(ifa->oa);
|
schedule_rt_lsa(ifa->oa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RX BUFF */
|
||||||
|
if (oldip->rxbuf != newip->rxbuf)
|
||||||
|
{
|
||||||
|
ifa->rxbuf = newip->rxbuf;
|
||||||
|
OSPF_TRACE(D_EVENTS,
|
||||||
|
"Changing rxbuf interface %s from %d to %d",
|
||||||
|
ifa->iface->name, oldip->rxbuf, newip->rxbuf);
|
||||||
|
ospf_iface_change_mtu(po, ifa);
|
||||||
|
}
|
||||||
|
|
||||||
/* strict nbma */
|
/* strict nbma */
|
||||||
if ((oldip->strictnbma == 0) && (newip->strictnbma != 0))
|
if ((oldip->strictnbma == 0) && (newip->strictnbma != 0))
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,19 +11,13 @@
|
||||||
|
|
||||||
#define MAXNETS 10
|
#define MAXNETS 10
|
||||||
#define OSPF_VLINK_MTU 576 /* RFC2328 - A.1 */
|
#define OSPF_VLINK_MTU 576 /* RFC2328 - A.1 */
|
||||||
#undef OSPF_BIG_PACKETS /*
|
#define OSPF_MAX_PKT_SIZE 65536
|
||||||
|
/*
|
||||||
* RFC 2328 says, maximum packet size is 65535
|
* RFC 2328 says, maximum packet size is 65535
|
||||||
* This could be too much for small systems, so I
|
* This could be too much for small systems, so I
|
||||||
* normally allocate 2*mtu - (I found one cisco
|
* normally allocate 2*mtu - (I found one cisco
|
||||||
* sending packets mtu+16)
|
* sending packets mtu+16)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef OSPF_BIG_PACKETS
|
|
||||||
#define OSPF_MAX_PKT_SIZE 65536
|
|
||||||
#else
|
|
||||||
#define OSPF_MAX_PKT_SIZE (ifa->iface->mtu * 2)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LOCAL_DEBUG
|
#ifdef LOCAL_DEBUG
|
||||||
#define OSPF_FORCE_DEBUG 1
|
#define OSPF_FORCE_DEBUG 1
|
||||||
#else
|
#else
|
||||||
|
@ -206,6 +200,7 @@ struct ospf_iface
|
||||||
list nbma_list;
|
list nbma_list;
|
||||||
u8 priority; /* A router priority for DR election */
|
u8 priority; /* A router priority for DR election */
|
||||||
u8 ioprob;
|
u8 ioprob;
|
||||||
|
u32 rxbuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_md5
|
struct ospf_md5
|
||||||
|
@ -572,6 +567,10 @@ struct ospf_iface_patt
|
||||||
#define OSPF_AUTH_SIMPLE 1
|
#define OSPF_AUTH_SIMPLE 1
|
||||||
#define OSPF_AUTH_CRYPT 2
|
#define OSPF_AUTH_CRYPT 2
|
||||||
#define OSPF_AUTH_CRYPT_SIZE 16
|
#define OSPF_AUTH_CRYPT_SIZE 16
|
||||||
|
u32 rxbuf;
|
||||||
|
#define OSPF_RXBUF_NORMAL 0
|
||||||
|
#define OSPF_RXBUF_LARGE 1
|
||||||
|
#define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */
|
||||||
list *passwords;
|
list *passwords;
|
||||||
list nbma_list;
|
list nbma_list;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue