proposition of addition to SLIP driver

Stanislav V. Voronyi (stas@use.kharkov.ua)
Fri, 22 Aug 1997 20:24:50 +0300


Hi All!

My addition to SLIP driver is one function which make allow to
setup linefill/keepalive (added by myself in 1.3 kernel) using
ifconfig utility. I test this patch on 3 pentium machine -
it works without any problem. After patch for slip.c I add
patch for ifconfig (from net-tools 1.42.1) to use with this
kernel patch.
-------------------------- CUT HERE -----------------------
--- linux-2.1.51/drivers/net/slip.c.orig Thu May 22 21:21:10 1997
+++ linux-2.1.51/drivers/net/slip.c Fri Aug 22 19:14:30 1997
@@ -106,6 +106,7 @@
#ifdef CONFIG_SLIP_SMART
static void sl_keepalive(unsigned long sls);
static void sl_outfill(unsigned long sls);
+static int sl_ioctl(struct device *dev,struct ifreq *rq,int cmd);
#endif

/* Find a free SLIP channel, and link in this `tty' line. */
@@ -1015,8 +1016,6 @@
#ifdef CONFIG_SLIP_SMART
/* VSV changes start here */
case SIOCSKEEPALIVE:
- if (sl->keepalive)
- (void)del_timer (&sl->keepalive_timer);
err = verify_area(VERIFY_READ, arg, sizeof(int));
if (err) {
return -err;
@@ -1024,6 +1023,8 @@
get_user(tmp,(int *)arg);
if (tmp > 255) /* max for unchar */
return -EINVAL;
+ if (sl->keepalive)
+ (void)del_timer (&sl->keepalive_timer);
if ((sl->keepalive = (unchar) tmp) != 0) {
sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
add_timer(&sl->keepalive_timer);
@@ -1040,8 +1041,6 @@
return 0;

case SIOCSOUTFILL:
- if (sl->outfill)
- (void)del_timer (&sl->outfill_timer);
err = verify_area(VERIFY_READ, arg, sizeof(int));
if (err) {
return -err;
@@ -1049,6 +1048,8 @@
get_user(tmp,(int *)arg);
if (tmp > 255) /* max for unchar */
return -EINVAL;
+ if (sl->outfill)
+ (void)del_timer (&sl->outfill_timer);
if ((sl->outfill = (unchar) tmp) != 0){
sl->outfill_timer.expires=jiffies+sl->outfill*HZ;
add_timer(&sl->outfill_timer);
@@ -1076,6 +1077,56 @@
}
}

+/* VSV changes start here */
+#ifdef CONFIG_SLIP_SMART
+/* function do_ioctl called from net/core/dev.c
+ to allow get/set outfill/keepalive parameter
+ by ifconfig */
+
+static int sl_ioctl(struct device *dev,struct ifreq *rq,int cmd)
+{
+ struct slip *sl = (struct slip*)(dev->priv);
+
+ if (sl == NULL) /* Allocation failed ?? */
+ return -ENODEV;
+
+ switch(cmd){
+ case SIOCSKEEPALIVE:
+ if (((unsigned)rq->ifr_data) > 255) /* max for unchar */
+ return -EINVAL;
+ if (sl->keepalive)
+ (void)del_timer (&sl->keepalive_timer);
+ if ((sl->keepalive = (unchar)((unsigned) rq->ifr_data)) != 0) {
+ sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
+ add_timer(&sl->keepalive_timer);
+ set_bit(SLF_KEEPTEST, &sl->flags);
+ }
+ break;
+
+ case SIOCGKEEPALIVE:
+ rq->ifr_data=(caddr_t)((int)sl->keepalive);
+ break;
+
+ case SIOCSOUTFILL:
+ if (((unsigned)rq->ifr_data) > 255) /* max for unchar */
+ return -EINVAL;
+ if (sl->outfill)
+ (void)del_timer (&sl->outfill_timer);
+ if ((sl->outfill = (unchar)((unsigned) rq->ifr_data)) != 0){
+ sl->outfill_timer.expires=jiffies+sl->outfill*HZ;
+ add_timer(&sl->outfill_timer);
+ set_bit(SLF_OUTWAIT, &sl->flags);
+ }
+ break;
+
+ case SIOCGOUTFILL:
+ rq->ifr_data=(caddr_t)((int)sl->outfill);
+ }
+ return 0;
+}
+#endif
+/* VSV changes end */
+
static int sl_open_dev(struct device *dev)
{
struct slip *sl = (struct slip*)(dev->priv);
@@ -1173,6 +1224,9 @@
dev->open = sl_open_dev;
dev->stop = sl_close;
dev->get_stats = sl_get_stats;
+#ifdef CONFIG_SLIP_SMART
+ dev->do_ioctl = sl_ioctl;
+#endif
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->type = ARPHRD_SLIP + SL_MODE_DEFAULT;
-------------------------- CUT HERE -----------------------
--- ifconfig.c.orig Fri Aug 22 11:11:41 1997
+++ ifconfig.c Fri Aug 22 15:24:50 1997
@@ -32,6 +32,9 @@
#include <string.h>
#include <unistd.h>
#include <netdb.h>
+#ifdef HAVE_HWSLIP
+#include <linux/if_slip.h>
+#endif

/* Ugh. But libc5 doesn't provide POSIX types. */
#include <asm/types.h>
@@ -105,6 +108,8 @@
short flags; /* various flags */
int metric; /* routing metric */
int mtu; /* MTU value */
+ int keepalive; /* keepalive value for SLIP */
+ int outfill; /* outfill value for SLIP */
struct ifmap map; /* hardware setup */
struct sockaddr addr; /* IP address */
struct sockaddr dstaddr; /* P-P IP address */
@@ -314,10 +319,16 @@
if (ptr->flags & IFF_SLAVE) printf("SLAVE ");
if (ptr->flags & IFF_MASTER) printf("MASTER ");
if (ptr->flags & IFF_MULTICAST) printf("MULTICAST ");
+#ifdef SIOCSOUTFILL
+ if( ptr->outfill || ptr->keepalive )
+ printf(NLS_CATGETS(catfd, ifconfigSet, ifconfig_mtu,
+ " MTU:%d Metric:%d Outfill:%d Keepalive:%d\n"),
+ ptr->mtu, ptr->metric?ptr->metric:1, ptr->outfill, ptr->keepalive);
+ else
+#endif
printf(NLS_CATGETS(catfd, ifconfigSet, ifconfig_mtu, " MTU:%d Metric:%d\n"),
ptr->mtu, ptr->metric?ptr->metric:1);

-
/* If needed, display the interface statistics. */
printf(" ");

@@ -467,7 +478,20 @@
ife->mtu = 0;
else
ife->mtu = ifr.ifr_mtu;
-
+#ifdef SIOCGOUTFILL
+ strcpy(ifr.ifr_name, ifname);
+ if (ioctl(skfd, SIOCGOUTFILL, &ifr) < 0)
+ ife->outfill=0;
+ else
+ ife->outfill=(unsigned int)ifr.ifr_data;
+#endif
+#ifdef SIOCGKEEPALIVE
+ strcpy(ifr.ifr_name, ifname);
+ if (ioctl(skfd, SIOCGKEEPALIVE, &ifr) < 0)
+ ife->keepalive=0;
+ else
+ ife->keepalive=(unsigned int)ifr.ifr_data;
+#endif
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
memset(&ife->map, 0, sizeof(struct ifmap));
@@ -552,7 +576,7 @@
struct interface ife;
struct ifconf ifc;
struct ifreq *ifr;
- int i;
+ int i=1;

if (ifname == (char *)NULL) {
if (ioctl(skfd, SIOCGIFCOUNT, &i) < 0) {
@@ -596,6 +620,7 @@
if (((ife.flags & IFF_UP) == 0) && !opt_a) continue;
ife_print(&ife);
}
+ free(ifc.ifc_buf);
} else {
if (if_fetch(ifname, &ife) < 0)
fprintf(stderr, NLS_CATGETS(catfd, ifconfigSet,
@@ -604,7 +629,6 @@
ife_print(&ife);
}

- free(ifc.ifc_buf);
}


@@ -664,6 +688,9 @@
" [hw] [ax25 address]\n"));
#endif
fprintf(stderr, " [metric NN] [mtu NN]\n");
+#ifdef SIOCSKEEPALIVE
+ fprintf(stderr, " [outfill NN] [keepalive NN]\n");
+#endif
fprintf(stderr, " [[-]trailers] [[-]arp]\n");
fprintf(stderr, " [[-]allmulti] [[-]promisc]\n");
fprintf(stderr, " [multicast]\n");
@@ -899,6 +926,32 @@
spp++;
continue;
}
+
+#ifdef SIOCSKEEPALIVE
+ if (!strcmp(*spp, "keepalive")) {
+ if (*++spp == NULL) usage();
+ ifr.ifr_data = (caddr_t)atoi(*spp);
+ if (ioctl(skfd, SIOCSKEEPALIVE, &ifr) < 0) {
+ fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno));
+ goterr = 1;
+ }
+ spp++;
+ continue;
+ }
+#endif
+
+#ifdef SIOCSOUTFILL
+ if (!strcmp(*spp, "outfill")) {
+ if (*++spp == NULL) usage();
+ ifr.ifr_data = (caddr_t)atoi(*spp);
+ if (ioctl(skfd, SIOCSOUTFILL, &ifr) < 0) {
+ fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno));
+ goterr = 1;
+ }
+ spp++;
+ continue;
+ }
+#endif

if (!strcmp(*spp, "-broadcast")) {
goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST);
-------------------------- CUT HERE -----------------------