Check-in [2d80cf430b]
Overview
Comment:Added brctl support
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2d80cf430beea1030b4a0dd85de2064cba1d11f2
User & Date: rkeene on 2012-08-22 03:31:33
Other Links: manifest | tags
Context
2012-08-22
03:36
Added stub for "vconfig" check-in: 1fce677508 user: rkeene tags: trunk
03:31
Added brctl support check-in: 2d80cf430b user: rkeene tags: trunk
2012-08-11
23:17
Corrected bug in "ifconfig" check-in: 704748fc41 user: rkeene tags: trunk
Changes

Modified build-dyn.sh from [02da656833] to [078554ca42].

     1      1   # /bin/bash
     2      2   
     3      3   # Perform common build options
     4      4   . build-common.sh
     5      5   
     6      6   # Compile using the same options as Tcl
     7         -TCLCONFIGSH="$(find /usr/lib /usr/local/lib /lib -name tclConfig.sh -print -quit)"
            7  +TCLCONFIGSH="$(find /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /lib /lib64 -name tclConfig.sh -print -quit)"
     8      8   
     9      9   . "${TCLCONFIGSH}"
    10     10   
    11         -echo "${TCL_CC} -Wall -DUSE_TCL_STUBS=1 ${TCL_DEFS} ${TCL_INCLUDE_SPEC} ${TCL_STUB_LIB_SPEC} -shared -rdynamic -o system.so system.c"
    12         -eval ${TCL_CC} -Wall -DUSE_TCL_STUBS=1 ${TCL_DEFS} ${TCL_INCLUDE_SPEC} ${TCL_STUB_LIB_SPEC} -shared -rdynamic -o system.so system.c
           11  +echo "${TCL_CC} -fPIC -DPIC -Wall -DUSE_TCL_STUBS=1 ${TCL_DEFS} ${TCL_INCLUDE_SPEC} ${TCL_STUB_LIB_SPEC} -shared -rdynamic -o system.so system.c"
           12  +eval ${TCL_CC} -fPIC -DPIC -Wall -DUSE_TCL_STUBS=1 ${TCL_DEFS} ${TCL_INCLUDE_SPEC} ${TCL_STUB_LIB_SPEC} -shared -rdynamic -o system.so system.c

Modified system.c from [382721d0da] to [1594c1fd70].

    16     16   #include <errno.h>
    17     17   #include <tcl.h>
    18     18   
    19     19   #include <linux/sockios.h>
    20     20   #include <linux/route.h>
    21     21   #include <linux/if.h>
    22     22   #include <linux/if_arp.h>
           23  +#include <linux/if_bridge.h>
    23     24   #include <linux/loop.h>
    24     25   #include <linux/fs.h>
    25     26   
    26     27   #ifndef HOST_NAME_MAX
    27     28   /* SUSv2 Limit */
    28     29   #define HOST_NAME_MAX 255
    29     30   #endif
