wait <num>;
dead count <num>;
dead <num>;
+ rx buffer [normal|large|<num>];
type [broadcast|nonbroadcast|pointopoint];
strict nonbroadcast <switch>;
authentication [none|simple];
<m/dead/ seconds, it will consider the neighbor down. If both directives
<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>
BIRD detects a type of a connected network automatically, but sometimes it's
convenient to force use of a different type manually.
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK)
+CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL)
%type <t> opttext
| AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE ; }
| AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE ; }
| 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; }
;
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 *
ospf_open_ip_socket(struct ospf_iface *ifa)
{
ipsk->tx_hook = ospf_tx_hook;
ipsk->err_hook = ospf_err_hook;
ipsk->iface = ifa->iface;
- ipsk->rbsize = OSPF_MAX_PKT_SIZE;
+ ipsk->rbsize = rxbufsize(ifa);
ipsk->tbsize = ifa->iface->mtu;
ipsk->data = (void *) ifa;
if (sk_open(ipsk) != 0)
ifa->dr_sk->tx_hook = ospf_tx_hook;
ifa->dr_sk->err_hook = ospf_err_hook;
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->data = (void *) ifa;
if (sk_open(ifa->dr_sk) != 0)
mcsk->tx_hook = ospf_tx_hook;
mcsk->err_hook = ospf_err_hook;
mcsk->iface = ifa->iface;
- mcsk->rbsize = OSPF_MAX_PKT_SIZE;
+ mcsk->rbsize = rxbufsize(ifa);
mcsk->tbsize = ifa->iface->mtu;
mcsk->data = (void *) ifa;
if (sk_open(mcsk) != 0)
ifa->stub = ip->stub;
ifa->autype = ip->autype;
ifa->passwords = ip->passwords;
+ ifa->rxbuf = ip->rxbuf;
if (ip->type == OSPF_IT_UNDEF)
ifa->type = ospf_iface_clasify(ifa->iface);
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
ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface)
{
if (flags & IF_CHANGE_MTU)
{
if ((ifa = ospf_iface_find((struct proto_ospf *) p, iface)) != NULL)
- {
- 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);
- }
- }
+ ospf_iface_change_mtu(po, ifa);
}
}
#define MAXNETS 10
#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
* This could be too much for small systems, so I
* normally allocate 2*mtu - (I found one cisco
* 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
#define OSPF_FORCE_DEBUG 1
#else
list nbma_list;
u8 priority; /* A router priority for DR election */
u8 ioprob;
+ u32 rxbuf;
};
struct ospf_md5
#define OSPF_AUTH_SIMPLE 1
#define OSPF_AUTH_CRYPT 2
#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 nbma_list;
};