summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErmal Luçi <eri@pfsense.org>2009-03-28 09:06:31 +0000
committerErmal Luçi <eri@pfsense.org>2009-03-28 09:08:31 +0000
commit5f1e1d2617c211ac680a6f56a202d504cdcb6991 (patch)
treee9fbbd60808b8085e85f2ebcb5128ae7fba8ba35
parentfa60d6f768958df2279cc4ebbf2210ae419dddcd (diff)
downloadpfsense-5f1e1d2617c211ac680a6f56a202d504cdcb6991.zip
pfsense-5f1e1d2617c211ac680a6f56a202d504cdcb6991.tar.gz
Bring in support for QinQ. At this time it is limited to only 2 levels.
-rw-r--r--etc/inc/interfaces.inc163
-rw-r--r--etc/inc/xmlparse.inc2
-rwxr-xr-xusr/local/www/interfaces_assign.php11
-rw-r--r--usr/local/www/interfaces_bridge.php11
-rw-r--r--usr/local/www/interfaces_gif.php11
-rw-r--r--usr/local/www/interfaces_gre.php11
-rwxr-xr-xusr/local/www/interfaces_groups.php11
-rw-r--r--usr/local/www/interfaces_lagg.php11
-rw-r--r--usr/local/www/interfaces_ppp.php11
-rwxr-xr-xusr/local/www/interfaces_vlan.php11
-rwxr-xr-xusr/local/www/interfaces_vlan_edit.php4
11 files changed, 208 insertions, 49 deletions
diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc
index fadb3eb..382066b 100644
--- a/etc/inc/interfaces.inc
+++ b/etc/inc/interfaces.inc
@@ -57,21 +57,27 @@ function interfaces_loopback_configure() {
function interfaces_vlan_configure() {
global $config;
- $i = 0;
if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
foreach ($config['vlans']['vlan'] as $vlan) {
if(empty($vlan['vlanif']))
- $vlan['vlanif'] = "vlan{$i}";
+ $vlan['vlanif'] = "vlan{$vlan['tag']}";
/* XXX: Maybe we should report any errors?! */
- interface_vlan_configure($vlan['if'], $vlan['tag'], $vlan['vlanif']);
- $i++;
+ interface_vlan_configure($vlan);
}
}
}
-function interface_vlan_configure($if, $tag, $vlanif = "") {
+function interface_vlan_configure($vlan) {
global $config, $g;
+ if (!is_array($vlan)) {
+ log_error("VLAN: called with wrong options. Problems with config!");
+ return;
+ }
+ $if = $vlan['if'];
+ $vlanif = empty($vlan['vlanif']) ? "vlan{$vlan['tag']}" : $vlan['vlanif'];
+ $tag = $vlan['tag'];
+
if(empty($if)) {
log_error("interface_vlan_confgure called with if undefined.");
return;
@@ -114,7 +120,7 @@ function interface_vlan_configure($if, $tag, $vlanif = "") {
*/
foreach($config['interfaces'] as $interfaces) {
if($interfaces['if'] == $if && $interfaces['spoofmac']) {
- mwexec("/sbin/ifconfig " . escapeshellarg($if) .
+ mwexec("/sbin/ifconfig " . escapeshellarg($vlanif) .
" link " . escapeshellarg($interfaces['spoofmac']));
}
}
@@ -125,6 +131,149 @@ function interface_vlan_configure($if, $tag, $vlanif = "") {
return $vlanif;
}
+function interface_qinq_configure($vlan) {
+ global $config, $g;
+
+ if (!is_array($vlan)) {
+ log_error("QinQ compat VLAN: called with wrong options. Problems with config!");
+ return;
+ }
+
+ $if = $vlan['if'];
+ $vlanif = empty($vlan['vlanif']) ? "vlan{$vlan['tag']}" : $vlan['vlanif'];
+ $tag = $vlan['tag'];
+ if(empty($if)) {
+ log_error("interface_qinq_confgure called with if undefined.");
+ return;
+ }
+
+ /* make sure the parent is converted to ng_vlan(4) and is up */
+ interfaces_bring_up($if);
+ /* Since we are going to add ng_vlan(4) try to enable all that hardware supports. */
+ mwexec("/sbin/ifconfig {$if} vlanhwtag");
+ mwexec("/sbin/ifconfig {$if} vlanmtu");
+
+ if ($g['booting'] || !(empty($vlanif))) {
+ /* before destroying, see if CARP is in use
+ If an interface containing an active CARP IP is destroyed,
+ the CARP interface will hang in INIT and must be destroyed
+ itself before it will function again (which causes a panic).
+ Trying to configure a CARP interface stuck in INIT will
+ cause a panic as well. -cmb
+ */
+ $carpcount = find_number_of_needed_carp_interfaces();
+ /* will continue to destroy VLANs where CARP is not in use
+ to retain previous behavior and avoid regressions */
+ if($carpcount < 1)
+ mwexec("/usr/sbin/ngctl shutdown {$if}qinq:");
+ exec("/usr/sbin/ngctl msg {$if}qinq: gettable", $result);
+ if (empty($result)) {
+ mwexec("/usr/sbin/ngctl mkpeer {$if}: vlan lower downstream");
+ mwexec("/usr/sbin/ngctl name {$if}:lower {$if}qinq");
+ mwexec("/usr/sbin/ngctl connect {$if}: {$if}qinq: upper nomatch");
+ }
+ } else {
+ mwexec("/usr/sbin/ngctl mkpeer {$if}: vlan lower downstream");
+ mwexec("/usr/sbin/ngctl name {$if}:lower {$if}qinq");
+ mwexec("/usr/sbin/ngctl connect {$if}: {$if}qinq: upper nomatch");
+ }
+
+ if (!$g['booting']) {
+ if (!empty($vlan['members'])) {
+ $members = explode(" ", $vlan['members']);
+ foreach ($members as $qtag) {
+ mwexec("/usr/sbin/ngctl shutdown {$vlanif}h{$qtag}:");
+ }
+ }
+ mwexec("/usr/sbin/ngctl shutdown vlanh{$tag}:");
+ }
+ mwexec("/usr/sbin/ngctl mkpeer {$if}qinq: eiface vlan{$tag} ether");
+ mwexec("/usr/sbin/ngctl name {$if}qinq:vlan{$tag} vlanh{$tag}");
+ mwexec("/usr/sbin/ngctl msg {$if}qinq: addfilter '{ vlan={$tag} hook=\"vlan{$tag}\" }'");
+ $result2 = array();
+ exec("/usr/sbin/ngctl msg vlanh{$tag}: getifname | /usr/bin/awk '/ngeth/ { print \$2 }' | sed s/\\\"//g", $result2);
+ mwexec("/usr/sbin/ngctl name {$result2[0]}: eth{$vlanif}");
+ mwexec("/usr/sbin/ngctl msg vlanh{$tag}: setifname \\\"{$vlanif}\\\"");
+ sleep(1);
+ mwexec("/sbin/ifconfig {$vlanif} link " . escapeshellarg(get_interface_mac($if)));
+
+ interfaces_bring_up($vlanif);
+
+ /* invalidate interface cache */
+ get_interface_arr(true);
+
+ if (!stristr($if, "vlan"))
+ mwexec("/sbin/ifconfig {$if} promisc");
+
+ if (!empty($vlan['members'])) {
+ $members = explode(" ", $vlan['members']);
+ foreach ($members as $qtag) {
+ $qinq = array();
+ $qinq['tag'] = $qtag;
+ $qinq['if'] = $vlanif;
+ interface_qinq2_configure($qinq);
+ }
+ }
+ interfaces_bring_up($if);
+
+ return $vlanif;
+}
+
+function interfaces_qinq_configure() {
+ global $config;
+ if (is_array($config['qinqs']['qinqentry']) && count($config['qinqs']['qinqentry'])) {
+ foreach ($config['qinqs']['qinqentry'] as $qinq) {
+ /* XXX: Maybe we should report any errors?! */
+ interface_qinq_configure($qinq);
+ }
+ }
+}
+
+function interface_qinq2_configure($qinq) {
+ global $config, $g;
+
+ if (!is_array($qinq)) {
+ log_error("QinQ compat VLAN: called with wrong options. Problems with config!");
+ echo "ERROR";
+ return;
+ }
+
+ $if = $qinq['if'];
+ $tag = $qinq['tag'];
+ $vlanif = "{$if}.{$tag}";
+ if(empty($if)) {
+ log_error("interface_qinq_confgure called with if undefined.");
+ return;
+ }
+
+ $result = array();
+ exec("/usr/sbin/ngctl msg {$if}qinq: gettable", $result);
+ if (empty($result)) {
+ mwexec("/usr/sbin/ngctl mkpeer eth{$if}: vlan lower downstream");
+ mwexec("/usr/sbin/ngctl name eth{$if}:lower {$if}qinq ");
+ mwexec("/usr/sbin/ngctl connect eth{$if}: {$if}qinq: upper nomatch");
+ }
+
+ mwexec("/usr/sbin/ngctl shutdown ${if}h{$tag}:");
+ mwexec("/usr/sbin/ngctl mkpeer {$if}qinq: eiface {$if}{$tag} ether");
+ mwexec("/usr/sbin/ngctl name {$if}qinq:{$if}{$tag} {$if}h{$tag}");
+ mwexec("/usr/sbin/ngctl msg {$if}qinq: addfilter '{ vlan={$tag} hook=\"{$if}{$tag}\" }'");
+ $result2 = array();
+ exec("/usr/sbin/ngctl msg {$if}h{$tag}: getifname | /usr/bin/awk '/ngeth/ { print \$2 }' | sed s/\\\"//g", $result2);
+ mwexec("/usr/sbin/ngctl name {$result2[0]}: eth{$if}_{$tag}");
+ mwexec("/usr/sbin/ngctl msg {$if}h{$tag}: setifname \\\"{$vlanif}\\\"");
+ sleep(1);
+ mwexec("/sbin/ifconfig {$vlanif} link " . escapeshellarg(get_interface_mac($if)));
+ interfaces_bring_up($vlanif);
+
+ /* invalidate interface cache */
+ get_interface_arr(true);
+
+ interfaces_bring_up($if);
+
+ return $vlanif;
+}
+
function interfaces_bridge_configure() {
global $config;
@@ -491,6 +640,8 @@ function interfaces_configure() {
/* set up VLAN virtual interfaces */
interfaces_vlan_configure();
+ interfaces_qinq_configure();
+
/* Set up PPP interfaces */
interfaces_ppp_configure();
diff --git a/etc/inc/xmlparse.inc b/etc/inc/xmlparse.inc
index 423679e..574e8f1 100644
--- a/etc/inc/xmlparse.inc
+++ b/etc/inc/xmlparse.inc
@@ -44,7 +44,7 @@ function listtags() {
"lbaction lbpool l7rules lbprotocol ".
"member menu tab mobilekey monitor_type mount ntpserver onetoone ".
"openvpn-server openvpn-client openvpn-csc " .
- "option ppp package passthrumac phase1 phase2 priv proxyarpnet queue ".
+ "option ppp package passthrumac phase1 phase2 priv proxyarpnet qinqentry queue ".
"pages pipe route row rrddatafile rule schedule service servernat servers ".
"serversdisabled earlyshellcmd shellcmd staticmap subqueue timerange ".
"tunnel user vip virtual_server vlan winsserver wolentry widget "
diff --git a/usr/local/www/interfaces_assign.php b/usr/local/www/interfaces_assign.php
index 00f58aa..ceb6069 100755
--- a/usr/local/www/interfaces_assign.php
+++ b/usr/local/www/interfaces_assign.php
@@ -318,11 +318,12 @@ if(file_exists("/var/run/interface_mismatch_reboot_needed"))
$tab_array[0] = array("Interface assignments", true, "interfaces_assign.php");
$tab_array[1] = array("Interface Groups", false, "interfaces_groups.php");
$tab_array[2] = array("VLANs", false, "interfaces_vlan.php");
- $tab_array[3] = array("PPP", false, "interfaces_ppp.php");
- $tab_array[4] = array("GRE", false, "interfaces_gre.php");
- $tab_array[5] = array("GIF", false, "interfaces_gif.php");
- $tab_array[6] = array("Bridges", false, "interfaces_bridge.php");
- $tab_array[7] = array("LAGG", false, "interfaces_lagg.php");
+ $tab_array[3] = array("QinQs", false, "interfaces_qinq.php");
+ $tab_array[4] = array("PPP", false, "interfaces_ppp.php");
+ $tab_array[5] = array("GRE", false, "interfaces_gre.php");
+ $tab_array[6] = array("GIF", false, "interfaces_gif.php");
+ $tab_array[7] = array("Bridges", false, "interfaces_bridge.php");
+ $tab_array[8] = array("LAGG", false, "interfaces_lagg.php");
display_top_tabs($tab_array);
?>
</td></tr>
diff --git a/usr/local/www/interfaces_bridge.php b/usr/local/www/interfaces_bridge.php
index 934dbd3..c7e4753 100644
--- a/usr/local/www/interfaces_bridge.php
+++ b/usr/local/www/interfaces_bridge.php
@@ -78,11 +78,12 @@ include("head.inc");
$tab_array[0] = array("Interface assignments", false, "interfaces_assign.php");
$tab_array[1] = array("Interface Groups", false, "interfaces_groups.php");
$tab_array[2] = array("VLANs", false, "interfaces_vlan.php");
- $tab_array[3] = array("PPP", false, "interfaces_ppp.php");
- $tab_array[4] = array("GRE", false, "interfaces_gre.php");
- $tab_array[5] = array("GIF", false, "interfaces_gif.php");
- $tab_array[6] = array("Bridges", true, "interfaces_bridge.php");
- $tab_array[7] = array("LAGG", false, "interfaces_lagg.php");
+ $tab_array[3] = array("QinQs", false, "interfaces_qinq.php");
+ $tab_array[4] = array("PPP", false, "interfaces_ppp.php");
+ $tab_array[5] = array("GRE", false, "interfaces_gre.php");
+ $tab_array[6] = array("GIF", false, "interfaces_gif.php");
+ $tab_array[7] = array("Bridges", true, "interfaces_bridge.php");
+ $tab_array[8] = array("LAGG", false, "interfaces_lagg.php");
display_top_tabs($tab_array);
?>
</td></tr>
diff --git a/usr/local/www/interfaces_gif.php b/usr/local/www/interfaces_gif.php
index 9e01b33..1407a6c 100644
--- a/usr/local/www/interfaces_gif.php
+++ b/usr/local/www/interfaces_gif.php
@@ -86,11 +86,12 @@ include("head.inc");
$tab_array[0] = array("Interface assignments", false, "interfaces_assign.php");
$tab_array[1] = array("Interface Groups", false, "interfaces_groups.php");
$tab_array[2] = array("VLANs", false, "interfaces_vlan.php");
- $tab_array[3] = array("PPP", false, "interfaces_ppp.php");
- $tab_array[4] = array("GRE", false, "interfaces_gre.php");
- $tab_array[5] = array("GIF", true, "interfaces_gif.php");
- $tab_array[6] = array("Bridges", false, "interfaces_bridge.php");
- $tab_array[7] = array("LAGG", false, "interfaces_lagg.php");
+ $tab_array[3] = array("QinQs", false, "interfaces_qinq.php");
+ $tab_array[4] = array("PPP", false, "interfaces_ppp.php");
+ $tab_array[5] = array("GRE", false, "interfaces_gre.php");
+ $tab_array[6] = array("GIF", true, "interfaces_gif.php");
+ $tab_array[7] = array("Bridges", false, "interfaces_bridge.php");
+ $tab_array[8] = array("LAGG", false, "interfaces_lagg.php");
display_top_tabs($tab_array);
?>
</td></tr>
diff --git a/usr/local/www/interfaces_gre.php b/usr/local/www/interfaces_gre.php
index 85540e5..79a43e2 100644
--- a/usr/local/www/interfaces_gre.php
+++ b/usr/local/www/interfaces_gre.php
@@ -86,11 +86,12 @@ include("head.inc");
$tab_array[0] = array("Interface assignments", false, "interfaces_assign.php");
$tab_array[1] = array("Interface Groups", false, "interfaces_groups.php");
$tab_array[2] = array("VLANs", false, "interfaces_vlan.php");
- $tab_array[3] = array("PPP", false, "interfaces_ppp.php");
- $tab_array[4] = array("GRE", true, "interfaces_gre.php");
- $tab_array[5] = array("GIF", false, "interfaces_gif.php");
- $tab_array[6] = array("Bridges", false, "interfaces_bridge.php");
- $tab_array[7] = array("LAGG", false, "interfaces_lagg.php");
+ $tab_array[3] = array("QinQs", false, "interfaces_qinq.php");
+ $tab_array[4] = array("PPP", false, "interfaces_ppp.php");
+ $tab_array[5] = array("GRE", true, "interfaces_gre.php");
+ $tab_array[6] = array("GIF", false, "interfaces_gif.php");
+ $tab_array[7] = array("Bridges", false, "interfaces_bridge.php");
+ $tab_array[8] = array("LAGG", false, "interfaces_lagg.php");
display_top_tabs($tab_array);
?>
</td></tr>
diff --git a/usr/local/www/interfaces_groups.php b/usr/local/www/interfaces_groups.php
index a14b3a6..2cec361 100755
--- a/usr/local/www/interfaces_groups.php
+++ b/usr/local/www/interfaces_groups.php
@@ -71,11 +71,12 @@ include("head.inc");
$tab_array[0] = array("Interface assignments", false, "interfaces_assign.php");
$tab_array[1] = array("Interface Groups", true, "interfaces_groups.php");
$tab_array[2] = array("VLANs", false, "interfaces_vlan.php");
- $tab_array[3] = array("PPP", false, "interfaces_ppp.php");
- $tab_array[4] = array("GRE", false, "interfaces_gre.php");
- $tab_array[5] = array("GIF", false, "interfaces_gif.php");
- $tab_array[6] = array("Bridges", false, "interfaces_bridge.php");
- $tab_array[7] = array("LAGG", false, "interfaces_lagg.php");
+ $tab_array[3] = array("QinQs", false, "interfaces_qinq.php");
+ $tab_array[4] = array("PPP", false, "interfaces_ppp.php");
+ $tab_array[5] = array("GRE", false, "interfaces_gre.php");
+ $tab_array[6] = array("GIF", false, "interfaces_gif.php");
+ $tab_array[7] = array("Bridges", false, "interfaces_bridge.php");
+ $tab_array[8] = array("LAGG", false, "interfaces_lagg.php");
display_top_tabs($tab_array);
?>
</td></tr>
diff --git a/usr/local/www/interfaces_lagg.php b/usr/local/www/interfaces_lagg.php
index fd46c9c..840f1c6 100644
--- a/usr/local/www/interfaces_lagg.php
+++ b/usr/local/www/interfaces_lagg.php
@@ -78,11 +78,12 @@ include("head.inc");
$tab_array[0] = array("Interface assignments", false, "interfaces_assign.php");
$tab_array[1] = array("Interface Groups", false, "interfaces_groups.php");
$tab_array[2] = array("VLANs", false, "interfaces_vlan.php");
- $tab_array[3] = array("PPP", false, "interfaces_ppp.php");
- $tab_array[4] = array("GRE", false, "interfaces_gre.php");
- $tab_array[5] = array("GIF", false, "interfaces_gif.php");
- $tab_array[6] = array("Bridges", false, "interfaces_bridge.php");
- $tab_array[7] = array("LAGG", true, "interfaces_lagg.php");
+ $tab_array[3] = array("QinQs", false, "interfaces_qinq.php");
+ $tab_array[4] = array("PPP", false, "interfaces_ppp.php");
+ $tab_array[5] = array("GRE", false, "interfaces_gre.php");
+ $tab_array[6] = array("GIF", false, "interfaces_gif.php");
+ $tab_array[7] = array("Bridges", false, "interfaces_bridge.php");
+ $tab_array[8] = array("LAGG", true, "interfaces_lagg.php");
display_top_tabs($tab_array);
?>
</td></tr>
diff --git a/usr/local/www/interfaces_ppp.php b/usr/local/www/interfaces_ppp.php
index b258762..c698cb6 100644
--- a/usr/local/www/interfaces_ppp.php
+++ b/usr/local/www/interfaces_ppp.php
@@ -100,11 +100,12 @@ include("head.inc");
$tab_array[0] = array("Interface assignments", false, "interfaces_assign.php");
$tab_array[1] = array("Interface Groups", false, "interfaces_groups.php");
$tab_array[2] = array("VLANs", false, "interfaces_vlan.php");
- $tab_array[3] = array("PPP", true, "interfaces_ppp.php");
- $tab_array[4] = array("GRE", false, "interfaces_gre.php");
- $tab_array[5] = array("GIF", false, "interfaces_gif.php");
- $tab_array[6] = array("Bridges", false, "interfaces_bridge.php");
- $tab_array[7] = array("LAGG", false, "interfaces_lagg.php");
+ $tab_array[3] = array("QinQs", false, "interfaces_qinq.php");
+ $tab_array[4] = array("PPP", true, "interfaces_ppp.php");
+ $tab_array[5] = array("GRE", false, "interfaces_gre.php");
+ $tab_array[6] = array("GIF", false, "interfaces_gif.php");
+ $tab_array[7] = array("Bridges", false, "interfaces_bridge.php");
+ $tab_array[8] = array("LAGG", false, "interfaces_lagg.php");
display_top_tabs($tab_array);
?>
</td></tr>
diff --git a/usr/local/www/interfaces_vlan.php b/usr/local/www/interfaces_vlan.php
index f8bf3f3..7b9569d 100755
--- a/usr/local/www/interfaces_vlan.php
+++ b/usr/local/www/interfaces_vlan.php
@@ -87,11 +87,12 @@ include("head.inc");
$tab_array[0] = array("Interface assignments", false, "interfaces_assign.php");
$tab_array[1] = array("Interface Groups", false, "interfaces_groups.php");
$tab_array[2] = array("VLANs", true, "interfaces_vlan.php");
- $tab_array[3] = array("PPP", false, "interfaces_ppp.php");
- $tab_array[4] = array("GRE", false, "interfaces_gre.php");
- $tab_array[5] = array("GIF", false, "interfaces_gif.php");
- $tab_array[6] = array("Bridges", false, "interfaces_bridge.php");
- $tab_array[7] = array("LAGG", false, "interfaces_lagg.php");
+ $tab_array[3] = array("QinQs", false, "interfaces_qinq.php");
+ $tab_array[4] = array("PPP", false, "interfaces_ppp.php");
+ $tab_array[5] = array("GRE", false, "interfaces_gre.php");
+ $tab_array[6] = array("GIF", false, "interfaces_gif.php");
+ $tab_array[7] = array("Bridges", false, "interfaces_bridge.php");
+ $tab_array[8] = array("LAGG", false, "interfaces_lagg.php");
display_top_tabs($tab_array);
?>
</td></tr>
diff --git a/usr/local/www/interfaces_vlan_edit.php b/usr/local/www/interfaces_vlan_edit.php
index 72224c5..85ed1f9 100755
--- a/usr/local/www/interfaces_vlan_edit.php
+++ b/usr/local/www/interfaces_vlan_edit.php
@@ -93,9 +93,9 @@ if ($_POST) {
$vlan['if'] = $_POST['if'];
$vlan['tag'] = $_POST['tag'];
$vlan['descr'] = $_POST['descr'];
- $vlan['vlanif'] = $_POST['vlanif'];
+ $vlan['vlanif'] = "vlan{$_POST['tag']}";
- $vlan['vlanif'] = interface_vlan_configure($vlan['if'], $vlan['tag'], "vlan" . $vlan['tag']);
+ $vlan['vlanif'] = interface_vlan_configure($vlan);
if ($vlan['vlanif'] == "" || !stristr($vlan['vlanif'], "vlan"))
$input_errors[] = "Error occured creating interface, please retry.";
else {
OpenPOWER on IntegriCloud