................................................................................
   114    115   	hashval_obj = Tcl_NewObj();
   115    116   	Tcl_SetWideIntObj(hashval_obj, hashval);
   116    117   
   117    118   	Tcl_SetObjResult(interp, hashval_obj);
   118    119   
   119    120   	return(TCL_OK);
   120    121   }
          122  +
          123  +static int tclsystem_internal_getsock(int *sock_v4_out, int *sock_v6_out) {
          124  +	int sock_v4 = -1, sock_v6 = -1;
          125  +	int sock;
          126  +
          127  +	if (sock_v4_out == NULL && sock_v6_out == NULL) {
          128  +		return(-1);
          129  +	}
          130  +
          131  +	if (sock_v4_out != NULL) {
          132  +		/*
          133  +		 * Check for IPv4 support before trying to create an IPv4 socket to
          134  +		 * avoid demand-loading IPv4 (XXX: TODO)
          135  +		 */
          136  +		sock_v4 = socket(AF_INET, SOCK_DGRAM, 0);
          137  +	}
          138  +
          139  +	if (sock_v6_out != NULL) {
          140  +		/*
          141  +		 * Check for IPv6 support before trying to create an IPv6 socket to
          142  +		 * avoid demand-loading IPv6 (XXX: TODO)
          143  +		 */
          144  +		sock_v6 = socket(AF_INET6, SOCK_DGRAM, 0);
          145  +	}
          146  +
          147  +	/* Pick a socket to query for the interface list */
          148  +	if (sock_v4 == -1 && sock_v6 == -1) {
          149  +		return(-1);
          150  +	}
          151  +
          152  +	if (sock_v6 != -1) {
          153  +		sock = sock_v6;
          154  +	} else {
          155  +		sock = sock_v4;
          156  +	}
          157  +
          158  +	if (sock_v4_out != NULL) {
          159  +		*sock_v4_out = sock_v4;
          160  +	}
          161  +
          162  +	if (sock_v6_out != NULL) {
          163  +		*sock_v6_out = sock_v6;
          164  +	}
          165  +
          166  +	return(sock);
          167  +}
   121    168   
   122    169   /*
   123    170    * Low-level System Call Wrapper Procedures
   124    171    *
   125    172    * These procedures should minimally wrap Linux or UNIX system calls to
   126    173    * expose to the Tcl-level.  Where possible accept symbolic names rather
   127    174    * than numeric values (.e.g, list of values to OR together to get flags).
................................................................................
  1411   1458   	return(TCL_OK);
  1412   1459   }
  1413   1460   
  1414   1461   static int tclsystem_ifconfig(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
  1415   1462   	int sock_v4, sock_v6, sock;
  1416   1463   	int retval = TCL_ERROR;
  1417   1464   
  1418         -	/*
  1419         -	 * Check for IPv4 support before trying to create an IPv4 socket to
  1420         -	 * avoid demand-loading IPv4 (XXX: TODO)
  1421         -	 */
  1422         -	sock_v4 = socket(AF_INET, SOCK_DGRAM, 0);
  1423         -
  1424         -	/*
  1425         -	 * Check for IPv6 support before trying to create an IPv6 socket to
  1426         -	 * avoid demand-loading IPv6 (XXX: TODO)
  1427         -	 */
  1428         -	sock_v6 = socket(AF_INET6, SOCK_DGRAM, 0);
  1429         -
  1430         -	/* Pick a socket to query for the interface list */
  1431         -	if (sock_v4 == -1 && sock_v6 == -1) {
  1432         -		/* Report failure */
         1465  +	sock = tclsystem_internal_getsock(&sock_v4, &sock_v6);
         1466  +	if (sock == -1) {
  1433   1467   		Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to create socket", -1));
  1434   1468   
  1435   1469   		return(TCL_ERROR);
  1436   1470   	}
  1437   1471   
  1438         -	if (sock_v6 != -1) {
  1439         -		sock = sock_v6;
  1440         -	} else {
  1441         -		sock = sock_v4;
  1442         -	}
  1443         -
  1444   1472   	switch (objc) {
  1445   1473   		case 0:
  1446   1474   		case 1: /* No arguments, list all interfaces */
  1447   1475   			retval = tclsystem_ifconfig_list(cd, interp, objc, objv, sock);
  1448   1476   
  1449   1477   			break;
  1450   1478   		case 2: /* One argument, give information about the interface */
................................................................................
  1656   1684   	return(TCL_OK);
  1657   1685   }
  1658   1686   
  1659   1687   static int tclsystem_route(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
  1660   1688   	int sock_v4, sock_v6, sock;
  1661   1689   	int retval = TCL_ERROR;
  1662   1690   
  1663         -	/*
  1664         -	 * Check for IPv4 support before trying to create an IPv4 socket to
  1665         -	 * avoid demand-loading IPv4 (XXX: TODO)
  1666         -	 */
  1667         -	sock_v4 = socket(AF_INET, SOCK_DGRAM, 0);
  1668         -
  1669         -	/*
  1670         -	 * Check for IPv6 support before trying to create an IPv6 socket to
  1671         -	 * avoid demand-loading IPv6 (XXX: TODO)
  1672         -	 */
  1673         -	sock_v6 = socket(AF_INET6, SOCK_DGRAM, 0);
  1674         -
  1675         -	/* Pick a socket to query for the interface list */
  1676         -	if (sock_v4 == -1 && sock_v6 == -1) {
  1677         -		/* Report failure */
         1691  +	sock = tclsystem_internal_getsock(&sock_v4, &sock_v6);
         1692  +	if (sock == -1) {
  1678   1693   		Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to create socket", -1));
  1679   1694   
  1680   1695   		return(TCL_ERROR);
  1681   1696   	}
  1682   1697   
  1683         -	if (sock_v6 != -1) {
  1684         -		sock = sock_v6;
  1685         -	} else {
  1686         -		sock = sock_v4;
  1687         -	}
  1688         -
  1689   1698   	switch (objc) {
  1690   1699   		case 0:
  1691   1700   		case 1: /* No arguments, list all interfaces */
  1692   1701   			retval = tclsystem_route_list(cd, interp, objc, objv, sock_v4, sock_v6);
  1693   1702   
  1694   1703   			break;
  1695   1704   		default:
  1696   1705   			/* Otherwise, modify routes */
  1697   1706   			retval = tclsystem_route_conf(cd, interp, objc, objv, sock_v4, sock_v6);
  1698   1707   
         1708  +			break;
         1709  +	}
         1710  +
         1711  +	/* Cleanup */
         1712  +	if (sock_v4 != -1) {
         1713  +		close(sock_v4);
         1714  +	}
         1715  +
         1716  +	if (sock_v6 != -1) {
         1717  +		close(sock_v6);
         1718  +	}
         1719  +
         1720  +	return(retval);
         1721  +}
         1722  +
         1723  +static int tclsystem_brctl_list(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock) {
         1724  +	Tcl_SetObjResult(interp, Tcl_NewStringObj("not implemented", -1));
         1725  +
         1726  +	return(TCL_ERROR);
         1727  +}
         1728  +
         1729  +static int tclsystem_brctl_conf(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int sock) {
         1730  +	Tcl_Obj *operation_obj, *bridge_name_obj, *interface_name_obj;
         1731  +	unsigned long arg[4];
         1732  +	struct ifreq ifr;
         1733  +	int ioctl_ret, ioctl_id;
         1734  +	int add = 0;
         1735  +
         1736  +	/* Determine operation */
         1737  +	operation_obj = objv[1];
         1738  +	switch (tclsystem_internal_simplehash_obj(operation_obj)) {
         1739  +		case 0x1c993272: /* addbr */
         1740  +			add = 1;
         1741  +		case 0x4cbb3272: /* delbr */
         1742  +			if (objc != 3) {
         1743  +				if (add) {
         1744  +					Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::brctl addbr bridge\"", -1));
         1745  +				} else {
         1746  +					Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::brctl delbr bridge\"", -1));
         1747  +				}
         1748  +
         1749  +				return(TCL_ERROR);
         1750  +			}
         1751  +
         1752  +			bridge_name_obj = objv[2];
         1753  +
         1754  +			if (add) {
         1755  +				arg[0] = BRCTL_ADD_BRIDGE;
         1756  +			} else {
         1757  +				arg[0] = BRCTL_DEL_BRIDGE;
         1758  +			}
         1759  +
         1760  +			arg[1] = (unsigned long) Tcl_GetString(bridge_name_obj);
         1761  +			arg[2] = 0;
         1762  +
         1763  +			ioctl_ret = ioctl(sock, SIOCGIFBR, &arg); 
         1764  +
         1765  +			break;
         1766  +		case 0x1C9937E6: /* addif */
         1767  +			add = 1;
         1768  +		case 0x4cbb37e6: /* delif */
         1769  +			if (objc != 4) {
         1770  +				if (add) {
         1771  +					Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::brctl addif bridge interface\"", -1));
         1772  +				} else {
         1773  +					Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args: should be \"::system::syscall::brctl delif bridge interface\"", -1));
         1774  +				}
         1775  +
         1776  +				return(TCL_ERROR);
         1777  +			}
         1778  +
         1779  +			if (add) {
         1780  +				ioctl_id = SIOCBRADDIF;
         1781  +			} else {
         1782  +				ioctl_id = SIOCBRDELIF;
         1783  +			}
         1784  +
         1785  +			bridge_name_obj = objv[2];
         1786  +			interface_name_obj = objv[3];
         1787  +
         1788  +			memset(&ifr, 0, sizeof(ifr));
         1789  +			snprintf(ifr.ifr_name, IFNAMSIZ, "%s", Tcl_GetString(interface_name_obj));
         1790  +
         1791  +			ioctl_ret = ioctl(sock, SIOCGIFINDEX, (void *) &ifr);
         1792  +			if (ioctl_ret == 0) {
         1793  +				snprintf(ifr.ifr_name, IFNAMSIZ, "%s", Tcl_GetString(bridge_name_obj));
         1794  +				ioctl_ret = ioctl(sock, ioctl_id, (void *) &ifr);
         1795  +			}
         1796  +
         1797  +			break;
         1798  +	}
         1799  +
         1800  +	if (ioctl_ret < 0) {
         1801  +		Tcl_SetObjResult(interp, Tcl_NewStringObj(strerror(errno), -1));
         1802  +
         1803  +		return(TCL_ERROR);
         1804  +	}
         1805  +
         1806  +	return(TCL_OK);
         1807  +}
         1808  +
         1809  +static int tclsystem_brctl(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
         1810  +	int sock_v4, sock_v6, sock;
         1811  +	int retval = TCL_ERROR;
         1812  +
         1813  +	sock = tclsystem_internal_getsock(&sock_v4, &sock_v6);
         1814  +	if (sock == -1) {
         1815  +		Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to create socket", -1));
         1816  +
         1817  +		return(TCL_ERROR);
         1818  +	}
         1819  +
         1820  +	switch (objc) {
         1821  +		case 0:
         1822  +		case 1: /* No arguments, list all bridges */
         1823  +			retval = tclsystem_brctl_list(cd, interp, objc, objv, sock);
         1824  +
         1825  +			break;
         1826  +		default:
         1827  +			/* Otherwise, modify routes */
         1828  +			retval = tclsystem_brctl_conf(cd, interp, objc, objv, sock);
         1829  +
  1699   1830   			break;
  1700   1831   	}
  1701   1832   
  1702   1833   	/* Cleanup */
  1703   1834   	if (sock_v4 != -1) {
  1704   1835   		close(sock_v4);
  1705   1836   	}
................................................................................
  1746   1877   	Tcl_CreateObjCommand(interp, "::system::syscall::kill", tclsystem_kill, NULL, NULL);
  1747   1878   	Tcl_CreateObjCommand(interp, "::system::syscall::ps", tclsystem_ps, NULL, NULL);
  1748   1879   	Tcl_CreateObjCommand(interp, "::system::syscall::execve", tclsystem_execve, NULL, NULL);
  1749   1880   
  1750   1881   	/* Network related commands */
  1751   1882   	Tcl_CreateObjCommand(interp, "::system::syscall::ifconfig", tclsystem_ifconfig, NULL, NULL);
  1752   1883   	Tcl_CreateObjCommand(interp, "::system::syscall::route", tclsystem_route, NULL, NULL);
         1884  +	Tcl_CreateObjCommand(interp, "::system::syscall::brctl", tclsystem_brctl, NULL, NULL);
  1753   1885   
  1754   1886   	/* Internal functions */
  1755   1887   	Tcl_CreateObjCommand(interp, "::system::internal::hash", tclsystem_internalproc_simplehash, NULL, NULL);
  1756   1888   
  1757   1889   	/* Define constants */
  1758   1890   	/** Create parent namespace **/
  1759   1891   	Tcl_CreateNamespace(interp, "::system::const", NULL, NULL);